Set up an easily-viewed shared task list for the group. Assign tasks to your fellow group members, or let them claim their own tasks to make it clear what everyone is working on!
+
+
+
+
+
+
+
Group Management Controls
+
Use task approvals to verify that a task that was really completed, add Group Managers to share responsibilities, and enjoy a private group chat for all team members.
+
+
+
+
+
+
+
In-Game Benefits
+
Group members get an exclusive Jackalope Mount, as well as full subscription benefits, including special monthly equipment sets and the ability to buy gems with gold.
+
+
+
+ 1-7 for normal contributors, 8 for moderators, 9 for staff. This determines which items, pets, and mounts are available, and name-tag coloring. Tiers 8 and 9 are automatically given admin status.
+ More details (1-7),
+ more details (8-9)
+
+
+
+
+
+
+
+
+
+
+
+ '{{ hero.balance }}' is in USD,
+ not in Gems. E.g., if this number is 1, it means 4 Gems. Only use this option when manually granting Gems to players, don't use it when granting contributor tiers. Contrib tiers will automatically add Gems.
+
+
+
+
+
+
+ Update Item
+
+
+
+
+ Enter the
+ item path. E.g.,
+ items.pets.BearCub-Zombie or
+ items.gear.owned.head_special_0 or
+ items.gear.equipped.head. You can find all the item paths below.
+
+
+
+
+ Enter the
+ item value. E.g.,
+ 5 or
+ false or
+ head_warrior_3. All values are listed in the All Item Paths section below.
+
+
+ Last updated July 27, 2015
+
+ (Corrected grammar errors and updated company name)
+
+
+
+
+ PLEASE READ THIS PRIVACY POLICY CAREFULLY.
+ By accessing or otherwise using habitica.com or any sub domains thereto ('the Sites'),
+ or using a habitica.com or Habitica application on a mobile device ('the Applications'),
+ you agree to be bound contractually by this Privacy Policy. Individually
+ or collectively, the Applications and the Sites may be referred to as
+ the 'Services.'
+
+
+ To review material modifications and their effective dates scroll
+ to the bottom of the page.
+
+
+
+ 1. Privacy Statement; Collection of Personal
+ Information.
+
+ 1.1 HabitRPG, Inc. owns and operates this business. All
+ references to 'we', 'us', shall be construed to mean HabitRPG, Inc..
+
+
+ 1.2 We understand that visitors to this website are concerned
+ about the privacy of information. The following describes our privacy
+ policy regarding information, including personal information, that we
+ collect through this website.
+
+
+ 2. Modification of Privacy Policy.
+ We reserve the right to modify this Privacy Policy at any time,
+ and without prior notice, by posting an amended Privacy Policy that is
+ always accessible by clicking on the 'Privacy Policy' link on this
+ site's home page. Your continued use of this site indicates your
+ acceptance of the amended Privacy Policy. You should check the Privacy
+ Policy through this link periodically for modifications by clicking on
+ the link provided near the top of the Privacy Policy for a listing of
+ material modifications and their effective dates. Regarding personal
+ information, if any modifications are materially less restrictive on our
+ use or disclosure of the personal information previously disclosed by
+ you, we will obtain your consent before implementing such revisions with
+ respect to such information.
+
+
+ 3. Collection of Anonymous, Passive Information.
+ We reserve the right to monitor your use of the services. As you
+ navigate through the services, certain anonymous information may be
+ passively collected (that is, gathered without your actively providing
+ the information) using various technologies, such as cookies, Internet
+ tags or web beacons, and navigational data collection (log files, server
+ logs, clickstream). The following is a listing and a brief explanation
+ of passive information collection methodologies which we may use from
+ time to time to better understand how the Services are being used.
+
+
+ 3.1 A 'cookie' is a text file that this site sends to your
+ browser in the form of a text file The information generated by the
+ cookie about your use of this site (including your IP address) will be
+ transmitted to and stored. Most browsers automatically accept cookies,
+ but they usually can be modified to decline cookies if you prefer;
+ however, certain features of this site might not work without cookies.
+
+
+ 3.2 'Session' cookies are temporary bits of information that are
+ used to improve navigation, block visitors from providing information
+ where inappropriate (the Services 'remembers' previous entries of age or
+ country of origin that were outside the specified parameters and blocks
+ subsequent changes), and collect aggregate statistical information on
+ the Services. They are erased once you exit your Web browser or
+ otherwise turn off your computer.
+
+
+ 3.3 'Persistent' cookies are more permanent bits of information
+ that are placed on the hard drive of your computer and stay there unless
+ you delete the cookie. Persistent cookies store information on your
+ computer for a number of purposes, such as retrieving certain
+ information you have previously provided, helping to determine what
+ areas of the Services you may find most valuable, and customizing the
+ Services based on your preferences on an ongoing basis. Persistent
+ cookies placed by this site in your computer do not hold personal
+ information.
+
+
+ 3.4 You can set your browser to accept all cookies, to reject all
+ cookies, or to notify you whenever a cookie is offered so that you can
+ decide each time whether to accept it. To learn more about cookies and
+ how to specify your preferences, please search for 'cookie' in the
+ 'Help' portion of your browser.
+
+
+ 3.5 An Internet Protocol (IP) address is a number assigned to
+ your computer by your Internet service provider so you can access the
+ Internet and is generally considered to be non-personally identifiable
+ information, because in most cases an IP address is dynamic (changing
+ each time you connect to the Internet), rather than static (unique to a
+ particular user's computer). The IP address can be used to diagnose
+ problems with a server, report aggregate information, determine the
+ fastest route for your computer to use in connecting to a site, and
+ administer and improve the Services.
+
+
+ 3.6 'Internet tags' (also known as Web Beacons, single-pixel
+ GIFs, clear GIFs, invisible GIFs, and 1-by-1 GIFs) are smaller than
+ cookies and tell the Web site server information such as the IP address
+ and browser type related to the visitor's computer. Tags may be placed
+ both on online advertisements that bring people to the Services and on
+ different pages of the Services. Such tags indicate how many times a
+ page is opened and which information is consulted.
+
+
+ 3.7 'Navigational data' (log files, server logs, and clickstream
+ data) are used for system management, to improve the content of the
+ Services, market research purposes, and to communicate information to
+ visitors.
+
+
+ 4. Use and Sharing of Anonymous, Passive Information.
+ The Services may make full use of passively collected anonymous
+ information, including without limitation the right to use such
+ information to provide better service to Service users, customize the
+ Services based on your preferences, compile and analyze statistics and
+ trends, and otherwise administer and improve the Services for your use. We
+ reserve the right to share this anonymous, passive information in
+ aggregated form.
+
+
+ 5. 3rd Party Behavioral Ads; Google's AdSense Network.
+ 5.1 We reserve the right to use anonymous, passive information
+ about your visits to this and other websites (not including your name,
+ address, email address or telephone number) for purposes of serving our
+ ads and third party ads that are targeted to your interests ('3rd Party
+ Behavioral Ads'). We reserve the right to share anonymous, passive
+ information collected on the services with third parties for purposes of
+ serving 3rd Party Behavioral Ads. These 3rd Party Behavioral Ads do not
+ identify you personally. Instead, they associate your behavioral data on
+ visited sites with your browser, so that the ads your computer sees on
+ this site are more likely to be relevant to your interests. 3rd Party
+ Behavioral Ads require that that you be served with a cookie containing
+ a tracking code. You may refuse the use of cookies by selecting the
+ appropriate settings on your browser; however, please note that if you
+ do this you may not be able to use the full functionality of this site.
+
+
+ 5.2 We reserve the right to participate in Google's AdSense
+ network for purposes of serving 3rd Party Behavioral Ads. Google uses
+ DoubleClick's DART cookie for serving 3rd Party Behavioral Ads over the
+ AdSense network. You may opt out of the use of the DART cookie. For
+ information regarding how to opt out, go to
+ http://www.google.com/privacy_ads.html.
+
+
+ 6. Use of 3rd Party Analytics.
+ We reserve the right to use analytics services provided by
+ third parties. These services use 3rd party cookies to collect
+ anonymous, passive information about your use of this site (see
+ explanation of cookies in Collection of Anonymous, Passive Information
+ above). We use this information for the purpose of evaluating your use
+ of the Services, compiling reports on activity, and providing other
+ services. These web analytics services may also transfer this
+ information to third parties where required to do so by law, or where
+ such third parties process the information on the service's behalf.
+
+
+ 7. Collection of Personal Information; Categories.
+ We will ask you for personal information when you sign up for any
+ specific benefit or purpose that requires registration. Personal
+ information that we collect may vary with each registration, and it may
+ include one or more of the following categories: name, physical
+ address, an email address, phone number, and credit card information
+ including credit card number, expiration date, and billing address,
+ emergency contact information, current medications, allergies, medical
+ insurance information.
+
+
+
+ 8. Use And Sharing of Personal Information: General
+ Policy And Exceptions.
+
+ Our general policy is that we will use your personal information,
+ including combining your personal information with passive information
+ collected from this site, only for: the performance of the services or
+ transaction for which it was given, our private, internal reporting for
+ this site, and security assessments for this site, and we will not
+ share, sell, or rent your personal information to others. The only
+ exceptions to this general policy: (i) are described in the subsections
+ below, and (ii) if you explicitly approve through our site.
+
+
+ 8.1 Affiliates And Service Providers. We reserve the right to
+ provide such information to our affiliates or subsidiaries, or trusted
+ service providers for the purpose of hosting our servers or processing
+ or archiving personal information for us. We require that these parties
+ agree to privacy and security safeguards for this information that are
+ consistent with this Privacy Policy.
+
+
+ 8.2 Acquisition; Bankruptcy. In the event that we are acquired by
+ or merged with a third party entity, we reserve the right to transfer
+ such information as part of such merger, acquisition, sale, or other
+ change of control. In the unlikely event of our bankruptcy, insolvency,
+ reorganization, receivership, or assignment for the benefit of
+ creditors, or the application of laws or equitable principles affecting
+ creditors' rights generally, we reserve the right to transfer such
+ information to protect our rights or as required by law.
+
+
+ 8.3 Enforcement; Legal Process. We reserve the right to transfer
+ such information if we have a good faith belief that access, use,
+ preservation or disclosure of such information is reasonably necessary
+ (i) to satisfy any applicable law, regulation, legal process or
+ enforceable governmental request, or (ii) to investigate or enforce
+ violations of our rights or the security of this site.
+
+
+ 8.4 Miscellaneous. We reserve the right to share personal
+ information with the following additional parties: online organizers
+ using our tools and resellers of our products and services from whose
+ site the sale originated (even though the sale originates at site of the
+ reseller, registration and collection of personal information occurs at
+ this site).
+
+
+
+ 9. Onward Transfer of Personal Information Outside Your
+ Country of Residence.
+
+ Any personal information which we may collect on this site will
+ be stored and processed in our servers located only in the United
+ States. By using this site, if you reside outside the United States, you
+ consent to the transfer of personal information outside your country of
+ residence to the United States.
+
+
+ 10. Security of Personal Information.
+ We follow reasonable and appropriate industry standards to
+ protect your personal information and data. Unfortunately, no data
+ transmission over the Internet or method of data storage can be
+ guaranteed 100% secure. Therefore, while we strive to protect your
+ personal information by following generally accepted industry standards,
+ we cannot ensure or warrant the absolute security of any information you
+ transmit to us or archive at this site.
+
+
+ 11. Changing And Updating Personal Information.
+ Upon request, we will permit you to request or make changes or
+ updates to your personal information for legitimate purposes. We request
+ identification prior to approving such requests. We reserve the right to
+ decline any requests that are unreasonably repetitive or systematic,
+ require unreasonable time or effort of our technical or administrative
+ personnel, or undermine the privacy rights of others. We reserve the
+ right to permit you to access your personal information in any account
+ you establish with this site for purposes of making your own changes or
+ updates, and in such case, instructions for making such changes or
+ updates will be provided where necessary.
+
+
+ 12. Email From This Site; Opt-Out Rights.
+ If you supply us with your e-mail address you may receive
+ periodic messages from us with information specific to the Services and
+ required for the normal functioning of the Services as well as for new
+ products or services or upcoming events. If you prefer not to receive
+ periodic email messages, you may opt-out by following the instructions
+ on the email.
+
+
+ 13. Children's Online Policy.
+ We are committed to preserving online privacy for all of our
+ website visitors, including children. This site is a general audience
+ site. Consistent with the Children's Online Privacy Protection Act
+ (COPPA), we will not knowingly collect any information from, or sell to,
+ children under the age of 13. If you are a parent or guardian who has
+ discovered that your child under the age of 13 has submitted his or her
+ personally identifiable information without your permission or consent,
+ we will remove the information from our active list, at your request. To
+ request the removal of your child's information, please email us at
+ admin@habitica.com and be sure to include in
+ your message the same login information that your child submitted.
+
+
+
+ 14. Email And Other Messages Through This Site; ECPA
+ Notice.
+
+ This site treats email messages and other electronic messages
+ that are sent through this site and not viewable by others as
+ confidential and private, except as required by law, including without
+ limitation, the Electronic Communications Privacy Act of 1986, 18 U.S.C.
+ Sections 2701-2711 (the 'ECPA'). The ECPA permits this site's limited
+ ability to intercept and/or disclose electronic messages, for example
+ (i) as necessary to operate our system or to protect our rights or
+ property, (ii) upon legal demand (court orders, warrants, subpoenas), or
+ (iii) where we receive information inadvertently which appears to
+ pertain to the commission of a crime. This site is not considered a
+ 'secure communications medium' under the ECPA.
+
+
+ 15. Contact Us.
+ If you have any questions regarding this Privacy Policy, please
+ contact the owner and operator of this website business:
+
+
+ HabitRPG, Inc.
+ 11870 Santa Monica Blvd., Suite 106-577
+ Los Angeles, CA 90025
+ Email:
+ admin@habitica.com
+
+
If you haven't requested a password reset, please ignore this email.",
"invalidLoginCredentialsLong": "Uh-oh - your email address / username or password is incorrect.\n- Make sure they are typed correctly. Your username and password are case-sensitive.\n- You may have signed up with Facebook or Google-sign-in, not email so double-check by trying them.\n- If you forgot your password, click \"Forgot Password\".",
"invalidCredentials": "There is no account that uses those credentials.",
- "accountSuspended": "This account, User ID \"<%= userId %>\", has been blocked for breaking the [Community Guidelines](https://habitica.com/static/community-guidelines) or [Terms of Service](https://habitica.com/static/terms). For details or to ask to be unblocked, please email our Community Manager at <%= communityManagerEmail %> or ask your parent or guardian to email them. Please copy your User ID into the email and include your username.",
+ "accountSuspended": "Tento účet, ID uživatele \"<%= userId %>\", byl zablokován kvůli porušení pokynů pro komunitu (https://habitica.com/static/community-guidelines) nebo smluvních podmínek (https://habitica.com/static/terms). Chcete-li získat podrobnosti nebo požádat o odblokování, pošlete e-mail našemu Správci komunity na <%= communityManagerEmail %> nebo požádejte svého rodiče nebo zákonného zástupce o zaslání e-mailu. Do e-mailu uveďte prosím své @uživatelské_jméno.",
"accountSuspendedTitle": "Account has been suspended",
"unsupportedNetwork": "Tato síť není momentálně dostupná.",
"cantDetachSocial": "Account lacks another authentication method; can't detach this authentication method.",
@@ -330,5 +330,6 @@
"signup": "Zaregistruj se",
"getStarted": "Get Started!",
"mobileApps": "Mobilní aplikace",
- "learnMore": "Zjisti více"
+ "learnMore": "Zjisti více",
+ "communityInstagram": "Instagram"
}
diff --git a/website/common/locales/cs/gear.json b/website/common/locales/cs/gear.json
index 66a58ac375..5af9caadb6 100644
--- a/website/common/locales/cs/gear.json
+++ b/website/common/locales/cs/gear.json
@@ -1747,5 +1747,9 @@
"eyewearArmoirePlagueDoctorMaskNotes": "An authentic mask worn by the doctors who battle the Plague of Procrastination. Increases Constitution and Intelligence by <%= attrs %> each. Enchanted Armoire: Plague Doctor Set (Item 2 of 3).",
"eyewearArmoireGoofyGlassesText": "Goofy Glasses",
"eyewearArmoireGoofyGlassesNotes": "Perfect for going incognito or just making your partymates giggle. Increases Perception by <%= per %>. Enchanted Armoire: Independent Item.",
- "twoHandedItem": "Two-handed item."
+ "twoHandedItem": "Two-handed item.",
+ "weaponSpecialSpring2019HealerText": "Jarní píseň",
+ "weaponSpecialSpring2019MageText": "Jantarová hůl",
+ "weaponSpecialSpring2019WarriorText": "Stonkový meč",
+ "weaponSpecialSpring2019RogueText": "Blesk"
}
diff --git a/website/common/locales/cs/generic.json b/website/common/locales/cs/generic.json
index 4032fc0667..e155df23b2 100644
--- a/website/common/locales/cs/generic.json
+++ b/website/common/locales/cs/generic.json
@@ -79,7 +79,7 @@
"continue": "Pokračovat",
"accept": "Přijmout",
"reject": "Odmítnout",
- "neverMind": "Odejít",
+ "neverMind": "Nevadí",
"buyMoreGems": "Koupit více drahokamů",
"notEnoughGems": "Nedostatek drahokamů",
"alreadyHave": "Oops! Tohle už máš. Nemusíš si to kupovat znovu!",
@@ -290,5 +290,9 @@
"selected": "Vybrané",
"howManyToBuy": "Kolik by jsi chtěl koupit?",
"habiticaHasUpdated": "Existuje nová verze Habiticy. Znovu načti, aby jsi dostal nejnovější verzi!",
- "contactForm": "Kontaktuj tým moderátorů"
+ "contactForm": "Kontaktuj tým moderátorů",
+ "loadEarlierMessages": "Načíst dřívější zprávy",
+ "demo": "Ukázka",
+ "options": "Možnosti",
+ "finish": "Dokončit"
}
diff --git a/website/common/locales/cs/groups.json b/website/common/locales/cs/groups.json
index 04e3867171..998f576b9d 100644
--- a/website/common/locales/cs/groups.json
+++ b/website/common/locales/cs/groups.json
@@ -227,9 +227,9 @@
"memberCannotRemoveYourself": "Nemůžete se sám odebrat!",
"groupMemberNotFound": "Uživatel nenalezen mezi členy skupiny",
"mustBeGroupMember": "Musí být členem skupiny.",
- "canOnlyInviteEmailUuid": "Can only invite using user IDs, emails, or usernames.",
+ "canOnlyInviteEmailUuid": "Může pozvat pouze pomocí ID Uživatelů, e-mailů nebo uživatelských jmen.",
"inviteMissingEmail": "Chybějící emailová adresa v pozvánce.",
- "inviteMissingUuid": "Missing user id in invite",
+ "inviteMissingUuid": "Chybí ID Uživatele na pozvání",
"inviteMustNotBeEmpty": "Invite must not be empty.",
"partyMustbePrivate": "Družiny musí být soukromé",
"userAlreadyInGroup": "UserID: <%= userId %>, User \"<%= username %>\" already in that group.",
@@ -250,19 +250,19 @@
"onlyGroupLeaderCanEditTasks": "Not authorized to manage tasks!",
"onlyGroupTasksCanBeAssigned": "Only group tasks can be assigned",
"assignedTo": "Assigned To",
- "assignedToUser": "Assigned to <%= userName %>",
- "assignedToMembers": "Assigned to <%= userCount %> members",
- "assignedToYouAndMembers": "Assigned to you and <%= userCount %> members",
+ "assignedToUser": "Přiřazeno <%= userName %>",
+ "assignedToMembers": "Přiřazeno <%= userCount %> members",
+ "assignedToYouAndMembers": "Přiřazeno vám a <%= userCount %> members",
"youAreAssigned": "You are assigned to this task",
"taskIsUnassigned": "This task is unassigned",
"confirmClaim": "Are you sure you want to claim this task?",
"confirmUnClaim": "Are you sure you want to unclaim this task?",
"confirmApproval": "Are you sure you want to approve this task?",
"confirmNeedsWork": "Are you sure you want to mark this task as needing work?",
- "userRequestsApproval": "<%= userName %> requests approval",
- "userCountRequestsApproval": "<%= userCount %> members request approval",
+ "userRequestsApproval": "<%= userName %> požaduje schválení",
+ "userCountRequestsApproval": "<%= userCount %> members požadují schválení",
"youAreRequestingApproval": "You are requesting approval",
- "chatPrivilegesRevoked": "You cannot do that because your chat privileges have been revoked.",
+ "chatPrivilegesRevoked": "Toto nelze provést, protože vaše oprávnění k chatu byla odstraněna. Chcete-li získat další informace nebo se zeptat, zda lze vaše oprávnění vrátit, pošlete e-mail našemu komunitnímu manažerovi na adrese admin@habitica.com nebo požádejte svého rodiče nebo zákonného zástupce o zaslání e-mailu. Do e-mailu uveďte prosím své @uživatelskéjméno. Pokud vám moderátor již řekl, že váš zákaz chatu je dočasný, nemusíte posílat e-maily.",
"cannotCreatePublicGuildWhenMuted": "You cannot create a public guild because your chat privileges have been revoked.",
"cannotInviteWhenMuted": "You cannot invite anyone to a guild or party because your chat privileges have been revoked.",
"newChatMessagePlainNotification": "New message in <%= groupName %> by <%= authorName %>. Click here to open the chat page!",
@@ -277,10 +277,10 @@
"confirmRemoveTag": "Do you really want to remove \"<%= tag %>\"?",
"groupHomeTitle": "Home",
"assignTask": "Assign Task",
- "claim": "Claim",
+ "claim": "Nárokovat úkol",
"removeClaim": "Remove Claim",
"onlyGroupLeaderCanManageSubscription": "Only the group leader can manage the group's subscription",
- "yourTaskHasBeenApproved": "Your task <%= taskText %> has been approved.",
+ "yourTaskHasBeenApproved": "Váš úkol <%= taskText %> byl schválený.",
"taskNeedsWork": "<%= managerName %> marked <%= taskText %> as needing additional work.",
"userHasRequestedTaskApproval": "<%= user %> requests approval for <%= taskName %>",
"approve": "Approve",
@@ -341,8 +341,8 @@
"leaderCannotLeaveGroupWithActiveGroup": "A leader can not leave a group while the group has an active plan",
"youHaveGroupPlan": "You have a free subscription because you are a member of a group that has a Group Plan. This will end when you are no longer in the group that has a Group Plan. Any months of extra subscription credit you have will be applied at the end of the Group Plan.",
"cancelGroupSub": "Cancel Group Plan",
- "confirmCancelGroupPlan": "Are you sure you want to cancel the group plan and remove its benefits from all members, including their free subscriptions?",
- "canceledGroupPlan": "Canceled Group Plan",
+ "confirmCancelGroupPlan": "Opravdu chcete zrušit Plán Družiny? Všichni členové Družiny ztratí předplatné a výhody.",
+ "canceledGroupPlan": "Plán Družiny byl zrušen",
"groupPlanCanceled": "Group Plan will become inactive on",
"purchasedGroupPlanPlanExtraMonths": "You have <%= months %> months of extra group plan credit.",
"addManager": "Assign Manager",
@@ -476,8 +476,13 @@
"whatIsGroupManager": "What is a Group Manager?",
"whatIsGroupManagerDesc": "A Group Manager is a user role that do not have access to the group's billing details, but can create, assign, and approve shared Tasks for the Group's members. Promote Group Managers from the Group’s member list.",
"goToTaskBoard": "Go to Task Board",
- "sharedCompletion": "Shared Completion",
+ "sharedCompletion": "Podmínka dokončení",
"recurringCompletion": "None - Group task does not complete",
"singleCompletion": "Single - Completes when any assigned user finishes",
- "allAssignedCompletion": "All - Completes when all assigned users finish"
+ "allAssignedCompletion": "All - Completes when all assigned users finish",
+ "groupActivityNotificationTitle": "<%= user %> publikoval v <%= group %>",
+ "suggestedGroup": "Navrženo, protože jste v Habitica nový/á.",
+ "taskClaimed": "<%= userName %> nárokoval úkol <%= taskText %>.",
+ "youHaveBeenAssignedTask": "<%= managerName %> vám přidělil úkol <%= taskText %>.",
+ "pmReported": "Děkujeme za nahlášení této zprávy."
}
diff --git a/website/common/locales/cs/limited.json b/website/common/locales/cs/limited.json
index 6b797be056..532eccc1e9 100644
--- a/website/common/locales/cs/limited.json
+++ b/website/common/locales/cs/limited.json
@@ -23,11 +23,11 @@
"turkey": "Krocan",
"gildedTurkey": "Pozlacený krocan",
"polarBearPup": "Lední medvídě",
- "jackolantern": "Jack-O-Lantern",
+ "jackolantern": "Jack-O-Lucerna",
"ghostJackolantern": "Příšerná halloweenská dýně",
- "glowJackolantern": "Glow-in-the-Dark Jack-O-Lantern",
+ "glowJackolantern": "Svit-ve-Tmě Jack-O-Lucerna",
"seasonalShop": "Sezónní obchod",
- "seasonalShopClosedTitle": "<%= linkStart %>Leslie<%= linkEnd %>",
+ "seasonalShopClosedTitle": "<%= linkStart %>Lesli<%= linkEnd %>",
"seasonalShopTitle": "<%= linkStart %>Sezónní mudrci<%= linkEnd %>",
"seasonalShopClosedText": "Sezónní obchod je momentálně zavřený!! Je otevřený pouze během Čtyř Velkých Slavností země Habitica.",
"seasonalShopSummerText": "Šťastný Letní Šplouch!! Chceš koupit nějaké vzácné předměty? Budou dostupné pouze do 31. Července!",
@@ -130,10 +130,10 @@
"fall2018CandymancerMageSet": "Mlskomancer (Mág)",
"fall2018CarnivorousPlantSet": "Masožravá kytka (Léčitel)",
"fall2018AlterEgoSet": "Alter Ego (Zloděj)",
- "winter2019BlizzardSet": "Blizzard (Warrior)",
- "winter2019PyrotechnicSet": "Pyrotechnic (Mage)",
- "winter2019WinterStarSet": "Winter Star (Healer)",
- "winter2019PoinsettiaSet": "Poinsettia (Rogue)",
+ "winter2019BlizzardSet": "Vánice (Válečník)",
+ "winter2019PyrotechnicSet": "Pyrotechnik (Mag)",
+ "winter2019WinterStarSet": "Zimní hvězda (Léčitel)",
+ "winter2019PoinsettiaSet": "Pryšec (Zloděj)",
"eventAvailability": "Dostupný k zakoupení do <%= date(locale) %>.",
"dateEndMarch": "Duben 30",
"dateEndApril": "Duben 19",
@@ -147,9 +147,25 @@
"dateEndJanuary": "Leden 31",
"dateEndFebruary": "Únor 28",
"winterPromoGiftHeader": "DARUJ PŘEDPLATNÉ A ZÍSKEJ JEDNO ZDARMA!",
- "winterPromoGiftDetails1": "Until January 15th only, when you gift somebody a subscription, you get the same subscription for yourself for free!",
+ "winterPromoGiftDetails1": "Až do 15. ledna, když někomu darujete předplatné, získáte stejné předplatné pro sebe zdarma!",
"winterPromoGiftDetails2": "Prosím, mějte však na paměti, že pokud ty nebo příjemce tvého dárku již máte probíhající předplatné, pak darované předplatné odstartuje až poté, co je stávající zrušeno, nebo až vyprší jeho platnost. Děkujeme ti moc za tvojí podporu! <3",
"discountBundle": "balíček",
- "g1g1Announcement": "Gift a Subscription, Get a Subscription Free event going on now!",
- "g1g1Details": "Gift a sub to a friend from their profile and you’ll receive the same sub for free!"
+ "g1g1Announcement": "Darujte předplatné, získejte akci zdarma na předplatné!",
+ "g1g1Details": "Darujte dárek příteli ze svého profilu a dostanete stejnou částku zdarma!",
+ "eventAvailabilityReturning": "K dispozici ke koupi do <%= availableDate(locale) %>. Tento lektvar byl naposledy k dispozici <%= previousDate(locale) %>.",
+ "fall2019CyclopsSet": "Kyklop (Mag)",
+ "fall2019OperaticSpecterSet": "Operní Přízrak (Zloděj)",
+ "summer2019HammerheadRogueSet": "Kladivoun (Zloděj)",
+ "september2018": "Září 2018",
+ "september2017": "Září 2017",
+ "june2018": "Červen 2018",
+ "fall2019RavenSet": "Vrána (Válečník)",
+ "fall2019LichSet": "Lich (Léčitel)",
+ "summer2019ConchHealerSet": "Ulita (Léčitel)",
+ "summer2019WaterLilyMageSet": "Vodní Lilie (Mag)",
+ "summer2019SeaTurtleWarriorSet": "Mořská želva (Válečník)",
+ "spring2019CloudRogueSet": "Mrak (Tulák)",
+ "spring2019RobinHealerSet": "Červenka (Léčitel)",
+ "spring2019AmberMageSet": "Jantar (Mág)",
+ "spring2019OrchidWarriorSet": "Orchidej (válečník)"
}
diff --git a/website/common/locales/cs/npc.json b/website/common/locales/cs/npc.json
index 8fb11441a9..df632f5cb7 100644
--- a/website/common/locales/cs/npc.json
+++ b/website/common/locales/cs/npc.json
@@ -91,7 +91,7 @@
"unlocked": "Předměty byly odemčeny",
"alreadyUnlocked": "Celý set je již odemčen.",
"alreadyUnlockedPart": "Celý set je již částečně odemčen.",
- "invalidQuantity": "Nákupní kvantita musí být číslo.",
+ "invalidQuantity": "Množství k nákupu musí být kladné celé číslo.",
"USD": "(USD)",
"newStuff": "Nové věci od Bailey",
"newBaileyUpdate": "Nový Bailey update!",
@@ -103,7 +103,7 @@
"donationDesc": "20 drahokamů, Příspěvek vývojářům",
"payWithCard": "Zaplatit kartou",
"payNote": "Poznámka: Zpracování platby přes PayPal někdy trvá delší dobu. Doporučujeme platit kartou.",
- "card": "Platební kartou (za použití proužku)",
+ "card": "Platební kartou",
"amazonInstructions": "Klikni pro zaplacení přes Amazon platby",
"paymentMethods": "Platební metody",
"paymentSuccessful": "Your payment was successful!",
@@ -167,5 +167,7 @@
"welcome4": "Vyvaruj se zlozvyků, které ti ubírají Zdraví (HP), nebo tvůj avatar zemře!",
"welcome5": "Nyní si upravíš svůj avatar a zadáš úkoly...",
"imReady": "Vstup do země Habitica",
- "limitedOffer": "Dostupné do <%= date %>"
+ "limitedOffer": "Dostupné do <%= date %>",
+ "paymentCanceledDisputes": "Na váš e-mail jsme zaslali potvrzení o zrušení. Pokud e-mail nevidíte, kontaktujte nás, abychom předešli budoucím sporům o fakturaci.",
+ "paymentAutoRenew": "Toto předplatné se automaticky obnoví, dokud nebude zrušeno. Pokud potřebujete předplatné zrušit, můžete tak učinit z nastavení."
}
diff --git a/website/common/locales/cs/pets.json b/website/common/locales/cs/pets.json
index cd9a4f8516..de35632d52 100644
--- a/website/common/locales/cs/pets.json
+++ b/website/common/locales/cs/pets.json
@@ -19,7 +19,7 @@
"veteranTiger": "Tygr veterán",
"veteranLion": "Lev veterán",
"veteranBear": "Medvěd Veterán",
- "veteranFox": "Veteran Fox",
+ "veteranFox": "Liška Veterán",
"cerberusPup": "Štěně Kerbera",
"hydra": "Hydra",
"mantisShrimp": "Strašek paví",
@@ -142,5 +142,8 @@
"clickOnPotionToHatch": "Klikni na líhnoucí lektvar pro jeho použití na tvé <%= eggName %> a vylíhne se nový mazlíček!",
"notEnoughPets": "Nenasbíral jsi dostatek Mazlíčků",
"notEnoughMounts": "Nenasbíral jsi dostatek Osedlaných mazlíčků",
- "notEnoughPetsMounts": "Nenasbíral jsi dostatek Mazlíčků a Osedlaných mazlíčků"
+ "notEnoughPetsMounts": "Nenasbíral jsi dostatek Mazlíčků a Osedlaných mazlíčků",
+ "filterByWacky": "Šílené",
+ "gryphatrice": "Gryfatrice",
+ "wackyPets": "Šílená zvířátka"
}
diff --git a/website/common/locales/cs/questscontent.json b/website/common/locales/cs/questscontent.json
index 7088aee494..70c861b7dc 100644
--- a/website/common/locales/cs/questscontent.json
+++ b/website/common/locales/cs/questscontent.json
@@ -15,7 +15,7 @@
"questGryphonCompletion": "Poražené zvíře se zahanbeně courá zpět ke svému pánovi. \"Páni! Výborná práce dobrodruzi!\" baconsaur zvolá, \"Prosím, vezměte si nějaká gryfova vejce. Jsem si jist, že ty mladé dobře vychováte!\"",
"questGryphonBoss": "Ohnivý Gryf",
"questGryphonDropGryphonEgg": "Gryf (vejce)",
- "questGryphonUnlockText": "Odemyká vejce gryfa na trhu",
+ "questGryphonUnlockText": "Odemkne vejce gryfa pro nákup na trhu",
"questHedgehogText": "Ježobluda",
"questHedgehogNotes": "Hedgehogs are a funny group of animals. They are some of the most affectionate pets a Habiteer could own. But rumor has it, if you feed them milk after midnight, they grow quite irritable. And fifty times their size. And InspectorCaracal did just that. Oops.",
"questHedgehogCompletion": "Tvá družina ježka úspěšně uklidnila! Po navrácení do své normální velikosti, spěchá rychle ke svým vejcím. Vrací se pištící a dává vám nějaká svá vejce. Doufejme, že těmhle ježkům bude mléko chutnat více!",
@@ -27,37 +27,37 @@
"questGhostStagCompletion": "Přízrak, na první pohled nezraněn, sklání nos k zemi. Uklidňující hlas obklopí tvou družinu. \"Omlouvám se za své chování. Právě jsem se probudil ze spánku a zdá se, že mi trochu přeskočilo. Prosím, přijměte tato vejce na důkaz mé omluvy.\" Shluk vajec se objeví na trávě před přízrakem. Bez jakéhokoliv dalšího slova přízrak prchá pryč do lesa a květiny za ním opadávají.",
"questGhostStagBoss": "Přízračný jelen",
"questGhostStagDropDeerEgg": "Jelen (Vejce)",
- "questGhostStagUnlockText": "Odemyká vejce jelena na Trhu",
+ "questGhostStagUnlockText": "Odemyká vejce Jelena na Trhu",
"questRatText": "Myší král",
"questRatNotes": "Nepořádek! Napříč zemí Habitica se válejí obří hromady nesplněných úkolů. Problém je tak vážný, že se všude objevily hordy myší. Všimneš si, že @Pandah jednu z nich láskyplně hladí. Vysvětlí ti, že myši jsou jemná stvoření živící se nesplněnými úkoly. Skutečným problémem je, že nesplněné úkoly spadly do stoky a vytvořily nebezpečnou jámu, kterou je třeba pročistit. Když se spouštíš do stoky, zaútočí na tebe obří myš s krvavě červenýma očima a děravými žlutými zuby a brání svojí hordu. Schoulíš se strachy, nebo se proslulému králi myší postavíš?",
"questRatCompletion": "Tvůj poslední úder vysává sílu obrovité myši a její oči zešednou. Bestie se rozpadá na mnoho malinkých myší, které se bázlivě rozprchnou. Všimneš si, že za tebou stojí @Pandah a kdysi mocnou příšeru sleduje. Vysvětlí ti, že obyvatelé země Habitica byly tvou odvahou inspirováni a rychle dokončují všechny své nesplněné úkoly. Varuje tě, že musíš být na pozoru, protože když začneme být lhostejní, král myší se může vrátit. Za odměnu ti @Pandah nabízí několik myších vajec. Všimla si tvého znepokojeného výrazu a usmívá se: \"Jsou z nich skvělí mazlíčci.\"",
"questRatBoss": "Myší král",
"questRatDropRatEgg": "Myšák (vejce)",
- "questRatUnlockText": "Odemyká vejce myšáka na Trhu",
+ "questRatUnlockText": "Odemyká vejce Myšáka na Trhu",
"questOctopusText": "Volání Octothulu",
"questOctopusNotes": "@Urse, vyděšený mladý písař, tě požádal o pomoc při průzkumu záhadné jeskyně na břehu moře. Mezi třpytícími se tůňkami se tkví obrovská brána ze stalaktitů a stalagmitů. Když se k té bráně přibližujete, začne se u ní točit tmavý vodní vír. Užasle zíráte jak se z něj vynořuje sépiovitý drak. \"Ulepený zplozenec hvězd se probudil,\" zaječí @Urse šíleně. \"Po všech těch věcích je velký Octothulu znovu volný a lační po potěšení!\"",
"questOctopusCompletion": "S posledním zásahem, se potvora vytratila do víru, ze kterého vzešla. Nejste si jistý jak se @Urse cítí, zda-li je šťastný, protože jste vyhráli nebo smutný, protože bestie zmizela. Bez jediného slova váš společník ukazuje na tři obrovská slizká vejce v nedalekém přílivovém jezírku, nacházejícím se v hroudě zlatých mincí. „Snad jsou to jen vajíčka nějakých chobotnic\", nervózně podotknete. Když se vracíte domu, @Urse šíleně čmárá do deníku, a vy tušíte, že tohle není naposledy co slyšíte o monstru zvaném „Octothulu\".",
"questOctopusBoss": "Oktothulu",
"questOctopusDropOctopusEgg": "Chobotnice (Vejce)",
- "questOctopusUnlockText": "Odemyká vejce chobotnice na Trhu",
+ "questOctopusUnlockText": "Odemyká vejce Chobotnice na Trhu",
"questHarpyText": "Pomoc! Harpyje!",
"questHarpyNotes": "Chrabrý dobrodruh @UncommonCriminal zmizel v lese, když sledoval stopu okřídleného monstra, které bylo spatřeno před několika dny. Zrovna chcete začít hledat, když ti na ruce přistane zraněný papoušek s ošklivou jizvou přes jeho krásná peříčka. K jeho nožce je připevněn vzkaz, který vysvětluje, že @UncommonCriminal byl zahat zlou harpyjí při obranně papoušků a naléhavě potřebuje vaši pomoc. Budete sledovat papouška, přemůžete Harpyji a zachráníte @UncommonCriminal?",
"questHarpyCompletion": "Poslední zásah harpyji srazí k zemi a všude kolem létá peří. Rychle vylezete do jejího hnízda, kde najdete @UncommonCriminal obklopeného papouščími vejci. Jako tým rychle přenesete vajíčka do nedalekých hnízd. Zjizvený papoušek, který vás našel, hlasitě zapíská a upustí několik vajec do vašich rukou. \"Kvůli útoku harpyje potřebují tato vejce ochranu,\" vysvětluje @UcommonCriminal. \"Zdá se, že jste se stali čestnými papoušky.\"",
"questHarpyBoss": "Harpyje",
"questHarpyDropParrotEgg": "Papoušek (vajíčko)",
- "questHarpyUnlockText": "Odemyká vejce papouška na Trhu",
+ "questHarpyUnlockText": "Odemyká vejce Papouška na Trhu",
"questRoosterText": "Kohoutí řádění",
"questRoosterNotes": "Léta používal farmář @extrajordanary kohouty jako budíček. Ale nyní se objevil obrovský kohout, který kokrhá hlasitěji než kterýkoliv kohout před ním - a budí všechny v zemi Habitica! Habiťané trpící nedostatkem spánkem zápolí se svými denními úkoly. @Pandoro se rozhodne, že nastal čas to kokrhání zastavit. \"Prosím, je tu někdo, kdo dokáže naučit toho kohouta kokrhat tišeji?\" Přihlásíte se dobrovolně a jednoho rána se ke kohoutu přiblížíte - ale on se otočí mávajíce svými obřími křídly, ukazuje své ostré drápy a kokrhá bojový pokřik.",
"questRoosterCompletion": "S finesou a silou jste zkrotili to divoké zvíře. Jeho uši, předtím zacpané peřím a napůl zapomenutými úkoly, jsou nyní úplně čisté. Potichu na vás zakokrhá a nabídne vám zobák k pohlazení. Následující den jste připraveni pokračovat dále v cestě, ale @EmeraldOx k vám běží se zakrytým košíkem. \"Počkejte! Ráno jsem šel do kurníku a našel jsem tato vejce u dveří. Myslím, že ten kohout chce, abyste si je vzali.\" Odkryjete košík a uvidíte jemně zabarvená vejce.",
"questRoosterBoss": "Kohout",
"questRoosterDropRoosterEgg": "Kohout (vejce)",
- "questRoosterUnlockText": "Odemyká vejce kohouta na Trhu",
+ "questRoosterUnlockText": "Odemyká vejce Kohouta na Trhu",
"questSpiderText": "Ledový Arachnid",
"questSpiderNotes": "Počasí je stále chladnější a na oknech Habiťanů se objevují ledové pavučinky.... Až na @Arcosine, jehož okna jsou úplně zamrzlá, protože u něj přebývá Mrazivý pavouk. Ajéje.",
"questSpiderCompletion": "Ledový pavouk padá na zem a zanechává za sebou malou kupičku ledu a několik kouzelných váčků s vajíčky. @Arcosine vám je až skoro moc rychle nabídne jako odměnu -- možná byste z nich mohli vychovat hodné pavoučí mazlíčky?",
"questSpiderBoss": "Pavouk",
"questSpiderDropSpiderEgg": "Pavouk (vejce)",
- "questSpiderUnlockText": "Odemyká vejce pavouka na Trhu",
+ "questSpiderUnlockText": "Odemyká vejce Pavouka na Trhu",
"questGroupVice": "Zlořád, Stínový Drak",
"questVice1Text": "Zlořád, část 1: Osvoboď se od vlivu draka",
"questVice1Notes": "
Říká se, že v jeskyních hory Habitica leží zlo. Stvůra, jejíž přítomnost svádí silné hrdiny země k lenosti a špatným zvykům! Tou stvůrou je obrovský ze stínů zrozený drak nepředstavitelné síly: Zlořád, zrádný Stínový Drak. Chrabří Habiťané, postavte se mu a zdolejte tuto příšernou stvůru jednou provždy. Ale pouze pokud věříte, že se dokážete postavit jeho nezměrné síle.
Zlořád část 1:
Jak chceš bojovat se stvůrou, když už nad tebou má moc? Nepodlehni lenosti a zlozvykům! Tvrdě pracuj, abys mohl odolat drakovu temnému vlivu a přemohl jeho vliv na tebe!
",
@@ -221,7 +221,7 @@
"questKrakenBoss": "Kraken Neúplnosti",
"questKrakenCompletion": "Při svém úprku za sebou Kraken nechává tři vejce. Lemoness je prozkoumává a její podezřívavý pohled se změní na potěšený. \"Vejce sépiáka!\" řekne. \"Na, vezmi si je jako odměnu za to, co jsi splnil.\"",
"questKrakenDropCuttlefishEgg": "Sépiák (vejce)",
- "questKrakenUnlockText": "Odemyká vejce Sépiáka na Trhu.",
+ "questKrakenUnlockText": "Odemyká vejce Sépiáka na Trhu",
"questWhaleText": "Nářek plejtváka",
"questWhaleNotes": "Dorazíš do Svědomitého přístavu a doufáš, že chytíš ponorku na Závody v Liknavosti. Najednou se ozve řev tak hlasitý, že si musíš zacpat uši. \"Támhle chrlí!\" křičí kapitán @krazjega a ukazuje na obrovského naříkajícího plejtváka. \"Není bezpečné posílat ponorky dokud se tam plácá!\"
\"Rychle,\" volá @UncommonCriminal. \"Pomoz mi toho chudáka uklidnit abychom zjistili, proč tam naříká!\"",
"questWhaleBoss": "Naříkající plejtvák",
@@ -257,13 +257,13 @@
"questCheetahCompletion": "Nový Habiťan po té divoké jízdě ztěžka oddychuje, ale děkuje tobě a tvým přátelům za pomoc. \"Jsem rád, že ten gepard už nebude moci ublížit nikomu jinému. Nechal nám tu nějaká gepardí vejce, tak je vychovejme ve vzorné mazlíčky!\"",
"questCheetahBoss": "gepard",
"questCheetahDropCheetahEgg": "Gepard (vejce)",
- "questCheetahUnlockText": "Odemyká vejce geparda na Trhu",
+ "questCheetahUnlockText": "Odemyká vejce Geparda na Trhu",
"questHorseText": "Vyjeď si na Noční Můře",
"questHorseNotes": "Při odpočinku v Krčmě s @beffymarroo a @JessicaChase se vyprávění stočilo k bodré chvále tvých dobrodružných zásluh. Pyšný na své skutky ses možná nechal trošku unést a vychloubáš se, že zkrotíš jakýkoliv úkol široko daleko. Cizinec, sedící vedle, se k tobě náhle otočí a usměje se. Mrkne na tebe a pozve tě, abys dostál svým slovům a projel se na jeho koni.\nCestou ke stájím ti @UncommonCriminal pošeptá: \"Možná sis ukousl víc než zvládneš spolknout. To není kůň - to je Noční Můra!\" Když vidíš, jak divoce hrabe kopyty, začínáš svých slov litovat...",
"questHorseCompletion": "Chce to všechny tvé dovednosti, ale nakonec kůň párkrát dupne, otře se ti o rameno a nechá tě nasednout. Krátce leč pyšně se za nadšeného povzbuzování přátel projedeš kolem Krčmy. Cizinec se široce zašklebí.\n\"Vidím, že to nebyly jen plané řeči! Tvé odhodlání je skutečně působivé. Vezmi si tato vejce, vychovej si vlastní koně, a možná se jednoho dne opět setkáme.\" Když si od něj vezmeš vejce, smekne před tebou klobou... a zmizí.",
"questHorseBoss": "Noční Můra",
"questHorseDropHorseEgg": "Kůň (Vejce)",
- "questHorseUnlockText": "Odemyká vejce koně na Trhu",
+ "questHorseUnlockText": "Odemyká vejce Koně na Trhu",
"questBurnoutText": "Vyhoření a Vyčerpaní duchové",
"questBurnoutNotes": "Je dlouho po půlnoci, horký vzduch se ani nehne, když v tom Redphoenix a kapitán průzkumníků Kiwibot vtrhnou do městské brány. \"Musíme evakuovat všechny dřevěné budovy!\" křičí Redphoenix. \"Rychle!\"
Kiwibot se chytá zdi aby popadla dech. \"Vysává to lidi a mění je ve Vyčerpané duchy! Proto vše tak trvá. To se stalo se všemi pohřešovanými lidmi. Krade to jejich energii!\"
\"To?\" ptá se Lemoness.
A najednou se horko zhmotní.
Vstává ze země jako kroutící se masa a vzduch je prosycen pachem kouře a sýry. Plameny olizují tavící se zemi a formují se do pařátů obrovských rozměrů. Kouřící oči se otevřou a příšera ze sebe vydá hluboký a praskavý smích.
Kiwibot zašeptá jediné slovo
\"Vyhoření.\"",
"questBurnoutCompletion": "Vyhoření je PORAŽENO!
V hlasitém ale jemném povzdechu Vyhoření pomalu vypustí žhnoucí energii, která přiživovala jeho plamen. Příšera se tiše rozpadne na popel, její energie se třpyt ve vzduchu a znovu oživuje Vyčerpané duchy a vrací jim jejich původní formu.
Ian, Daniel, a mudrci ze Sezonního obchodu jásají a Habiťané je běží pozdravit, všichni pohřešovaní Habiťané z Kvetoucích polí objímají své přátele a rodiny. Poslední Vyčerpaný duch se přeměnil na samotnou Veselou smrtku!
\"Podívej!\" šeptá @Baconsaur když se popel začne blyštit. Pomalu se blyštivý popel přemění na stovky třpytivých fénixů!
Jeden ze zářících ptáků přistane na ruce Veselé smrtky a ona se na něj zašklebí. \"Je to tak dávno, co jsem viděla totoho úžasného fénixe na Kvetoucích polích,\" říká. \"I když za těchto okolností to je opravdu tématické!\"
Její tón se vyjasní, ale její škleb (přirozeně) zůstává. \"Jsme známí pro svou píli, ale také pro naše festivaly a slavnosti. Trochu ironické, řekla bych, že i při plánování párty jsme si nedovolili žádný oddechový čas. Takovou chybu už znovu neuděláme!\"
Tleskne. \"Tak - a jdeme slavit!\"",
@@ -281,37 +281,37 @@
"questFrogCompletion": "The frog cowers back into the muck, defeated. As it slinks away, the blue slime fades, leaving the way ahead clear.
Sitting in the middle of the path are three pristine eggs. \"You can even see the tiny tadpoles through the clear casing!\" @Breadstrings says. \"Here, you should take them.\"",
"questFrogBoss": "Nepořádný žabák",
"questFrogDropFrogEgg": "Žabák (vejce)",
- "questFrogUnlockText": "Odemyká vejce žabáka na Trhu",
+ "questFrogUnlockText": "Odemyká vejce Žabáka na Trhu",
"questSnakeText": "Had Rozptýlení",
"questSnakeNotes": "Jen houževnatá duše může žít v Písečných dunách Rozptýlení. Vyprahlá poušť je stěží dobrým místem pro produktivitu a mystický třpyt dun již svedl spoustu poutníků na scestí. Avšak, jedna věc děsí i místní. poslední dobou se písek hýbe a obrací vesnice vzhůru nohama. Obyvatelé se dušují, že v písku žije hadovitá příšera a všichni se složili na odměnu, kterou nabízejí každému, kdo jim pomůže příšeru zastavit. Legendární zaříkávači hadů, @EmeraldOx a @PainterProphet, souhlasili, že ti pomůžou příšeru vypátrat. Dokážeš zastavit Hada Rozptýlení?",
"questSnakeCompletion": "S pomocí zaříkávačů se vám povede Hada Rozptýlení zahnat. I když jste rádi, že jste pomohli obyvatelům Dun, trochu cítíš s padlým nepřítelem. Když se zamyšleně díváš v dál, přistoupí k tobě @LordDarkly. \"Děkujeme vám! Není to moc, ale doufáme, že tohle bude jako díky stačit.\" Podá vám nějaké zlaťáky a... pár hadích vajec! Tak přeci jen to majestátné zvíře uvidíš znovu.",
"questSnakeBoss": "Had Rozptýlení",
"questSnakeDropSnakeEgg": "Had (vejce)",
- "questSnakeUnlockText": "Odemyká vejce hada na Trhu",
+ "questSnakeUnlockText": "Odemyká vejce Hada na Trhu",
"questUnicornText": "Přesvědčování královny jednorožců",
"questUnicornNotes": "Potok Dobytí se zabahnil a zničil tak jediný zdroj pitné vody pro Habit City! Naštěstí @Lukreja zná starou legendu, ve které se vypráví, že roh jednorožce dokáže vyčistit i tu nejzakalenější vodu. Společně se se svým neohroženým průvodcem, @UncommonCriminal, vydáváte na túru přes zamrzlé vršky Meandrujících hor. Nakonec najdete mezi třpytícími se sněhy na ledovém sumitu hory Habitica královnu jendorožců. \"Vaše prosby jsou přesvědčivé,\" říká vám. \"Ale nejdřív musíte prokázat, že jste hodni mé pomoci!\"",
"questUnicornCompletion": "Ohromena vaší vytrvalostí, královna jednorožců souhlasí, že vám pomůže, protože vaše poslání je vznešené. Dovolí vám jet na jejím hřbetě po cestě k pramenu potoka Dobytí. Jakmile skloní svůj zlatý roh ke zkalené vodě, vytryskne z ní modré světlo. Je tak oslepující, že musíte zavřít oči. Když je po chvilce otevřete, jednorožec je pryč. Avšak, @rosiesully se zaraduje: voda je zase čistá a na břehu potoka se lesknou tři vejce jednorožce.",
"questUnicornBoss": "Královna jednorožců",
"questUnicornDropUnicornEgg": "Jednorožec (vejce)",
- "questUnicornUnlockText": "Odemyká vejce jednorožce na Trhu",
+ "questUnicornUnlockText": "Odemyká vejce Jednorožce na Trhu",
"questSabretoothText": "Šavlozubá kočka",
"questSabretoothNotes": "A roaring monster is terrorizing Habitica! The creature stalks through the wilds and woods, then bursts forth to attack before vanishing again. It's been hunting innocent pandas and frightening the flying pigs into fleeing their pens to roost in the trees. @InspectorCaracal and @icefelis explain that the Zombie Sabre Cat was set free while they were excavating in the ancient, untouched ice-fields of the Stoïkalm Steppes. \"It was perfectly friendly at first – I don't know what happened. Please, you have to help us recapture it! Only a champion of Habitica can subdue this prehistoric beast!\"",
"questSabretoothCompletion": "After a long and tiring battle, you wrestle the Zombie Sabre Cat to the ground. As you are finally able to approach, you notice a nasty cavity in one of its sabre teeth. Realising the true cause of the cat's wrath, you're able to get the cavity filled by @Fandekasp, and advise everyone to avoid feeding their friend sweets in future. The Sabre Cat flourishes, and in gratitude, its tamers send you a generous reward – a clutch of sabretooth eggs!",
"questSabretoothBoss": "Zombie šavlozubá kočka",
"questSabretoothDropSabretoothEgg": "Šavlozubec (vejce)",
- "questSabretoothUnlockText": "Odemyká vejce šavlozubce na Trhu",
+ "questSabretoothUnlockText": "Odemyká vejce Šavlozubce na Trhu",
"questMonkeyText": "Obludný mandril a opice neplechy",
"questMonkeyNotes": "The Sloensteadi Savannah is being torn apart by the Monstrous Mandrill and his Mischief Monkeys! They shriek loudly enough to drown out the sound of approaching deadlines, encouraging everyone to avoid their duties and keep monkeying around. Alas, plenty of people ape this bad behavior. If no one stops these primates, soon everyone's tasks will be as red as the Monstrous Mandrill's face!
\"It will take a dedicated adventurer to resist them,\" says @yamato.
\"Quick, let's get this monkey off everyone's backs!\" @Oneironaut yells, and you charge into battle.",
"questMonkeyCompletion": "Zvládl jsi to! Ti zlosynové dnes žádné banány nedostanou. Přemoceni tvou pracovitostí, opice v panice prchají. „Podívej,\" říká @Misceo. „Nechali za sebou pár vajec.\"
@Leephon se šklebí. „Možná ti vytrénovaná opice pomůže stejně tak, jako ta divoká uškodí!\"",
"questMonkeyBoss": "Obludný mandril",
"questMonkeyDropMonkeyEgg": "Opice (vejce)",
- "questMonkeyUnlockText": "Odemyká vejce opic na Trhu",
+ "questMonkeyUnlockText": "Odemyká vejce Opic na Trhu",
"questSnailText": "Šnek otrockého bahna",
"questSnailNotes": "You're excited to begin questing in the abandoned Dungeons of Drudgery, but as soon as you enter, you feel the ground under your feet start to suck at your boots. You look up to the path ahead and see Habiticans mired in slime. @Overomega yells, \"They have too many unimportant tasks and dailies, and they're getting stuck on things that don't matter! Pull them out!\"
\"You need to find the source of the ooze,\" @Pfeffernusse agrees, \"or the tasks that they cannot accomplish will drag them down forever!\"
Pulling out your weapon, you wade through the gooey mud.... and encounter the fearsome Snail of Drudgery Sludge.",
"questSnailCompletion": "You bring your weapon down on the great Snail's shell, cracking it in two, releasing a flood of water. The slime is washed away, and the Habiticans around you rejoice. \"Look!\" says @Misceo. \"There's a small group of snail eggs in the remnants of the muck.\"",
"questSnailBoss": "Šnek otrockého bahna",
"questSnailDropSnailEgg": "Šnek (vejce)",
- "questSnailUnlockText": "Odemyká vejce šneka na Trhu",
+ "questSnailUnlockText": "Odemyká vejce Šneka na Trhu",
"questBewilderText": "Be-Wilder",
"questBewilderNotes": "The party begins like any other.
The appetizers are excellent, the music is swinging, and even the dancing elephants have become routine. Habiticans laugh and frolic amid the overflowing floral centerpieces, happy to have a distraction from their least-favorite tasks, and the April Fool whirls among them, eagerly providing an amusing trick here and a witty twist there.
As the Mistiflying clock tower strikes midnight, the April Fool leaps onto the stage to give a speech.
“Friends! Enemies! Tolerant acquaintances! Lend me your ears.” The crowd chuckles as animal ears sprout from their heads, and they pose with their new accessories.
“As you know,” the Fool continues, “my confusing illusions usually only last a single day. But I’m pleased to announce that I’ve discovered a shortcut that will guarantee us non-stop fun, without having to deal with the pesky weight of our responsibilities. Charming Habiticans, meet my magical new friend... the Be-Wilder!”
Lemoness pales suddenly, dropping her hors d'oeuvres. “Wait! Don’t trust--”
But suddenly mists are pouring into the room, glittering and thick, and they swirl around the April Fool, coalescing into cloudy feathers and a stretching neck. The crowd is speechless as an monstrous bird unfolds before them, its wings shimmering with illusions. It lets out a horrible screeching laugh.
“Oh, it has been ages since a Habitican has been foolish enough to summon me! How wonderful it feels, to have a tangible form at last.”
Buzzing in terror, the magic bees of Mistiflying flee the floating city, which sags from the sky. One by one, the brilliant spring flowers wither up and wisp away.
“My dearest friends, why so alarmed?” crows the Be-Wilder, beating its wings. “There’s no need to toil for your rewards any more. I’ll just give you all the things that you desire!”
A rain of coins pours from the sky, hammering into the ground with brutal force, and the crowd screams and flees for cover. “Is this a joke?” Baconsaur shouts, as the gold smashes through windows and shatters roof shingles.
PainterProphet ducks as lightning bolts crackle overhead, and fog blots out the sun. “No! This time, I don’t think it is!”
Quickly, Habiticans, don’t let this World Boss distract us from our goals! Stay focused on the tasks that you need to complete so we can rescue Mistiflying -- and hopefully, ourselves.",
"questBewilderCompletion": "The Be-Wilder is DEFEATED!
We've done it! The Be-Wilder lets out a ululating cry as it twists in the air, shedding feathers like falling rain. Slowly, gradually, it coils into a cloud of sparkling mist. As the newly-revealed sun pierces the fog, it burns away, revealing the coughing, mercifully human forms of Bailey, Matt, Alex.... and the April Fool himself.
Mistiflying is saved!
The April Fool has enough shame to look a bit sheepish. “Oh, hm,” he says. “Perhaps I got a little…. carried away.”
The crowd mutters. Sodden flowers wash up on sidewalks. Somewhere in the distance, a roof collapses with a spectacular splash.
“Er, yes,” the April Fool says. “That is. What I meant to say was, I’m dreadfully sorry.” He heaves a sigh. “I suppose it can’t all be fun and games, after all. It might not hurt to focus occasionally. Maybe I’ll get a head start on next year’s pranking.”
Redphoenix coughs meaningfully.
“I mean, get a head start on this year’s spring cleaning!” the April Fool says. “Nothing to fear, I’ll have Habit City in spit-shape soon. Luckily nobody is better than I at dual-wielding mops.”
Encouraged, the marching band starts up.
It isn’t long before all is back to normal in Habit City. Plus, now that the Be-Wilder has evaporated, the magical bees of Mistiflying bustle back to work, and soon the flowers are blooming and the city is floating once more.
As Habiticans cuddle the magical fuzzy bees, the April Fool’s eyes light up. “Oho, I’ve had a thought! Why don’t you all keep some of these fuzzy Bee Pets and Mounts? It’s a gift that perfectly symbolizes the balance between hard work and sweet rewards, if I’m going to get all boring and allegorical on you.” He winks. “Besides, they don’t have stingers! Fool’s honor.”",
@@ -328,7 +328,7 @@
"questFalconCompletion": "Když konečně porazíte ptáky otálení, posadíte se, abyste si užili výhled a váš zasloužený odpočinek.
„Vau!\", řekla @Trogdorina. „Zvládl jsi to!\"
@Squish se přidá, „Vem si tyto vajíčka, které jsem našel, jako odměnu.\"",
"questFalconBoss": "Ptáci otálení",
"questFalconDropFalconEgg": "Sokol (vejce)",
- "questFalconUnlockText": "Odemyká vejce sokola na Trhu",
+ "questFalconUnlockText": "Odemyká vejce Sokola na Trhu",
"questTreelingText": "The Tangle Tree",
"questTreelingNotes": "It's the annual Garden Competition, and everyone is talking about the mysterious project which @aurakami has promised to unveil. You join the crowd on the day of the big announcement, and marvel at the introduction of a moving tree. @fuzzytrees explains that the tree will help with garden maintenance, showing how it can mow the lawn, trim the hedge and prune the roses all at the same time – until the tree suddenly goes wild, turning its secateurs on its creator! The crowd panics as everyone tries to flee, but you aren't afraid – you leap forward, ready to do battle.",
"questTreelingCompletion": "You dust yourself off as the last few leaves drift to the floor. In spite of the upset, the Garden Competition is now safe – although the tree you just reduced to a heap of wood chips won't be winning any prizes! \"Still a few kinks to work out there,\" @PainterProphet says. \"Perhaps someone else would do a better job of training the saplings. Do you fancy a go?\"",
@@ -634,5 +634,10 @@
"questVelociraptorCompletion": "You burst through the grass, confronting the Veloci-Rapper.
See here, rapper, you’re no quitter, You’re Bad Habits' hardest hitter! Check off your To-Dos like a boss, Don’t mourn over one day’s loss!
Filled with renewed confidence, it bounds off to freestyle another day, leaving behind three eggs where it sat.",
"questVelociraptorBoss": "Veloci-Rapper",
"questVelociraptorDropVelociraptorEgg": "Velociraptor (Egg)",
- "questVelociraptorUnlockText": "Unlocks purchasable Velociraptor eggs in the Market"
+ "questVelociraptorUnlockText": "Unlocks purchasable Velociraptor eggs in the Market",
+ "questBronzeUnlockText": "Odemkne líhnoucí lektvary pro nákup na trhu",
+ "questBronzeDropBronzePotion": "Bronzový líhnoucí lektvar",
+ "questBronzeBoss": "Brazen Brouk",
+ "questBronzeText": "Bitva s Brazenem Broukem",
+ "mythicalMarvelsText": "Balíček mýtických zázraků"
}
diff --git a/website/common/locales/cs/rebirth.json b/website/common/locales/cs/rebirth.json
index 4452e26505..c259a930c2 100644
--- a/website/common/locales/cs/rebirth.json
+++ b/website/common/locales/cs/rebirth.json
@@ -25,5 +25,6 @@
"rebirthName": "Koule znovuzrození",
"reborn": "Znovuzrozen, maximální úroveň <%= reLevel %>",
"confirmReborn": "Jsi si jistý?",
- "rebirthComplete": "Byl jste znovuzrozen!"
+ "rebirthComplete": "Byl jste znovuzrozen!",
+ "nextFreeRebirth": "<%= days %> dni do bezplatného Koule znovuzrození"
}
diff --git a/website/common/locales/cs/settings.json b/website/common/locales/cs/settings.json
index c315bde6f8..da210ebbfc 100644
--- a/website/common/locales/cs/settings.json
+++ b/website/common/locales/cs/settings.json
@@ -119,8 +119,8 @@
"giftedSubscriptionInfo": "<%= name %> ti daroval <%= months %> měsíční předplatné",
"giftedSubscriptionFull": "Ahoj <%= username %>, <%= sender %> ti poslal <%= monthCount %> měsíce předplatného!",
"giftedSubscriptionWinterPromo": "Hello <%= username %>, you received <%= monthCount %> months of subscription as part of our holiday gift-giving promotion!",
- "invitedParty": "Pozván do Družiny",
- "invitedGuild": "Pozván do Cechu",
+ "invitedParty": "Byli jste pozváni do Družiny",
+ "invitedGuild": "Byli jste pozváni do Cechu",
"importantAnnouncements": "Reminders to check in to complete tasks and receive prizes",
"weeklyRecaps": "Shrnutí aktivity tvého účtu za poslední týden (Poznámka: momentálně vypnuto kvůli problémům s výkonem, ale doufáme že se to vyřeší a budeme brzy znovu posílat e-maily!)",
"onboarding": "Guidance with setting up your Habitica account",
@@ -177,7 +177,7 @@
"mysticHourglass": "<%= amount %> Mystických přesýpacích hodin",
"mysticHourglassText": "Mystické přesýpací hodiny ti umožní koupit si záhadné sety předmětů z předchozích měsíců.",
"purchasedPlanId": "Opakovaně $<%= price %> každé <%= months %> měsíce (<%= plan %>)",
- "purchasedPlanExtraMonths": "Máš <%= months %> měsíců dalšího kreditu předlatného",
+ "purchasedPlanExtraMonths": "Máš <%= months %> měsíců dalšího kreditu předplatného.",
"consecutiveSubscription": "Nepřetržité předplatné",
"consecutiveMonths": "Počet po sobě jdoucích měsíců:",
"gemCapExtra": "Strop drahokamů extra:",
@@ -205,5 +205,6 @@
"usernameNotVerified": "Please confirm your username.",
"changeUsernameDisclaimer": "We will be transitioning login names to unique, public usernames soon. This username will be used for invitations, @mentions in chat, and messaging.",
"verifyUsernameVeteranPet": "One of these Veteran Pets will be waiting for you after you've finished confirming!",
- "subscriptionReminders": "Připomenutí pro předplatitele"
+ "subscriptionReminders": "Připomenutí pro předplatitele",
+ "newPMNotificationTitle": "Nová zpráva od <%= name %>"
}
diff --git a/website/common/locales/cs/subscriber.json b/website/common/locales/cs/subscriber.json
index 6414dc9539..1582c546e7 100644
--- a/website/common/locales/cs/subscriber.json
+++ b/website/common/locales/cs/subscriber.json
@@ -214,5 +214,16 @@
"purchaseAll": "Purchase Set",
"gemsPurchaseNote": "Předplatitelé mohou zakoupit drahokamy za zlato na Trhu! Pro jednoduchý přístup si můžeš drahokamy také připnout do tvého sloupečku s Odměnami.",
"gemsRemaining": "zbývající drahokamy",
- "notEnoughGemsToBuy": "Nemůžeš zakoupit toto množství drahokamů"
+ "notEnoughGemsToBuy": "Nemůžeš zakoupit toto množství drahokamů",
+ "subCanceledTitle": "Předplatné bylo zrušeno",
+ "mysterySet201909": "Sada Spolehlivých žaludů",
+ "mysterySet201908": "Footloose Faun sada",
+ "mysterySet201907": "Sada plážového kámoše",
+ "mysterySet201906": "Laskavá Koi sada",
+ "mysterySet201905": "Oslňující dračí sada",
+ "mysterySet201904": "Opulentní sada opálů",
+ "mysterySet201903": "Egg-squisite sada",
+ "mysterySet201902": "Cryptic Crush sada",
+ "subWillBecomeInactive": "Stane se neaktivní",
+ "confirmCancelSub": "Opravdu chcete zrušit předplatné? Ztratíte všechny své předplacené benefity."
}
diff --git a/website/common/locales/cs/tasks.json b/website/common/locales/cs/tasks.json
index 5bf459e13b..baf8d27684 100644
--- a/website/common/locales/cs/tasks.json
+++ b/website/common/locales/cs/tasks.json
@@ -173,7 +173,7 @@
"habitCounterDown": "Negativní počítadlo (Resetuje se <%= frequency %>)",
"taskRequiresApproval": "Tento úkol musí být schválen před dokončením. O schválení bylo již zažádáno",
"taskApprovalHasBeenRequested": "Bylo požádáno schválení",
- "taskApprovalWasNotRequested": "Pouze úkol, který čeká na schválení, může být označen jako potřebující více práce",
+ "taskApprovalWasNotRequested": "Pro tento úkol nebylo požadováno schválení.",
"approvals": "Schválení",
"approvalRequired": "Potřebuje schválení",
"repeatZero": "Denní úkol nikdy nemá splatnost",
diff --git a/website/common/locales/de/achievements.json b/website/common/locales/de/achievements.json
index 04dd2f2dbe..a5e673ec85 100644
--- a/website/common/locales/de/achievements.json
+++ b/website/common/locales/de/achievements.json
@@ -7,10 +7,10 @@
"achievementLostMasterclasser": "Quest-Erfüller: Klassenmeister-Reihe",
"achievementLostMasterclasserText": "Hat alle sechzehn Quests in der Klassenmeister-Questreihe abgeschlossen und das Rätsel des Verschwundenen Klassenmeisters gelöst!",
"achievementJustAddWater": "Einfach Wasser hinzugeben",
- "achievementMindOverMatterModalText": "Du hast die Rockende, Schleim- und Zwirnhaustier-Quests erfüllt!",
- "achievementMindOverMatterText": "Hat die Rockende, Schleim- und Zwirnhaustier-Quests erfüllt.",
+ "achievementMindOverMatterModalText": "Du hast die Fels-, Schleim- und Wollknäuelhaustier-Quests erfüllt!",
+ "achievementMindOverMatterText": "Hat die Fels-, Schleim- und Wollknäuelhaustier-Quests erfüllt.",
"achievementMindOverMatter": "Geist Über Materie",
- "achievementLostMasterclasserModalText": "Du hast alle sechzehn Quests der Masterklasser-Quest-Reihe erfüllt und das Rätsel der Verloren Masterklasser gelüftet!",
+ "achievementLostMasterclasserModalText": "Du hast alle sechzehn Quests der Masterklasser-Quest-Reihe erfüllt und das Rätsel der Verlorenen Klassenmeisterin gelüftet!",
"achievementAllYourBase": "Dein Standard",
"achievementAridAuthorityModalText": "Du hast alle wüstenfarbenen Reittiere gezähmt!",
"achievementAridAuthorityText": "Hat alle wüstenfarbenen Reittiere gezähmt.",
@@ -24,5 +24,7 @@
"achievementBackToBasicsText": "Hat alle Standard-Haustiere eingesammelt.",
"achievementBackToBasics": "Zurück zu den Anfängen",
"achievementJustAddWaterModalText": "Du hast die Oktopus-, Seepferdchen-, Tintenfisch-, Wal-, Meeresschildkröten-, Nacktkiemerschnecken-, Seeschlagen- und Delfinhaustier-Quests erfüllt!",
- "achievementJustAddWaterText": "Hat die Oktopus-, Seepferdchen-, Tintenfisch-, Wal-, Meeresschildkröten-, Nacktkiemerschnecken-, Seeschlangen- und Delfinhaustier-Quests erfüllt."
+ "achievementJustAddWaterText": "Hat die Oktopus-, Seepferdchen-, Tintenfisch-, Wal-, Meeresschildkröten-, Nacktkiemerschnecken-, Seeschlangen- und Delfinhaustier-Quests erfüllt.",
+ "achievementKickstarter2019Text": "Hat das Pin-Kickstarter-Projekt 2019 unterstützt",
+ "achievementKickstarter2019": "Pin-Kickstarter-Unterstützer"
}
diff --git a/website/common/locales/de/backgrounds.json b/website/common/locales/de/backgrounds.json
index 89511cec56..6122347497 100644
--- a/website/common/locales/de/backgrounds.json
+++ b/website/common/locales/de/backgrounds.json
@@ -464,5 +464,12 @@
"backgroundInAnAncientTombText": "Uraltes Grab",
"backgroundAutumnFlowerGardenNotes": "Lass die Wärme des Herbstblumengartens Dich erfüllen.",
"backgroundAutumnFlowerGardenText": "Herbstblumengarten",
- "backgrounds092019": "Set 64: Veröffentlicht im September 2019"
+ "backgrounds092019": "Set 64: Veröffentlicht im September 2019",
+ "backgroundPumpkinCarriageNotes": "Fahre in einer verzauberten Kürbiskutsche bevor die Uhr Mitternacht schlägt.",
+ "backgroundPumpkinCarriageText": "Kürbiskutsche",
+ "backgroundFoggyMoorText": "Nebliges Moor",
+ "backgrounds102019": "Set 65: Veröffentlicht im Oktober 2019",
+ "backgroundMonsterMakersWorkshopNotes": "Experimentiere mit verachteten Wissenschaften in einer Monster-Macher-Werkstatt.",
+ "backgroundMonsterMakersWorkshopText": "Monster-Macher-Werkstatt",
+ "backgroundFoggyMoorNotes": "Pass auf wo Du hintrittst beim Gang über das Neblige Moor."
}
diff --git a/website/common/locales/de/communityguidelines.json b/website/common/locales/de/communityguidelines.json
index 77c9543281..1f1f9b0297 100644
--- a/website/common/locales/de/communityguidelines.json
+++ b/website/common/locales/de/communityguidelines.json
@@ -3,27 +3,27 @@
"tavernCommunityGuidelinesPlaceholder": "Freundliche Erinnerung: Dieser Chat ist für alle Altersgruppen, also bitte benutze eine angemessene Sprache und poste nur angemessenen Inhalt! Falls Du Fragen hast, sieh bitte in den Community-Richtlinien weiter unten nach.",
"lastUpdated": "Zuletzt aktualisiert:",
"commGuideHeadingWelcome": "Willkommen in Habitica!",
- "commGuidePara001": "Sei gegrüßt, Abenteurer! Willkommen in Habitica, dem Land der Produktivität, des gesunden Lebens und dem gelegentlich randalierenden Greif. Wir sind eine fröhliche Gemeinschaft voller hilfreicher Menschen, die sich auf ihrem Weg der persönlichen Entwicklung gegenseitig unterstützen. Alles was dazu gehört, ist eine positive Einstellung, ein respektvoller Umgang miteinander, und etwas Verständnis dafür, dass jeder unterschiedliche Fähigkeiten und Grenzen hat - auch Du! Habiticaner gehen geduldig miteinander um und versuchen zu helfen, wo immer sie können.",
- "commGuidePara002": "Damit sich hier jeder sicher fühlen, glücklich und produktiv sein kann, gibt es ein paar Richtlinien. Wir haben uns große Mühe gegeben, sie möglichst nett und leicht verständlich zu formulieren. Bitte nimm Dir die Zeit, sie durchzulesen, bevor Du anfängst zu Chatten.",
- "commGuidePara003": "Diese Regeln gelten an allen sozialen Orten die wir verwenden, unter anderem (aber nicht nur) bei Trello, GitHub, Transifex und dem Wiki. Manchmal werden unvorhergesehende Situationen auftreten, wie ein neuer Krisenherd oder ein bösartiger Totenbeschwörer. Wenn das passiert, werden die Moderatoren reagieren, indem sie diese Richtlinien überarbeiten, um die Gemeinschaft vor neuen Gefahren zu schützen. Hab keine Angst: Du wirst von Bailey informiert werden, wenn sich die Richtlinien ändern.",
+ "commGuidePara001": "Sei gegrüßt, Abenteurer! Willkommen in Habitica, dem Land der Produktivität, des gesunden Lebens und des gelegentlich randalierenden Greifs. Wir sind eine fröhliche Gemeinschaft voller hilfreicher Menschen, die sich auf ihrem Weg der persönlichen Entwicklung gegenseitig unterstützen. Alles was dazu gehört, ist eine positive Einstellung, ein respektvoller Umgang miteinander und etwas Verständnis dafür, dass jeder unterschiedliche Fähigkeiten und Grenzen hat - auch Du! Habiticaner gehen geduldig miteinander um und versuchen zu helfen, wo immer sie können.",
+ "commGuidePara002": "Damit sich hier jeder sicher fühlen, glücklich und produktiv sein kann, gibt es ein paar Richtlinien. Wir haben uns große Mühe gegeben, sie möglichst nett und leicht verständlich zu formulieren. Bitte nimm Dir die Zeit, sie durchzulesen, bevor Du anfängst zu chatten.",
+ "commGuidePara003": "Diese Regeln gelten an allen sozialen Orten die wir verwenden, unter anderem (aber nicht nur) bei Trello, GitHub, Weblate und dem Wiki. Manchmal werden unvorhergesehende Situationen auftreten, z.B. ein neuer Krisenherd oder ein bösartiger Totenbeschwörer. Wenn das passiert, werden die Moderatoren reagieren, indem sie diese Richtlinien überarbeiten, um die Gemeinschaft vor neuen Gefahren zu schützen. Hab keine Angst: Du wirst von Bailey informiert werden, wenn sich die Richtlinien ändern.",
"commGuidePara004": "Zum Mitschreiben, halte Deinen Federkiel und Deine Schriftrolle bereit. Los geht's!",
"commGuideHeadingInteractions": "Interaktionen in Habitica",
- "commGuidePara015": "Habitica hat zwei Arten sozialer Orte: öffentliche und private. Öffentliche Orte sind die Taverne, öffentliche Gilden, GitHub, Trello und das Wiki. Private Orte sind private Gilden, der Gruppenchat und Private Nachrichten. Alle Anzeigenamen müssen den Community-Richtlinien für öffentliche Orte entsprechen. Um Deinen Anzeigenamen zu ändern, wähle auf der Webseite Benutzer Icon > Profil und klicke auf den \"Bearbeiten\"-Knopf.",
+ "commGuidePara015": "Habitica hat zwei Arten sozialer Orte: öffentliche und private. Öffentliche Orte sind die Taverne, öffentliche Gilden, GitHub, Trello und das Wiki. Private Orte sind private Gilden, der Gruppenchat und private Nachrichten. Alle Anzeigenamen müssen den Community-Richtlinien für öffentliche Orte entsprechen. Um Deinen Anzeigenamen zu ändern, wähle auf der Webseite Benutzer Icon > Profil und klicke auf den \"Bearbeiten\"-Knopf.",
"commGuidePara016": "Wenn Du Dich durch die öffentlichen Orte in Habitica bewegst, gibt es ein paar allgemeine Regeln, damit jeder sicher und glücklich ist. Diese sollten für einen Abenteurer wie Dich einfach sein!",
- "commGuideList02A": "Respektiert einander. Sei höflich, freundlich und hilfsbereit. Vergiss nicht: Habiticaner kommen aus den verschiedensten Hintergründen und haben sehr unterschiedliche Erfahrungen gemacht. Das macht Habitica so eigenartig! Es ist wichtig, das man beim Aufbauen einer Community seine Unterschiede und Ähnlichkeiten respektieren, aber natürlich auch feiern kann. Dies sind einfache Möglichkeiten einander zu respektieren:",
+ "commGuideList02A": "Respektiert einander. Sei höflich, freundlich und hilfsbereit. Vergiss nicht: Habiticaner kommen aus den verschiedensten Hintergründen und haben sehr unterschiedliche Erfahrungen gemacht. Das macht Habitica so eigenartig! Es ist wichtig, dass man beim Aufbauen einer Community seine Unterschiede und Ähnlichkeiten respektieren, aber natürlich auch feiern kann. Dies sind einfache Möglichkeiten einander zu respektieren:",
"commGuideList02B": "Halte Dich an die allgemeinen Geschäftsbedingungen.",
- "commGuideList02C": "Poste bitte keine Bilder oder Texte, die Gewalt darstellen, andere einschüchtern, oder eindeutig/indirekt sexuell sind, die Diskriminierung, Fanatismus, Rassismus, Sexismus, Hass, Belästigungen oder Hetze gegen jedwede Individuen oder Gruppen beinhalten. Auch nicht als Scherz. Das bezieht sowohl Sprüche als auch Stellungnahmen mit ein. Nicht jeder hat den gleichen Humor, etwas, was Du als Witz wahrnimmst, kann für jemand anderen verletzend sein. Greift eure Tagesaufgaben an, nicht einander.",
+ "commGuideList02C": "Poste keine Bilder oder Texte, die Gewalt darstellen, andere einschüchtern, oder eindeutig/indirekt sexuell sind, die Diskriminierung, Fanatismus, Rassismus, Sexismus, Hass, Belästigungen oder Hetze gegen jedwede Individuen oder Gruppen beinhalten. Auch nicht als Scherz. Das bezieht sowohl Sprüche als auch Stellungnahmen mit ein. Nicht jeder hat den gleichen Humor, etwas, was Du als Witz wahrnimmst, kann für jemand anderen verletzend sein. Greift eure Tagesaufgaben an, nicht einander.",
"commGuideList02D": "Halte die Diskussionen für alle Altersgruppen angemessen. Wir haben viele junge Habiticaner, die die Seite nutzen! Lasst uns keine Unschuldigen beflecken oder Habiticaner in ihren Zielen behindern.",
"commGuideList02E": "Vermeide vulgäre Ausdrücke. Dazu gehören auch mildere, religiöse Verwünschungen, die woanders akzeptiert werden. Unter uns sind Menschen aus allen religiösen und kulturellen Hintergründen und wir wünschen uns, dass sich Alle im öffentlichen Raum wohl fühlen. Wenn Dir ein Moderator oder Mitarbeiter mitteilt, dass ein bestimmter Ausdruck, der Dir selbst vielleicht nicht problematisch vorkommt, in Habitica nicht erlaubt ist, ist diese Entscheidung endgültig. Zusätzlich werden verbale Angriffe jeder Art strenge Konsequenzen haben, insbesondere auch, da sie unsere Nutzungsbedingungen verletzen.",
"commGuideList02F": "Vermeide längere Diskussionen über spaltende Themen in der Taverne und wo sie außerhalb des Themenbereichs liegen. Wenn Du das Gefühl hast, dass jemand etwas Unhöfliches oder Verletzendes gesagt hat, dann lass Dich nicht mit ihm ein. Wenn jemand etwas erwähnt, das von den Richtlinien erlaubt ist, das aber für Dich verletzend ist, ist es in Ordnung, das höflich jemandem mitzuteilen. Wenn es gegen die Richtlinien oder die Nutzungsbedingungen verstößt, solltest Du es markieren und einen Moderator antworten lassen. Im Zweifelsfall markiere den Beitrag.",
"commGuideList02G": "Erfülle alle Moderator-Anfragen sofort. Dies könnte Folgendes beinhalten, ist aber nicht darauf beschränkt: Dich aufzufordern, Deine Beiträge in einem bestimmten Bereich zu begrenzen, Dein Profil zu bearbeiten, um ungeeignete Inhalte zu entfernen, Dich zu bitten, Deine Diskussion in einen geeigneteren Bereich zu verschieben, etc.",
"commGuideList02H": "Denk zuerst gründlich nach bevor Du wütend reagierst wenn Dir jemand sagt, dass etwas was Du getan oder gesagt hast ihm/ihr nicht gefallen hat. Es zeigt große Stärke, sich ehrlich bei jemandem zu entschuldigen. Wenn Du findest, dass die Art, wie er/sie Dir geantwortet hat unangemessen war, kontaktiere einen Mod statt ihn/sie öffentlich damit zu konfrontieren.",
"commGuideList02I": "Spaltende/kontroverse Gespräche sollten an Moderatoren gemeldet werden, indem man die betreffenden Nachrichten markiert oder das Moderatoren-Kontaktformular verwendet. Wenn Du das Gefühl hast, dass ein Gespräch erhitzt, übermäßig emotional oder verletzend wird, nimm nicht weiter teil. Melde stattdessen die Beiträge, um uns darüber zu informieren. Die Moderatoren werden so schnell wie möglich antworten. Es ist unsere Aufgabe, Dich zu schützen. Wenn Du der Meinung bist, dass mehr Kontext erforderlich ist, kannst Du das Problem über das Moderatoren-Kontaktformular melden.",
- "commGuideList02J": "Poste keinen Spam. Spamming kann Folgendes beinhalten, ist aber nicht beschränkt auf: das Posten desselben Kommentars oder einer Anfrage an mehreren Stellen, das Posten von Links ohne Erklärung oder Kontext, das Posten unsinniger Nachrichten, das Posten mehrerer Werbebotschaften über eine Gilde, Party oder einen Wettbewerb oder das Posten vieler Nachrichten in Serie. Das Bitten um Edelsteine oder ein Abonnement in einem der Chaträume oder per privater Nachricht gilt ebenfalls als Spamming. Wenn Personen, die auf einen Link klicken, Dir einen Nutzen bringen, musst Du dies im Text Deiner Nachricht offenlegen, sonst wird das auch als Spam betrachtet.
Es liegt an den Mods zu entscheiden, ob etwas Spam darstellt oder zu Spam führen könnte, auch wenn Du nicht das Gefühl hast, dass Du Spamming betrieben hast. Zum Beispiel ist die Werbung für eine Gilde ein- oder zweimal akzeptabel, aber mehrere Beiträge an einem Tag würden wahrscheinlich Spam darstellen, egal wie nützlich die Gilde ist!",
+ "commGuideList02J": "Poste keinen Spam. Spamming kann Folgendes beinhalten, ist aber nicht beschränkt auf: das Posten desselben Kommentars oder einer Anfrage an mehreren Stellen, das Posten von Links ohne Erklärung oder Kontext, das Posten unsinniger Nachrichten, das Posten mehrerer Werbebotschaften über eine Gilde, Party oder eine Herausforderung oder das Posten vieler Nachrichten in Serie. Das Betteln nach Edelsteinen oder einem Abonnement in einem der Chaträume oder per privater Nachricht gilt ebenfalls als Spamming. Wenn Personen, die auf einen Link klicken, Dir einen Nutzen bringen, musst Du dies im Text Deiner Nachricht offenlegen, sonst wird das auch als Spam betrachtet.
Es liegt an den Mods zu entscheiden, ob etwas Spam darstellt oder zu Spam führen könnte, auch wenn Du nicht das Gefühl hast, dass Du Spamming betrieben hast. Zum Beispiel ist die Werbung für eine Gilde ein- oder zweimal akzeptabel, aber mehrere Beiträge an einem Tag würden wahrscheinlich Spam darstellen, egal wie nützlich die Gilde ist!",
"commGuideList02K": "Bitte vermeide große Überschriften in öffentlichen Chats, vor allem in der Taverne. Ähnlich wie bei GROSSBUCHSTABEN liest sich der Text, als ob Du schreien würdest, und beeinträchtigt die gemütliche Atmosphäre.",
"commGuideList02L": "Wir raten Dir dringend davon ab, persönliche Informationen - besonders solche, mit denen Du identifiziert werden könntest - in öffentlichen Chats zu teilen. Zu den identifizierenden Informationen gehören unter anderem: Deine Adresse, Deine E-Mail-Adresse und Dein API-Token/Passwort. Dies dient nur Deiner Sicherheit! Mitarbeiter oder Moderatoren werden solche Beiträge nach eigenem Ermessen entfernen. Wenn Du nach persönlichen Informationen in einer privaten Gilde, Party oder per PN gefragt wirst, empfehlen wir dringend, dass Du höflich ablehnst und Mitarbeiter und Moderatoren informierst, indem Du entweder 1) den Beitrag über das Fähnchen meldest, wenn er in einer Party oder privaten Gilde ist, oder 2) das Moderator-Kontaktformular ausfüllst und einen Screenshot anhängst.",
- "commGuidePara019": "An privaten Orten haben Benutzer die Freiheit, alle möglichen Themen zu besprechen, solange diese nicht den AGB widersprechen. Dies umfasst das Posten von diskriminierenden, gewalttätigen oder einschüchternden Inhalten. Beachte, dass Wettbewerbsnamen im öffentlichen Profil des Gewinners angezeigt werden, daher müssen ALLE Wettbewerbsnamen den Community-Richtlinien für öffentliche Orte entsprechen, auch wenn sie an privaten Orten genutzt werden.",
- "commGuidePara020": "Für private Nachrichten (PNs) gibt es einige zusätzliche Richtlinien. Falls Dich jemand geblockt hat, kontaktiere ihn nicht über andere Wege, um ihn oder sie zu bitten Dich nicht mehr zu blocken. Außerdem solltest Du keine PNs schicken, wenn Du Hilfe mit der Seite, also \"Support\" brauchst (allgemein zugängliche Antworten auf diese Fragen im Gasthaus oder Forum kommen der Gemeinschaft zugute). Schließlich schicke bitte keine PNs, in denen Du um Edelsteine oder ein Abonnement bettelst, da dies als Spam gewertet werden kann.",
+ "commGuidePara019": "An privaten Orten haben Benutzer die Freiheit, alle möglichen Themen zu besprechen, solange diese nicht den AGB widersprechen. Dies umfasst das Posten von diskriminierenden, gewalttätigen oder einschüchternden Inhalten. Beachte, dass Herausforderungsnamen im öffentlichen Profil des Gewinners angezeigt werden, daher müssen ALLE Herausforderungsnamen den Community-Richtlinien für öffentliche Orte entsprechen, auch wenn sie an privaten Orten genutzt werden.",
+ "commGuidePara020": "Für private Nachrichten (PNs) gibt es einige zusätzliche Richtlinien. Falls Dich jemand geblockt hat, kontaktiere ihn nicht über andere Wege, um ihn oder sie zu bitten Dich nicht mehr zu blocken. Außerdem solltest Du keine PNs schicken, wenn Du Hilfe mit der Seite, also \"Support\" brauchst (allgemein zugängliche Antworten auf diese Fragen in der Taverne oder im Forum kommen der Gemeinschaft zugute). Schicke auch bitte keine PNs, in denen Du um Edelsteine oder ein Abonnement bettelst, da dies als Spam gewertet werden kann.",
"commGuidePara020A": "Siehst Du einen Beitrag, der Dich beunruhigt oder von dem Du glaubst, er verletze die oben zusammengefassten Community-Richtlinien für öffentliche Orte, kannst Du ihn bei Moderatoren und Mitarbeitern melden, indem Du auf das Fähnchen klickst. Ein Mitarbeiter oder Moderator wird sich dieser Meldung sobald wie möglich annehmen. Bitte beachte, dass das vorsätzliche Melden harmloser Beiträge eine Verletzung dieser Richtlinien darstellt (siehe unten unter “Regelverletzung”). PNs können derzeit nicht über das Fähnchen gemeldet werden. Um eine PN zu melden, benutze bitte das Moderatoren-Kontaktformular auf der “Kontakt”-Seite oder über “Kontaktiere das Moderatoren-Team” im Hilfe-Menü. Du kannst dies tun, wenn es mehrere problematische Beiträge derselben Person in verschiedenen Gilden gibt, oder wenn die Situation einer Erklärung bedarf. Du kannst uns in Deiner Muttersprache kontaktieren, wenn das für Dich einfacher ist: Wir müssen vielleicht Google Translate verwenden, aber wir möchten, dass Du Dich wohl fühlst, wenn Du uns ein Problem mitteilst.",
"commGuidePara021": "Manche öffentliche Orte in Habitica haben außerdem noch weitere Regeln.",
"commGuideHeadingTavern": "Die Taverne",
@@ -33,29 +33,29 @@
"commGuidePara027": "Wenn ein Moderator Dich anweist, ein Gespräch an anderer Stelle zu führen und wenn es keine relevante Gilde gibt, kann er Dir vorschlagen, die Hinterzimmer-Gilde zu benutzen. Die Hinterzimmer-Gilde ist ein freier öffentlicher Raum, um potenziell sensible Themen zu diskutieren. Sie sollte nur verwendet werden, wenn sie von einem Moderator geleitet wird. Sie wird vom Moderatorenteam sorgfältig überwacht. Sie ist kein Ort für allgemeine Diskussionen oder Gespräche, und Du wirst nur dann von einem Mod dorthin geleitet, wenn es angebracht ist.",
"commGuideHeadingPublicGuilds": "Öffentliche Gilden",
"commGuidePara029": "Öffentliche Gilden sind der Taverne ziemlich ähnlich, außer dass die Gespräche dort nicht so allgemein sind, sondern sich um ein bestimmtes Thema drehen. Der öffentliche Gildenchat sollte sich auf dieses Thema konzentrieren. Zum Beispiel könnte es sein, dass Mitglieder der Wordsmith-Gilde genervt sind, wenn sich das Gespräch plötzlich um Gärtnern statt um Schreiben dreht, und eine Drachenliebhaber-Gilde interessiert sich wahrscheinlich nicht dafür, antike Runen zu entziffern. Manche Gilden sind dabei lockerer als andere, aber versuche generell beim Thema zu bleiben!",
- "commGuidePara031": "Einige öffentliche Gilden werden sensible Themen wie Depressionen, Religion, Politik usw. enthalten. Dies ist in Ordnung, solange die Gespräche darin nicht gegen die Allgemeinen Geschäftsbedingungen oder die Regeln des öffentlichen Raums verstoßen und solange sie beim Thema bleiben.",
+ "commGuidePara031": "Einige öffentlichen Gilden werden sensible Themen wie Depressionen, Religion, Politik usw. enthalten. Dies ist in Ordnung, solange die Gespräche darin nicht gegen die Allgemeinen Geschäftsbedingungen oder die Regeln des öffentlichen Raums verstoßen und solange sie beim Thema bleiben.",
"commGuidePara033": "Öffentliche Gilden dürfen KEINE Inhalte \"ab 18\" enthalten. Wenn geplant ist, regelmäßig über sensible Inhalte zu diskutieren, sollte dies in der Gildenbeschreibung angegeben werden. Auf diese Weise soll Habitica sicher und angenehm für alle sein.",
"commGuidePara035": "Wenn die betreffende Gilde verschiedene Arten von heiklen Themen hat, ist es respektvoll gegenüber Deinen Habiticanern, eine Warnung vor Deinen Kommentar zu stellen (z.B. \"Warnung: erwähnt Selbstverletzung\"). Diese können als Triggerwarnungen und/oder Inhaltshinweise bezeichnet werden, und Gilden können zusätzlich zu den hier angegebenen Regeln eigene Regeln haben. Wenn möglich, verwende bitte Markdown um die potenziell heiklen Inhalte unterhalb von Zeilenumbrüchen auszublenden, damit diejenigen, die sie nicht lesen möchten, darüber hinweg scrollen können, ohne den Inhalt zu sehen. Mitarbeiter und Moderatoren von Habitica können dieses Material nach eigenem Ermessen trotzdem entfernen.",
"commGuidePara036": "Außerdem sollte das heikle Material themenrelevant sein - Selbstverletzung in einer Gilde, die sich auf die Bekämpfung von Depressionen konzentriert, kann sinnvoll sein, ist aber in einer Musikgilde wahrscheinlich weniger angebracht. Wenn Du jemanden siehst, der wiederholt gegen diese Richtlinie verstößt, insbesondere nach mehreren Anfragen, markiere bitte die Beiträge und benachrichtige die Moderatoren über das Moderatoren-Kontaktformular.",
"commGuidePara037": "Es sollte niemals eine Gilde, egal ob öffentlich oder privat, gegründet werden, die als Ziel hat, ein Individuum oder eine Gruppe anzugreifen. So eine Gilde zu erstellen führt zu einer sofortigen Accountsperre. Bekämpfe schlechte Angewohnheiten, nicht Deine Mitabenteurer!",
- "commGuidePara038": "Alle Tavernen-Wettbewerbe und Wettbewerbe öffentlicher Gilden müssen sich ebenfalls an diese Regeln halten.",
+ "commGuidePara038": "Alle Tavernen-Herausforderungen und Herausforderungen öffentlicher Gilden müssen sich ebenfalls an diese Regeln halten.",
"commGuideHeadingInfractionsEtc": "Regelverletzungen, Konsequenzen und Wiederherstellung",
"commGuideHeadingInfractions": "Regelverletzungen",
"commGuidePara050": "Zum größten Teil unterstützen sich Habiticaner gegenseitig, zeigen Respekt und geben ihr Bestes um die Community unterhaltsam und freundlich zu halten. Jedoch kann es immer wieder vorkommen, dass ein Habiticaner die obigen Richtlinien missachtet. Sollte das passieren, werden die Moderatoren Maßnahmen ergreifen, die sie für notwenig erachten, um Habitica sicher und komfortabel für alle zu halten.",
"commGuidePara051": "Es gibt eine Vielzahl von Verletzungen, und sie werden je nach Schweregrad behandelt. Dies sind keine abschliessenden Listen, und die Mods können nach eigenem Ermessen Entscheidungen zu Themen treffen, die hier nicht behandelt werden. Die Mods berücksichtigen den Kontext bei der Bewertung von Verstößen.",
"commGuideHeadingSevereInfractions": "Schwere Regelverletzungen",
"commGuidePara052": "Schwere Regelverletzungen bedrohen die Sicherheit von Habiticas Gemeinschaft und Nutzern stark, deshalb folgen darauf schwere Konsequenzen.",
- "commGuidePara053": "In folgender Liste sind Beispiele für schwere Regelverletzungen. Die Liste ist nicht vollständig.",
+ "commGuidePara053": "In folgender Liste sind Beispiele für schwere Regelverletzungen. Die Liste ist nicht abschliessend.",
"commGuideList05A": "Verletzung der AGB",
"commGuideList05B": "Hassparolen/-Bilder, Belästigung/Stalking, Cyber-Bullying und Trollen",
"commGuideList05C": "Verletzung der Bewährung",
"commGuideList05D": "Sich als Mitarbeiter oder Moderator ausgeben",
"commGuideList05E": "Wiederholte mittlere Regelverletzungen",
- "commGuideList05F": "Erstellen eines zweiten Kontos um Konsequenzen zu entgehen (zum Beispiel, ein neues Konto erstellen um zu chatten, nachdem die Chat Privilegien entzogen wurden)",
+ "commGuideList05F": "Erstellen eines zweiten Kontos um Konsequenzen zu entgehen (zum Beispiel, ein neues Konto erstellen um zu chatten, nachdem die Chat-Privilegien entzogen wurden)",
"commGuideList05G": "Absichtliche Täuschung eines Mitarbeiters oder Moderators mit dem Ziel, einer Strafe zu entgehen oder einem anderen Benutzer Probleme zu machen",
"commGuideHeadingModerateInfractions": "Mittlere Regelverletzungen",
"commGuidePara054": "Mäßige Verstöße machen unsere Community nicht unsicher, aber sie machen sie unangenehm. Diese Verstöße haben mäßige Konsequenzen. Mehrere mäßige Verstöße können jedoch zu ernsteren Konsequenzen führen.",
- "commGuidePara055": "Die folgende Liste sind Beispiele für mittlere Regelverletzungen. Die Liste ist nicht vollständig.",
+ "commGuidePara055": "Die folgende Liste sind Beispiele für mittlere Regelverletzungen. Die Liste ist nicht abschliessend.",
"commGuideList06A": "Ignorieren, Nichtrespektieren oder Hinterfragen eines Moderators. Dies umfasst öffentliches Beklagen über Moderatoren oder andere Nutzer, öffentliche Glorifizierung oder Verteidigung gesperrter Nutzer, oder Debattieren ob eine Massnahme eines Moderators angemessen war oder nicht. Falls Bedenken bei einer oder mehrerer Regeln oder Moderatoren bestehen, sende bitte eine E-Mail an unsere Mitarbeiter (admin@habitica.com).",
"commGuideList06B": "\"Besserwisser-Moderieren\" durch Nicht-Moderatoren. Um vorher etwas klarzustellen: ein freundliches Erwähnen der Regeln ist völlig in Ordnung. \"Besserwisser-Moderieren\" ist es, wenn man sagt, verlangt oder deutlich andeutet dass jemand eine bestimmte Handlung durchführen muss, um einen Fehler zu korrigieren. Du kannst jemandem Bescheid sagen, dass er/sie eine Regel verletzt hat, aber bitte verlange keine bestimmte Konsequenz - z. B. wäre es besser zu sagen \"Nur dass Du es weißt, Fluchen ist in der Taverne nicht erlaubt, deshalb solltest Du das vielleicht besser löschen\" als \"Lösch jetzt diesen Kommentar.\"",
"commGuideList06C": "Absichtliches Markieren harmloser Beiträge.",
@@ -63,7 +63,7 @@
"commGuideList06E": "Wiederholte kleinere Vergehen",
"commGuideHeadingMinorInfractions": "Leichte Regelverletzungen",
"commGuidePara056": "Leichte Regelverletzungen sollten zwar nicht passieren, haben aber nur leichte Konsequenzen. Wenn sie wiederholt auftreten, können sie mit der Zeit zu schwereren Konsequenzen führen.",
- "commGuidePara057": "In folgender Liste sind Beispiele für leichte Regelverletzungen. Die Liste ist nicht vollständig.",
+ "commGuidePara057": "In folgender Liste sind Beispiele für leichte Regelverletzungen. Die Liste ist nicht abschliessend.",
"commGuideList07A": "Erstmalige Verletzung von Richtlinien für öffentliche Orte",
"commGuideList07B": "Jegliche Aussagen oder Handlungen die ein \"Bitte nicht\" auslösen. Wenn ein Mod zu einem Nutzer \"Bitte mach' das nicht\" sagen muss, kann das für diesen Nutzer als eine sehr leichte Regelverletzung zählen. Ein Beispiel dafür wäre \"Mod Talk: Bitte argumentiere nicht weiter für ein Feature, wenn bereits festgestellt wurde, dass es nicht umsetzbar ist.\" In vielen Fällen wird das \"Bitte nicht\" auch gleichzeitig die leichte Konsequenz sein, aber wenn es die Mods zum gleichen Nutzer sehr häufig sagen müssen werden die leichten Regelverletzungen irgendwann als mittlere Regelverletzungen zählen.",
"commGuidePara057A": "Manche Beiträge werden eventuell versteckt, da sie persönliche Informationen enthalten oder einen falschen Eindruck erwecken. Normalerweise wird dies nicht als Verstoß gewertet, vor allem nicht beim ersten Mal!",
@@ -81,8 +81,8 @@
"commGuideList09C": "Der Aufstieg in höhere Mitwirkendenstufen kann dauerhaft verwehrt (\"eingefroren\") werden",
"commGuideHeadingModerateConsequences": "Beispiele für mittlere Konsequenzen",
"commGuideList10A": "Beschränkte öffentliche und/oder private Chat-Berechtigungen",
- "commGuideList10A1": "Führen deine Handlungen zur Aufhebung deiner Chatrechte, wird Dich ein Moderator oder Mitarbeiter per PM und/oder in dem Forum, in dem Du stummgeschaltet wurdest, über die Dauer und Gründe für das Stummschalten informieren. Nach Abauf dieser Zeit erhältst Du Deine Chatrechte zurück, vorausgesetzt Du stimmst zu, Dein Verhalten zu ändern und Dich fortan an die Community-Richtlinien zu halten.",
- "commGuideList10C": "Beschränkte Berechtigung, Gilden/Wettbewerbe zu gründen",
+ "commGuideList10A1": "Führen Deine Handlungen zur Aufhebung Deiner Chatrechte, wird Dich ein Moderator oder Mitarbeiter per PM und/oder in dem Forum, in dem Du stummgeschaltet wurdest, über die Dauer und Gründe für das Stummschalten informieren. Nach Abauf dieser Zeit erhältst Du Deine Chatrechte zurück, vorausgesetzt Du stimmst zu, Dein Verhalten zu ändern und Dich fortan an die Community-Richtlinien zu halten.",
+ "commGuideList10C": "Beschränkte Berechtigung, Gilden/Herausforderungen zu gründen",
"commGuideList10D": "Der Aufstieg in höhere Mitwirkendenstufen kann temporär verwehrt (\"eingefroren\") werden",
"commGuideList10E": "Herabstufung von Mitwirkenden",
"commGuideList10F": "Nutzer auf \"Bewährung\" setzen",
@@ -107,8 +107,8 @@
"commGuidePara010": "Es gibt außerdem mehrere Moderatoren, welche die Mitarbeiter unterstützen. Sie wurden sorgfältig ausgewählt, also behandle sie mit Respekt und höre Dir ihre Vorschläge an.",
"commGuidePara011": "Die derzeitigen Moderatoren sind (von links nach rechts):",
"commGuidePara011a": "im Tavernen-Chat",
- "commGuidePara011b": "auf GitHub/im Wiki",
- "commGuidePara011c": "im Wiki",
+ "commGuidePara011b": "auf GitHub/Wikia",
+ "commGuidePara011c": "auf Wikia",
"commGuidePara011d": "auf GitHub",
"commGuidePara012": "Falls es bei Deinem Kontakt mit einem Moderator zu Problemen gekommen ist oder Du Bedenken bei einem bestimmten Moderator hegst, sende bitte eine E-Mail an unsere Mitarbeiter (admin@habitica.com).",
"commGuidePara013": "In einer so großen Gemeinschaft wie Habitica kommen und gehen die Nutzer, und manchmal muss ein Mitarbeiter oder Moderator seinen noblen Mantel ablegen und sich entspannen. Nachfolgend sind die Mitarbeiter und Moderatoren Emeritus aufgeführt. Sie handeln nicht mehr mit der Macht eines Mitarbeiters oder Moderators, aber wir möchten ihre Arbeit trotzdem würdigen!",
diff --git a/website/common/locales/de/content.json b/website/common/locales/de/content.json
index c235fb6fa0..6b10b39e14 100644
--- a/website/common/locales/de/content.json
+++ b/website/common/locales/de/content.json
@@ -77,8 +77,8 @@
"questEggBunnyText": "Kaninchen",
"questEggBunnyMountText": "Kaninchen",
"questEggBunnyAdjective": "ein knuddeliges",
- "questEggSlimeText": "Marshmallow-Jungtier",
- "questEggSlimeMountText": "Marshmallow-Reittier",
+ "questEggSlimeText": "Marshmallow-Schleim-Jungtier",
+ "questEggSlimeMountText": "Marshmallow-Schleim-Reittier",
"questEggSlimeAdjective": "ein süßes",
"questEggSheepText": "Schaf",
"questEggSheepMountText": "Schaf",
@@ -350,5 +350,6 @@
"questEggRobotAdjective": "ein futuristischer",
"questEggRobotMountText": "Roboter",
"questEggRobotText": "Roboter",
- "hatchingPotionShadow": "Schatten"
+ "hatchingPotionShadow": "Schatten",
+ "premiumPotionUnlimitedNotes": "Nicht auf Eier von Quest-Haustieren anwendbar."
}
diff --git a/website/common/locales/de/front.json b/website/common/locales/de/front.json
index e6d94df123..260c7a81f9 100644
--- a/website/common/locales/de/front.json
+++ b/website/common/locales/de/front.json
@@ -41,7 +41,7 @@
"elmiQuote": "Jeden Morgen freue ich mich aufzustehen und etwas Gold zu verdienen!",
"forgotPassword": "Passwort vergessen?",
"emailNewPass": "Einen Link per E-Mail senden, um das Passwort zurückzusetzen",
- "forgotPasswordSteps": "Tragen Sie die E-Mail-Adresse ein, mit der Sie Ihren Habitica-Account aktiviert haben.",
+ "forgotPasswordSteps": "Trage die E-Mail-Adresse ein, mit der Du Deinen Habitica-Account aktiviert hast.",
"sendLink": "Link senden",
"evagantzQuote": "Mein erster Zahnarztbesuch, bei dem die Assistentin tatsächlich begeistert über meine Zahnseide-Gewohnheiten war. Danke [Habitica]!",
"examplesHeading": "Spieler benutzen Habitica, um folgendes zu organisieren ...",
@@ -84,7 +84,7 @@
"kazuiQuote": "Vor [Habitica] kam ich mit meiner Dissertation nicht weiter und war unzufrieden mit meiner Selbstdisziplin bei Hausarbeiten, Vokabellernen und dem Studium der Go-Theorie. Es hat sich herausgestellt, dass das Aufteilen der Aufgaben in kleinere, machbare Checklisten etwas ist, das mich motiviert und zum konstanten Arbeiten anregt.",
"landingend": "Noch nicht überzeugt?",
"landingend2": "Sieh Dir hier eine detaillierte Liste der [Funktionen und Spielelemente](/static/overview) an. Oder suchst Du eine vertraulichere Plattform? Dann schau in unsere [Team-Pläne](/static/plans), welche sich vor allem für Familien, Lehrer, Unterstützer und Unternehmen eignen.",
- "landingp1": "Das Problem der meisten Produktivitäts-Apps auf dem Markt ist, dass sie keinen Anreiz bieten, sie dauerhaft zu benutzen. Habitica löst dieses Problem, indem es das Aufbauen von Gewohnheiten zum Spiel macht. Durch Belohnen von Erfolgen und Bestrafen von Misserfolgen, bietet Habitica eine Motivation für Ihre täglichen Aktivitäten.",
+ "landingp1": "Das Problem der meisten Produktivitäts-Apps auf dem Markt ist, dass sie keinen Anreiz bieten, sie dauerhaft zu benutzen. Habitica löst dieses Problem, indem es das Aufbauen von Gewohnheiten zum Spiel macht. Durch Belohnen von Erfolgen und Bestrafen von Misserfolgen, bietet Habitica eine Motivation für Deine täglichen Aktivitäten.",
"landingp2": "Jedes Mal, wenn Du eine gute Angewohnheit trainierst, eine Tagesaufgabe erfüllst oder Dich um ein altes To-Do kümmerst, belohnt Dich Habitica sofort mit Erfahrungspunkten und Gold. Durch Erfahrungspunkte steigst Du im Level auf, verbesserst Deine Statuswerte und schaltest weitere Features wie Klassen und Haustiere frei. Gold kann für Spielgegenstände, die Deinem Charakter nützen, ausgegeben werden oder für persönliche Belohnungen, die Du zur Motivation erstellen kannst. Wenn Dir sogar der kleinste Erfolg eine sofortige Belohnung verspricht, wirst Du Deine Aufgaben immer weniger aufschieben.",
"landingp2header": "Sofortige Belohnung",
"landingp3": "Jedes Mal, wenn Du einer schlechten Angewohnheit nachgibst oder Deine Tagesaufgaben vernachlässigst, verlierst Du Lebenspunkte. Wenn Deine Lebenspunkte zu weit sinken, stirbst Du und verlierst einen Teil Deines Fortschritts. Indem es Konsequenzen setzt, kann Habitica dabei helfen, schlechte Angewohnheiten und ständiges Hinausschieben zu beenden, bevor sie zu Problemen in Deinem Leben werden.",
@@ -110,17 +110,17 @@
"marketing2Lead2Title": "Bezwinge Monster",
"marketing2Lead2": "Was ist schon ein Rollenspiel ohne Kämpfe? Bezwinge Monster mit Deiner Party. Monster sind der \"super Verantwortlichkeitsmodus\": wenn Du an einem Tag nicht ins Fitnessstudio gehst, dann verletzt das Monster *alle!*",
"marketing2Lead3Title": "Fordert Euch gegenseitig heraus",
- "marketing2Lead3": "Bei Wettbewerben kannst Du Dich mit Freunden und Unbekannten messen. Wer sich bis zum Ende des Wettbewerbs am besten schlägt, gewinnt spezielle Preise.",
+ "marketing2Lead3": "Bei Herausforderungen kannst Du Dich mit Freunden und Unbekannten messen. Wer sich bis zum Ende der Herausforderung am besten schlägt, gewinnt spezielle Preise.",
"marketing3Header": "Apps und Erweiterungen",
"marketing3Lead1": "Mit den **iPhone & Android** Apps kannst Du alles von Unterwegs erledigen. Wir wissen, dass es manchmal schwierig ist die Webseite zu benutzen.",
"marketing3Lead2Title": "Einbindungen",
- "marketing3Lead2": "Andere **Tools von Drittanbietern** binden Habitica in Bereiche Deines Lebens ein. Unser API stellt eine einfache Verknüpfung z.B. mit [Chrome Extension](https://chrome.google.com/webstore/detail/habitica/pidkmpibnnnhneohdgjclfdjpijggmjj?hl=en-US) her, die es ermöglicht, für das Besuchen unproduktiver Webseiten Punkte zu verlieren oder für das Besuchen produktiver Webseiten, Punkte zu erhalten. [Mehr dazu hier](http://habitica.fandom.com/wiki/Extensions,_Add-Ons,_and_Customizations).",
- "marketing4Header": "Verwendung zur Organisation",
+ "marketing3Lead2": "Andere **Tools von Drittanbietern** binden Habitica in Bereiche Deines Lebens ein. Unser API stellt eine einfache Verknüpfung z.B. mit [Chrome Extension](https://chrome.google.com/webstore/detail/habitica/pidkmpibnnnhneohdgjclfdjpijggmjj?hl=en-US) her, die es ermöglicht, für das Besuchen unproduktiver Webseiten Punkte zu verlieren oder für das Besuchen produktiver Webseiten Punkte zu erhalten. [Mehr dazu hier](http://habitica.fandom.com/wiki/Extensions,_Add-Ons,_and_Customizations).",
+ "marketing4Header": "Verwendung in einer Organisation",
"marketing4Lead1": "Bildung ist einer der besten Bereiche für Gamifizierung. Wir wissen alle, wie sehr Schüler heutzutage an ihren Handys und Spielen hängen. Nutze diese Macht! Lass Deine Schüler in freundlichen Wettbewerben gegeneinander antreten und belohne gutes Verhalten mit seltenen Preisen. Beobachte, wie sich ihre Noten und ihr Verhalten verbessern.",
"marketing4Lead1Title": "Betrachtungwinkel Ausbildung",
"marketing4Lead2": "Die Kosten für medizinische Versorgung steigen und irgendjemand muss sie tragen. Zahlreiche Pläne wurden entwickelt, um Kosten zu reduzieren und das Wohlbefinden zu verbessern. Wir glauben, dass Habitica einen wesentlichen Beitrag zu gesünderen Lebensstilen leisten kann.",
"marketing4Lead2Title": "Betrachtungswinkel Gesundheit und Erholung",
- "marketing4Lead3-1": "Wollen Sie ihr Leben einmal als Spiel betrachten?",
+ "marketing4Lead3-1": "Willst Du Dein Leben einmal als Spiel betrachten?",
"marketing4Lead3-2": "Willst Du eine Gruppe für Ausbildung, Wohlbefinden usw. leiten?",
"marketing4Lead3-3": "Möchtest Du mehr erfahren?",
"marketing4Lead3Title": "Mache Alles zum Spiel",
@@ -132,7 +132,7 @@
"oldNews": "Neuigkeiten",
"newsArchive": "Neuigkeiten-Archiv auf Wikia (mehrsprachig)",
"passConfirm": "Passwort bestätigen",
- "setNewPass": "Neues Passwort Setzen",
+ "setNewPass": "Neues Passwort setzen",
"passMan": "Falls Du einen Passwortmanager (wie 1Password) verwendest und Probleme beim Einloggen hast, versuche, Deinen Benutzername und Dein Passwort manuell einzugeben.",
"password": "Passwort",
"playButton": "Spielen",
diff --git a/website/common/locales/de/gear.json b/website/common/locales/de/gear.json
index b7383997f4..d5b0d6b481 100644
--- a/website/common/locales/de/gear.json
+++ b/website/common/locales/de/gear.json
@@ -1918,7 +1918,7 @@
"armorSpecialFall2019HealerNotes": "Es heißt, diese Robe sei aus reiner Nacht gemacht. Nutze die dunkle Macht weise! Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2019 Herbstausrüstung.",
"armorSpecialFall2019HealerText": "Robe der Dunkelheit",
"armorSpecialFall2019WarriorText": "Schwingen der Nacht",
- "armorSpecialFall2019RogueText": "Opernkutte mit Kapuze",
+ "armorSpecialFall2019RogueText": "Operncut mit Cape",
"weaponSpecialFall2019HealerText": "Furchterregendes Phylakterium",
"weaponSpecialFall2019MageNotes": "Sei es die Beschwörung von Blitz und Donner, das Hochziehen von Barrikaden oder schlichtweg die Verbreitung von Angst und Schrecken unter den Sterblichen, dieser Stab verleiht Dir die Kraft der Giganten, um Wunder zu bewirken. Erhöht Intelligenz um <%= int %> und Wahrnehmung um <%= per %>. Limitierte Ausgabe 2019 Herbstausrüstung.",
"eyewearSpecialFall2019HealerText": "Dunkles Antlitz",
@@ -1936,5 +1936,28 @@
"headSpecialKS2019Text": "Mythischer Greifenhelm",
"armorSpecialFall2019MageNotes": "Sein Namensvetter wurde von einem schrecklichen Schicksal ereilt. Aber Dich legt man nicht so leicht rein! Gewande Dich mit diesem Mantel aus Legenden und niemand wird Dich übertreffen. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2019 Herbstausrüstung.",
"armorSpecialKS2019Text": "Mytische Greifenrüstung",
- "weaponSpecialKS2019Text": "Mythische Greifenglefe"
+ "weaponSpecialKS2019Text": "Mythische Greifenglefe",
+ "armorArmoireShadowMastersRobeNotes": "Der Stoff dieser fließenden Robe wird aus den dunkelsten Schatten in den tiefsten Höhlen Habiticas gewoben. Erhöht Ausdauer um <%= con %>. Verzauberter Schrank: Schattenmeister Set (Gegenstand 1 von 4).",
+ "armorSpecialFall2019WarriorNotes": "Diese gefiederte Robe befähigt zum Fliegen, sie erlaubt Dir Dich über alle Kämpfe zu erheben. Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2019 Herbstausrüstung.",
+ "armorSpecialKS2019Notes": "Von innen heraus strahlend wie das noble Herz eines Greifes, ermutigt Dich diese prächtige Rüstung dazu stolz auf Deine Errungenschaften zu sein. Erhöht Ausdauer um <%= con %>.",
+ "weaponArmoireShadowMastersMaceNotes": "Kreaturen der Dunkelheit werden jedem Deiner Befehle folgen, wenn Du diesen leuchtenden Streitkolben schwingst. Erhöht Wahrnehmung um <%= per %>. Verzauberter Schrank: Schattenmeister Set (Gegenstand 3 von 4).",
+ "headArmoireShadowMastersHoodText": "Kapuze des Schattenmeisters",
+ "armorArmoireShadowMastersRobeText": "Robe des Schattenmeisters",
+ "weaponArmoireShadowMastersMaceText": "Streitkolben des Schattenmeisters",
+ "weaponSpecialFall2019HealerNotes": "Dieses Phylakterium kann die Geister längst niedergestreckter Aufgaben anrufen und ihre Heilkraft nutzen. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2019 Herbstausrüstung.",
+ "weaponSpecialKS2019Notes": "Gebogen wie des Greifen Schnabel und Krallen, erinnert Dich diese verzierte Stangenwaffe daran Dich durchzubeißen, wenn die bevorstehende Aufgabe einschüchternd wirkt. Erhöht Stärke um <%= str %>.",
+ "shieldArmoireMasteredShadowText": "Gemeisterter Schatten",
+ "headMystery201909Text": "Einnehmender Eichelhut",
+ "eyewearSpecialFall2019HealerNotes": "Stähle Dich gegen die härtesten Feinde mit dieser undurchschaubaren Maske. Gewährt keinen Attributbonus. Limitierte Ausgabe 2019 Herbstausrüstung.",
+ "eyewearSpecialFall2019RogueNotes": "Man sollte meinen, dass eine Vollmaske Deine Identität besser schützen würde, aber die Menschen neigen dazu, zu sehr von diesem schlichten Design beeindruckt zu sein, um alle identifizierenden Merkmale zur Kenntnis zu nehmen, die offenbart bleiben. Gewährt keinen Attributbonus. Limitierte Ausgabe 2019 Herbstausrüstung.",
+ "shieldArmoireMasteredShadowNotes": "Deine Kräfte haben diese wirbelnden Schatten auf Deine Seite gebracht, um Dir zu dienen. Erhöht Wahrnehmung und Ausdauer um je <%= attrs %>. Verzauberter Schrank: Schattenmeister-Set (Gegenstand 4 von 4).",
+ "shieldSpecialFall2019WarriorNotes": "Der dunkle Glanz einer Rabenfeder wurde verfestigt: dieser Schild wird alle Angriffe vereiteln. Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2019 Herbstausrüstung.",
+ "shieldSpecialKS2019Notes": "Dieser prächtige Schild funkelt wie die Schale eines Greifeneis und zeigt Dir, wie Du bereit sein kannst zu helfen, wenn Deine eigenen Lasten leicht sind. Erhöht Wahrnehmung um <%= per %>.",
+ "headArmoireShadowMastersHoodNotes": "Diese Kapuze gibt dir die Kraft, auch durch die tiefste Dunkelheit zu sehen. Sie kann jedoch gelegentlich Augentropfen benötigen. Erhöht Wahrnehmung und Ausdauer um je <%= attrs %>. Verzauberter Schrank: Schattenmeister-Set (Gegenstand 2 von 4).",
+ "headMystery201909Notes": "Jede Eichel braucht einen Hut! Äh, Becher, wenn Du technisch werden willst. Gewährt keinen Attributbonus. Abonnentengegenstand, September 2019.",
+ "headSpecialFall2019HealerNotes": "Zieh diese dunkle Mitra an, um die Kräfte des furchterregenden Lichs zu nutzen. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2019 Herbstausrüstung.",
+ "headSpecialFall2019MageNotes": "Ihr einzelnes bösartiges Auge hemmt die Tiefenwahrnehmung, aber das ist ein kleiner Preis für die Art und Weise, wie sie Deinen Fokus auf einen einzigen, intensiven Punkt lenkt. Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2019 Herbstausrüstung.",
+ "headSpecialFall2019WarriorNotes": "Die dunklen Augenhöhlen dieses Schädelhelms werden auch die Mutigsten Deiner Feinde abschrecken.Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2019 Herbstausrüstung.",
+ "headSpecialKS2019Notes": "Dieser glorreiche Helm, der mit einem Greifenbild und Gefieder geschmückt ist, symbolisiert die Art und Weise, wie Deine Fähigkeiten und Deine Haltung als Vorbild für andere stehen. Erhöht Intelligenz um <%= int %>.",
+ "armorSpecialFall2019RogueNotes": "Dieses Outfit wird komplett mit weißen Handschuhen geliefert und ist ideal, um in Deiner Privatloge über der Bühne zu brüten oder überraschende Auftritte auf der großen Treppe zu machen. Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2019 Herbstausrüstung."
}
diff --git a/website/common/locales/de/groups.json b/website/common/locales/de/groups.json
index 10ab1d56d3..ec071681f4 100644
--- a/website/common/locales/de/groups.json
+++ b/website/common/locales/de/groups.json
@@ -5,7 +5,7 @@
"innCheckIn": "Im Gasthaus erholen",
"innText": "Du erholst Dich im Gasthaus! Während Du dort verweilst, werden Dir Deine Tagesaufgaben keinen Schaden zufügen, aber trotzdem täglich aktualisiert. Vorsicht: Wenn Du an einem Bosskampf teilnimmst, erhältst Du weiterhin Schaden für die verpassten Aufgaben Deiner Gruppenmitglieder, sofern sich diese nicht auch im Gasthaus befinden! Außerdem wird der Schaden, den Du dem Boss zufügst, (und gefundene Gegenstände) erst angewendet, wenn Du das Gasthaus verlässt.",
"innTextBroken": "Du erholst Dich im Gasthaus, schätze ich ... Während Du dort verweilst, werden Dir Deine Tagesaufgaben keinen Schaden zufügen, aber trotzdem täglich aktualisiert ... Wenn Du an einem Bosskampf teilnimmst, erhältst Du weiterhin Schaden für die verpassten Tagesaufgaben Deiner Gruppenmitglieder ... sofern sich diese nicht auch im Gasthaus befinden ... Außerdem wird Dein Schaden am Boss (oder gesammelte Gegenstände) nicht berücksichtigt, bis Du das Gasthaus verlässt ... So müde ...",
- "innCheckOutBanner": "Du hast derzeit in das Gasthaus eingecheckt. Deine Tagesaufgaben können Dir nicht schaden und Du erzielst keinen Fortschritt bei Deinen Quests.",
+ "innCheckOutBanner": "Du bist derzeit im Gasthaus eingecheckt. Deine Tagesaufgaben können Dir nicht schaden und Du erzielst keinen Fortschritt bei Deinen Quests.",
"innCheckOutBannerShort": "Du bist im Gasthaus eingecheckt.",
"resumeDamage": "Schaden fortsetzen",
"helpfulLinks": "Weiterführende Links",
@@ -18,14 +18,14 @@
"askQuestionGuild": "Stell eine Frage (Habitica Hilfe Gilde)",
"contributing": "Mitwirken",
"faq": "Häufige Fragen",
- "lfgPosts": "Nach Gruppeneinträgen suchen",
+ "lfgPosts": "Nach neuen Party-Mitgliedern suchen",
"tutorial": "Anleitung",
"glossary": "Glossar",
"wiki": "Wiki",
"wikiLink": "Wiki",
"reportAP": "Problem melden",
"requestAF": "Feature vorschlagen",
- "community": "Forum",
+ "community": "Community Forum",
"dataTool": "Werkzeug zur Datenanzeige",
"resources": "Ressourcen",
"askQuestionNewbiesGuild": "Stelle eine Frage (Die Habitica-Help-Gilde)",
@@ -36,7 +36,7 @@
"communityGuidelinesRead1": "Bitte lies unsere",
"communityGuidelinesRead2": "vor dem Chatten.",
"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.",
+ "bannedSlurUsed": "Dein Beitrag enthielt unangebrachten Inhalt und Deine Chat Privilegien wurden Dir entzogen.",
"party": "Party",
"createAParty": "Party erstellen",
"updatedParty": "Partyeinstellungen wurden aktualisiert.",
@@ -52,7 +52,7 @@
"userId": "Benutzer-ID",
"invite": "Einladen",
"leave": "Verlassen",
- "invitedToParty": "Du wurdest zu der Party <%= party %> eingeladen",
+ "invitedToParty": "Du wurdest in die Party <%= party %> eingeladen",
"invitedToPrivateGuild": "Du wurdest eingeladen, der privaten Gilde <%= guild %> beizutreten",
"invitedToPublicGuild": "Du wurdest eingeladen, der Gilde <%= guild %> beizutreten",
"partyInvitationsText": "Du hast <%= numberInvites %> Einladungen, einer Party beizutreten! Überlege Dir gut für welche Du Dich entscheidest, da Du immer nur in einer Party sein kannst.",
@@ -70,7 +70,7 @@
"newMsgParty": "Deine Party, <%= name %>, hat neue Beiträge",
"chat": "Chat",
"sendChat": "Nachricht senden",
- "toolTipMsg": "Nachrichten abholen",
+ "toolTipMsg": "Neue Nachrichten abholen",
"sendChatToolTip": "Du kannst eine Nachricht mit der Tastatur senden, indem Du mit Tab zum Senden-Knopf wechselst und Enter drückst, oder durch Drücken von Strg (Cmd auf einem Mac) + Enter.",
"syncPartyAndChat": "Synchronisiere Party und Chat",
"guildBankPop1": "Gildenbank",
@@ -88,7 +88,7 @@
"members": "Mitglieder",
"memberList": "Mitglieder-Liste",
"partyList": "Sortierung der Gruppenmitglieder in der Kopfzeile",
- "banTip": "Mitglied ausschließen",
+ "banTip": "Mitglied rauswerfen",
"moreMembers": "weitere Mitglieder",
"invited": "Eingeladen",
"leaderMsg": "Nachricht vom Gruppenleiter (Markdown Okay)",
@@ -96,7 +96,7 @@
"description": "Beschreibung",
"public": "Öffentlich",
"inviteOnly": "Nur auf Einladung",
- "gemCost": "Die Edelsteinkosten fördern Gilden von hoher Qualität, die Edelsteine werden direkt auf Eure Gildenbank transferiert. Von dort können sie für Gildenwettbewerbe verwendet werden!",
+ "gemCost": "Die Edelsteinkosten fördern Gilden von hoher Qualität, die Edelsteine werden direkt auf Eure Gildenbank transferiert. Von dort können sie für Gildenherausforderungen verwendet werden!",
"search": "Suchen",
"publicGuilds": "Öffentliche Gilden",
"createGuild": "Gilde gründen",
@@ -109,20 +109,20 @@
"yesRemove": "Ja, entferne sie",
"foreverAlone": "\"Gefällt mir\" funktioniert nicht bei eigenen Nachrichten. Sei nicht so einer.",
"sortBackground": "Nach Hintergrund sortieren",
- "sortClass": "Sortiere nach Klasse",
+ "sortClass": "Nach Klasse sortieren",
"sortDateJoined": "Nach Beitrittsdatum sortieren",
- "sortLogin": "Sortiere nach Login Datum",
+ "sortLogin": "Nach Login Datum sortieren",
"sortLevel": "Nach Level sortieren",
- "sortName": "Sortiere nach Name",
+ "sortName": "Nach Name sortieren",
"sortTier": "Nach Rang sortieren",
"ascendingAbbrev": "Aufsteigend",
"descendingAbbrev": "Absteigend",
"applySortToHeader": "Sortieroptionen auf die Party-Kopfzeile anwenden",
"confirmGuild": "Gilde für 4 Edelsteine gründen?",
- "leaveGroupCha": "Gildenwettbewerbe verlassen und ...",
+ "leaveGroupCha": "Gildenherausforderungen verlassen und ...",
"confirm": "Bestätigen",
"leaveGroup": "Gilde verlassen",
- "leavePartyCha": "Gruppenwettbewerbe verlassen und...",
+ "leavePartyCha": "Partyherausforderungen verlassen und...",
"leaveParty": "Party verlassen",
"sendPM": "Private Nachricht schicken",
"send": "Abschicken",
@@ -134,7 +134,7 @@
"confirmDeleteAllMessages": "Bist Du sicher, dass Du alle Nachrichten im Posteingang löschen möchtest? Andere Benutzer können immer noch die Nachrichten sehen, die Du ihnen geschickt hast.",
"PMPlaceholderTitle": "Es gibt noch nichts hier",
"PMPlaceholderDescription": "Wähle links ein Gespräch aus",
- "PMPlaceholderTitleRevoked": "Dir wurden Deine Chat Privilegien entzogen",
+ "PMPlaceholderTitleRevoked": "Dir wurden Deine Chat-Privilegien entzogen",
"PMPlaceholderDescriptionRevoked": "Du kannst keine privaten Nachrichten versenden, weil deine Chat-Berechtigung entzogen wurde. Bitte kontaktiere admin@habitica.com, falls Du Deine Fragen oder Anliegen dazu ansprechen möchtest.",
"PMReceive": "Private Nachrichten erhalten",
"PMEnabledOptPopoverText": "Private Nachrichten sind aktiviert. Benutzer können Dich über Dein Profil kontaktieren.",
@@ -163,7 +163,7 @@
"abuseAlreadyReported": "Du hast diese Nachricht bereits gemeldet.",
"whyReportingPost": "Wieso meldest Du diesen Post?",
"whyReportingPostPlaceholder": "Bitte hilf unseren Moderatoren und gib einen Grund an, warum Du diesen Beitrag als Verstoß gemeldet hast, z.B. Spam, Fluchen, Religiöse Schwüre, Intoleranz, Beleidigungen, Nicht jugendfreie Themen, Gewalt.",
- "optional": "Wahlweise",
+ "optional": "Optional",
"needsText": "Bitte gib eine Nachricht ein.",
"needsTextPlaceholder": "Gib Deine Nachricht hier ein.",
"copyMessageAsToDo": "Nachricht als To-Do übernehmen",
@@ -171,7 +171,7 @@
"messageAddedAsToDo": "Nachricht als To-Do übernommen.",
"messageWroteIn": "<%= user %> schrieb in <%= group %>",
"msgPreviewHeading": "Nachrichtenvorschau",
- "leaderOnlyChallenges": "Nur der Gruppenleiter kann Wettbewerbe erstellen",
+ "leaderOnlyChallenges": "Nur der Gruppenleiter kann Herausforderungen erstellen",
"sendGift": "Geschenk schicken",
"inviteFriends": "Lade Freunde ein",
"partyMembersInfo": "Deine Party hat aktuell <%= memberCount %> Mitglieder und <%= invitationCount %> ausstehende Einladungen. Die maximale Anzahl an Mitgliedern in einer Party ist <%= limitMembers %>. Einladungen über diesem Limit können nicht verschickt werden.",
@@ -190,7 +190,7 @@
"invitedFriend": "Hat einen Freund eingeladen",
"invitedFriendText": "Dieser Benutzer hat einen Freund (oder Freunde) eingeladen, die ihn nun bei diesem Abenteuer begleiten!",
"inviteAlertInfo2": "Oder teile diesen Link (kopieren/einfügen):",
- "inviteLimitReached": "Du hast bereits die maximale Anzahl an E-Mail-Einladungen verschickt. Wir haben ein Limit, um Spam-Mails zu vermeiden. Wenn du mehr Einladungen versenden möchtest, schreibe uns unter <%= techAssistanceEmail %> und wir werden eine gemeinsame Lösung finden!",
+ "inviteLimitReached": "Du hast bereits die maximale Anzahl an E-Mail-Einladungen verschickt. Wir haben ein Limit, um Spam-Mails zu vermeiden. Wenn Du mehr Einladungen versenden möchtest, schreibe uns unter <%= techAssistanceEmail %> und wir werden eine gemeinsame Lösung finden!",
"sendGiftHeading": "Sende Geschenk an <%= name %>",
"sendGiftGemsBalance": "Von <%= number %> Edelsteinen",
"sendGiftCost": "Insgesamt: $<%= cost %> USD",
@@ -205,7 +205,7 @@
"addToParty": "Füge jemanden Deiner Party hinzu",
"likePost": "Klicke wenn Dir dieser Beitrag gefällt!",
"partyExplanation1": "Spiele Habitica mit Freunden, um verantwortungsbewusst zu bleiben!",
- "partyExplanation2": "Bekämpfe Monster und nimm an Wettbewerben teil!",
+ "partyExplanation2": "Bekämpfe Monster und nimm an Herausforderungen teil!",
"partyExplanation3": "Lade jetzt Freunde ein und erhalte eine Questschriftrolle!",
"wantToStartParty": "Willst Du eine Party gründen?",
"exclusiveQuestScroll": "Wenn Du Freunde in Deine Party einlädst, erhältst Du eine exklusive Questschriftrolle, mit der ihr gemeinsam den Basi-List bekämpfen könnt!",
@@ -230,8 +230,8 @@
"canOnlyInviteEmailUuid": "Du kannst nur über Benutzer ID, E-Mail oder Benutzernamen einladen.",
"inviteMissingEmail": "Fehlende E-Mailadresse zum Einladen.",
"inviteMissingUuid": "User-ID in der Einladung fehlt",
- "inviteMustNotBeEmpty": "Einladung muss Daten enthalten.",
- "partyMustbePrivate": "Gruppen müssen privat sein",
+ "inviteMustNotBeEmpty": "Einladung darf nicht leer sein.",
+ "partyMustbePrivate": "Partys müssen privat sein",
"userAlreadyInGroup": "Nutzer-ID: <%= userId %>, Nutzer \"<%= username %>\" ist bereits in dieser Gruppe.",
"youAreAlreadyInGroup": "Du bist bereits Mitglied dieser Gruppe.",
"cannotInviteSelfToGroup": "Du kannst Dich nicht selbst in eine Gruppe einladen.",
@@ -245,8 +245,8 @@
"emailsMustBeAnArray": "E-Mail-Adress-Einladungen müssen ein Array sein.",
"usernamesMustBeAnArray": "Benutzernamen-Einladungen müssen ein Array sein.",
"canOnlyInviteMaxInvites": "Du kannst nur \"<%= maxInvites %>\" Benutzer gleichzeitig einladen",
- "partyExceedsMembersLimit": "Die Gruppengröße ist begrenzt auf <%= maxMembersParty %> Mitglieder",
- "onlyCreatorOrAdminCanDeleteChat": "Löschen der Nachricht nicht erlaubt!",
+ "partyExceedsMembersLimit": "Die Partygröße ist begrenzt auf <%= maxMembersParty %> Mitglieder",
+ "onlyCreatorOrAdminCanDeleteChat": "Keine Berechtigung diese Nachricht zu löschen!",
"onlyGroupLeaderCanEditTasks": "Nicht berechtigt, Aufgaben zu bearbeiten!",
"onlyGroupTasksCanBeAssigned": "Nur Team-Aufgaben können verteilt werden",
"assignedTo": "Zugewiesen an",
@@ -254,7 +254,7 @@
"assignedToMembers": "<%= userCount %> Mitgliedern zugewiesen",
"assignedToYouAndMembers": "Dir und <%= userCount %> Mitliedern zugewiesen",
"youAreAssigned": "Du bist dieser Aufgabe zugewiesen",
- "taskIsUnassigned": "Dieser Aufgabe ist niemand zugewiesen",
+ "taskIsUnassigned": "Diese Aufgabe ist niemandem zugewiesen",
"confirmClaim": "Bist Du sicher, dass Du diese Aufgabe beanspruchen möchtest?",
"confirmUnClaim": "Bist Du sicher, dass Du diese Aufgabe abgeben möchtest?",
"confirmApproval": "Bist Du sicher, dass Du dieser Aufgabe zustimmen möchtest?",
@@ -265,11 +265,11 @@
"chatPrivilegesRevoked": "Du kannst dies nicht tun, da Dir Deine Chat-Privilegien entzogen wurden. Für genauere Angaben oder um zu fragen, ob Dir Deine Chat-Privilegien zurückgegeben werden können, schreibe bitte eine E-Mail an den Community-Manager unter admin@habitica.com oder bitte Deine Eltern diese E-Mail zu schreiben. Bitte gib Deinen @Usernamen in der E-Mail an. Falls ein Moderator Dir bereits mitgeteilt hat, dass diese Sperre zeitlich begrenzt ist, brauchst Du keine E-Mail zu schreiben.",
"cannotCreatePublicGuildWhenMuted": "Du kannst keine öffentliche Gilde erstellen, da Dir Deine Chat-Privilegien entzogen wurden.",
"cannotInviteWhenMuted": "Du kannst niemanden zu einer Party oder Gilde einladen, da Dir Deine Chat-Privilegien entzogen wurden.",
- "newChatMessagePlainNotification": "Neue Nachricht in <%= groupName %> von <%= authorName %>. Hier geht's zur Chat Seite!",
+ "newChatMessagePlainNotification": "Neue Nachricht in <%= groupName %> von <%= authorName %>. Hier geht's zur Chat-Seite!",
"newChatMessageTitle": "Neue Nachricht in <%= groupName %>",
"exportInbox": "Nachrichten exportieren",
"exportInboxPopoverTitle": "Exportiere Deine Nachrichten als HTML",
- "exportInboxPopoverBody": "HTML erlaubt es Nachrichten einfach im Browser zu lesen. Für ein Maschinen-lesbares Format, verwende Daten > Daten exportieren",
+ "exportInboxPopoverBody": "HTML erlaubt es Nachrichten einfach im Browser zu lesen. Für ein maschinenlesbares Format verwende Daten > Daten exportieren",
"to": "An:",
"from": "Von:",
"desktopNotificationsText": "Wir benötigen Deine Erlaubnis, um die Desktop-Benachrichtigungen für neue Nachrichten im Gruppen-Chat zu aktivieren! Folge den Anweisungen Deines Browsers um sie anzuschalten.
Du wirst diese Benachrichtigungen nur erhalten, solange Habitica geöffnet ist. Wenn Dir diese nicht gefallen sollten, können sie in Deinen Browser-Einstellungen deaktiviert werden.
Dieser Hinweis wird automatisch geschlossen, sobald eine Entscheidung getroffen wurde.",
@@ -298,16 +298,16 @@
"groupBenefitTwoTitle": "Weise Gruppenmitgliedern Aufgaben zu",
"groupBenefitTwoDescription": "Möchtest Du, dass ein Kollege eine wichtige E-Mail beantwortet? Soll Dein Mitbewohner Lebensmittel mitbringen? Weise ihnen Aufgaben zu, die Du erstellst, und sie werden automatisch in deren Aufgabenliste erscheinen.",
"groupBenefitThreeTitle": "Kennzeichne Aufgaben, an denen Du arbeitest",
- "groupBenefitThreeDescription": "Sichere Dir eine Team-Aufgabe mit nur einem Klick. Dadurch wird klar, woran die Gruppenmitglieder gerade arbeiten!",
+ "groupBenefitThreeDescription": "Sichere Dir eine Gruppen-Aufgabe mit nur einem Klick. Dadurch wird klar, woran die Gruppenmitglieder gerade arbeiten!",
"groupBenefitFourTitle": "Markiere Aufgaben, die eine besondere Zustimmung brauchen",
"groupBenefitFourDescription": "Muss die Erledigung einer Aufgabe erst überprüft werden, bevor der Nutzer seine Belohnung dafür erhält? Passe einfach nur die Zustimmungs-Einstellungen an, um zusätzliche Kontrolle zu erhalten.",
"groupBenefitFiveTitle": "Kommuniziere privat mit Deinem Team",
- "groupBenefitFiveDescription": "Bleib auf dem Laufenden über wichtige Entscheidungen in dem einfach zu benutzenden Chatraum!",
+ "groupBenefitFiveDescription": "Bleib auf dem Laufenden über wichtige Entscheidungen im einfach zu benutzenden Chatraum!",
"groupBenefitSixTitle": "Erhalte ein kostenloses Abonnement",
- "groupBenefitSixDescription": "Erhalte volle Abonnenten-Vorteile mit exklusiven monatlichen Gegenständen und der Möglichkeit, Edelsteine mit Gold zu kaufen! (Wenn Du bereits über ein Abonnement verfügst, wird Dein bisheriges Abonnement beendet, deine aufeinanderfolgenden Abonnenten-Vorteile wie monatliche mystische Sanduhren bleiben jedoch erhalten.)",
+ "groupBenefitSixDescription": "Erhalte volle Abonnenten-Vorteile mit exklusiven monatlichen Gegenständen und der Möglichkeit, Edelsteine mit Gold zu kaufen! (Wenn Du bereits über ein Abonnement verfügst, wird Dein bisheriges Abonnement beendet, Deine aufeinanderfolgenden Abonnenten-Vorteile wie monatliche mystische Sanduhren bleiben jedoch erhalten.)",
"groupBenefitSevenTitle": "Erhalte ein brandneues, exklusives Wolpertinger-Reittier",
"groupBenefitEightTitle": "Füge Gruppen-Organisatoren hinzu, damit sie helfen die Aufgaben zu organisieren",
- "groupBenefitEightDescription": "Möchtest du die Gruppenverantwortung aufteilen? Befördere Andere zu Gruppen-Organisatoren, die dem Gruppenleiter helfen, Aufgaben hinzuzufügen, zuzuordnen und zuzustimmen!",
+ "groupBenefitEightDescription": "Möchtest Du die Gruppenverantwortung aufteilen? Befördere Andere zu Gruppen-Organisatoren, die dem Gruppenleiter helfen, Aufgaben hinzuzufügen, zuzuordnen und zuzustimmen!",
"groupBenefitMessageLimitTitle": "Erhöhe die Höchstanzahl der Nachrichten",
"groupBenefitMessageLimitDescription": "Dein Nachrichtenlimit wird verdoppelt auf bis zu 400 Nachrichten!",
"teamBasedTasks": "Gruppenorientierte Aufgaben",
@@ -315,16 +315,16 @@
"funExtras": "Spaßige Extras",
"enterprisePlansButton": "Frage nach Unternehmensplänen",
"enterprisePlansDescription": "Suchst Du nach einer größeren Installation mit Nutzerbedürfnissen? Vielleicht sind unsere Unternehmenspläne genau das Richtige für Dich.",
- "familyPlansButton": "Melde dich für eine Familienplan-Nachrichtenliste an",
+ "familyPlansButton": "Melde Dich für eine Familienplan-Nachrichtenliste an",
"familyPlansDescription": "Suchst Du nach einer gemütlicheren Lösung Deinen Haushalt zu organisieren? Bald gibt es Familienpläne!",
"createAGroup": "Erstelle eine Gruppe",
- "getAGroupPlanToday": "Erhalte noch heute einen Gruppenplan",
+ "getAGroupPlanToday": "Besorg Dir noch heute einen Gruppenplan",
"assignFieldPlaceholder": "Gib den Profilnamen eines Gruppen-Mitglieds ein",
"cannotDeleteActiveGroup": "Du kannst keine Gruppe mit einem laufenden Abonnement löschen",
"groupTasksTitle": "Gruppen-Aufgabenliste",
"approvalsTitle": "Aufgaben-Zustimmung erwartet",
"upgradeTitle": "Upgrade",
- "blankApprovalsDescription": "Wenn Deine Gruppe Aufgaben erledigt, die deine Zustimmung brauchen, erscheinen sie hier! Passe die Zustimmungs-Einstellungen in den Aufgaben an.",
+ "blankApprovalsDescription": "Wenn Deine Gruppe Aufgaben erledigt, die Deine Zustimmung brauchen, erscheinen sie hier! Passe die Zustimmungs-Einstellungen in den Aufgaben an.",
"userIsClamingTask": "`<%= username %> beansprucht:` <%= task %>",
"approvalRequested": "Zustimmung erbeten",
"refreshApprovals": "Zustimmungen aktualisieren",
@@ -339,13 +339,13 @@
"aboutToJoinCancelledGroupPlan": "Du bist dabei einer Gruppe mit gekündigtem Plan beizutreten. Du erhältst KEIN freies Abonnement.",
"cannotChangeLeaderWithActiveGroupPlan": "Du kannst den Leiter nicht ändern während das Team einen aktiven Plan hat.",
"leaderCannotLeaveGroupWithActiveGroup": "Ein Leiter kann eine Gruppe nicht verlassen, während es noch einen aktiven Plan gibt",
- "youHaveGroupPlan": "Du hast ein kostenloses Abonnement, weil Du einer Gruppe angehörst, die einen Gruppenplan hat. Dies endet, wenn Du die Gruppe mit dem Gruppenplan verlässt. Deine zusätzlichen Abonnementsguthaben-Monate werden nach Ablauf des Gruppenplans fortgesetzt.",
- "cancelGroupSub": "Gruppenplan abbrechen",
+ "youHaveGroupPlan": "Du hast ein kostenloses Abonnement, weil Du einer Gruppe angehörst, die einen Gruppenplan hat. Dies endet, wenn Du die Gruppe mit dem Gruppenplan verlässt. Deine zusätzlichen Abonnementsguthaben-Monate aus anderen Abonnementen werden nach Ablauf des Gruppenplans fortgesetzt.",
+ "cancelGroupSub": "Gruppenplan kündigen",
"confirmCancelGroupPlan": "Bist Du Dir sicher, dass Du Deinen Gruppenplan abbrechen möchtest? Alle Gruppenmitglieder werden ihre Abonnements und die Vorteile verlieren.",
"canceledGroupPlan": "Gruppenplan abgebrochen",
"groupPlanCanceled": "Der Gruppenplan wird inaktiv am",
"purchasedGroupPlanPlanExtraMonths": "Du hast <%= months %> Monate zusätzliches Gruppenplan-Guthaben.",
- "addManager": "Organistator zuweisen",
+ "addManager": "Organisator zuweisen",
"removeManager2": "Organisator-Zuordnung aufheben",
"userMustBeMember": "Der Nutzer muss ein Mitglied sein",
"userIsNotManager": "Der Nutzer ist kein Organisator",
@@ -360,20 +360,20 @@
"guildMembers": "Gildenmitglieder",
"guildBank": "Gildenbankkonto",
"chatPlaceholder": "Füge die Botschaft an Gildenmitglieder hier ein",
- "partyChatPlaceholder": "Füge die Botschaft an Gruppenmitglieder hier ein",
- "fetchRecentMessages": "Neue Nachrichten Abrufen",
+ "partyChatPlaceholder": "Füge die Botschaft an Partymitglieder hier ein",
+ "fetchRecentMessages": "Neue Nachrichten abrufen",
"like": "Like",
"liked": "Liked",
"joinGuild": "Der Gilde beitreten",
- "inviteToGuild": "In Gilde Einladen",
+ "inviteToGuild": "In Gilde einladen",
"inviteToParty": "In die Party einladen",
"inviteEmailUsername": "Via E-Mail oder Benutzernamen einladen",
"inviteEmailUsernameInfo": "Einladung von Benutzern über eine gültige E-Mailadresse oder Benutzernamen. Wenn eine E-Mail noch nicht registriert ist, werden wir sie einladen, beizutreten.",
"emailOrUsernameInvite": "E-Mailadresse oder Benutzername",
- "messageGuildLeader": "Gildenleiter Benachrichtigen",
- "donateGems": "Edelsteine Spenden",
- "updateGuild": "Gilde Aktualisieren",
- "viewMembers": "Mitglieder Ansehen",
+ "messageGuildLeader": "Gildenleiter benachrichtigen",
+ "donateGems": "Edelsteine spenden",
+ "updateGuild": "Gilde aktualisieren",
+ "viewMembers": "Mitglieder ansehen",
"memberCount": "Anzahl Mitglieder",
"recentActivity": "Kürzliche Aktivitäten",
"myGuilds": "Meine Gilden",
@@ -387,25 +387,25 @@
"silverTier": "Silber",
"bronzeTier": "Bronze",
"privacySettings": "Datenschutzeinstellungen",
- "onlyLeaderCreatesChallenges": "Nur der Leiter kann Wettbewerbe erstellen",
- "onlyLeaderCreatesChallengesDetail": "Wenn diese Option ausgewählt ist, können gewöhnliche Gruppenmitglieder keine Wettbewerbe für die Gruppe erstellen.",
+ "onlyLeaderCreatesChallenges": "Nur der Leiter kann Herausforderungen erstellen",
+ "onlyLeaderCreatesChallengesDetail": "Wenn diese Option ausgewählt ist, können gewöhnliche Gruppenmitglieder keine Herausforderungen für die Gruppe erstellen.",
"privateGuild": "Private Gilde",
"charactersRemaining": "<%= characters %> Zeichen übrig",
"guildSummary": "Zusammenfassung",
- "guildSummaryPlaceholder": "Schreibe eine Kurzbeschreibung um Deine Gilde anderen Habiticanern bekannt zu machen. Was ist der Hauptzweck der Gilde und warum sollten Leute dem ihr beitreten? Verwende hilfreiche Schlüsselwörter in der Beschreibung, um die Suche für andere Habiticaner zu erleichtern!",
+ "guildSummaryPlaceholder": "Schreibe eine Kurzbeschreibung um Deine Gilde anderen Habiticanern bekannt zu machen. Was ist der Hauptzweck der Gilde und warum sollten Leute ihr beitreten? Verwende hilfreiche Schlüsselwörter in der Beschreibung, um die Suche für andere Habiticaner zu erleichtern!",
"groupDescription": "Beschreibung",
"guildDescriptionPlaceholder": "Nutze diesen Abschnitt um alles, was Mitglieder der Gilde über Deine Gilde wissen sollten, ausführlicher darzustellen. Nützliche Tipps, hilfreiche Links und ermutigende Worte gehören hier hin!",
"markdownFormattingHelp": "[Markdown Formatierungshilfe](http://habitica.fandom.com/wiki/Markdown_Cheat_Sheet)",
"partyDescriptionPlaceholder": "Das ist unsere Partybeschreibung. Sie beschreibt, was wir in unserer Party so tun. Wenn Du mehr darüber wissen willst, was wir in unserer Party so machen, lies die Beschreibung. Party on!",
- "guildGemCostInfo": "Eine Edelstein-Gebühr fördert die Qualität der Gilde und wird der Gildenbank gutgeschrieben.",
+ "guildGemCostInfo": "Eine Edelstein-Gebühr fördert die Qualität der Gilden und wird der Gildenbank gutgeschrieben.",
"noGuildsTitle": "Du bist nicht Mitglied einer Gilde.",
"noGuildsParagraph1": "Gilden sind von anderen Spielern erstellte soziale Gruppen, die Dir Unterstützung, Verantwortlichkeit und aufmunternde Unterhaltung bieten können.",
- "noGuildsParagraph2": "Klicke auf den \"Gilden entdecken\"-Reiter, um basierend auf Deinen Interessen empfohlene Gilden zu sehen, stöbere durch Habitica's öffentliche Gilden, oder erstelle Deine eigene Gilde.",
+ "noGuildsParagraph2": "Klicke auf den \"Gilden entdecken\"-Reiter, um basierend auf Deinen Interessen empfohlene Gilden zu sehen, stöbere durch Habiticas öffentliche Gilden, oder erstelle Deine eigene Gilde.",
"noGuildsMatchFilters": "Wir haben keine passenden Gilden gefunden.",
"privateDescription": "Private Gilden werden nicht in Habiticas Gildenübersicht angezeigt. Neue Mitglieder können nur durch eine Einladung hinzugefügt werden.",
"removeInvite": "Einladung entfernen",
- "removeMember": "Mitglied Entfernen",
- "sendMessage": "Nachricht Senden",
+ "removeMember": "Mitglied entfernen",
+ "sendMessage": "Nachricht senden",
"promoteToLeader": "Gruppenleitung übertragen",
"inviteFriendsParty": "Wenn Du Freunde in Deine Party einlädst, erhältst Du eine exklusive Questschriftrolle, mit der Ihr gemeinsam den Basi-List bekämpfen könnt!",
"upgradeParty": "Upgrade die Party",
@@ -416,21 +416,21 @@
"startYourOwnPartyTitle": "Starte Deine eigene Party",
"startYourOwnPartyDescription": "Bezwinge Monster allein oder lade so viele Deiner Freunde ein, wie Du möchtest!",
"wantToJoinPartyTitle": "Möchtest Du einer Party beitreten?",
- "wantToJoinPartyDescription": "Gib Deinen Benutzernamen einem Freund an, der bereits eine Party hat, oder gehe zur Gilde \"Party wanted\", um potenzielle Verbündete zu finden!",
+ "wantToJoinPartyDescription": "Gib Deinen Benutzernamen einem Freund an, der bereits in einer Party ist, oder gehe zur Gilde \"Party wanted\", um potenzielle Verbündete zu finden!",
"copy": "Kopieren",
"inviteToPartyOrQuest": "Party zur Quest einladen",
"inviteInformation": "Indem Du auf \"Einladen\" klickst, sendest Du eine Einladung an Deine Partymitglieder. Sobald alle Mitglieder diese angenommen oder abgelehnt haben, beginnt die Quest.",
"questOwnerRewards": "Belohnungen für Besitzer der Quest",
"updateParty": "Party Aktualisieren",
"upgrade": "Upgrade",
- "selectPartyMember": "Ein Gruppenmitglied Auswählen",
+ "selectPartyMember": "Ein Partymitglied auswählen",
"areYouSureDeleteMessage": "Bist Du sicher, dass Du diese Nachricht löschen willst?",
- "reverseChat": "Chat-Reihenfolge Umkehren",
+ "reverseChat": "Chat-Reihenfolge umkehren",
"invites": "Einladungen",
"details": "Details",
"participantDesc": "Die Quest beginnt, nachdem alle Mitglieder sie angenommen oder abgelehnt haben. Nur wer \"annehmen\" gewählt hat, kann an der Quest teilnehmen und die Belohnung einstreichen.",
"groupGems": "Team-Edelsteine",
- "groupGemsDesc": "Gilden-Edelsteine können für Wettbewerbe verwendet werden! Zukünftig kannst Du weitere Gilden-Edelsteine hinzufügen.",
+ "groupGemsDesc": "Gilden-Edelsteine können für Herausforderungen verwendet werden! Zukünftig kannst Du weitere Gilden-Edelsteine hinzufügen.",
"groupTaskBoard": "Aufgabenliste",
"groupInformation": "Gruppen-Informationen",
"groupBilling": "Gruppen-Abrechnung",
@@ -440,12 +440,12 @@
"leaderChanged": "Gruppenleitung wurde gewechselt",
"groupNoNotifications": "Diese Gilde ist zu groß, um Hinweismeldungen zu unterstützen! Schau öfter rein, um keine Antwort auf Deine Nachrichten zu verpassen!",
"whatIsWorldBoss": "Was ist ein Weltboss?",
- "worldBossDesc": "Ein Weltboss ist ein besonderes Ereignis, bei dem die ganze Habitica Community zusammen arbeitet, um ein mächtiges Monster durch ihre Aufgaben zu besiegen! Alle Benutzer Habiticas erhalten nach dem Sieg eine Belohnung, sogar diejenigen, die im Gasthaus waren oder Habitica während der ganzen Quest nicht genutzt haben.",
+ "worldBossDesc": "Ein Weltboss ist ein besonderes Ereignis, bei dem die ganze Habitica-Community zusammen arbeitet, um ein mächtiges Monster durch ihre Aufgaben zu besiegen! Alle Benutzer Habiticas erhalten nach dem Sieg eine Belohnung, sogar diejenigen, die im Gasthaus waren oder Habitica während der ganzen Quest nicht genutzt haben.",
"worldBossLink": "Erfahre mehr über die vorigen Weltbosse von Habitica im Wiki.",
- "worldBossBullet1": "Erfülle Deine Aufgaben, um dem Welt-Boss Schaden zuzufügen",
- "worldBossBullet2": "Der Welt-Boss wird Dir keinen Schaden für nicht erledigte Aufgaben zufügen, aber sein Raserei-Balken wird ansteigen. Wenn dieser voll ist, wird der Boss einen von Habiticas Händlern angreifen!",
- "worldBossBullet3": "Du kannst weiterhin Quest-Bosse bekämpfen, Dein Schaden wird beiden zugefügt werden",
- "worldBossBullet4": "Besuche regelmäßig die Taverne um den Fortschritt des Welt-Bosses und seine Raserei-Angriffe zu prüfen",
+ "worldBossBullet1": "Erfülle Deine Aufgaben, um dem Weltboss Schaden zuzufügen",
+ "worldBossBullet2": "Der Weltboss wird Dir keinen Schaden für nicht erledigte Aufgaben zufügen, aber sein Raserei-Balken wird ansteigen. Wenn dieser voll ist, wird der Boss einen von Habiticas Händlern angreifen!",
+ "worldBossBullet3": "Du kannst weiterhin normale Quest-Bosse bekämpfen, Dein Schaden wird beiden zugefügt werden",
+ "worldBossBullet4": "Besuche regelmäßig die Taverne um den Fortschritt des Weltbosses und seine Raserei-Angriffe zu prüfen",
"worldBoss": "Weltboss",
"groupPlanTitle": "Brauchst Du mehr Leute für Deine Crew?",
"groupPlanDesc": "Ein kleines Team leiten oder Hausarbeiten organisieren? Unsere Gruppenpläne gewähren Dir exklusiven Zugang zu einem privaten Task-Board und Chat-Bereich, der Dir und Deinen Gruppenmitgliedern gewidmet ist!",
@@ -469,7 +469,7 @@
"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.",
"howToAssignTask": "Wie weise ich eine Aufgabe zu?",
- "howToAssignTaskDesc": "Weise eine Aufgabe einem oder mehreren Gruppenmitgliedern (einschließlich des Gruppenleiters oder der 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\" 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!",
"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.",
@@ -482,6 +482,7 @@
"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 <%= taskText %> übernommen.",
- "youHaveBeenAssignedTask": "<%= managerName %> hat Dir die Aufgabe <%= taskText %> zugeteilt."
+ "taskClaimed": "<%= userName %> hat die Aufgabe <%= taskText %> übernommen.",
+ "youHaveBeenAssignedTask": "<%= managerName %> hat Dir die Aufgabe <%= taskText %> zugeteilt.",
+ "groupActivityNotificationTitle": "<%= user %> hat in <%= group %> gepostet"
}
diff --git a/website/common/locales/de/maintenance.json b/website/common/locales/de/maintenance.json
index bc4322d212..fd2b91ca19 100644
--- a/website/common/locales/de/maintenance.json
+++ b/website/common/locales/de/maintenance.json
@@ -15,7 +15,7 @@
"maintenanceInfoTechDetails": "Möchtest Du mehr über die technische Seite des Prozesses erfahren? Besuche Die Schmiede, unseren Entwicklerblog.",
"maintenanceInfoMore": "Mehr Informationen",
"maintenanceInfoAccountChanges": "Welche Änderungen werde ich in meinem Account sehen, wenn die Wartungsarbeiten fertig sind?",
- "maintenanceInfoAccountChangesText": "Anfangs wird es keine merklichen Änderungen – außer den Performanceverbesserungen für Features wie Wettbewerbe – geben. Falls Du Änderungen bemerkst, die es so nicht geben sollte, schreibe uns eine E-Mail an <%= hrefTechAssistanceEmail %> und wir werden die Angelegenheit für Dich untersuchen!",
+ "maintenanceInfoAccountChangesText": "Anfangs wird es keine merklichen Änderungen – außer den Performanceverbesserungen für Features wie Herausforderungen – geben. Falls Du Änderungen bemerkst, die es so nicht geben sollte, schreibe uns eine E-Mail an <%= hrefTechAssistanceEmail %> und wir werden die Angelegenheit für Dich untersuchen!",
"maintenanceInfoAddFeatures": "Welche Features werden dadurch auf Habitica möglich?",
"maintenanceInfoAddFeaturesText": "Mit Abschluss dieser Wartungen wird es uns möglich sein, den Chat und die Gilden zu verbessern und Pläne für Organisationen und Familien umzusetzen, sowie mehr Produktivitätsfeatures einzuführen, wie zum Beispiel monatliche Aufgaben und die Möglichkeit, Aktivitäten vom Vortag aufzuzeichnen! All das sind große, einzelne Projekte, weshalb es Zeit brauchen wird sie einzuführen, vor dem Abschluss dieser Wartungen gab es leider noch keine Möglichkeiten damit zu beginnen.",
"maintenanceInfoHowLong": "Wie lange werden die Wartungsarbeiten dauern?",
@@ -26,7 +26,7 @@
"maintenanceInfoSeeTasks": "Aber was mache ich, wenn ich meine Aufgabenliste sehen möchte?",
"maintenanceInfoSeeTasksText": "Wenn Du weißt, dass Du Deine Aufgabenliste am Samstag ansehen musst um Dich an Deine Pflichten zu erinnern, dann empfehlen wir Dir vor den Wartungsarbeiten einen Screenshot Deiner Aufgaben zu erstellen, damit Du nachsehen kannst.",
"maintenanceInfoRarePet": "Welches seltene Tier werde ich bekommen?",
- "maintenanceInfoRarePetText": "Um Dir für Deine Geduld während der Wartungszeit zu danken, bekommt jeder ein seltenes Veteranhaustier. Falls Du noch nie eines bekommen hast, wirst Du einen Veteranwolf bekommen. Falls Du schon einen hast, bekommst Du einen Veterantiger. Und falls Du schon sowohl einen Veteranwolf, als auch einen Veterantiger besitzt, bekommst Du ein noch-nie-gesehenes Veterantier! Nach der Migration kann es allerdings einige Stunden dauern, bis Dein neues Haustier auftaucht. Aber keine Angst! Du bekommst eins.",
+ "maintenanceInfoRarePetText": "Um Dir für Deine Geduld während der Wartungszeit zu danken, bekommt jeder ein seltenes Veteranhaustier. Falls Du noch nie eines bekommen hast, wirst Du einen Veteranwolf bekommen. Falls Du schon einen hast, bekommst Du einen Veterantiger. Und falls Du schon sowohl einen Veteranwolf, als auch einen Veterantiger besitzt, bekommst Du ein noch nie gesehenes Veterantier! Nach der Migration kann es allerdings einige Stunden dauern, bis Dein neues Haustier auftaucht. Aber keine Angst! Du bekommst eins.",
"maintenanceInfoWho": "Wer arbeitete an diesem Riesenprojekt?",
"maintenanceInfoWhoText": "Super, dass Du nachfragst! Es wurde mit viel Hilfe von Blade, TheHollidayInn, SabreCat, Victor Pudeyev, TheUnknown und Alys unter Leitung von unserem wunderbaren Mitwirkenden paglias eingeführt.",
"maintenanceInfoTesting": "Die neue Version wurde auch unermüdlich von einer Reihe unserer tollen Open Source Freiwilligen getestet. Vielen Dank -- wir hätten es nicht ohne Euch geschafft."
diff --git a/website/common/locales/de/pets.json b/website/common/locales/de/pets.json
index f09a3e1a97..c21361f0c8 100644
--- a/website/common/locales/de/pets.json
+++ b/website/common/locales/de/pets.json
@@ -144,5 +144,6 @@
"notEnoughMounts": "Du hast noch nicht genug Reittiere gesammelt",
"notEnoughPetsMounts": "Du hast noch nicht genug Haus- und Reittiere gesammelt",
"wackyPets": "Durchgeknallte Haustiere",
- "filterByWacky": "Durchgeknallt"
+ "filterByWacky": "Durchgeknallt",
+ "gryphatrice": "Greifatrice"
}
diff --git a/website/common/locales/de/quests.json b/website/common/locales/de/quests.json
index f5d6aab9c5..ce516e60b6 100644
--- a/website/common/locales/de/quests.json
+++ b/website/common/locales/de/quests.json
@@ -126,5 +126,16 @@
"bossHealth": "<%= currentHealth %> / <%= maxHealth %> Lebenspunkte",
"rageAttack": "Raserei-Angriff:",
"bossRage": "<%= currentRage %> / <%= maxRage %> Raserei",
- "rageStrikes": "Raserei-Angriffe"
+ "rageStrikes": "Raserei-Angriffe",
+ "chatQuestCancelled": "<%= username %> hat die Partyquest <%= questName %> widerrufen.",
+ "chatQuestAborted": "<%= username %> hat die Partyquest <%= questName %> abgebrochen.",
+ "chatItemQuestFinish": "Alle Gegenstände gefunden! Die Party hat ihre Belohnungen erhalten.",
+ "chatFindItems": "<%= username %> hat <%= items %> gefunden.",
+ "chatBossDefeated": "Ihr habt <%= bossName %> besiegt! Die am Quest teilnehmenden Partymitglieder erhalten die Belohnungen für den Sieg.",
+ "chatBossDamage": "<%= username %> greift <%= bossName %> an und fügt <%= userDamage %> Schaden zu. <%= bossName %> greift die Party an und fügt <%= bossDamage %> Schaden zu.",
+ "chatQuestStarted": "Deine Quest, <%= questName %>, hat begonnen.",
+ "questInvitationNotificationInfo": "Du wurdest eingeladen, an einer Quest teilzunehmen",
+ "hatchingPotionQuests": "Magische Schlüpfelixier-Quests",
+ "tavernBossTired": "<%= bossName %> versucht, seinen <%= rageName %> loszulassen, aber er ist zu müde.",
+ "chatBossDontAttack": "<%= username %> greift <%= bossName %> für <%= userDamage %> Schaden an. <%= bossName %> greift nicht an, weil er die Tatsache respektiert, dass es nach der Wartung einige Bugs gibt, und er will niemanden unfair verletzen will. Bald wird er seine Randale weiterführen!"
}
diff --git a/website/common/locales/de/questscontent.json b/website/common/locales/de/questscontent.json
index ded7bf280c..557be333b6 100644
--- a/website/common/locales/de/questscontent.json
+++ b/website/common/locales/de/questscontent.json
@@ -60,7 +60,7 @@
"questSpiderUnlockText": "Schaltet den Kauf von Spinneneiern auf dem Marktplatz frei",
"questGroupVice": "Laster, der Schatten-Wyrm",
"questVice1Text": "Laster, Teil 1: Befreie Dich vom Einfluss des Drachen",
- "questVice1Notes": "
Man sagt, dass ein schreckliches Unheil in den Höhlen von Mt. Habitica lauert. Ein Monster, dessen bloße Anwesenheit den Willen der stärksten Helden des Landes so verdreht, dass sie von ihren schlechten Gewohnheiten und ihrer Faulheit überkommen werden. Diese Bestie ist ein gewaltiger, aus Schatten bestehender Drache: Vice, der heimtückische Schatten-Wyrm. Mutige Habiticaner, erhebt Euch und bezwingt diese verdorbene Bestie ein für alle Mal, aber nur, wenn ihr daran glaubt, gegen seine immense Kraft bestehen zu können.
Laster Teil 1:
Wie kannst Du erwarten gegen ein Biest zu kämpfen, wenn es Dich bereits unter Kontrolle hat? Falle Deiner Faulheit und Deinen Lastern nicht zum Opfer! Arbeite hart gegen den finsteren Einfluss des Drachens und vertreibe seine Macht über Dich!
",
+ "questVice1Notes": "
Man sagt, dass ein schreckliches Unheil in den Höhlen von Mt. Habitica lauert. Ein Monster, dessen bloße Anwesenheit den Willen der stärksten Helden des Landes so verdreht, dass sie von ihren schlechten Gewohnheiten und ihrer Faulheit überkommen werden. Diese Bestie ist ein gewaltiger, aus Schatten bestehender Drache: Laster, der heimtückische Schatten-Wyrm. Mutige Habiticaner, erhebt Euch und bezwingt diese verdorbene Bestie ein für alle Mal, aber nur, wenn ihr daran glaubt, gegen seine immense Kraft bestehen zu können.
Laster Teil 1:
Wie kannst Du erwarten gegen ein Biest zu kämpfen, wenn es Dich bereits unter Kontrolle hat? Falle Deiner Faulheit und Deinen Lastern nicht zum Opfer! Arbeite hart gegen den finsteren Einfluss des Drachens und vertreibe seine Macht über Dich!
",
"questVice1Boss": "Lasters Schatten",
"questVice1Completion": "Mit dem abgeschüttelten Einfluss des Lasters spürt Ihr eine Kraft zurückkehren die Ihr lange vergeßen hattet. Gratulation! Jedoch erwartet Euch ein noch schrecklicherer Gegner...",
"questVice1DropVice2Quest": "Laster Teil 2 (Schriftrolle)",
@@ -71,7 +71,7 @@
"questVice2DropVice3Quest": "Laster Teil 3 (Schriftrolle)",
"questVice3Text": "Laster, Teil 3: Laster erwacht",
"questVice3Notes": "Nach einer langen Suche hat die Party Lasters Hort gefunden. Das kolossale Monster beäugt Deine Party mit Abscheu. Während Schatten um Euch huschen, scheint eine Stimme zu Euch zu flüstern: \"Weitere Narren aus Habitica, die mich aufhalten wollen? Wie niedlich. Ihr hättet besser daran getan zu Hause zu bleiben.\" Der schuppige Titan hebt seinen Kopf und bereitet sich vor anzugreifen. Das ist Eure Chance! Gebt alles und besiegt Laster ein für allemal!",
- "questVice3Completion": "Die Schatten lösen sich auf und verschwinden aus der Höhle, eine undurchdringbare Stille macht sich breit. Ihr habt es geschafft! Ihr habt Vice besiegt! Du und Deine Party könnt endlich eine Verschnaufpause einlegen. Genießt euren Sieg, mutige Habiticaner, aber lernt aus eurem Kampf mit Vice und macht weiter. Es gibt noch mehr Aufgaben zu meistern und möglicherweise noch schlimmere Übel zu bekämpfen!",
+ "questVice3Completion": "Die Schatten lösen sich auf und verschwinden aus der Höhle, eine undurchdringbare Stille macht sich breit. Ihr habt es geschafft! Ihr habt Laster besiegt! Du und Deine Party könnt endlich eine Verschnaufpause einlegen. Genießt euren Sieg, mutige Habiticaner, aber lernt aus eurem Kampf mit Laster und macht weiter. Es gibt noch mehr Aufgaben zu meistern und möglicherweise noch schlimmere Übel zu bekämpfen!",
"questVice3Boss": "Laster, der Schattenwyrm",
"questVice3DropWeaponSpecial2": "Stephen Webers Drachenschaft",
"questVice3DropDragonEgg": "Drache (Ei)",
@@ -209,7 +209,7 @@
"questSlimeBoss": "Glibberkönig",
"questSlimeCompletion": "Mit einem letzten Mopstoß stößt Du den Glibberkönig in die Falle, einen riesigen Donut, den @Overomega, @LordDarkly und @Shaner, die gewitzten Anführer der Feingebäck-Gilde, herangebracht haben. Anerkennend klopfen Dir die Habiticaner auf den Rücken, als Du fühlst, wie Dir jemand etwas in die Tasche rutschen lässt. Es ist die Belohnung für Deinen süßen Erfolg: drei Marshmallow-Schleim-Eier.",
"questSlimeDropSlimeEgg": "Marshmallow-Schleim (Ei)",
- "questSlimeUnlockText": "Schaltet den Kauf von Schleimeiern auf dem Marktplatz frei",
+ "questSlimeUnlockText": "Schaltet den Kauf von Marshmallow-Schleimeiern auf dem Marktplatz frei",
"questSheepText": "Der Donnerbock",
"questSheepNotes": "Als Du mit Deinen Freunden durch das ländliche Aufgabistan wanderst und eine \"kurze Pause\" von Deinen Verpflichtungen einlegst, findest Du einen gemütlichen Garnladen. Du bist so in Deine Aufgabenaufschieberei vertieft, dass Du die Unheil verkündenden Wolken am Horizont kaum bemerkst. \"Ich habe ein schlechtes Gefühl bei diesem Wetter\", murmelt @Misceo und Du schaust nach oben. Stürmische Wolken brauen sich zusammen und sie sehen fast aus wie ... \"Wir haben keine Zeit, in die Wolken zu schauen\", ruft @starsystemic. \"Er greift an!\" Der Donnerbock rast los und schleudert Blitze direkt auf Dich zu!",
"questSheepBoss": "Donnerbock",
@@ -542,8 +542,8 @@
"questLostMasterclasser3DropPinkPotion": "Zuckerwattenrosanes Schlüpfelixier",
"questLostMasterclasser3DropShadePotion": "Schattenhaftes Schlüpfelixier",
"questLostMasterclasser3DropZombiePotion": "Zombifiziertes Schlüpfelixier",
- "questLostMasterclasser4Text": "Das Geheimnis der Klassenmeister, Teil 4: Der verlorene Klassenmeister",
- "questLostMasterclasser4Notes": "Du tauchst aus dem Portal auf, aber du bist immer noch in einer seltsamen, sich verändernden Unterwelt gefangen. “Das war kühn”, sagt eine kalte Stimme. “Ich muss zugeben, ich hatte noch keine direkte Konfrontation geplant.” Eine Frau erhebt sich aus dem wirbelnden Strudel der Dunkelheit. “Willkommen im Reich der Leere.”
Du versuchst, Deine aufkommende Übelkeit zu unterdrücken. “Bist du Zinnya?”, fragst du.
“Dieser alte Name für eine junge Idealistin”, sagt sie, ihr Mund dreht sich, und die Welt krümmt sich unter dir. “Nein. Wenn überhaupt, solltest du mich jetzt Anti'zinnya nennen, nach allem, was ich getan und rückgängig gemacht habe.”
Plötzlich öffnet sich das Portal hinter dir wieder, und als die vier Klassenmeister herausspringen und auf dich zuschießen, blitzen die Augen von Anti'zinnya vor Hass. “Ich sehe, dass meine erbärmlichen Ersatzleute es geschafft haben, Dir zu folgen.”
Du starrst. “Ersatzleute?”
“Als Meister Aethermancer war ich der erste Meisterklassiker - der einzige Meisterklassiker. Diese vier sind ein Hohn, jeder besitzt nur einen Bruchteil von dem, was ich einst hatte! Ich beherrschte jeden Zauber und lernte jede Fähigkeit. Ich habe eure Welt nach meiner Laune geformt - bis der verräterische Äther selbst unter dem Gewicht meiner Talente und meiner durchaus vernünftigen Erwartungen zusammenbrach. Ich bin seit Jahrtausenden in dieser entstandenen Leere gefangen und erhole mich. Stell Dir meinen Ekel vor, als ich erfuhr, dass mein Erbe beschädigt wurde.” Sie stösst ein leises, widerhallendes Lachen aus. “Mein Plan war, ihre Herrschaften zu zerstören, bevor ich sie zerstöre, aber ich schätze, die Reihenfolge ist irrelevant.” In einem Ausbruch unheimlicher Kraft stürmt sie nach vorne, und das Reich der Leere explodiert im Chaos.",
+ "questLostMasterclasser4Text": "Das Geheimnis der Klassenmeister, Teil 4: Die verlorene Klassenmeisterin",
+ "questLostMasterclasser4Notes": "Du tauchst aus dem Portal auf, aber du bist immer noch in einer seltsamen, sich verändernden Unterwelt gefangen. “Das war kühn”, sagt eine kalte Stimme. “Ich muss zugeben, ich hatte noch keine direkte Konfrontation geplant.” Eine Frau erhebt sich aus dem wirbelnden Strudel der Dunkelheit. “Willkommen im Reich der Leere.”
Du versuchst, Deine aufkommende Übelkeit zu unterdrücken. “Bist du Zinnya?”, fragst du.
“Dieser alte Name für eine junge Idealistin”, sagt sie, ihr Mund dreht sich, und die Welt krümmt sich unter dir. “Nein. Wenn überhaupt, solltest du mich jetzt Anti'zinnya nennen, nach allem, was ich getan und rückgängig gemacht habe.”
Plötzlich öffnet sich das Portal hinter dir wieder, und als die vier Klassenmeister herausspringen und auf dich zuschießen, blitzen die Augen von Anti'zinnya vor Hass. “Ich sehe, dass meine erbärmlichen Ersatzleute es geschafft haben, Dir zu folgen.”
Du starrst. “Ersatzleute?”
“Als Master Aethermancer war ich die erste Klassenmeisterin - die einzige Klassenmeisterin. Diese vier sind ein Hohn, jeder besitzt nur einen Bruchteil von dem, was ich einst hatte! Ich beherrschte jeden Zauber und lernte jede Fähigkeit. Ich habe eure Welt nach meiner Laune geformt - bis der verräterische Äther selbst unter dem Gewicht meiner Talente und meiner durchaus vernünftigen Erwartungen zusammenbrach. Ich bin seit Jahrtausenden in dieser entstandenen Leere gefangen und erhole mich. Stell Dir meinen Ekel vor, als ich erfuhr, dass mein Erbe beschädigt wurde.” Sie stösst ein leises, widerhallendes Lachen aus. “Mein Plan war, ihre Herrschaften zu zerstören, bevor ich sie zerstöre, aber ich schätze, die Reihenfolge ist irrelevant.” In einem Ausbruch unheimlicher Kraft stürmt sie nach vorne, und das Reich der Leere explodiert im Chaos.",
"questLostMasterclasser4Completion": "Unter dem Ansturm Deines letzten Angriffs schreit die Verlorene Klassenmeisterin frustriert, ihr Körper flackert und wird durchscheinend. Die fuchtelnde Leere umgibt sie während sie nach vorne sackt, und für einen Moment scheint sie sich zu verändern, jünger, ruhiger zu werden, mit einem Ausdruck des Friedens auf ihrem Gesicht.... aber dann schmilzt alles fast geräuschlos weg, und Du kniest wieder im Wüstensand.
“Es scheint, dass wir viel über unsere eigene Geschichte zu lernen haben”, sagt König Manta und starrt auf die zerbrochenen Ruine. “Nachdem Meister Aethermancer überwältigt war und sie die Kontrolle über ihre Fähigkeiten verloren hatte, muss die Ausbreitung der Leere das Leben aus dem ganzen Land getilgt haben. Wahrscheinlich wurde so alles hier zu einer Wüste.”
“Kein Wunder, dass die Ältesten, die Habitica gegründet haben, ein Gleichgewicht von Produktivität und Wohlbefinden betont haben”, murmelt der Fröhliche Reaper. “Der Wiederaufbau ihrer Welt wäre eine gewaltige Aufgabe gewesen, die viel harte Arbeit erfordert hätte, aber sie hätten verhindern wollen, dass sich eine solche Katastrophe wiederholt.”
“Oho, schaut euch all das Zeugs an, das vorher besessen war!”, sagt der April-Scherzkeks. Tatsächlich schimmert alles mit einer blassen, funkelnden Transluzenz aus dem letzten Ätherausbruch, der ausgelöst wurde, als Du den Geist von Anti'zinnya zur Ruhe gebracht hast. “Was für ein blendender Effekt. Das muss ich mir notieren.”
“Die konzentrierten Ätherreste in diesem Bereich haben wahrscheinlich dazu geführt, dass diese Tiere auch unsichtbar wurden”, sagt Lady Glaciate und kratzt sich einen Fleck der Leere von den Ohren. Du spürst einen unsichtbaren, flauschigen Kopfstoß in Deiner Hand und hast den Verdacht, dass Du in den Ställen zu Hause etwas erklären musst. Als Du die Ruinen ein letztes Mal betrachtest, entdeckst Du, was alles von der ersten Meisterin übrig geblieben ist: ihr schimmernder Umhang. Du legst ihn um Deine Schultern, gehst zurück nach Habit City und denkst über alles nach, was Du gelernt hast.
",
"questLostMasterclasser4Boss": "Anti'zinnya",
"questLostMasterclasser4RageTitle": "Absaugende Leere",
diff --git a/website/common/locales/de/settings.json b/website/common/locales/de/settings.json
index 74dee78f8d..3b11dc1878 100644
--- a/website/common/locales/de/settings.json
+++ b/website/common/locales/de/settings.json
@@ -119,8 +119,8 @@
"giftedSubscriptionInfo": "<%= name %> hat Dir ein <%= months %>-monatiges Abonnement geschenkt",
"giftedSubscriptionFull": "Hallo <%= username %>, <%= sender %> hat Dir <%= monthCount %> Monate Abonnement geschickt!",
"giftedSubscriptionWinterPromo": "Hallo <%= username %>, Du hast durch unsere Festtags-Promo <%= monthCount %>Monate Abonnement geschenkt bekommen!",
- "invitedParty": "In die Party eingeladen",
- "invitedGuild": "In die Gilde eingeladen",
+ "invitedParty": "Du wurdest in eine Party eingeladen",
+ "invitedGuild": "Du wurdest in eine Gilde eingeladen",
"importantAnnouncements": "Erinnerungen zur Anmeldung, um Aufgaben zu komplettieren und Preise zu erhalten",
"weeklyRecaps": "Zusammenfassung Deiner Account-Aktivitäten in dieser Woche (Notiz: Ist zurzeit wegen Performance-Problemen deaktiviert. Wir hoffen, dass es bald wieder zurück ist und werden demnächst wieder E-Mails verschicken!)",
"onboarding": "Hilfe, um Dein Habitica-Konto einzurichten",
@@ -205,5 +205,6 @@
"usernameNotVerified": "Bitte bestätige Deinen Benutzernamen.",
"changeUsernameDisclaimer": "Wir werden bald die Anmeldenamen zu eindeutigen, öffentlichen Benutzernamen umstellen. Dieser Benutzername wird für Einladungen, @Erwähnungen im Chat und Nachrichten verwendet werden.",
"verifyUsernameVeteranPet": "Eines dieser Veteranen-Haustiere wartet auf Dich wenn Du die Bestätigung abgeschlossen hast!",
- "subscriptionReminders": "Abonnement-Erinnerung"
+ "subscriptionReminders": "Abonnement-Erinnerung",
+ "newPMNotificationTitle": "Neue Nachricht von <%= name %>"
}
diff --git a/website/common/locales/en/achievements.json b/website/common/locales/en/achievements.json
index 7de4a1baf9..357e0f7ff3 100644
--- a/website/common/locales/en/achievements.json
+++ b/website/common/locales/en/achievements.json
@@ -22,9 +22,17 @@
"achievementDustDevil": "Dust Devil",
"achievementDustDevilText": "Has collected all Desert Pets.",
"achievementDustDevilModalText": "You collected all the Desert Pets!",
+ "achievementPartyUp": "You teamed up with a party member!",
"achievementAridAuthority": "Arid Authority",
"achievementAridAuthorityText": "Has tamed all Desert Mounts.",
"achievementAridAuthorityModalText": "You tamed all the Desert Mounts!",
"achievementKickstarter2019": "Pin Kickstarter Backer",
- "achievementKickstarter2019Text": "Backed the 2019 Pin Kickstarter Project"
+ "achievementKickstarter2019Text": "Backed the 2019 Pin Kickstarter Project",
+ "achievementPartyOn": "Your party grew to 4 members!",
+ "achievementMonsterMagus": "Monster Magus",
+ "achievementMonsterMagusText": "Has collected all Zombie Pets.",
+ "achievementMonsterMagusModalText": "You collected all the Zombie Pets!",
+ "achievementUndeadUndertaker": "Undead Undertaker",
+ "achievementUndeadUndertakerText": "Has tamed all Zombie Mounts.",
+ "achievementUndeadUndertakerModalText": "You tamed all the Zombie Mounts!"
}
diff --git a/website/common/locales/en/content.json b/website/common/locales/en/content.json
index dce755e033..3fdca1f98f 100644
--- a/website/common/locales/en/content.json
+++ b/website/common/locales/en/content.json
@@ -298,6 +298,7 @@
"hatchingPotionNotes": "Pour this on an egg, and it will hatch as a <%= potText(locale) %> pet.",
"premiumPotionAddlNotes": "Not usable on quest pet eggs. Available for purchase until <%= date(locale) %>.",
+ "premiumPotionUnlimitedNotes": "Not usable on quest pet eggs.",
"foodMeat": "Meat",
"foodMeatThe": "the Meat",
diff --git a/website/common/locales/en/gear.json b/website/common/locales/en/gear.json
index 8b7c5397ab..f79d02db4f 100644
--- a/website/common/locales/en/gear.json
+++ b/website/common/locales/en/gear.json
@@ -863,6 +863,8 @@
"armorMystery201908Notes": "These legs were made for dancing! And that's just what they'll do. Confers no benefit. August 2019 Subscriber Item.",
"armorMystery201909Text": "Affable Acorn Armor",
"armorMystery201909Notes": "Your tough exterior is protective, but it's still best to keep an eye out for squirrels... Confers no benefit. September 2019 Subscriber Item.",
+ "armorMystery201910Text": "Cryptic Armor",
+ "armorMystery201910Notes": "This enigmatic armor will protect you from terrors seen and unseen. Confers no benefit. October 2019 Subscriber Item.",
"armorMystery301404Text": "Steampunk Suit",
"armorMystery301404Notes": "Dapper and dashing, wot! Confers no benefit. February 3015 Subscriber Item.",
"armorMystery301703Text": "Steampunk Peacock Gown",
@@ -1399,6 +1401,8 @@
"headMystery201907Notes": "Nothing says “I'm relaxing here!” like a backwards cap. Confers no benefit. July 2019 Subscriber Item.",
"headMystery201909Text": "Affable Acorn Hat",
"headMystery201909Notes": "Every acorn needs a hat! Er, cupule, if you want to get technical about it. Confers no benefit. September 2019 Subscriber Item.",
+ "headMystery201910Text": "Cryptic Flame",
+ "headMystery201910Notes": "These flames reveal arcane secrets before your very eyes! Confers no benefit. October 2019 Subscriber Item.",
"headMystery301404Text": "Fancy Top Hat",
"headMystery301404Notes": "A fancy top hat for the finest of gentlefolk! January 3015 Subscriber Item. Confers no benefit.",
"headMystery301405Text": "Basic Top Hat",
diff --git a/website/common/locales/en/npc.json b/website/common/locales/en/npc.json
index 41dcbf3016..b196d5205a 100644
--- a/website/common/locales/en/npc.json
+++ b/website/common/locales/en/npc.json
@@ -24,7 +24,7 @@
"sleepDescription": "Need a break? Check into Daniel's Inn to pause some of Habitica's more difficult game mechanics:",
"sleepBullet1": "Missed Dailies won't damage you",
"sleepBullet2": "Tasks won't lose streaks or decay in color",
- "sleepBullet3": "Bosses won't do damage for your missed Dailies",
+ "sleepBullet3": "Bosses won't do damage for your own missed Dailies",
"sleepBullet4": "Your boss damage or collection Quest items will stay pending until check-out",
"pauseDailies": "Pause Damage",
"unpauseDailies": "Unpause Damage",
diff --git a/website/common/locales/en/settings.json b/website/common/locales/en/settings.json
index 4790f09773..5f11bb67ea 100644
--- a/website/common/locales/en/settings.json
+++ b/website/common/locales/en/settings.json
@@ -205,6 +205,10 @@
"goToSettings": "Go to Settings",
"usernameVerifiedConfirmation": "Your username, <%= username %>, is confirmed!",
"usernameNotVerified": "Please confirm your username.",
- "changeUsernameDisclaimer": "We will be transitioning login names to unique, public usernames soon. This username will be used for invitations, @mentions in chat, and messaging.",
- "verifyUsernameVeteranPet": "One of these Veteran Pets will be waiting for you after you've finished confirming!"
+ "changeUsernameDisclaimer": "This username will be used for invitations, @mentions in chat, and messaging.",
+ "verifyUsernameVeteranPet": "One of these Veteran Pets will be waiting for you after you've finished confirming!",
+ "mentioning": "Mentioning",
+ "suggestMyUsername": "Suggest my username",
+ "everywhere": "Everywhere",
+ "onlyPrivateSpaces": "Only in private spaces"
}
diff --git a/website/common/locales/en/subscriber.json b/website/common/locales/en/subscriber.json
index 9b83cdfc28..2468656e08 100644
--- a/website/common/locales/en/subscriber.json
+++ b/website/common/locales/en/subscriber.json
@@ -163,6 +163,7 @@
"mysterySet201907": "Beach Buddy Set",
"mysterySet201908": "Footloose Faun Set",
"mysterySet201909": "Affable Acorn Set",
+ "mysterySet201910": "Cryptic Flame Set",
"mysterySet301404": "Steampunk Standard Set",
"mysterySet301405": "Steampunk Accessories Set",
"mysterySet301703": "Peacock Steampunk Set",
diff --git a/website/common/locales/en@lolcat/achievements.json b/website/common/locales/en@lolcat/achievements.json
index 99c0c5c573..4cb9d1bf2a 100755
--- a/website/common/locales/en@lolcat/achievements.json
+++ b/website/common/locales/en@lolcat/achievements.json
@@ -1,9 +1,30 @@
{
- "achievement": "Achievement",
- "share": "Share",
- "onwards": "Onwardz!",
- "levelup": "BY ACCOMPLISHIN UR REAL-LIFE GOALS, U LEVELD UP AN IZ NOW FULE HEELD!",
- "reachedLevel": "U reechd level <%= level %>",
- "achievementLostMasterclasser": "Kwest completionist: masterclasr seriez",
- "achievementLostMasterclasserText": "Completd al sixtin kwestz in teh masterclasr quest seriez an solvd teh mystery for teh losed masterclaser!"
+ "achievement": "Acheevment",
+ "share": "Share",
+ "onwards": "Onwardz!",
+ "levelup": "BY ACCOMPLISHIN UR REAL-LIFE GOALS, U LEVELD UP AN IZ NOW FULE HEELD!",
+ "reachedLevel": "U reechd level <%= level %>",
+ "achievementLostMasterclasser": "Kwest completionist: masterclasr seriez",
+ "achievementLostMasterclasserText": "Completd al sixtin kwestz in teh masterclasr quest seriez an solvd teh mystery for teh losed masterclaser!",
+ "achievementAridAuthority": "Arid authoritie",
+ "achievementDustDevil": "Dus devil",
+ "achievementJustAddWaterModalText": "U completd teh octopuz, seehurz, cuttlefish, wal, turtl, nudibranch, see serpen, an dolfin pet kwestz!",
+ "achievementJustAddWaterText": "Haz completd octopuz, seehurz, cuttlefish, wal, turtl, nudibranch, see serpen, an dolfin pet kwestz.",
+ "achievementJustAddWater": "Jus Add Watr",
+ "achievementMindOverMatter": "Mind Ovar Mattr",
+ "achievementKickstarter2019Text": "Backd teh 2019 Pin Kickstarter Projekd",
+ "achievementKickstarter2019": "Pin Kickstarter Backur",
+ "achievementAridAuthorityModalText": "U taemd all teh deserd mountz!",
+ "achievementAridAuthorityText": "Haz taemd all deserd mountz.",
+ "achievementDustDevilModalText": "U collected all teh deserd petz!",
+ "achievementDustDevilText": "Haz collectd all deserd petz.",
+ "achievementAllYourBaseModalText": "U taemd all teh baez mountz!",
+ "achievementAllYourBaseText": "Haz taemd all baez mountz.",
+ "achievementAllYourBase": "All ur baez",
+ "achievementBackToBasicsModalText": "U collectd all teh baez petz!",
+ "achievementBackToBasicsText": "Haz collectd all baez petz.",
+ "achievementBackToBasics": "Bak 2 baesikz",
+ "achievementMindOverMatterModalText": "U completd teh rok, sml, an yarn pet kwestz!",
+ "achievementMindOverMatterText": "Haz completd rok, sml, an yarn pet kwestz.",
+ "achievementLostMasterclasserModalText": "U completd al sixtin kwestz in teh masterclasr quest seriez an solvd teh mystery for teh losed masterclaser!"
}
diff --git a/website/common/locales/en@lolcat/challenge.json b/website/common/locales/en@lolcat/challenge.json
index cf5ead319a..ac1f1c9737 100755
--- a/website/common/locales/en@lolcat/challenge.json
+++ b/website/common/locales/en@lolcat/challenge.json
@@ -1,6 +1,6 @@
{
- "challenge": "Challenge",
- "challengeDetails": "Chalengez iz communitie eventz in wich playerz compete and eern prizez by completin group for relatd taskz. K?",
+ "challenge": "Chalenge",
+ "challengeDetails": "Chalengez iz communitie eventz in wich playerz compeet an eern praizez by completin group ov relatd taskz.",
"brokenChaLink": "Challenge Lynk iz Broked",
"brokenTask": "Challenge Link wuz brokd: dis task wuz part of challenge, but wuz removed frum id. What do nao?",
"keepIt": "Keeps It",
@@ -13,11 +13,11 @@
"challengeWinner": "Wuz teh winnar in teh followeeng challengez",
"challenges": "Challengez",
"challengesLink": "Chalengez",
- "challengePrize": "Challenge Prize",
- "endDate": "Ends",
+ "challengePrize": "Chalenge Praiz",
+ "endDate": "Endz",
"noChallenges": "No haz challengez yets. Visit",
- "toCreate": "2 create wun",
- "selectWinner": "Selecd winnar an cloas teh challenge",
+ "toCreate": "2 create wun.",
+ "selectWinner": "Selecd winnar an cloas teh chalenge:",
"deleteOrSelect": "Deleet or select winnar",
"endChallenge": "End Challengs",
"challengeDiscription": "Deez is teh challenge's taskz that wil be addd to ur task dashboard win u join thiz chalenge. Teh sampl chalenge taskz below wll change colr an gaen graphz 2 show u teh ovrell prawgres of teh groop.",
@@ -25,9 +25,9 @@
"filter": "Filtur",
"groups": "Groopz",
"noNone": "Nonez",
- "category": "Category",
+ "category": "Kategory",
"membership": "Membarship",
- "ownership": "Ownership",
+ "ownership": "Ownrship",
"participating": "Participaeting",
"notParticipating": "Not Participaeting",
"either": "Eathur",
@@ -41,9 +41,9 @@
"challengeTagPop": "Challengez appeer on tag-lists an task-tooltips. So u want discripteev titol abbav, u'll need 'short naem' 2. Srsly. Liek 'looz 10 poundz in 3 munfs' can becomez '-10lb' (Cliek 4 moar infoz).",
"challengeDescr": "Descripshun",
"prize": "Priez",
- "prizePop": "So sumwun cna 'win' ur challenge. Srsly. Den u can optionalleh awrd winnor an Gem priez. Maximum numbr u can orard r teh numbn for gemz u haz (pluz teh numbr for guild gemz if u creetd thiz chalengez guild). Noat: Dis priez can no be changet laetr, k?",
+ "prizePop": "So sumwun cna 'win' ur chalenge. Srsly! Den u can optionalleh awrd winnor an Gem priez. Maximum numbr u can award r teh numbr for gemz u haz (pluz teh numbr for guild gemz if u creetd thiz chalengez guild). Noat: Dis priez can no be changet laetr.",
"prizePopTavern": "So sumwun cna 'win' ur challenge. Srsly. Den u can awrd winnor an Gem priez. Max = numbr for gemz u own. Noat: Dis priez can no be changet laetr an tavern chalengez will no be refunded if challenge wuz canceld.",
- "publicChallenges": "Minimum 1 gem 4 pooblic challengez (helpz prevent teh spamz, really duz. Srsly.)!!1!",
+ "publicChallenges": "Minimum 1 gem 4 pooblic chalengez (helpz prevent teh spamz, really duz. Srsly!!1!).",
"publicChallengesTitle": "Peowblic chalengez",
"officialChallenge": "Offishul Habitica Challenge",
"by": "by",
@@ -52,13 +52,13 @@
"exportChallengeCSV": "Export 2 CSV",
"selectGroup": "Pleez select groop",
"challengeCreated": "Challenge creatd",
- "sureDelCha": "R u sures u wants 2 bahleet dis challenge? ",
+ "sureDelCha": "R u sures u wants 2 delet dis chalenge?",
"sureDelChaTavern": "R u sures u wants to bahleet dis challenge? U no get Gemz backs.",
"removeTasks": "Remoov Taskz",
"keepTasks": "Keep Taskz",
"closeCha": "Clooz challenge an...",
"leaveCha": "Leev challenge an...",
- "challengedOwnedFilterHeader": "Ownership",
+ "challengedOwnedFilterHeader": "Ownrship",
"challengedOwnedFilter": "Ownd",
"owned": "Ownd",
"challengedNotOwnedFilter": "Not ownd",
@@ -66,7 +66,7 @@
"not_participating": "Not Participaeting",
"challengedEitherOwnedFilter": "Eathr",
"backToChallenges": "Bak to al chalengez",
- "prizeValue": "<%= gemcount %> <%= gemicon %> Prize",
+ "prizeValue": "<%= gemcount %> <%= gemicon %> Praiz",
"clone": "Clone",
"challengeNotEnoughGems": "U donut haz enuff gems 2 post dis challenge.",
"noPermissionEditChallenge": "U donut haz permisionz to edit thiz challenge",
@@ -78,7 +78,7 @@
"noChallengeOwnerPopover": "Thiz challenge dus not haz an ownr becos teh person wo creetd teh challenge deeletd their akownt.",
"challengeMemberNotFound": "Usr not finded imong challengez memberz",
"onlyGroupLeaderChal": "Onle teh group leedr can creete chalengez",
- "tavChalsMinPrize": "Prize mus be at leest 1 gem fr peowblic chalengez",
+ "tavChalsMinPrize": "Praiz mus be at leest 1 gem fr peowblic chalengez.",
"cantAfford": "No, u cant afford thiz prize, meow, Purrrchas moar gemz or lowr teh prize imount.",
"challengeIdRequired": "\"challengeId\" mus be a valid UUID.",
"winnerIdRequired": "\"winnerId\" mus be a valid UUID.",
@@ -99,7 +99,7 @@
"noChallengeTitle": "U dun haz any challengez.",
"challengeDescription1": "Challengez iz communitie eventz in wich playerz compete an eern prizez by completin group for relatd taskz.",
"challengeDescription2": "Fin recommendd chalengez basd on ur enterests, brows Habiticaz peowblic challengez or creete ur meown chalengez.",
- "noChallengeMatchFilters": "We couldn't find any matching Challenges.",
+ "noChallengeMatchFilters": "We couldnt find ne matchin chalengez.",
"createdBy": "Creetd by",
"joinChallenge": "Join challenge",
"leaveChallenge": "Leev challenge",
@@ -111,10 +111,10 @@
"doYouWantedToDeleteChallenge": "Do u want to deelete thiz challenge?",
"deleteChallenge": "Deelete challenge",
"challengeNamePlaceholder": "Wat r ur challenge neme?",
- "challengeSummary": "Summary",
- "challengeSummaryPlaceholder": "Write short deescripshun advertisin ur challenge to othr habiticanz. Wat r teh main purpos for ur challenge an y peepl join it? Try to enclude usefool keywordz in teh deescripshun so that habiticanz can eesileh fin it win they seerch! K?",
+ "challengeSummary": "Sumary",
+ "challengeSummaryPlaceholder": "Rite short deescripshun advertisin ur challenge to othr habiticanz. Wat r teh main purpos 4 ur challenge an y peepl join it? Try 2 enclude usefool keywordz n teh deescripshun so habiticanz can eesileh fin it win they seerch!",
"challengeDescriptionPlaceholder": "Use thiz secshun to go ento moar deetail abowt everyfin that challenge pawrticipantz should no abowt ur chalenge.",
- "challengeGuild": "Add to",
+ "challengeGuild": "Ad 2",
"challengeMinimum": "Minimum 1 gem fr public challengez (helpz prevnt spam, it reele dus).",
"participantsTitle": "Partizipentz",
"shortName": "Short neme",
@@ -136,4 +136,4 @@
"selectMember": "CHOOZE member",
"confirmKeepChallengeTasks": "Do u want to kep challenge tasks?",
"selectParticipant": "CHOOZE partizipent"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/en@lolcat/character.json b/website/common/locales/en@lolcat/character.json
index 769379a6f1..0849604299 100755
--- a/website/common/locales/en@lolcat/character.json
+++ b/website/common/locales/en@lolcat/character.json
@@ -1,15 +1,15 @@
{
- "communityGuidelinesWarning": "Plz keep in mind dat ur Display Naym, profiel footo, an blurb must comply wif teh Commeownity Guidelines (e.g. no profanity, no adult topicz, no insults, etc), Srsly. If u haz any queshuns bout whefr or not somefin iz appropriaet, feelz free 2 email <%= hrefBlankCommunityManagerEmail %>! ",
+ "communityGuidelinesWarning": "Plz keep in mind dat ur Display Naym, profiel footo, an blurb must comply wif teh Commeownity Guidelines (e.g. no profanity, no adult topicz, no insults, etc), Srsly. If u haz any queshuns bout whefr or not somefin iz appropriaet, feelz free 2 email <%= hrefBlankCommunityManagerEmail %>!",
"profile": "MAH INFOS",
"avatar": "KUZTOMIZE UR AVATAR",
- "editAvatar": "Edit Avatar",
- "noDescription": "This Habitican hasn't added a description.",
- "noPhoto": "This Habitican hasn't added a photo.",
+ "editAvatar": "Chaeng Avtar",
+ "noDescription": "Dis Habitican no haz aded descripshun.",
+ "noPhoto": "Dis Habitican no haz aded photo.",
"other": "OTTER",
"fullName": "FULL NAEM",
- "displayName": "Display name",
- "changeDisplayName": "Change Display Name",
- "newDisplayName": "New Display Name",
+ "displayName": "Display naem",
+ "changeDisplayName": "Chaeng Display Naem",
+ "newDisplayName": "New Display Naem",
"displayPhoto": "PHOTO PIKCHUR",
"displayBlurb": "BLORB",
"displayBlurbPlaceholder": "Do teh introduzin",
@@ -21,7 +21,7 @@
"buffed": "BUFFD",
"bodyBody": "BODDEH",
"bodySize": "BIGNESS",
- "size": "Size",
+ "size": "Siez",
"bodySlim": "ITTEH BITTEH",
"bodyBroad": "BROADCAT",
"unlockSet": "UN LOCK SET - <%= cost %>",
@@ -35,20 +35,20 @@
"color": "COLUR",
"bodyHair": "HAIRS",
"hair": "Hair",
- "bangs": "Bangs",
+ "bangs": "Bangz",
"hairBangs": "FOREHEAD HAIRS",
"ponytail": "Ponytail",
- "glasses": "Glasses",
+ "glasses": "Glasez",
"hairBase": "HAIRS BASE",
"hairSet1": "HAIRS SET 1",
"hairSet2": "HAIRS SET TOO",
- "hairSet3": "Hairstyel Set 3 ",
+ "hairSet3": "Hairstyel Set 3",
"bodyFacialHair": "FACE FUR",
"beard": "BEARD FUR",
"mustache": "MUSTACHE FUR",
"flower": "FLOWAR",
- "accent": "Accent",
- "headband": "Headband",
+ "accent": "Aksent",
+ "headband": "Hedban",
"wheelchair": "WHEELCHAIR SPOT",
"extra": "Extra",
"basicSkins": "BASIC SKINZ",
@@ -64,17 +64,17 @@
"winteryColors": "WINTUR COLURS",
"equipment": "EQUIPMENTS",
"equipmentBonus": "EKWIPMENTS",
- "equipmentBonusText": "Stat bonuses provided by your equipped battle gear. See the Equipment tab under Inventory to select your battle gear.",
- "classBonusText": "Your class (Warrior, if you haven't unlocked or selected another class) uses its own equipment more effectively than gear from other classes. Equipped gear from your current class gets a 50% boost to the Stat bonus it grants.",
+ "equipmentBonusText": "Stat bonusez givd by ur ekwipd battl geer. See teh Ekwipment tab undr Inventory 2 choosd ur battl geer.",
+ "classBonusText": "Ur clas (Warrior, if u no haz unlokd or choosd anothr clas) usez itz own ekwipment moar effectivly then geer frum othr clasez. Ekwipd geer frum ur current clas getz 50% boost 2 teh Stat bonus it givz.",
"classEquipBonus": "CLASS BONUS",
"battleGear": "BATTLE GEARS",
- "gear": "Gear",
+ "gear": "Geer",
"battleGearText": "DIS AR TEH TEH GEERS U WEAR INTO BATTLE; IT AFFECTS NUMBERS WHEN INTERACTIN WIF UR TASKZ.",
"autoEquipBattleGear": "AUTO-EQWIP NU GEERS",
"costume": "COSTOOM",
"costumeText": "IF U PREFERZ LOOK OF OTHER GEAR TO WAT U HAS EQUIPPED, CHECK THE \"USE COSTOOM\" BOX TO WEAR COSTUME WIF ARMORS AND THINGS UNDERNEAF.",
"useCostume": "USE COSTOOM",
- "useCostumeInfo1": "Click \"Use Costume\" to equip items to your avatar without affecting the Stats from your Battle Gear! This means that you can equip for the best Stats on the left, and dress up your avatar with your equipment on the right.",
+ "useCostumeInfo1": "Clik \"Ues Costum\" 2 ekwip itemz 2 ur avtar wifout affectin Statz frum ur Battl Geer! Dis meenz u can ekwip 4 teh best Statz on teh left, an dres up ur avtar wif ur ekwipment on teh rite.",
"useCostumeInfo2": "Once you click \"Use Costume\" your avatar will look pretty basic... but don't worry! If you look on the left, you'll see that your Battle Gear is still equipped. Next, you can make things fancy! Anything you equip on the right won't affect your Stats, but can make you look super awesome. Try out different combos, mixing sets, and coordinating your Costume with your pets, mounts, and backgrounds.
Got more questions? Check out the Costume page on the wiki. Find the perfect ensemble? Show it off in the Costume Carnival guild or brag in the Tavern!",
"costumePopoverText": "Select \"Use Costume\" to equip items to your avatar without affecting the Stats from your Battle Gear! This means that you can dress up your avatar in whatever outfit you like while still having your best Battle Gear equipped.",
"autoEquipPopoverText": "Select this option to automatically equip gear as soon as you purchase it.",
@@ -97,13 +97,13 @@
"xp": "XP",
"health": "HELFS",
"allocateStr": "POINTZ ALLOCATED TO STRENGF:",
- "allocateStrPop": "Add a Point to Strength",
+ "allocateStrPop": "Ad Point 2 Strengf",
"allocateCon": "POINTS ALLOCATED TO CONSTITUSHUN:",
- "allocateConPop": "Add a Point to Constitution",
+ "allocateConPop": "Ad Point 2 Constitushun",
"allocatePer": "POINTS ALLOCATED TO PERCEPSHUN:",
- "allocatePerPop": "Add a Point to Perception",
+ "allocatePerPop": "Ad Point 2 Percepshun",
"allocateInt": "POINTS ALLOCATED TO SMARTNESS:",
- "allocateIntPop": "Add a Point to Intelligence",
+ "allocateIntPop": "Ad Point 2 Smartness",
"noMoreAllocate": "Now that you've hit level 100, you won't gain any more Stat Points. You can continue leveling up, or start a new adventure at level 1 by using the Orb of Rebirth, now available for free in the Market.",
"stats": "Stats",
"achievs": "Acheevments",
@@ -118,7 +118,7 @@
"levelBonus": "LEVEL BONUS",
"levelBonusText": "Each Stat gets a bonus equal to half of (your Level minus 1).",
"allocatedPoints": "ALLOCATED POINTZ",
- "allocatedPointsText": "Stat Points you've earned and assigned. Assign Points using the Character Build column.",
+ "allocatedPointsText": "Stat Pointz uve ernd an asignd. Asign Pointz usin teh Charaktr Bild colum.",
"allocated": "ALLOCATED",
"buffs": "BUFFS",
"buffsText": "Temporary Stat bonuses from abilities and achievements. These wear off at the end of your day. The abilities you've unlocked appear in the Rewards list of your Tasks page.",
@@ -129,25 +129,25 @@
"healer": "DR TINYCAT",
"rogue": "NINJA KITTEH",
"mage": "WIZZARD",
- "wizard": "Mage",
+ "wizard": "Maeg",
"mystery": "MYSTERI",
- "changeClass": "Change Class, Refund Stat Points",
+ "changeClass": "Chaeng Clas, Giv Bak Stat Pointz",
"lvl10ChangeClass": "2 chanje ur class u muzt b at lvl 10.",
- "changeClassConfirmCost": "Are you sure you want to change your class for 3 Gems?",
+ "changeClassConfirmCost": "Do u rly wanna chaneg ur clas for 3 Gemz?",
"invalidClass": "Invalid clas. Plz specify 'waryur', 'roeg', 'wizard', or 'heelur'.",
"levelPopover": "Each level earns you one Point to assign to a Stat of your choice. You can do so manually, or let the game decide for you using one of the Automatic Allocation options.",
"unallocated": "Unallocated Stat Points",
- "haveUnallocated": "You have <%= points %> unallocated Stat Point(s)",
+ "haveUnallocated": "U haz <%= points %> unalocatd Stat Point(z)",
"autoAllocation": "AUTOMATIC ALLOCASHUN",
"autoAllocationPop": "Places Points into Stats according to your preferences, when you level up.",
"evenAllocation": "Distribute Stat Points evenly",
- "evenAllocationPop": "Assigns the same number of Points to each Stat.",
+ "evenAllocationPop": "Asignz teh saem numbr ov Pointz 2 eech Stat.",
"classAllocation": "Distribute Points based on Class",
- "classAllocationPop": "Assigns more Points to the Stats important to your Class.",
+ "classAllocationPop": "Asignz moar Pointz 2 teh Statz importan 2 ur Clas.",
"taskAllocation": "Distribute Points based on task activity",
- "taskAllocationPop": "Assigns Points based on the Strength, Intelligence, Constitution, and Perception categories associated with the tasks you complete.",
+ "taskAllocationPop": "Asignz Pointz basd on teh Strenf, Smartness, Constitushun, an Percepshun categoryz associatd wif teh taskz u complet.",
"distributePoints": "DISTRIBUTE UNALLOCATED POINTZ",
- "distributePointsPop": "Assigns all unallocated Stat Points according to the selected allocation scheme.",
+ "distributePointsPop": "Asignz al unalocatd Stat Pointz acordin 2 teh selectd alocashun skeem.",
"warriorText": "WARRIOR KITTEHS SCORE MORE N BETTER \"CRITICAL HITS\" WHICH RANDOMLY GIVE U BONUS GOLDS, EXPERIENCES, N DROP CHANCE FOR SCORING TASK. DEY ALSO DEAL HEAVY DAMAGE 2 BOSS MONSTERS. PLAY WARRIOR KITTEH IF U FINDZ MOTIVATION FROM UNPREDICTABLE JACKPOT REWARDZ OR WANT TO BRING TEH HURTS IN BOSS QUESTS!",
"wizardText": "Mages learn swiftly, gaining Experience and Levels faster than other classes. They also get a great deal of Mana for using special abilities. Play a Mage if you enjoy the tactical game aspects of Habitica, or if you are strongly motivated by leveling up and unlocking advanced features!",
"mageText": "Mages learn swiftly, gaining Experience and Levels faster than other classes. They also get a great deal of Mana for using special abilities. Play a Mage if you enjoy the tactical game aspects of Habitica, or if you are strongly motivated by leveling up and unlocking advanced features!",
@@ -155,10 +155,10 @@
"healerText": "DRS TINYCAT CANNOT BE HURTED, N EXTEND THEIR PROTECTION 2 OTTERS. MISSED DAILIES N BAD HABITS DONT FAZE THEM MUCH, N THEY CAN HAZ RECOVERING HEALTHS FROM FAILURE. PLAY DR TINYCAT IF U ENJOY HELPING UR FRIENDS IN PARTY, OR IF U LIKES CHEATING BASEMENT CAT THRU HARD WORK!",
"optOutOfClasses": "OPT OUT",
"optOutOfPMs": "OPT OUT",
- "chooseClass": "Choose your Class",
+ "chooseClass": "Chooes ur Clas",
"chooseClassLearnMarkdown": "[Learn more about Habitica's class system](http://habitica.wikia.com/wiki/Class_System)",
"optOutOfClassesText": "Can't be bothered with classes? Want to choose later? Opt out - you'll be a warrior with no special abilities. You can read about the class system later on the wiki and enable classes at any time under User Icon > Settings.",
- "selectClass": "Select <%= heroClass %>",
+ "selectClass": "Chooze <%= heroClass %>",
"select": "CHOOZE",
"stealth": "STEALTH",
"stealthNewDay": "WHEN NEW DAY BEGINZ, U AVOID DAMAGE FROM DIS MANY MISSED DAILIES.",
@@ -169,28 +169,28 @@
"dieText": "U HAZ LOST LEVEL, ALL UR GOLD, N RANDOM PIECE OF EQUIPMENTS. ARISE, HABITEER, N TRY AGAIN! CURB UR NEGATIVE HABITZ, COMPLETE UR DAILIES WIF VIGILANCE, N HOLD BASEMENT CAT AT ARMS LENGTH WIF HEALTH POTION IF U FALTERS!",
"sureReset": "Are you sure? This will reset your character's class and allocated Stat Points (you'll get them all back to re-allocate), and costs 3 Gems.",
"purchaseFor": "PURCHASE FOR <%= cost %> GEMS?",
- "purchaseForHourglasses": "Purchase for <%= cost %> Hourglasses?",
+ "purchaseForHourglasses": "Perchis 4 <%= cost %> Hourglasz?",
"notEnoughMana": "NOT ENOUGH MANNAZ.",
- "invalidTarget": "You can't cast a skill on that.",
+ "invalidTarget": "U cant cast skil on dat.",
"youCast": "U CAST <%= spell %>.",
"youCastTarget": "U CAST <%= spell %> ON <%= target %>.",
"youCastParty": "U CAST <%= spell %> FOR TEH PARTEE.",
- "critBonus": "CRITICAL HIT! BONUS:",
- "gainedGold": "You gained some Gold",
- "gainedMana": "You gained some Mana",
- "gainedHealth": "You gained some Health",
- "gainedExperience": "You gained some Experience",
- "lostGold": "You spent some Gold",
- "lostMana": "You used some Mana",
- "lostHealth": "You lost some Health",
- "lostExperience": "You lost some Experience",
+ "critBonus": "CRITICAL HIT! BONUS: ",
+ "gainedGold": "U can haz Gold",
+ "gainedMana": "U can haz Mana",
+ "gainedHealth": "U can haz Helf",
+ "gainedExperience": "U can haz Experianc",
+ "lostGold": "U spended Gold",
+ "lostMana": "U uesd Mana",
+ "lostHealth": "U lostd Helf",
+ "lostExperience": "U lostd Experianc",
"displayNameDescription1": "This is what appears in messages you post in the Tavern, guilds, and party chat, along with what is displayed on your avatar. To change it, click the Edit button above. If instead you want to change your username, go to",
"displayNameDescription2": "SETTINGZ->SITE",
- "displayNameDescription3": "an look in teh Registration secshun. ",
+ "displayNameDescription3": "an look n teh Registration secshun.",
"unequipBattleGear": "TAKE OFF BATTLE GEARS",
"unequipCostume": "TAKE OFF COSTOOM",
- "equip": "Equip",
- "unequip": "Unequip",
+ "equip": "Ekwip",
+ "unequip": "Unekwip",
"unequipPetMountBackground": "TAKE OFF PET, MOWNT, BACK PIKCHUR",
"animalSkins": "ANIMUL SKINZ",
"chooseClassHeading": "CHOOSE UR CLAS! OR OPT OUT 2 CHOOSE LATR.",
@@ -206,23 +206,27 @@
"showQuickAllocation": "Show Stat Allocation",
"hideQuickAllocation": "Hide Stat Allocation",
"quickAllocationLevelPopover": "Each level earns you one Point to assign to a Stat of your choice. You can do so manually, or let the game decide for you using one of the Automatic Allocation options found in User Icon > Stats.",
- "notEnoughAttrPoints": "You don't have enough Stat Points.",
+ "notEnoughAttrPoints": "U no haz enuf Stat Pointz.",
"classNotSelected": "You must select Class before you can assign Stat Points.",
"style": "Style",
- "facialhair": "Facial",
+ "facialhair": "Fashul",
"photo": "Photo",
"info": "Info",
- "joined": "Joined",
+ "joined": "Joind",
"totalLogins": "Total Check Ins",
"latestCheckin": "Latest Check In",
- "editProfile": "Edit Profile",
- "challengesWon": "Challenges Won",
- "questsCompleted": "Quests Completed",
+ "editProfile": "Chaeng Profiel",
+ "challengesWon": "Chalengez Wun",
+ "questsCompleted": "Kwestz Completd",
"headAccess": "Head Access.",
"backAccess": "Back Access.",
"bodyAccess": "Body Access.",
"mainHand": "Main-Hand",
"offHand": "Off-Hand",
"statPoints": "Stat Points",
- "pts": "pts"
-}
\ No newline at end of file
+ "pts": "pts",
+ "chatCastSpellUser": "<%= username %> castz <%= spell %> on <%= target %>.",
+ "chatCastSpellParty": "<%= username %> castz <%= spell %> 4 teh party.",
+ "purchasePetItemConfirm": "Dis perchis wil exseed teh numbr ov items u ned 2 hatch al posibl <%= itemText %> petz. R u sure?",
+ "purchaseForGold": "Perchis 4 <%= cost %> Gold?"
+}
diff --git a/website/common/locales/en@lolcat/communityguidelines.json b/website/common/locales/en@lolcat/communityguidelines.json
index 1196691264..a310bc3a66 100755
--- a/website/common/locales/en@lolcat/communityguidelines.json
+++ b/website/common/locales/en@lolcat/communityguidelines.json
@@ -55,7 +55,7 @@
"commGuideList05G": "Intentional deception of Staff or Moderators in order to avoid consequences or to get another user in trouble",
"commGuideHeadingModerateInfractions": "Modurate Enfractuns",
"commGuidePara054": "Moderate infractions do not make our community unsafe, but they do make it unpleasant. These infractions will have moderate consequences. When in conjunction with multiple infractions, the consequences may grow more severe.",
- "commGuidePara055": "Dese lizt is exumples uf Modurate Enfractuns. Dis not compulte lest!",
+ "commGuidePara055": "Dese lizt is exumples uf Modurate Enfractuns. Dis not compulte lest.",
"commGuideList06A": "Ignoring, disrespecting or arguing with a Mod. This includes publicly complaining about moderators or other users, publicly glorifying or defending banned users, or debating whether or not a moderator action was appropriate. If you are concerned about one of the rules or the behaviour of the Mods, please contact the staff via email (admin@habitica.com).",
"commGuideList06B": "Backseat Modding. To quickly clarify a relevant point: A friendly mention of the rules is fine. Backseat modding consists of telling, demanding, and/or strongly implying that someone must take an action that you describe to correct a mistake. You can alert someone to the fact that they have committed a transgression, but please do not demand an action -- for example, saying, \"Just so you know, profanity is discouraged in the Tavern, so you may want to delete that,\" would be better than saying, \"I'm going to have to ask you to delete that post.\"",
"commGuideList06C": "Intentionally flagging innocent posts.",
@@ -64,7 +64,7 @@
"commGuideHeadingMinorInfractions": "Minur Enfructions",
"commGuidePara056": "Minor Infractions, while discouraged, still have minor consequences. If they continue to occur, they can lead to more severe consequences over time.",
"commGuidePara057": "The following are some examples of Minor Infractions. This is not a comprehensive list.",
- "commGuideList07A": "1st times violations uf Publick Space Guidelinehs ",
+ "commGuideList07A": "1st times violations uf Publick Space Guidelinehs",
"commGuideList07B": "Any statements or actions that trigger a \"Please Don't\". When a Mod has to say \"Please don't do this\" to a user, it can count as a very minor infraction for that user. An example might be \"Please don't keep arguing in favor of this feature idea after we've told you several times that it isn't feasible.\" In many cases, the Please Don't will be the minor consequence as well, but if Mods have to say \"Please Don't\" to the same user enough times, the triggering Minor Infractions will start to count as Moderate Infractions.",
"commGuidePara057A": "Some posts may be hidden because they contain sensitive information or might give people the wrong idea. Typically this does not count as an infraction, particularly not the first time it happens!",
"commGuideHeadingConsequences": "Cunsequencehz",
@@ -125,4 +125,4 @@
"commGuideLink06": "The Art Trello: for submitting pixel art.",
"commGuideLink07": "The Quest Trello: for submitting quest writing.",
"commGuidePara069": "The following talented artists contributed to these illustrations:"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/en@lolcat/content.json b/website/common/locales/en@lolcat/content.json
index df9f5d16b8..a4fa4dc2a1 100755
--- a/website/common/locales/en@lolcat/content.json
+++ b/website/common/locales/en@lolcat/content.json
@@ -1,9 +1,9 @@
{
"potionText": "Helf Potiun",
- "potionNotes": "Recovr 15 helf (Instant oos) Srsyly!!!1!",
+ "potionNotes": "Recovr 15 helf (Instan use) Srsyly!!!1!",
"armoireText": "Enchanted Armoier",
"armoireNotesFull": "Open the Armoire to randomly receive special Equipment, Experience, or food! Equipment pieces remaining:",
- "armoireLastItem": "U've findz teh last pieec ov raer Equipment in teh Enchanted Armoier. ",
+ "armoireLastItem": "Uve findz teh last pieec ov raer Ekwipment n teh Enchantd Armoier.",
"armoireNotesEmpty": "Teh armoire wil haz new ekwipmeoent in teh ferst wek for every month. Until then kep clikin fr experians an cat fod!",
"dropEggWolfText": "Wulv",
"dropEggWolfMountText": "Wulv",
@@ -231,7 +231,7 @@
"foodFish": "Fish",
"foodFishThe": "the Fish",
"foodFishA": "a Fish",
- "foodRottenMeat": "Rottened Meet. Srsly.",
+ "foodRottenMeat": "Rottened Meet",
"foodRottenMeatThe": "the Rotten Meat",
"foodRottenMeatA": "Rotten Meat",
"foodCottonCandyPink": "Pink Cawtun Candeh",
@@ -264,7 +264,7 @@
"foodCakeGolden": "Hunne Caek",
"foodCakeGoldenThe": "the Honey Cake",
"foodCakeGoldenA": "a Honey Cake",
- "foodCakeZombie": "Rottened Caek. Liek srsly rottened.",
+ "foodCakeZombie": "Rottened Caek",
"foodCakeZombieThe": "the Rotten Cake",
"foodCakeZombieA": "a Rotten Cake",
"foodCakeDesert": "Sand Caek",
@@ -294,7 +294,7 @@
"foodCandyGolden": "Hunne Candeh",
"foodCandyGoldenThe": "the Honey Candy",
"foodCandyGoldenA": "Honey Candy",
- "foodCandyZombie": "Rottened Candeh. Liek ew.",
+ "foodCandyZombie": "Rottened Candeh",
"foodCandyZombieThe": "the Rotten Candy",
"foodCandyZombieA": "Rotten Candy",
"foodCandyDesert": "Sand Candeh",
@@ -306,5 +306,14 @@
"foodSaddleText": "Saddul",
"foodSaddleNotes": "Raisez wun of ur petz into maunt in wun tiem.",
"foodSaddleSellWarningNote": "Hey! This is a pretty useful item! Are you familiar with how to use a Saddle with your Pets?",
- "foodNotes": "Feed dis 2 an pet an it gro into an sturdeh steed maebeh."
-}
\ No newline at end of file
+ "foodNotes": "Feed dis 2 an pet an it gro into an sturdeh steed maebeh.",
+ "hatchingPotionSilver": "Silvr",
+ "hatchingPotionSunshine": "Sunshien",
+ "hatchingPotionRoseQuartz": "Roes Kwartz",
+ "questEggRobotAdjective": "a futuristic",
+ "questEggRobotMountText": "Robot",
+ "questEggRobotText": "Robot",
+ "questEggDolphinAdjective": "a chippr",
+ "questEggDolphinMountText": "Dolfin",
+ "questEggDolphinText": "Dolfin"
+}
diff --git a/website/common/locales/en@lolcat/contrib.json b/website/common/locales/en@lolcat/contrib.json
index f8333a814a..bd0f2fd1ce 100755
--- a/website/common/locales/en@lolcat/contrib.json
+++ b/website/common/locales/en@lolcat/contrib.json
@@ -1,54 +1,54 @@
{
- "playerTiersDesc": "The colored usernames you see in chat represent a person's contributor tier. The higher the tier, the more the person has contributed to habitica through art, code, the community, or more!",
- "tier1": "Tier 1 (Friend)",
- "tier2": "Tier 2 (Friend)",
- "tier3": "Tier 3 (Elite)",
- "tier4": "Tier 4 (Elite)",
- "tier5": "Tier 5 (Champion)",
- "tier6": "Tier 6 (Champion)",
- "tier7": "Tier 7 (Legendary)",
- "tierModerator": "Moderator (Guardian)",
- "tierStaff": "Staff (Heroic)",
+ "playerTiersDesc": "Teh colrd usrnaemz u see n chat r 4 pplz contributr teer. Teh highr teh teer, teh moar teh persun haz helpd Habitica thru art, code, teh community, an moar!",
+ "tier1": "Teer 1 (Fren)",
+ "tier2": "Teer 2 (Fren)",
+ "tier3": "Teer 3 (1337)",
+ "tier4": "Teer 4 (1337)",
+ "tier5": "Teer 5 (Champyon)",
+ "tier6": "Teer 6 (Champyon)",
+ "tier7": "Teer 7 (Legendareh)",
+ "tierModerator": "Moderatr (Gardian)",
+ "tierStaff": "Staf (Herowik)",
"tierNPC": "NPC",
"friend": "Frand",
"friendFirst": "WEN UR FERST SIT UF SUBMISIONS IS DEPOLYED, U WELL RECIVE THE Habitica CONTRIBUTARS BADGE. UR NAIM IN TAVURN CHET WIL PRODLY DISPLAI DAT U AR AN CONTRIBUTAR. AS \nA BUNTY FER UR WERK, U WIL ALSO RECIVE 3 GEMZ.",
"friendSecond": "Wen ur second set ov submishuns iz deployed, teh Crystal Armur will bees availabel 4 purchaes in teh rewardz shop. As bounty 4 ur continud werk, u will alos receiev 3 Gems.",
"elite": "1337",
"eliteThird": "When ur third set ov submishuns iz deployed, teh Crystal Helmet will bees availabel 4 purchaes in teh rewardz shop. Srsly. As bounty 4 ur continud werk, u will alos receiev 3 Gems.",
- "eliteFourth": "When your fourth set of submissions is deployed, the Crystal Sword will be available for purchase in the Rewards shop. As a bounty for your continued work, you will also receive 4 Gems.",
+ "eliteFourth": "Wen ur 4th set ov submishuns is deploid, teh Krystul Swurd wil be available 4 perchis n da Rewardz shop. As bounty 4 ur continud wurk, u can also haz 4 Gems.",
"champion": "Champyun",
- "championFifth": "When your fifth set of submissions is deployed, the Crystal Shield will be available for purchase in the Rewards shop. As a bounty for your continued work, you will also receive 4 Gems.",
- "championSixth": "When your sixth set of submissions is deployed, you will receive a Hydra Pet. You will also receive 4 Gems.",
+ "championFifth": "Wen ur 5th set ov submishuns is deploid, teh Krystul Sheeld wil be available 4 perchis n da Rewardz shop. As bounty 4 ur continud wurk, u can also haz 4 Gems.",
+ "championSixth": "Wen ur 6th set ov submishuns is deploid, u can haz Hydra Pet. U can also haz 4 Gems.",
"legendary": "Legundareh",
- "legSeventh": "When your seventh set of submissions is deployed, you will receive 4 Gems and become a member of the honored Contributor's Guild and be privy to the behind-the-scenes details of Habitica! Further contributions do not increase your tier, but you may continue to earn Gem bounties and titles.",
+ "legSeventh": "Wen ur 7th set of submishuns is deploid, u can haz 4 Gems an becum membr ov honrd Contributorz Gild an be privy 2 teh behin-teh-sceenz detalz ov Habitica! Moar contribushunz do not increes ur teer, but u may continue 2 earn Gem bountyz an titlz.",
"moderator": "Moderatur",
"guardian": "Gawrdiyun",
- "guardianText": "Moderators were selected carefully from high tier contributors, so please give them your respect and listen to their suggestions.",
+ "guardianText": "Moderaturs wer selecd carefulie frum hai teer contributrz, so pls give dem ur respec an listn 2 there sugestionz.",
"staff": "Staf",
"heroic": "Heroik",
- "heroicText": "The Heroic tier contains Habitica staff and staff-level contributors. If you have this title, you were appointed to it (or hired!).",
+ "heroicText": "Teh Heroik teer contanez Habitica staf an staf-lvl contributrz. If u haz dis titl, u wer appointd 2 it (or hierd!).",
"npcText": "NPCs backed Habitica'z Kickstartr at teh highest teer. U cna fiend dere avaturz watching ovur sait feeturz! SRS!",
"modalContribAchievement": "Contributar Acheevment!",
- "contribModal": "<%= name %>, you awesome person! You're now a tier <%= level %> contributor for helping Habitica.",
- "contribLink": "See what prizes you've earned for your contribution!",
+ "contribModal": "<%= name %>, u awsum persn! Ur now teer <%= level %> contributr 4 helpin Habitica.",
+ "contribLink": "See wat praizez u can haz 4 ur contribushun!",
"contribName": "Contributar",
- "contribText": "Has contributed to Habitica, whether via code, art, music, writing, or other methods. To learn more, join the Aspiring Legends Guild!",
+ "contribText": "Haz contributd 2 Habitica, wethr via code, art, musik, ritin, or othr methodz. 2 lern moar, join teh Aspiring Legends Gild!",
"readMore": "Reed MOAR",
- "kickstartName": "Kickstarter Backer - $<%= key %> Tier",
+ "kickstartName": "Kickstarter Bakr - $<%= key %> Teer",
"kickstartText": "Backd teh Kickstartur Projekd",
- "helped": "Helped Habitica Grow",
+ "helped": "Helpd Habitica Groah",
"helpedText1": "Helpd Habitica groo bai filling aut",
- "helpedText2": "dis survae",
- "hall": "Hall of Heroes",
+ "helpedText2": "dis survae.",
+ "hall": "Hal ov Heroz",
"contribTitle": "Contributar Taitul (liek \"Blacksmif\")",
"contribLevel": "CONTRIB TEER",
"contribHallText": "1-7 for normal contributors, 8 for moderators, 9 for staff. This determines which items, pets, and mounts are available. Also determines name-tag coloring. Tiers 8 and 9 are automatically given admin status.",
- "hallContributors": "Hall of Contributors",
+ "hallContributors": "Hal ov Contributrz",
"hallPatrons": "Hall of Paytronz",
"rewardUser": "Reward Yooser",
"UUID": "User ID",
"loadUser": "Load Yooser",
- "noAdminAccess": "You don't have admin access.",
+ "noAdminAccess": "U no haz admin access.",
"userNotFound": "User not found.",
"invalidUUID": "UUID must be valid",
"title": "Taitul",
@@ -57,10 +57,10 @@
"contributions": "Contributionz",
"admin": "Admin",
"notGems": "is in USD, not in Gems. Aka, if this number is 1, it means 4 gems. Only use this option when manually granting gems to players, don't use it when granting contributor tiers. Contrib tiers will automatically add gems.",
- "gamemaster": "Game Master (staff/moderator)",
+ "gamemaster": "Gaem Mastr (staf/moderatur)",
"backerTier": "Backur Teer",
"balance": "Balanz",
- "tierPop": "Click teer labelz 4 deetailz",
+ "tierPop": "Click teer labelz 4 deetailz.",
"playerTiers": "Playur Teerz",
"tier": "Teer",
"visitHeroes": "Vizzid teh Hall of Heerooz (contributarz and backurz)",
@@ -68,13 +68,13 @@
"conLearnHow": "Learn hao 2 contribyoot 2 Habitica",
"conLearnURL": "http://habitica.wikia.com/wiki/Contributing_to_Habitica",
"conRewardsURL": "http://habitica.wikia.com/wiki/Contributor_Rewards",
- "surveysSingle": "Helped Habitica grow, either by filling out a survey or helping with a major testing effort. Thank you!",
- "surveysMultiple": "Helped Habitica grow on <%= count %> occasions, either by filling out a survey or helping with a major testing effort. Thank you!",
- "currentSurvey": "Current Survey",
- "surveyWhen": "The badge will be awarded to all participants when surveys have been processed, in late March.",
- "blurbInbox": "This is where your private messages are stored! You can send someone a message by clicking on the envelope icon next to their name in Tavern, Party, or Guild Chat. If you've received an inappropriate PM, you should email a screenshot of it to Lemoness (<%= hrefCommunityManagerEmail %>)",
- "blurbGuildsPage": "Guilds are common-interest chat groups created by the players, for players. Browse through the list and join the Guilds that interest you!",
- "blurbChallenges": "Challenges are created by your fellow players. Joining a Challenge will add its tasks to your task dashboard, and winning a Challenge will give you an achievement and often a gem prize!",
- "blurbHallPatrons": "This is the Hall of Patrons, where we honor the noble adventurers who backed Habitica's original Kickstarter. We thank them for helping us bring Habitica to life!",
+ "surveysSingle": "Helpd Habitica groah, eithr by filin out survai or helpin wif majur testin efort. Thx!",
+ "surveysMultiple": "Helpd Habitica groah on <%= count %> ocashunz, eithr by filin out survai or helpin wif majur testin efort. Thx!",
+ "currentSurvey": "Curent Survai",
+ "surveyWhen": "Teh badge wil be award 2 al participantz wen survais haz been proces, n laet March.",
+ "blurbInbox": "Dis ar wer ur privet mesagez r stored! U can sen sumwun mesage by clikin on teh envelope icon next 2 there naem n Tavern, Party, or Gild Chat. If uve gotd inappropriet PM, u shud email picchur ov it 2 Lemoness (<%= hrefCommunityManagerEmail %>)",
+ "blurbGuildsPage": "Gildz r commn-interest chat grupz creatd by teh playrz, 4 teh playrz. Brows thru teh list an join teh Gildz u liek!",
+ "blurbChallenges": "Chalengez r creatd by ur felow playrz. Joinin Chalenge wil ad itz taskz 2 ur task dashbord, an winin Chalenge meenz u can haz acheevment an mayb even gem praiz!",
+ "blurbHallPatrons": "Dis is teh Hal ov Patronz, where we honr teh nobl aventururz hoo backd Habiticaz originul Kickstarter. We thank dem 4 helpin us bring Habitica 2 laif!",
"blurbHallContributors": "This is the Hall of Contributors, where open-source contributors to Habitica are honored. Whether through code, art, music, writing, or even just helpfulness, they have earned gems, exclusive equipment, and prestigious titles. You can contribute to Habitica, too! Find out more here. "
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/en@lolcat/death.json b/website/common/locales/en@lolcat/death.json
index e5b667a850..0bedff9c5f 100755
--- a/website/common/locales/en@lolcat/death.json
+++ b/website/common/locales/en@lolcat/death.json
@@ -5,13 +5,13 @@
"refillHealthTryAgain": "Reefell Helth & Tri Agen",
"dyingOftenTips": "Iz tis happenin oftin? Here r sum tips!",
"losingHealthWarning": "Carefuls - Urs loosing helth!",
- "losingHealthWarning2": "Don't let your Health drop to zero! If you do, you'll lose a level, your Gold, and a piece of equipment.",
+ "losingHealthWarning2": "Dont let ur helth get 2 zero! If u do, u can loose lvl, ur gold, an 1 piece ov ekwipment.",
"toRegainHealth": "2 regain Health:",
"lowHealthTips1": "Lvls up 2 full healz!",
- "lowHealthTips2": "Buy a Health Potion from the Rewards column to restore 15 Health Points.",
+ "lowHealthTips2": "Buy Helth Poshun frum teh Rewardz colum 2 give u 15 Helf Pointz.",
"losingHealthQuickly": "Lozin Helth kuikly?",
- "lowHealthTips3": "Incomplete Dailies hurt you overnight, so be careful not to add too many at first!",
- "lowHealthTips4": "If a Daily isn't due on a certain day, you can disable it by clicking the pencil icon.",
+ "lowHealthTips3": "Incompleet Dailyz hurt u ovrnite, so try not 2 ad 2 meny at first!",
+ "lowHealthTips4": "If Daily isnt due on certin day, u can haz it disabld by clikin teh pencil icon.",
"goodLuck": "Gud Luk!",
- "cannotRevive": "Cannot revive if not dead"
-}
\ No newline at end of file
+ "cannotRevive": "Cant revive if not daed"
+}
diff --git a/website/common/locales/en@lolcat/defaulttasks.json b/website/common/locales/en@lolcat/defaulttasks.json
index 3fbab59bb0..56fa498a8d 100755
--- a/website/common/locales/en@lolcat/defaulttasks.json
+++ b/website/common/locales/en@lolcat/defaulttasks.json
@@ -1,28 +1,65 @@
{
"defaultHabit1Text": "Pruductive Wurk (Click teh pencul 2 edits)",
"defaultHabit1Notes": "Sumple Gud habbitz: +Eats un veggietabble + 15 minutez products wrk",
- "defaultHabit2Text": "Eat Junk Food (Click teh pencil 2 edit) ",
- "defaultHabit2Notes": "Sampel Wet Habits: - Smoek - Procrastinaet ",
+ "defaultHabit2Text": "Eet Junk Fewd (Clik teh pencil 2 edit)",
+ "defaultHabit2Notes": "Sampel Bad Habitz: - Smoek - Procrastinaet",
"defaultHabit3Text": "Taek teh Stairs/Elevator (Click teh pencil 2 edit)",
- "defaultHabit3Notes": "Sample Good or Bad Habits: +/- Took Stairs/Elevator ; +/- Drank Water/Soda",
- "defaultHabit4Text": "Add a task to Habitica",
- "defaultHabit4Notes": "Either a Habit, a Daily, or a To-Do",
- "defaultHabit5Text": "Tap here to edit this into a bad habit you'd like to quit",
- "defaultHabit5Notes": "Or delete from the edit screen",
- "defaultDaily1Text": "Use Habitica to keep track of your tasks",
- "defaultTodo1Text": "Join Habitica (Check me off!)",
- "defaultTodoNotes": "You can either complete this To-Do, edit it, or remove it.",
- "defaultTodo2Text": "Finish Justin's task walkthrough",
- "defaultTodo2Notes": "Visit all the sections of the bottom bar",
+ "defaultHabit3Notes": "Sample Gud or Bad Habitz: +/- Tok Staers/Elevatr ; +/- Drinkd Watr/Soda",
+ "defaultHabit4Text": "Add task 2 Habitica",
+ "defaultHabit4Notes": "Eithr Habit, Daily, or ToDo",
+ "defaultHabit5Text": "Tap here 2 edit into bad habit ud liek 2 kwit",
+ "defaultHabit5Notes": "Or delet from teh edit screen",
+ "defaultDaily1Text": "Ues Habitica 2 keep trak of ur taskz",
+ "defaultTodo1Text": "Join Habitica (Chek me off pls!)",
+ "defaultTodoNotes": "U can eithr complet thiz To-Do, edit it, or remove it.",
+ "defaultTodo2Text": "Finish Justinz task walkthru",
+ "defaultTodo2Notes": "Visit all teh secshunz of teh bottum bar",
"defaultReward1Text": "15 mins breaks",
- "defaultReward1Notes": "Custom rewards can come in many forms. Some people will hold off watching their favorite show unless they have the gold to pay for it.",
- "defaultReward2Text": "Reward yourself",
- "defaultReward2Notes": "Watch TV, play a game, eat a treat, it's up to you!",
- "defaultTag1": "Work",
- "defaultTag2": "Exercise",
- "defaultTag3": "Health + Wellness",
- "defaultTag4": "School",
+ "defaultReward1Notes": "Custum rewardz can comd in many formz. Sum peepl will hold off watchin their favrit show unlez they haz teh gold 2 pai 4 it.",
+ "defaultReward2Text": "Reward urself",
+ "defaultReward2Notes": "Wach TV, play gaem, eet treet, itz up 2 u!",
+ "defaultTag1": "Wurk",
+ "defaultTag2": "Exerciz",
+ "defaultTag3": "Helth + Welnes",
+ "defaultTag4": "Skul",
"defaultTag5": "Teams",
- "defaultTag6": "Chores",
- "defaultTag7": "Creativity"
-}
\ No newline at end of file
+ "defaultTag6": "Chorz",
+ "defaultTag7": "Creatiftie",
+ "selfCareTodoText": "I can haz fun activitie",
+ "schoolHabit": "Studie/Procrastinaet",
+ "defaultHabitNotes": "Or delet frum teh edit screen",
+ "defaultHabitText": "Clik here 2 edit into bad habit ud liek 2 kwit",
+ "creativityTodoNotes": "Tap 2 specify teh naem of ur projekd",
+ "creativityTodoText": "Finish creatif projekd",
+ "creativityDailyNotes": "Tap 2 specify teh naem of ur currnt projekd + set teh skedul!",
+ "creativityDailyText": "Werk on creatif projekd",
+ "creativityHabit": "Study master of teh craf >> + Practicd new creatif techneek",
+ "choresTodoNotes": "Tap 2 specify teh cluttrd plas!",
+ "choresTodoText": "Organize closet >> Organize cluttr",
+ "choresDailyNotes": "Tap 2 choosed ur skedul!",
+ "choresDailyText": "Wash dishez",
+ "choresHabit": "10 minuets cleenin",
+ "selfCareTodoNotes": "Tap 2 specify wat u plan 2 do!",
+ "selfCareDailyNotes": "Tap 2 choosed ur skedul!",
+ "selfCareDailyText": "5 minuets of kwiet breevin",
+ "selfCareHabit": "Tak short brak",
+ "schoolTodoNotes": "Tap 2 naem teh asignmnt an choosed due daet!",
+ "schoolTodoText": "Finish asignmnt for claz",
+ "schoolDailyNotes": "Tap 2 choosed ur hoemwerk skedul!",
+ "schoolDailyText": "Finish hoemwerk",
+ "healthTodoNotes": "Tap 2 add cheklistz!",
+ "healthTodoText": "Skedul chekup >> Branestorm healthee change",
+ "healthDailyNotes": "Tap 2 maek any changez!",
+ "healthDailyText": "Floz",
+ "healthHabit": "Eet helth/junk fewd",
+ "exerciseTodoNotes": "Tap 2 add cheklis!",
+ "exerciseTodoText": "Set up werkowt skedul",
+ "exerciseDailyNotes": "Tap 2 choosed ur skedul an specify exercizez!",
+ "exerciseDailyText": "Stretchin >> Daily werkowt rewtine",
+ "exerciseHabit": "10 min cardio >> + 10 minuets cardio",
+ "workTodoProjectNotes": "Tap 2 specify teh naem of ur currnt projekd + set due daet!",
+ "workDailyImportantTaskNotes": "Tap 2 specify ur most emportant task",
+ "workDailyImportantTask": "Most emportant task >> Werkd on todayz most emportant task",
+ "workTodoProject": "Werk projekd >> Complet werk projekd",
+ "workHabitMail": "Proces email"
+}
diff --git a/website/common/locales/en@lolcat/faq.json b/website/common/locales/en@lolcat/faq.json
index 48142e9593..a477393d8c 100755
--- a/website/common/locales/en@lolcat/faq.json
+++ b/website/common/locales/en@lolcat/faq.json
@@ -1,14 +1,14 @@
{
- "frequentlyAskedQuestions": "Frequently Askd Queshuns ",
+ "frequentlyAskedQuestions": "Frequently Askd Queshuns",
"faqQuestion0": "HJALP. WAT DO I DO?",
"iosFaqAnswer0": "FURST, ULL SET UP TASKZ DAT U WANTS 2 DO IN UR EVRYDAI LIFE. DEN, AS U COMPLETE TEH TASKZ IN REAL LIFE AN CHECK THEM OFF, ULL EARN ECKSPEERIUNCE AN GOLD. GOLD IZ USD 2 BUY EQUIPMENT AN SUM ITEMS, AS WELL AS CUSTOM REWARDZ. ECKSPEERIUNCE CAUSEZ UR CHARACTR 2 LEVEL UP AN UNLOCK CONTENT SUCH AS PETS, SKILLS, AN KWESTS! U CAN CUSTOMIZE UR CHARACTR UNDR MENU > CUSTOMIZE PIKCHUR.\n\nSUM BASIC WAYS 2 INTERACT: CLICK TEH (+) IN DA UPPR-RITE-HAND CORNR 2 ADD NEW TASK. TAP ON AN EXISTIN TASK 2 EDIT IT, AN SWIPE LEFT ON TASK 2 DELETE IT. U CAN SORT TASKZ USIN TAGS IN DA UPPR-LEFT-HAND CORNR, AN EXPAND AN CONTRACT CHECKLISTS BY CLICKIN ON TEH CHECKLIST BUBBLE.",
"androidFaqAnswer0": "FURST, ULL SET UP TASKZ DAT U WANTS 2 DO IN UR EVRYDAI LIFE. DEN, AS U COMPLETE TEH TASKZ IN REAL LIFE AN CHECK THEM OFF, ULL EARN ECKSPEERIUNCE AN GOLD. GOLD IZ USD 2 BUY EQUIPMENT AN SUM ITEMS, AS WELL AS CUSTOM REWARDZ. ECKSPEERIUNCE CAUSEZ UR CHARACTR 2 LEVEL UP AN UNLOCK CONTENT SUCH AS PETS, SKILLS, AN KWESTS! U CAN CUSTOMIZE UR CHARACTR UNDR MENU > [INVENTORY >] PIKCHUR.\n\nSUM BASIC WAYS 2 INTERACT: CLICK TEH (+) IN DA UPPR-RITE-HAND CORNR 2 ADD NEW TASK. TAP ON AN EXISTIN TASK 2 EDIT IT, AN SWIPE LEFT ON TASK 2 DELETE IT. U CAN SORT TASKZ USIN TAGS IN DA UPPR-LEFT-HAND CORNR, AN EXPAND AN CONTRACT CHECKLISTS BY CLICKIN ON TEH CHECKLIST BUBBLE.",
"webFaqAnswer0": "First, you'll set up tasks that you want to do in your everyday life. Then, as you complete the tasks in real life and check them off, you'll earn Experience and Gold. Gold is used to buy equipment and some items, as well as custom rewards. Experience causes your character to level up and unlock content such as pets, skills, and quests! For more detail, check out a step-by-step overview of the game at [Help -> Overview for New Users](https://habitica.com/static/overview).",
"faqQuestion1": "How 2 set up taskz?",
- "iosFaqAnswer1": "Good Habits (the ones with a +) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a -) are tasks that you should avoid, like biting nails. Habits with a + and a - have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award experience and gold. Bad Habits subtract health.\n\n Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by tapping to edit it. If you skip a Daily that is due, your avatar will take damage overnight. Be careful not to add too many Dailies at once!\n\n To-Dos are your To-Do list. Completing a To-Do earns you gold and experience. You never lose health from To-Dos. You can add a due date to a To-Do by tapping to edit.",
+ "iosFaqAnswer1": "Gud Habitz (teh 1s wif +) r taskz u can do many tiemz eech dai liek eetin vegetables. Bad Habitz (teh 1s wif -) r taskz u should avoid liek biting nailz. Habitz wif + an - can haz gud choiec an bad choiec liek tak teh stairs vs. tak teh elevator. Gud Habitz give experience an gold. Bad Habitz subtract helf.\n\n Dailyz r taskz u have to do eech dai liek brushin ur teeth or chekin ur email. U can adjust the days Dailyz iz due by tapping 2 edit it. If u skip Dailyz that iz due, ur avatar will take damage overnight. Be careful not 2 add 2 many Dailyz at once!\n\n ToDoz r ur ToDo list. Completin ToDoz earnz u gold an experience. U never lose helf frum ToDoz. U can add due date 2 ToDoz by tapping 2 edit.",
"androidFaqAnswer1": "Good Habits (the ones with a +) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a -) are tasks that you should avoid, like biting nails. Habits with a + and a - have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award experience and gold. Bad Habits subtract health.\n\n Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by tapping to edit it. If you skip a Daily that is due, your character will take damage overnight. Be careful not to add too many Dailies at once!\n\n To-Dos are your To-Do list. Completing a To-Do earns you gold and experience. You never lose health from To-Dos. You can add a due date to a To-Do by tapping to edit.",
"webFaqAnswer1": "* Good Habits (the ones with a :heavy_plus_sign:) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a :heavy_minus_sign:) are tasks that you should avoid, like biting nails. Habits with a :heavy_plus_sign: and a :heavy_minus_sign: have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award Experience and Gold. Bad Habits subtract Health.\n* Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by clicking the pencil item to edit it. If you skip a Daily that is due, your avatar will take damage overnight. Be careful not to add too many Dailies at once!\n* To-Dos are your To-Do list. Completing a To-Do earns you Gold and Experience. You never lose Health from To-Dos. You can add a due date to a To-Do by clicking the pencil icon to edit.",
- "faqQuestion2": "I NEED EXAMPLEZ",
+ "faqQuestion2": "I NEED EXAMPLEZ????",
"iosFaqAnswer2": "The wiki has four lists of sample tasks to use as inspiration:\n
\n * [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits)\n * [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies)\n * [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos)\n * [Sample Custom Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards)",
"androidFaqAnswer2": "The wiki has four lists of sample tasks to use as inspiration:\n
\n * [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits)\n * [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies)\n * [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos)\n * [Sample Custom Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards)",
"webFaqAnswer2": "The wiki has four lists of sample tasks to use as inspiration:\n * [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits)\n * [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies)\n * [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos)\n * [Sample Custom Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards)",
@@ -55,4 +55,4 @@
"iosFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the Tavern chat under Menu > Tavern! We're happy to help.",
"androidFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the Tavern chat under Menu > Tavern! We're happy to help.",
"webFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the [Habitica Help guild](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)! We're happy to help."
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/en@lolcat/gear.json b/website/common/locales/en@lolcat/gear.json
index 03eaeac2b6..f421256a89 100755
--- a/website/common/locales/en@lolcat/gear.json
+++ b/website/common/locales/en@lolcat/gear.json
@@ -1,19 +1,19 @@
{
"set": "Set",
"equipmentType": "Tyep",
- "klass": "Class",
+ "klass": "Clas",
"groupBy": "Groop By <%= type %>",
- "classBonus": "(This item matches your class, so it gets an additional 1.5 Stat multiplier.)",
- "classArmor": "Class Armor",
- "featuredset": "Featured Set <%= name %>",
- "mysterySets": "Mystery Sets",
- "gearNotOwned": "You do not own this item.",
- "noGearItemsOfType": "You don't own any of these.",
- "noGearItemsOfClass": "You already have all your class equipment! More will be released during the Grand Galas, near the solstices and equinoxes.",
+ "classBonus": "(Dis item matchz ur clas, so it getz adishunal 1.5 Stat multiplir.)",
+ "classArmor": "Clas Armur",
+ "featuredset": "Featurd Set <%= name %>",
+ "mysterySets": "Mystry Sets",
+ "gearNotOwned": "U no haz dis item.",
+ "noGearItemsOfType": "U no haz ne of deez.",
+ "noGearItemsOfClass": "U alredy haz al ur clas ekwipmnt! U can haz moar durin teh Gran Galaz, neer teh solsticz an ekwinoxz.",
"classLockedItem": "This item is only available to a specific class. Change your class under the User icon > Settings > Character Build!",
"tierLockedItem": "This item is only available once you've purchased the previous items in sequence. Keep working your way up!",
"sortByType": "Type",
- "sortByPrice": "Price",
+ "sortByPrice": "Praice",
"sortByCon": "CON",
"sortByPer": "PER",
"sortByStr": "STR",
@@ -21,23 +21,23 @@
"weapon": "waepon",
"weaponCapitalized": "Main-Hand Item",
"weaponBase0Text": "Nos waepon",
- "weaponBase0Notes": "No Weapon.",
- "weaponWarrior0Text": "Training Sword",
- "weaponWarrior0Notes": "Practice weapon. Confers no benefit.",
+ "weaponBase0Notes": "No Wepon.",
+ "weaponWarrior0Text": "Trainin Sord",
+ "weaponWarrior0Notes": "Practis wepon. Givez no benefit.",
"weaponWarrior1Text": "Swurd",
- "weaponWarrior1Notes": "Common soldier's blade. Increases Strength by <%= str %>.",
+ "weaponWarrior1Notes": "Comon soldierz blayd. Increesez Strength by <%= str %>.",
"weaponWarrior2Text": "Axeh",
- "weaponWarrior2Notes": "Double-bitted chopping weapon. Increases Strength by <%= str %>",
+ "weaponWarrior2Notes": "Duble-bittd chopin wepon. Increesez Strength by <%= str %>",
"weaponWarrior3Text": "Murning Starr",
- "weaponWarrior3Notes": "Heavy club with brutal spikes. Increases Strength by <%= str %>.",
- "weaponWarrior4Text": "Sapphire Blade",
- "weaponWarrior4Notes": "Sword whose edge bites like the north wind. Increases Strength by <%= str %>.",
- "weaponWarrior5Text": "Rooby Swurd ",
- "weaponWarrior5Notes": "Weapon whose forge-glow never fades. Increases Strength by <%= str %>.",
- "weaponWarrior6Text": "Golden Sword",
+ "weaponWarrior3Notes": "Hevy club wif brootl spaikz. Increesez Strength by <%= str %>.",
+ "weaponWarrior4Text": "Safire Blayd",
+ "weaponWarrior4Notes": "Swerd whos edge bitez liek teh north wind. Increesez Strength by <%= str %>.",
+ "weaponWarrior5Text": "Rooby Swurd",
+ "weaponWarrior5Notes": "Wepon whos forge-glow nevr fadez. Increesez Strength by <%= str %>.",
+ "weaponWarrior6Text": "Goldn Swurd",
"weaponWarrior6Notes": "Bane of creatures of darkness. Increases Strength by <%= str %>.",
"weaponRogue0Text": "Dagger",
- "weaponRogue0Notes": "A rogue's most basic weapon. Confers no benefit.",
+ "weaponRogue0Notes": "Rougez most baesik wepon. Givez no benefit.",
"weaponRogue1Text": "Short Sword",
"weaponRogue1Notes": "Light, concealable blade. Increases Strength by <%= str %>.",
"weaponRogue2Text": "Scimitar",
@@ -1742,4 +1742,4 @@
"eyewearArmoireGoofyGlassesText": "Goofy Glasses",
"eyewearArmoireGoofyGlassesNotes": "Perfect for going incognito or just making your partymates giggle. Increases Perception by <%= per %>. Enchanted Armoire: Independent Item.",
"twoHandedItem": "Two-handed item."
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/en@lolcat/limited.json b/website/common/locales/en@lolcat/limited.json
index c55cf5ad16..7df51d8318 100755
--- a/website/common/locales/en@lolcat/limited.json
+++ b/website/common/locales/en@lolcat/limited.json
@@ -3,10 +3,10 @@
"seasonalEdition": "Seasonal Edishun",
"winterColors": "Wintah Colors",
"annoyingFriends": "Annoyin Frandz",
- "annoyingFriendsText": "Got snowballed <%= count %> times by party members.",
- "alarmingFriends": "Alarming Friends",
+ "annoyingFriendsText": "Getd snowbald <%= count %> tiemz by party membrz.",
+ "alarmingFriends": "Alarmin Frandz",
"alarmingFriendsText": "Got spooked <%= count %> times by party members.",
- "agriculturalFriends": "Agricultural Friends",
+ "agriculturalFriends": "Farmr Frandz",
"agriculturalFriendsText": "Got transformed into a flower <%= count %> times by party members.",
"aquaticFriends": "Aquatic Friends",
"aquaticFriendsText": "Got splashed <%= count %> times by party members.",
@@ -152,4 +152,4 @@
"discountBundle": "bundle",
"g1g1Announcement": "Gift a Subscription, Get a Subscription Free event going on now!",
"g1g1Details": "Gift a sub to a friend from their profile and you’ll receive the same sub for free!"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/en@lolcat/loadingscreentips.json b/website/common/locales/en@lolcat/loadingscreentips.json
index df78c3e6de..92b7342efd 100755
--- a/website/common/locales/en@lolcat/loadingscreentips.json
+++ b/website/common/locales/en@lolcat/loadingscreentips.json
@@ -1,38 +1,38 @@
{
- "tipTitle": "Tip #<%= tipNumber %>",
- "tip1": "Check taskz on teh go wif teh Habitica mobiel appz. ",
- "tip2": "Click any equipment to see a preview, or equip it instantly by clicking the star in its upper-left corner!",
- "tip3": "Ues emoij 2 kwyckly differentiaet tween ur taskz. ",
- "tip4": "Use the # sign before a task name to make it really big!",
- "tip5": "It’s best to use skills that cause buffs in the morning so they last longer.",
- "tip6": "Hover over a task and click the dots to access advanced task controls, such as the ability to push tasks to the top/bottom of your list.",
- "tip7": "Some backgrounds connect perfectly if Party members use the same background. Ex: Mountain Lake, Pagodas, and Rolling Hills.",
- "tip8": "Send a Message to someone by clicking their name in chat and then clicking the envelope icon at the top of their profile!",
- "tip9": "Use the filters + search bar in the Inventories, Shops, Guilds, and Challenges to quickly find what you want.",
- "tip10": "You can win gems by competing in Challenges. New ones are added every day!",
- "tip11": "Having more than four Party members increases accountability!",
- "tip12": "Add checklists to your To-Dos to multiply your rewards!",
- "tip13": "Click “Tags” on your task page to make an unwieldy task list very manageable!",
- "tip14": "You can add headers or inspirational quotes to your list as Habits with no (+/-).",
- "tip15": "Complete all the Masterclasser Quest-lines to learn about Habitica’s secret lore.",
- "tip16": "Click the link to the Data Display Tool in the footer for valuable insights on your progress.",
- "tip17": "Use the mobile apps to set reminders for your tasks.",
- "tip18": "Habits that are just positive or just negative gradually “fade” and return to yellow.",
- "tip19": "Boost your Intelligence Stat to gain more experience when you complete a task.",
- "tip20": "Boost your Perception Stat to get more drops and gold.",
- "tip21": "Boost your Strength Stat to do more boss damage or get critical hits.",
- "tip22": "Boost your Constitution Stat to lessen the damage from incomplete Dailies.",
- "tip23": "Reach level 100 to unlock the Orb of Rebirth for free and start a new adventure!",
- "tip24": "Have a question? Ask in the Habitica Help Guild!",
- "tip25": "The four seasonal Grand Galas start near the solstices and equinoxes.",
- "tip26": "You can look for a Party or find Party members in the Party Wanted Guild!",
- "tip27": "Did a Daily yesterday, but forgot to check it off? Don't worry! With Record Yesterday's Activity, you'll have a chance to record what you did before starting your new day.",
- "tip28": "Set a Custom Day Start under User Icon > Settings to control when your day restarts.",
- "tip29": "Complete all your Dailies to get a Perfect Day Buff that increases your Stats!",
- "tip30": "You can invite people to Guilds, not just Parties.",
- "tip31": "Check out the pre-made lists in the Library of Tasks and Challenges Guild for example tasks.",
- "tip32": "Lots of Habitica’s code, art, and writing is made by volunteer contributors! Head to the Aspiring Legends Guild to help.",
- "tip33": "Check out The Bulletin Board Guild for news about Guilds, Challenges, and other player-created events - and announce your own there!",
- "tip34": "Occasionally re-evaluate your tasks to make sure they’re up-to-date!",
- "tip35": "Users who are part of a Group Plan gain the ability to assign tasks to other users in that Group for extra task management and accountability."
+ "tipTitle": "Tip #<%= tipNumber %>",
+ "tip1": "Check taskz on teh go wif teh Habitica mobiel appz.",
+ "tip2": "Clik ne ekwipment 2 see preview, or ekwip instantly by cliking teh star n itz upper-left kornr!",
+ "tip3": "Ues emoij 2 kwyckly differentiaet tween ur taskz.",
+ "tip4": "Use teh # sign be4 task naem 2 maek it realy big!",
+ "tip5": "Itz best 2 use skilz dat giv buffz n da mornin so they last longr.",
+ "tip6": "Hover over a task an click teh dots 2 access advanced task controls, liek teh ability 2 push taskz 2 teh top/bottom of ur list.",
+ "tip7": "Sum bakgrounz connect perfecly if Party membrz use teh same bakgroun. Ex: Mountain Laek, Pagodaz, an Rolin Hilz.",
+ "tip8": "Sen Mesege 2 sumwon by clikin their naem n chat an den clikin teh envelope icon at teh top ov their profile!!",
+ "tip9": "Use teh filtrz + serch bar n teh Inventoriez, Shopz, Gildz, an Chalengez 2 kwickly find wat u wants.",
+ "tip10": "U can haz gems by competin n Chalengez. New 1s getz aded evry day!",
+ "tip11": "Havin moar than 4 Party membrz increesez acountabiltie!",
+ "tip12": "Ad checklistz 2 ur ToDoz 2 multiplai ur rewardz!",
+ "tip13": "Clik “Tagz” on ur task paeg 2 maek unweildy task lis vry manegeble!",
+ "tip14": "U can ad hederz or insprashunal kwotz 2 ur list as Habitz wif no (+/-).",
+ "tip15": "Complet al teh Mastrclasr Kwest-lienz 2 lern bout Habiticaz seekret loar.",
+ "tip16": "Clik teh link 2 teh Data Display Tool n teh footr 4 valuble insaitz on ur progres.",
+ "tip17": "Use teh mobil apz 2 seted remaindrz 4 ur taskz.",
+ "tip18": "Habitz wich r jus positiv or jus negativ graduly “fade” an return 2 yelow.",
+ "tip19": "Boost ur Intelligence Stat 2 get moar experiance wen u complet taskz.",
+ "tip20": "Boost ur Purcepshun Stat 2 get moar drops an gold.",
+ "tip21": "Boost ur Strength Stat 2 do moar bos damege or get kriticul hitz.",
+ "tip22": "Boost ur Constitution Stat 2 maek damege frum incompleet Dailyz smalr.",
+ "tip23": "Reech lvl 100 2 unlok teh Orb of Rebirth 4 free an start new aventurz!",
+ "tip24": "U can haz kwestion? Ask in teh Habitica Help Guild!",
+ "tip25": "Teh 4 seesonl Gran Galaz start neer teh solsticz an ekwinoxz.",
+ "tip26": "U can look 4 Party or fin Party membrz n teh Party Wanted Guild!",
+ "tip27": "Did Daily yesturdai, but forgeted 2 chek it off? Dont worry! Wif Record Yesturdaiz Actiftie, u can haz chans 2 record wat u did be4 startin ur new dai.",
+ "tip28": "Seted Custom Day Start undr User Icon > Settings 2 control wen ur day restarts.",
+ "tip29": "Complet al ur Dailyz 2 get Perfec Day Buff an increes ur Statz!",
+ "tip30": "U can invait ppl 2 Gildz, not jus Partyz.",
+ "tip31": "Chek teh pre-made listz n teh Library of Tasks and Challenges Guild 4 example taskz.",
+ "tip32": "Lotz ov Habiticaz code, art, an ritin iz maed by volunteer contributrz! U can go 2 teh Aspiring Legends Gild 2 help.",
+ "tip33": "Chek The Bulletin Board Guild 4 newz bout Gildz, Chalengez, an othr playr-creatd eventz - an anouns ur own ther!",
+ "tip34": "Ocashunaly re-evaluaet ur taskz 2 maek sure there up-2-daet!",
+ "tip35": "Usrz hoo r part ov Group Plan get teh abiltie 2 asign taskz 2 othr usrz n dat Group 4 xtra task manigment an accountbiltie."
}
diff --git a/website/common/locales/en@lolcat/loginincentives.json b/website/common/locales/en@lolcat/loginincentives.json
index 1ad190f91c..147785a3c4 100755
--- a/website/common/locales/en@lolcat/loginincentives.json
+++ b/website/common/locales/en@lolcat/loginincentives.json
@@ -1,29 +1,29 @@
{
- "unlockedReward": "U haz recieved <%= reward %>",
- "earnedRewardForDevotion": "You have earned <%= reward %> for being committed to improving your life.",
- "nextRewardUnlocksIn": "Check-ins until your next prize: <%= numberOfCheckinsLeft %>",
- "awesome": "Awesome!",
- "totalCount": "<%= count %> total count",
- "countLeft": "Check-ins until next reward: <%= count %>",
- "incentivesDescription": "When it comes to building habits, consistency is key. Each day you check-in you get closer to a prize.",
- "totalCheckins": "<%= count %> Check-Ins",
- "checkinEarned": "Your Check-In Counter went up!",
- "unlockedCheckInReward": "You unlocked a Check-In Prize!",
- "totalCheckinsTitle": "Total Check-Ins",
- "checkinProgressTitle": "Progress until next",
- "incentiveBackgroundsUnlockedWithCheckins": "Locked Plain Backgrounds will unlock with Daily Check-Ins.",
- "checkinReceivedAllRewardsMessage": "You have received all the Check-In prizes available! Congratulations!",
- "oneOfAllPetEggs": "one of each standard Pet Egg",
- "twoOfAllPetEggs": "two of each standard Pet Egg",
- "threeOfAllPetEggs": "three of each standard Pet Egg",
- "oneOfAllHatchingPotions": "one of each standard Hatching Potion",
- "threeOfEachFood": "three of each standard Pet Food",
- "fourOfEachFood": "four of each standard Pet Food",
- "twoSaddles": "two Saddles",
- "threeSaddles": "three Saddles",
- "incentiveAchievement": "the Royally Loyal achievement",
- "royallyLoyal": "Royally Loyal",
- "royallyLoyalText": "This user has checked in over 500 times, and has earned every Check-In Prize!",
- "checkInRewards": "Check-In Rewards",
- "backloggedCheckInRewards": "You received Check-In Prizes! Visit your Inventory and Equipment to see what's new."
+ "unlockedReward": "U haz recieved <%= reward %>",
+ "earnedRewardForDevotion": "U haz ernd <%= reward %> 4 bean commitd 2 improovin ur life.",
+ "nextRewardUnlocksIn": "Chek-inz til ur next priez: <%= numberOfCheckinsLeft %>",
+ "awesome": "Awsum!",
+ "totalCount": "<%= count %> totel count",
+ "countLeft": "Chek-inz til next reward: <%= count %>",
+ "incentivesDescription": "Wen it coemz 2 bildin habitz, consistency iz srsly important! Eech dai u chek-in u get closr 2 priez.",
+ "totalCheckins": "<%= count %> Chek-Inz",
+ "checkinEarned": "Ur Chek-In Countr goed up!",
+ "unlockedCheckInReward": "U can haz Chek-In Priez!!!!",
+ "totalCheckinsTitle": "Totel Chek-Inz",
+ "checkinProgressTitle": "Progres til next",
+ "incentiveBackgroundsUnlockedWithCheckins": "Lokd Plane Bakgroundz wil unlok wif Daily Chek-Inz.",
+ "checkinReceivedAllRewardsMessage": "U haz gotd al teh Chek-In priezez u can haz! Congratulashunz!",
+ "oneOfAllPetEggs": "1 ov eech standrd Pet Egg",
+ "twoOfAllPetEggs": "2 ov eech standrd Pet Egg",
+ "threeOfAllPetEggs": "3 ov eech standrd Pet Egg",
+ "oneOfAllHatchingPotions": "1 ov eech standrd Hatchin Poshun",
+ "threeOfEachFood": "3 ov eech standrd Pet Food",
+ "fourOfEachFood": "4 ov eech standrd Pet Food",
+ "twoSaddles": "2 Sadlez",
+ "threeSaddles": "3 Sadlez",
+ "incentiveAchievement": "teh Royely Loyel acheevment",
+ "royallyLoyal": "Royely Loyel",
+ "royallyLoyalText": "Dis usr haz chekd in ovar 500 tiemz, an haz ernd evry Chek-In Priez!",
+ "checkInRewards": "Chek-In Rewardz",
+ "backloggedCheckInRewards": "U gotd Chek-In Priezez! Chek ur Inventory an Ekwipment 2 see watz nu."
}
diff --git a/website/common/locales/en@lolcat/maintenance.json b/website/common/locales/en@lolcat/maintenance.json
index 395ac94325..c3c48eee04 100755
--- a/website/common/locales/en@lolcat/maintenance.json
+++ b/website/common/locales/en@lolcat/maintenance.json
@@ -1,34 +1,33 @@
{
- "habiticaBackSoon": "Dun worwee, Habitica will bees bak soon! ",
- "importantMaintenance": "We r doin important manetenanec dat we estimaet will last til 10pm Pacific tiem (5am UTC).",
- "maintenance": "Manetenanec",
- "maintenanceMoreInfo": "Wantz moar informashun bout teh manetenanec? <%= linkStart %>Check out r inof paeg<%= linkEnd %>.",
- "noDamageKeepStreaks": "You will NOT take damage or lose streaks!",
- "thanksForPatience": "Thanks for your patience!",
- "twitterMaintenanceUpdates": "For the most recent updates, watch our Twitter, where we will be posting status information.",
- "veteranPetAward": "At the end, you will receive a Veteran pet!",
-
- "maintenanceInfoTitle": "Information about Upcoming Maintenance to Habitica",
- "maintenanceInfoWhat": "What is happening?",
- "maintenanceInfoWhatText": "On May 21, Habitica will be down for maintenance for most of the day. You will not take any damage or have your account harmed during that weekend, even if you can’t log in to check off your Dailies in time! We will be working very hard to make the downtime as short as possible, and will be posting regular updates on our Twitter account. At the end of the downtime, to thank everyone for their patience, you will all receive a rare pet!",
- "maintenanceInfoWhy": "Why is this happening?",
- "maintenanceInfoWhyText": "For the past several months, we have been thoroughly revamping Habitica behind-the-scenes. Specifically, we have rewritten the API. While it may not look much different on the surface, it’s a whole new world underneath. This will allow us WAY more flexibility when we want to build features in the future, and lead to improved performance!",
- "maintenanceInfoTechDetails": "Want more details on the technical side of the process? Visit The Forge, our dev blog.",
- "maintenanceInfoMore": "More Information",
- "maintenanceInfoAccountChanges": "What changes will I see to my account after the rewrite is complete?",
- "maintenanceInfoAccountChangesText": "At first, there won’t be any notable changes aside from performance improvements for features such as Challenges. If you notice any changes that shouldn’t be there, email us at <%= hrefTechAssistanceEmail %> and we will investigate them for you!",
- "maintenanceInfoAddFeatures": "What kind of features will this allow Habitica to add?",
- "maintenanceInfoAddFeaturesText": "Completing this rewrite will allow us to start building out improved chat and Guilds, plans for organizations and families, and additional productivity features like Monthlies and the ability to record yesterday’s activity! Those are all involved features on their own, so it will take time to build them, but until we were finished with this rewrite, there was no way we could start them.",
- "maintenanceInfoHowLong": "How long will the maintenance take?",
- "maintenanceInfoHowLongText": "We have to migrate tasks and data for all 1.3 million Habitica users -- not an easy task! We anticipate that it will take place between approximately 1pm Pacific Time (8pm UTC) and 10pm Pacific Time (5am UTC). Rest assured that we’re doing everything we can to make it go as quickly as possible! You can follow updates on our Twitter.",
- "maintenanceInfoStatsAffected": "How will my Dailies, Streaks, Buffs, and Quests be affected?",
- "maintenanceInfoStatsAffectedText1": "You will NOT take any damage or lose any streaks that weekend, but otherwise, your day will reset normally! Dailies that you checked will become unchecked, buffs will reset, etc. If you are in a Collection Quest, you will still find items. If you are in a Boss Battle, you will still deal damage to the Boss, but the Boss will not deal damage to you. (Even monsters need a break!)",
- "maintenanceInfoStatsAffectedText2": "After a lot of thought, our team concluded that this was the most fair way to handle the fact that many users will not be able to check off their Dailies normally during the maintenance. We’re sorry for any inconvenience this causes!",
- "maintenanceInfoSeeTasks": "What if I need to see my task list?",
- "maintenanceInfoSeeTasksText": "If you know that you will need to see your task list on Saturday to remind yourself what you have to do, we recommend that before the maintenance begins, you take a screenshot of your tasks so that you can use it as a reference.",
- "maintenanceInfoRarePet": "What kind of rare pet will I receive?",
- "maintenanceInfoRarePetText": "To thank you for your patience during the downtime, everyone will get a rare Veteran Pet. If you’ve never received a Veteran Pet before, you will receive a Veteran Wolf. If you already have a Veteran Wolf, you will receive a Veteran Tiger. And if you already have a Veteran Wolf and a Veteran Tiger, you will receive a never-before-seen Veteran pet! After the migration is completed, it may take several hours for your pet to show up, but never fear, everyone will get one.",
- "maintenanceInfoWho": "Who worked on this massive project?",
- "maintenanceInfoWhoText": "We’re glad you asked! It was spearheaded by our amazing contributor paglias, with lots of help from Blade, TheHollidayInn, SabreCat, Victor Pudeyev, TheUnknown, and Alys.",
- "maintenanceInfoTesting": "The new version was also tirelessly tested by a bunch of our amazing open-source volunteers. Thank you -- we couldn't have done this without you."
+ "habiticaBackSoon": "Dun worwee, Habitica will bees bak soon!",
+ "importantMaintenance": "We r doin important manetenanec dat we estimaet will last til 10pm Pacific tiem (5am UTC).",
+ "maintenance": "Manetenanec",
+ "maintenanceMoreInfo": "Wantz moar informashun bout teh manetenanec? <%= linkStart %>Check out r inof paeg<%= linkEnd %>.",
+ "noDamageKeepStreaks": "You will NOT take damage or lose streaks!",
+ "thanksForPatience": "Thz 4 ur patience!",
+ "twitterMaintenanceUpdates": "For the most recent updates, watch our Twitter, where we will be posting status information.",
+ "veteranPetAward": "At the end, you will receive a Veteran pet!",
+ "maintenanceInfoTitle": "Informashun bout Upcoming Manetenanec 2 Habitica",
+ "maintenanceInfoWhat": "Watz happenin??",
+ "maintenanceInfoWhatText": "On May 21, Habitica will be down for maintenance for most of the day. You will not take any damage or have your account harmed during that weekend, even if you can’t log in to check off your Dailies in time! We will be working very hard to make the downtime as short as possible, and will be posting regular updates on our Twitter account. At the end of the downtime, to thank everyone for their patience, you will all receive a rare pet!",
+ "maintenanceInfoWhy": "Why is this happening?",
+ "maintenanceInfoWhyText": "For the past several months, we have been thoroughly revamping Habitica behind-the-scenes. Specifically, we have rewritten the API. While it may not look much different on the surface, it’s a whole new world underneath. This will allow us WAY more flexibility when we want to build features in the future, and lead to improved performance!",
+ "maintenanceInfoTechDetails": "Want more details on the technical side of the process? Visit The Forge, our dev blog.",
+ "maintenanceInfoMore": "Moar Informashun",
+ "maintenanceInfoAccountChanges": "What changes will I see to my account after the rewrite is complete?",
+ "maintenanceInfoAccountChangesText": "At first, there won’t be any notable changes aside from performance improvements for features such as Challenges. If you notice any changes that shouldn’t be there, email us at <%= hrefTechAssistanceEmail %> and we will investigate them for you!",
+ "maintenanceInfoAddFeatures": "What kind of features will this allow Habitica to add?",
+ "maintenanceInfoAddFeaturesText": "Completing this rewrite will allow us to start building out improved chat and Guilds, plans for organizations and families, and additional productivity features like Monthlies and the ability to record yesterday’s activity! Those are all involved features on their own, so it will take time to build them, but until we were finished with this rewrite, there was no way we could start them.",
+ "maintenanceInfoHowLong": "How long will the maintenance take?",
+ "maintenanceInfoHowLongText": "We have to migrate tasks and data for all 1.3 million Habitica users -- not an easy task! We anticipate that it will take place between approximately 1pm Pacific Time (8pm UTC) and 10pm Pacific Time (5am UTC). Rest assured that we’re doing everything we can to make it go as quickly as possible! You can follow updates on our Twitter.",
+ "maintenanceInfoStatsAffected": "How will my Dailies, Streaks, Buffs, and Quests be affected?",
+ "maintenanceInfoStatsAffectedText1": "You will NOT take any damage or lose any streaks that weekend, but otherwise, your day will reset normally! Dailies that you checked will become unchecked, buffs will reset, etc. If you are in a Collection Quest, you will still find items. If you are in a Boss Battle, you will still deal damage to the Boss, but the Boss will not deal damage to you. (Even monsters need a break!)",
+ "maintenanceInfoStatsAffectedText2": "After a lot of thought, our team concluded that this was the most fair way to handle the fact that many users will not be able to check off their Dailies normally during the maintenance. We’re sorry for any inconvenience this causes!",
+ "maintenanceInfoSeeTasks": "What if I need to see my task list?",
+ "maintenanceInfoSeeTasksText": "If you know that you will need to see your task list on Saturday to remind yourself what you have to do, we recommend that before the maintenance begins, you take a screenshot of your tasks so that you can use it as a reference.",
+ "maintenanceInfoRarePet": "What kind of rare pet will I receive?",
+ "maintenanceInfoRarePetText": "To thank you for your patience during the downtime, everyone will get a rare Veteran Pet. If you’ve never received a Veteran Pet before, you will receive a Veteran Wolf. If you already have a Veteran Wolf, you will receive a Veteran Tiger. And if you already have a Veteran Wolf and a Veteran Tiger, you will receive a never-before-seen Veteran pet! After the migration is completed, it may take several hours for your pet to show up, but never fear, everyone will get one.",
+ "maintenanceInfoWho": "Who worked on this massive project?",
+ "maintenanceInfoWhoText": "We’re glad you asked! It was spearheaded by our amazing contributor paglias, with lots of help from Blade, TheHollidayInn, SabreCat, Victor Pudeyev, TheUnknown, and Alys.",
+ "maintenanceInfoTesting": "The new version was also tirelessly tested by a bunch of our amazing open-source volunteers. Thank you -- we couldn't have done this without you."
}
diff --git a/website/common/locales/en@lolcat/merch.json b/website/common/locales/en@lolcat/merch.json
index 09f149a100..5ba9d1be16 100755
--- a/website/common/locales/en@lolcat/merch.json
+++ b/website/common/locales/en@lolcat/merch.json
@@ -1,20 +1,14 @@
{
- "merch" : "Merchandiez",
- "merchandiseDescription": "Lukingz 4 t-shurts, mugs, or stickers 2 show off ur Habitica pried? Click hah! ",
-
- "merch-teespring-summary" : "Teespring iz platform dat makez it easy 4 anyoen 2 creaet an sell high-quality productz ppl luv, wif no cost or risk.",
- "merch-teespring-goto" : "Get a Habitica T-shirt",
-
- "merch-teespring-mug-summary" : "Teespring is a platform that makes it easy for anyone to create and sell high-quality products people love, with no cost or risk.",
- "merch-teespring-mug-goto" : "Get a Habitica Mug",
-
- "merch-teespring-eu-summary" : "EUROPEAN VERSION : Teespring is a platform that makes it easy for anyone to create and sell high-quality products people love, with no cost or risk.",
- "merch-teespring-eu-goto" : "Get a Habitica T-shirt (EU)",
-
- "merch-teespring-mug-eu-summary" : "EUROPEAN VERSION : Teespring is a platform that makes it easy for anyone to create and sell high-quality products people love, with no cost or risk.",
- "merch-teespring-mug-eu-goto" : "Get a Habitica Mug (EU)",
-
- "merch-stickermule-summary" : "Stick proud Melior wherever you (or someone else) need a reminder of both present and future accomplishments!",
- "merch-stickermule-goto" : "Get Habitica stickers"
-
+ "merch": "Merchandiez",
+ "merchandiseDescription": "Lukingz 4 t-shurts, mugs, or stickers 2 show off ur Habitica pried? Click hah!",
+ "merch-teespring-summary": "Teespring iz platform dat makez it easy 4 anyoen 2 creaet an sell high-quality productz ppl luv, wif no cost or risk.",
+ "merch-teespring-goto": "Get Habitica T-shirt",
+ "merch-teespring-mug-summary": "Teespring iz platform wich maekz it ez 4 ne1 2 maek an sell rly gud products ppl luv, wif no cost or risk.",
+ "merch-teespring-mug-goto": "Get Habitica Mug",
+ "merch-teespring-eu-summary": "EUROPEAN VERSHUN : Teespring iz platform wich maekz it ez 4 ne1 2 maek an sell rly gud products ppl luv, wif no cost or risk.",
+ "merch-teespring-eu-goto": "Get Habitica T-shirt (EU)",
+ "merch-teespring-mug-eu-summary": "EUROPEAN VERSHUN : Teespring iz platform wich maekz it ez 4 ne1 2 maek an sell rly gud products ppl luv, wif no cost or risk.",
+ "merch-teespring-mug-eu-goto": "Get Habitica Mug (EU)",
+ "merch-stickermule-summary": "Stik prowd Melior wherevar u (or sumwun els) ned remindr ov bof present an futur acomplishmentz!",
+ "merch-stickermule-goto": "Get Habitica stikrz"
}
diff --git a/website/common/locales/en@lolcat/messages.json b/website/common/locales/en@lolcat/messages.json
index 97f76a6acf..5bb3590e2d 100755
--- a/website/common/locales/en@lolcat/messages.json
+++ b/website/common/locales/en@lolcat/messages.json
@@ -9,30 +9,30 @@
"messageCannotFeedPet": "Can't feed this pet.",
"messageAlreadyMount": "You already have that mount. Try feeding another pet.",
"messageEvolve": "You have tamed <%= egg %>, let's go for a ride!",
- "messageLikesFood": "<%= egg %> really likes <%= foodText %>!",
- "messageDontEnjoyFood": "<%= egg %> eats <%= foodText %> but doesn't seem to enjoy it.",
- "messageBought": "Bought <%= itemText %>",
+ "messageLikesFood": "<%= egg %> realy liekz <%= foodText %>!",
+ "messageDontEnjoyFood": "<%= egg %> eetz <%= foodText %> but doesnt seem 2 liek it.",
+ "messageBought": "Buyd <%= itemText %>",
"messageEquipped": "<%= itemText %> equipped.",
- "messageUnEquipped": "<%= itemText %> unequipped.",
+ "messageUnEquipped": "<%= itemText %> unekwipd.",
"messageMissingEggPotion": "You're missing either that egg or that potion",
"messageInvalidEggPotionCombo": "You can't hatch Quest Pet Eggs with Magic Hatching Potions! Try a different egg.",
"messageAlreadyPet": "You already have that pet. Try hatching a different combination!",
"messageHatched": "Your egg hatched! Visit your stable to equip your pet.",
"messageNotEnoughGold": "Not Enough Gold",
- "messageTwoHandedEquip": "Wielding <%= twoHandedText %> takes two hands, so <%= offHandedText %> has been unequipped.",
- "messageTwoHandedUnequip": "Wielding <%= twoHandedText %> takes two hands, so it was unequipped when you armed yourself with <%= offHandedText %>.",
- "messageDropFood": "You've found <%= dropText %>!",
- "messageDropEgg": "You've found a <%= dropText %> Egg!",
- "messageDropPotion": "You've found a <%= dropText %> Hatching Potion!",
- "messageDropQuest": "You've found a quest!",
+ "messageTwoHandedEquip": "U ned 2 hanz 2 weild <%= twoHandedText %> so <%= offHandedText %> wuz unekwipd.",
+ "messageTwoHandedUnequip": "U ned 2 hanz 2 weild <%= twoHandedText %> so it wuz unekwipd wen u armd urself wif <%= offHandedText %>.",
+ "messageDropFood": "U finded <%= dropText %>!",
+ "messageDropEgg": "U finded <%= dropText %> Egg!",
+ "messageDropPotion": "U finded <%= dropText %> Hatching Potion!",
+ "messageDropQuest": "U finded kwest!",
"messageDropMysteryItem": "You open the box and find <%= dropText %>!",
- "messageFoundQuest": "You've found the quest \"<%= questText %>\"!",
+ "messageFoundQuest": "U finded teh kwest \"<%= questText %>\"!",
"messageAlreadyPurchasedGear": "You purchased this gear in the past, but do not currently own it. You can buy it again in the rewards column on the tasks page.",
"messageAlreadyOwnGear": "You already own this item. Equip it by going to the equipment page.",
"previousGearNotOwned": "You need to purchase a lower level gear before this one.",
"messageHealthAlreadyMax": "You already have maximum health.",
"messageHealthAlreadyMin": "Oh no! You have already run out of health so it's too late to buy a health potion, but don't worry - you can revive!",
- "armoireEquipment": "<%= image %> You found a piece of rare Equipment in the Armoire: <%= dropText %>! Awesome!",
+ "armoireEquipment": "<%= image %> U finded peice of rare Ekwipment n teh Armoire: <%= dropText %>! Awsum!!",
"armoireFood": "<%= image %> You rummage in the Armoire and find <%= dropText %>. What's that doing in here?",
"armoireExp": "You wrestle with the Armoire and gain Experience. Take that!",
"messageInsufficientGems": "Not enough gems!",
@@ -47,20 +47,20 @@
"messageGroupRequiresInvite": "Can't join a group you're not invited to.",
"messageGroupCannotRemoveSelf": "You cannot remove yourself!",
"messageGroupChatBlankMessage": "You cannot send a blank message",
- "messageGroupChatLikeOwnMessage": "Can't like your own message. Don't be that person.",
+ "messageGroupChatLikeOwnMessage": "Ur own messig cant haz ur own liek! Dont be dat persun.",
"messageGroupChatFlagAlreadyReported": "You have already reported this message",
"messageGroupChatNotFound": "Message not found!",
"messageGroupChatAdminClearFlagCount": "Only an admin can clear the flag count!",
"messageCannotFlagSystemMessages": "You cannot flag a system message. If you need to report a violation of the Community Guidelines related to this message, please email a screenshot and explanation to Lemoness at <%= communityManagerEmail %>.",
- "messageGroupChatSpam": "Whoops, looks like you're posting too many messages! Please wait a minute and try again. The Tavern chat only holds 200 messages at a time, so Habitica encourages posting longer, more thoughtful messages and consolidating replies. Can't wait to hear what you have to say. :)",
+ "messageGroupChatSpam": "Oh noes! Lookz liek ure ritin 2 many mesagez! Plz wait a minuet an try agin. Teh Tavern chat can only haz 200 mesagez at tiem, so Habitica encuragez postin longr, moar thoughtful mesagez an consolidatin replyz. Cant wait 2 hear wut u haz 2 say!!! :)",
"messageCannotLeaveWhileQuesting": "You cannot accept this party invitation while you are in a quest. If you'd like to join this party, you must first abort your quest, which you can do from your party screen. You will be given back the quest scroll.",
"messageUserOperationProtected": "path `<%= operation %>` was not saved, as it's a protected path.",
"messageUserOperationNotFound": "<%= operation %> operation not found",
"messageNotificationNotFound": "Notification not found.",
"messageNotAbleToBuyInBulk": "This item cannot be purchased in quantities above 1.",
"notificationsRequired": "Notification ids are required.",
- "unallocatedStatsPoints": "You have <%= points %> unallocated Stat Points",
+ "unallocatedStatsPoints": "U haz <%= points %> unallocated Stat Points",
"beginningOfConversation": "This is the beginning of your conversation with <%= userName %>. Remember to be kind, respectful, and follow the Community Guidelines!",
"messageDeletedUser": "Sorry, this user has deleted their account.",
"messageMissingDisplayName": "Missing display name."
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/en@lolcat/npc.json b/website/common/locales/en@lolcat/npc.json
index 116a8d076a..4950f0eeb6 100755
--- a/website/common/locales/en@lolcat/npc.json
+++ b/website/common/locales/en@lolcat/npc.json
@@ -145,7 +145,7 @@
"tourEquipmentPage": "This is where your Equipment is stored! Your Battle Gear affects your Stats. If you want to show different Equipment on your avatar without changing your Stats, click \"Enable Costume.\"",
"equipmentAlreadyOwned": "You already own that piece of equipment",
"tourOkay": "Okay!",
- "tourAwesome": "Awesome!",
+ "tourAwesome": "Awsum!",
"tourSplendid": "Splendid!",
"tourNifty": "Nifty!",
"tourAvatarProceed": "Show me my tasks!",
@@ -168,4 +168,4 @@
"welcome5": "Now you'll customize your avatar and set up your tasks...",
"imReady": "Enter Habitica",
"limitedOffer": "Available until <%= date %>"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/en@lolcat/overview.json b/website/common/locales/en@lolcat/overview.json
index d4a2f987d0..3d12071c77 100755
--- a/website/common/locales/en@lolcat/overview.json
+++ b/website/common/locales/en@lolcat/overview.json
@@ -1,14 +1,10 @@
{
- "needTips": "Ned sum tips on how 2 begin? Herez straightforward guied! ",
-
- "step1": "Step 1: Entr Taskz",
- "webStep1Text": "Habitica is nothing without real-world goals, so enter a few tasks. You can add more later as you think of them! All tasks can be added by clicking the green \"Create\" button.\n* **Set up [To-Dos](http://habitica.wikia.com/wiki/To-Dos):** Enter tasks you do once or rarely in the To-Dos column, one at a time. You can click on the tasks to edit them and add checklists, due dates, and more!\n* **Set up [Dailies](http://habitica.wikia.com/wiki/Dailies):** Enter activities you need to do daily or on a particular day of the week, month, or year in the Dailies column. Click task to edit when it will be due and/or set a start date. You can also make it due on a repeating basis, for example, every 3 days.\n* **Set up [Habits](http://habitica.wikia.com/wiki/Habits):** Enter habits you want to establish in the Habits column. You can edit the Habit to change it to just a good habit :heavy_plus_sign: or a bad habit :heavy_minus_sign:\n* **Set up [Rewards](http://habitica.wikia.com/wiki/Rewards):** In addition to the in-game Rewards offered, add activities or treats which you want to use as a motivation to the Rewards column. It's important to give yourself a break or allow some indulgence in moderation!\n* If you need inspiration for which tasks to add, you can look at the wiki's pages on [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits), [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies), [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos), and [Sample Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards).",
-
- "step2": "STEP 2: GET POINS BY DO THINGS IN LYFE",
- "webStep2Text": "Now, start tackling your goals from the list! As you complete tasks and check them off in Habitica, you will gain [Experience](http://habitica.wikia.com/wiki/Experience_Points), which helps you level up, and [Gold](http://habitica.wikia.com/wiki/Gold_Points), which allows you to purchase Rewards. If you fall into bad habits or miss your Dailies, you will lose [Health](http://habitica.wikia.com/wiki/Health_Points). In that way, the Habitica Experience and Health bars serve as a fun indicator of your progress toward your goals. You'll start seeing your real life improve as your character advances in the game.",
-
- "step3": "STEP 3: COOZTUMIZ AND XPLORE HABITICA",
- "webStep3Text": "Once you're familiar with the basics, you can get even more out of Habitica with these nifty features:\n * Organize your tasks with [tags](http://habitica.wikia.com/wiki/Tags) (edit a task to add them).\n * Customize your [avatar](http://habitica.wikia.com/wiki/Avatar) by clicking the user icon in the upper-right corner.\n * Buy your [Equipment](http://habitica.wikia.com/wiki/Equipment) under Rewards or from the [Shops](<%= shopUrl %>), and change it under [Inventory > Equipment](<%= equipUrl %>).\n * Connect with other users via the [Tavern](http://habitica.wikia.com/wiki/Tavern).\n * Starting at Level 3, hatch [Pets](http://habitica.wikia.com/wiki/Pets) by collecting [eggs](http://habitica.wikia.com/wiki/Eggs) and [hatching potions](http://habitica.wikia.com/wiki/Hatching_Potions). [Feed](http://habitica.wikia.com/wiki/Food) them to create [Mounts](http://habitica.wikia.com/wiki/Mounts).\n * At level 10: Choose a particular [class](http://habitica.wikia.com/wiki/Class_System) and then use class-specific [skills](http://habitica.wikia.com/wiki/Skills) (levels 11 to 14).\n * Form a party with your friends (by clicking [Party](<%= partyUrl %>) in the navigation bar) to stay accountable and earn a Quest scroll.\n * Defeat monsters and collect objects on [quests](http://habitica.wikia.com/wiki/Quests) (you will be given a quest at level 15).",
-
- "overviewQuestions": "Have questions? Check out the [FAQ](<%= faqUrl %>)! If your question isn't mentioned there, you can ask for further help in the [Habitica Help guild](<%= helpGuildUrl %>).\n\nGood luck with your tasks!"
+ "needTips": "Ned sum tipz 4 how 2 begin? Herez straitforwrd guied!",
+ "step1": "Step 1: Entr Taskz",
+ "webStep1Text": "Habitica is nothing without real-world goals, so enter a few tasks. You can add more later as you think of them! All tasks can be added by clicking the green \"Create\" button.\n* **Set up [To-Dos](http://habitica.wikia.com/wiki/To-Dos):** Enter tasks you do once or rarely in the To-Dos column, one at a time. You can click on the tasks to edit them and add checklists, due dates, and more!\n* **Set up [Dailies](http://habitica.wikia.com/wiki/Dailies):** Enter activities you need to do daily or on a particular day of the week, month, or year in the Dailies column. Click task to edit when it will be due and/or set a start date. You can also make it due on a repeating basis, for example, every 3 days.\n* **Set up [Habits](http://habitica.wikia.com/wiki/Habits):** Enter habits you want to establish in the Habits column. You can edit the Habit to change it to just a good habit :heavy_plus_sign: or a bad habit :heavy_minus_sign:\n* **Set up [Rewards](http://habitica.wikia.com/wiki/Rewards):** In addition to the in-game Rewards offered, add activities or treats which you want to use as a motivation to the Rewards column. It's important to give yourself a break or allow some indulgence in moderation!\n* If you need inspiration for which tasks to add, you can look at the wiki's pages on [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits), [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies), [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos), and [Sample Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards).",
+ "step2": "STEP 2: GET POINS BY DO THINGS IN LYFE",
+ "webStep2Text": "Now, start tackling your goals from the list! As you complete tasks and check them off in Habitica, you will gain [Experience](http://habitica.wikia.com/wiki/Experience_Points), which helps you level up, and [Gold](http://habitica.wikia.com/wiki/Gold_Points), which allows you to purchase Rewards. If you fall into bad habits or miss your Dailies, you will lose [Health](http://habitica.wikia.com/wiki/Health_Points). In that way, the Habitica Experience and Health bars serve as a fun indicator of your progress toward your goals. You'll start seeing your real life improve as your character advances in the game.",
+ "step3": "STEP 3: COOZTUMIZ AND XPLORE HABITICA",
+ "webStep3Text": "Once you're familiar with the basics, you can get even more out of Habitica with these nifty features:\n * Organize your tasks with [tags](http://habitica.wikia.com/wiki/Tags) (edit a task to add them).\n * Customize your [avatar](http://habitica.wikia.com/wiki/Avatar) by clicking the user icon in the upper-right corner.\n * Buy your [Equipment](http://habitica.wikia.com/wiki/Equipment) under Rewards or from the [Shops](<%= shopUrl %>), and change it under [Inventory > Equipment](<%= equipUrl %>).\n * Connect with other users via the [Tavern](http://habitica.wikia.com/wiki/Tavern).\n * Starting at Level 3, hatch [Pets](http://habitica.wikia.com/wiki/Pets) by collecting [eggs](http://habitica.wikia.com/wiki/Eggs) and [hatching potions](http://habitica.wikia.com/wiki/Hatching_Potions). [Feed](http://habitica.wikia.com/wiki/Food) them to create [Mounts](http://habitica.wikia.com/wiki/Mounts).\n * At level 10: Choose a particular [class](http://habitica.wikia.com/wiki/Class_System) and then use class-specific [skills](http://habitica.wikia.com/wiki/Skills) (levels 11 to 14).\n * Form a party with your friends (by clicking [Party](<%= partyUrl %>) in the navigation bar) to stay accountable and earn a Quest scroll.\n * Defeat monsters and collect objects on [quests](http://habitica.wikia.com/wiki/Quests) (you will be given a quest at level 15).",
+ "overviewQuestions": "U haz questions? Chek teh [FAQ](<%= faqUrl %>)! If ur kwestion isnt mention ther, u can haz moar help n teh [Habitica Help guild](<%= helpGuildUrl %>).\n\nGud luk wif ur taskz!"
}
diff --git a/website/common/locales/en@lolcat/rebirth.json b/website/common/locales/en@lolcat/rebirth.json
index 24da12e607..99eb7ed778 100755
--- a/website/common/locales/en@lolcat/rebirth.json
+++ b/website/common/locales/en@lolcat/rebirth.json
@@ -1,29 +1,30 @@
{
- "rebirthNew": "Reburth: nu Advenchur Availabel! ",
+ "rebirthNew": "Reburth: nu Advenchur Availabel!",
"rebirthUnlock": "U've unlockd Reburth! Dis speshul Markit item allowz u 2 begin nu gaem at level 1 whiel keepin ur taskz, achievements, pets, an moar. Ues it 2 breaef nu lief inot Habitica if u feelZ u've achieved it all, or 2 eckspeeriunce nu featurez wif teh fresh eyes ov beginnin charactah!",
"rebirthBegin": "Reburth: Begin nu Advenchur",
"rebirthStartOver": "Reburth startz ur charactah ovar frum Level 1.",
"rebirthAdvList1": "Yu returnz 2 full Helths.",
- "rebirthAdvList2": "You have no Experience or Gold.",
- "rebirthAdvList3": "Your Habits, Dailies, and To-Dos reset to yellow, and streaks reset, except for challenge tasks.",
- "rebirthAdvList4": "You have the starting class of Warrior until you earn a new class.",
- "rebirthInherit": "Your new character inherits a few things from their predecessor:",
- "rebirthInList1": "Tasks, history, equipment, and settings remain.",
- "rebirthInList2": "Challenge, Guild, and Party memberships remain.",
- "rebirthInList3": "Gems, backer tiers, and contributor levels remain.",
- "rebirthInList4": "Items obtained from Gems or drops (such as pets and mounts) remain.",
- "rebirthEarnAchievement": "You also earn an Achievement for beginning a new adventure!",
+ "rebirthAdvList2": "U haz no Experianc or Gold.",
+ "rebirthAdvList3": "Ur Habitz, Dailyz, an ToDoz reset to yelow, an streekz reset, excep 4 chaleng taskz.",
+ "rebirthAdvList4": "U haz teh startin clas ov Warrior until u ern nu clas.",
+ "rebirthInherit": "Ur nu charaktr inheritz cuple thingz frum befoar:",
+ "rebirthInList1": "Taskz, history, ekwipment, an setingz remain.",
+ "rebirthInList2": "Chaleng, Gild, an Party membrshipz remain.",
+ "rebirthInList3": "Gemz, backr teerz, an contributr lvlz remain.",
+ "rebirthInList4": "Itemz obtaind frum Gemz or dropz (liek petz an mowntz) remain.",
+ "rebirthEarnAchievement": "U also ern Achieevment 4 beginin nu avenchur!",
"beReborn": "B Reboarned",
- "rebirthAchievement": "You've begun a new adventure! This is Rebirth <%= number %> for you, and the highest Level you've attained is <%= level %>. To stack this Achievement, begin your next new adventure when you've reached an even higher Level!",
- "rebirthAchievement100": "You've begun a new adventure! This is Rebirth <%= number %> for you, and the highest Level you've attained is 100 or higher. To stack this Achievement, begin your next new adventure when you've reached at least 100!",
+ "rebirthAchievement": "Uve beganz nu avenchur! Dis iz Reboarn <%= number %> 4 u, an teh highest Lvl uve gotd iz <%= level %>. U can haz stakin 4 dis Acheevment by startn ur next nu avenchur wen uve reechd even highr Lvl!",
+ "rebirthAchievement100": "Uve beganz nu avenchur! Dis iz Reboarn <%= number %> 4 u, an teh highest Lvl uve gotd iz 100 or moar!!!! Awsum! U can haz stakin 4 dis Acheevment by startn ur next nu avenchur wen uve reechd at leest 100!",
"rebirthBegan": "Beganz a New Avenchur",
"rebirthText": "Beganz <%= rebirths %> New Advenchurs",
- "rebirthOrb": "Used an Orb of Rebirth to start over after attaining Level <%= level %>.",
- "rebirthOrb100": "Used an Orb of Rebirth to start over after attaining Level 100 or higher.",
+ "rebirthOrb": "Used Shiny Ball 2 start ovr aftr getd Lvl <%= level %>.",
+ "rebirthOrb100": "Used Shiny Ball 2 start ovr aftr getd Lvl 100 or moar.",
"rebirthOrbNoLevel": "USED A SHINY BALL 2 START OVR.",
"rebirthPop": "Instantly restart your character as a Level 1 Warrior while retaining achievements, collectibles, and equipment. Your tasks and their history will remain but they will be reset to yellow. Your streaks will be removed except from challenge tasks. Your Gold, Experience, Mana, and the effects of all Skills will be removed. All of this will take effect immediately. For more information, see the wiki's Orb of Rebirth page.",
"rebirthName": "SHINY BALL DAT MAKE U BORN AGAIN",
- "reborn": "Reborn, max level <%= reLevel %>",
- "confirmReborn": "Are you sure?",
- "rebirthComplete": "You have been reborn!"
-}
\ No newline at end of file
+ "reborn": "Reboarnd, max lvl <%= reLevel %>",
+ "confirmReborn": "R u sure??",
+ "rebirthComplete": "U haz ben reboarnd!",
+ "nextFreeRebirth": "<%= days %> daiz until FREE SHINY BALL"
+}
diff --git a/website/common/locales/en@lolcat/spells.json b/website/common/locales/en@lolcat/spells.json
index 5888cc66bf..df07de26a2 100755
--- a/website/common/locales/en@lolcat/spells.json
+++ b/website/common/locales/en@lolcat/spells.json
@@ -1,59 +1,59 @@
{
"spellWizardFireballText": "BURST OV FLAMEZ",
- "spellWizardFireballNotes": "You summon XP and deal fiery damage to Bosses! (Based on: INT)",
+ "spellWizardFireballNotes": "U sumon XP an do feiry damege 2 Bosez! (Basd on: INT)",
"spellWizardMPHealText": "ETHREAL SURGE",
- "spellWizardMPHealNotes": "You sacrifice Mana so the rest of your Party, except Mages, gains MP! (Based on: INT)",
+ "spellWizardMPHealNotes": "U sacrifiec Mana so teh res ov ur Party, excep Maegz, getz MP! (Basd on: INT)",
"spellWizardEarthText": "EARTHQUAEK",
- "spellWizardEarthNotes": "Your mental power shakes the earth and buffs your Party's Intelligence! (Based on: Unbuffed INT)",
+ "spellWizardEarthNotes": "Ur mentl powr shaekz da erth an buffz ur Partyz Intelligence! (Basd on: Unbuffd INT)",
"spellWizardFrostText": "CHILLIN FROST",
- "spellWizardFrostNotes": "With one cast, ice freezes all your streaks so they won't reset to zero tomorrow!",
- "spellWizardFrostAlreadyCast": "U ALREDI CAST DIS. UR STREKS R FROZEN, U NO CAST DIS AGAIN.",
+ "spellWizardFrostNotes": "Wif 1 cast, ice freezez al ur streekz so they wont reset 2 zero tomrrw! ",
+ "spellWizardFrostAlreadyCast": " U ALREDI CAST DIS. UR STREKS R FROZEN, U NO CAST DIS AGAIN.",
"spellWarriorSmashText": "BROOTUL SMASH",
- "spellWarriorSmashNotes": "You make a task more blue/less red and deal extra damage to Bosses! (Based on: STR)",
+ "spellWarriorSmashNotes": "U maek task moar blue/les red an do xtra damage 2 Bosez! (Basd on: STR)",
"spellWarriorDefensiveStanceText": "DEFENSIV STANCE",
- "spellWarriorDefensiveStanceNotes": "You crouch low and gain a buff to Constitution! (Based on: Unbuffed CON)",
+ "spellWarriorDefensiveStanceNotes": "U crouch low liek gud kat an get buff 2 Constitution! (Basd on: Unbuffd CON)",
"spellWarriorValorousPresenceText": "VALOROUS PRESENSE",
- "spellWarriorValorousPresenceNotes": "Your boldness buffs your whole Party's Strength! (Based on: Unbuffed STR)",
+ "spellWarriorValorousPresenceNotes": "Ur boldnes buffz ur hole Partyz Strength! (Basd on: Unbuffd STR)",
"spellWarriorIntimidateText": "INTIMIDATIN GAZE",
- "spellWarriorIntimidateNotes": "Your fierce stare buffs your whole Party's Constitution! (Based on: Unbuffed CON)",
+ "spellWarriorIntimidateNotes": "Ur feirce stair buffz ur hole Partyz Constitution! (Basd on: Unbuffd CON)",
"spellRoguePickPocketText": "PICPAWKET",
- "spellRoguePickPocketNotes": "You rob a nearby task and gain gold! (Based on: PER)",
+ "spellRoguePickPocketNotes": "U steel frum neerby task an get gold! (Basd on: PER)",
"spellRogueBackStabText": "BAKSTAB",
- "spellRogueBackStabNotes": "You betray a foolish task and gain gold and XP! (Based on: STR)",
+ "spellRogueBackStabNotes": "U betrai foolish task an get gold an XP! (Basd on: STR)",
"spellRogueToolsOfTradeText": "TOOLS OV TEH TRADE",
- "spellRogueToolsOfTradeNotes": "Your tricky talents buff your whole Party's Perception! (Based on: Unbuffed PER)",
+ "spellRogueToolsOfTradeNotes": "Ur triky talenz buff ur hole Partyz Perception! (Basd on: Unbuffd PER)",
"spellRogueStealthText": "STEALF",
- "spellRogueStealthNotes": "With each cast, a few of your undone Dailies won't cause damage tonight. Their streaks and colors won't change. (Based on: PER)",
+ "spellRogueStealthNotes": "Wif eech cast, sum ov ur undun Dailyz wont give u damege 2nite. There streekz an colrz wont chaeng. (Basd on: PER)",
"spellRogueStealthDaliesAvoided": "<%= originalText %> NUMBR OV DAYLEES AVOIDD: <%= number %>.",
- "spellRogueStealthMaxedOut": "U HAS ALREADY AVOIDD ALL UR DAYLEES; DERE'S NO NEED 2 CAST DIS AGAIN.",
+ "spellRogueStealthMaxedOut": " U HAS ALREADY AVOIDD ALL UR DAYLEES; DERE'S NO NEED 2 CAST DIS AGAIN.",
"spellHealerHealText": "HEALIN LITE",
- "spellHealerHealNotes": "Shining light restores your health! (Based on: CON and INT)",
+ "spellHealerHealNotes": "Shinin lite givez u helth! (Basd on: CON an INT)",
"spellHealerBrightnessText": "SEARIN BRIGHTNES",
- "spellHealerBrightnessNotes": "A burst of light makes your tasks more blue/less red! (Based on: INT)",
+ "spellHealerBrightnessNotes": "Burs ov lite maekz ur taskz moar blue/les red! (Basd on: INT)",
"spellHealerProtectAuraText": "PROTECTIV AURA",
- "spellHealerProtectAuraNotes": "You shield your Party by buffing their Constitution! (Based on: Unbuffed CON)",
+ "spellHealerProtectAuraNotes": "U sheild ur Party by buffin there Constitution! (Basd on: Unbuffd CON)",
"spellHealerHealAllText": "BLESIN",
- "spellHealerHealAllNotes": "Your soothing spell restores your whole Party's health! (Based on: CON and INT)",
+ "spellHealerHealAllNotes": "Ur soothin spel restorz ur hole Partyz helth! (Basd on: CON an INT)",
"spellSpecialSnowballAuraText": "SNOBAL",
- "spellSpecialSnowballAuraNotes": "Turn a friend into a frosty snowman!",
+ "spellSpecialSnowballAuraNotes": "Turn fren into frosty snowman!!",
"spellSpecialSaltText": "SALT",
- "spellSpecialSaltNotes": "Reverse the spell that made you a snowman.",
+ "spellSpecialSaltNotes": "Revers teh spel dat maed u snowman.",
"spellSpecialSpookySparklesText": "SPOOPY SPARKLEZ",
- "spellSpecialSpookySparklesNotes": "Turn your friend into a transparent pal!",
+ "spellSpecialSpookySparklesNotes": "Turn ur fren into transparent pal!",
"spellSpecialOpaquePotionText": "OPAQUE POSHUN",
- "spellSpecialOpaquePotionNotes": "Reverse the spell that made you transparent.",
+ "spellSpecialOpaquePotionNotes": "Revers teh spel dat maed u transparent.",
"spellSpecialShinySeedText": "SHINY SED",
"spellSpecialShinySeedNotes": "TURN FRAND INTO JOYOUS FLOWR!",
"spellSpecialPetalFreePotionText": "PETAL-FREE POSHUN",
- "spellSpecialPetalFreePotionNotes": "Reverse the spell that made you a flower.",
+ "spellSpecialPetalFreePotionNotes": "Revers teh spel dat maed u flowr.",
"spellSpecialSeafoamText": "SEEFOM",
"spellSpecialSeafoamNotes": "TURN FRAND INTO SEA CREACHUR!",
"spellSpecialSandText": "SAND",
- "spellSpecialSandNotes": "Reverse the spell that made you a sea star.",
+ "spellSpecialSandNotes": "Revers teh spel dat maed u sea star.",
"partyNotFound": "NO FOUND PARTY",
"targetIdUUID": "\"targetId\" must be a valid User ID.",
- "challengeTasksNoCast": "Casting a skill on challenge tasks is not allowed.",
- "groupTasksNoCast": "Casting a skill on group tasks is not allowed.",
+ "challengeTasksNoCast": "Castin skil on chalenge taskz is not allowd.",
+ "groupTasksNoCast": "Castin skil on group taskz is not allowd.",
"spellNotOwned": "U NO OWN DIS SKILL.",
"spellLevelTooHigh": "U MUST B LEVOOL <%= level %> 2 YOOSE DIS SKILL."
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/en@pirate/achievements.json b/website/common/locales/en@pirate/achievements.json
index e486776f83..53f479a8eb 100644
--- a/website/common/locales/en@pirate/achievements.json
+++ b/website/common/locales/en@pirate/achievements.json
@@ -24,5 +24,7 @@
"achievementMindOverMatterModalText": "Ye've vanquished yon Rock, Slime, n' Yarn Beasties!",
"achievementMindOverMatterText": "Vanquished yon Rock, Slime, n' Yarn beasties.",
"achievementMindOverMatter": "Mind O'er Matter",
- "achievementLostMasterclasserModalText": "Ye've vanquished all sixteen Adventures in th' Masterclasser series n' found th' Hidden Treasure o' th' Lost Masterclasser!"
+ "achievementLostMasterclasserModalText": "Ye've vanquished all sixteen Adventures in th' Masterclasser series n' found th' Hidden Treasure o' th' Lost Masterclasser!",
+ "achievementKickstarter2019": "Pin Kickstarter Backer",
+ "achievementKickstarter2019Text": "Backed the 2019 Pin Kickstarter Project"
}
diff --git a/website/common/locales/en@pirate/front.json b/website/common/locales/en@pirate/front.json
index da5fa965c8..be9b1de4b5 100644
--- a/website/common/locales/en@pirate/front.json
+++ b/website/common/locales/en@pirate/front.json
@@ -101,50 +101,50 @@
"marketing1Lead1Title": "Yer Life, th' Role Playin' Game",
"marketing1Lead1": "Habitica be a video game to help ye improve real life habits. It \"gamifies\" ye life by turnin' all ye tasks (habits, dailies, 'n to-dos) into wee monsters ye have to conquer. th' better ye be at 'tis, th' more ye progress in th' game. If ye slip up in life, ye character starts backslidin' in th' game.",
"marketing1Lead2Title": "Get Fancy Gear",
- "marketing1Lead2": "Improve your habits to build up your avatar. Show off the sweet gear you've earned!",
+ "marketing1Lead2": "Improve yer habits t' build up yer avatar. Show off the fancy gear ye've earned!",
"marketing1Lead3Title": "Find Random Treasures",
"marketing1Lead3": "For some, it's th' gamble what motivates 'em: a system called \"stochastic rewards.\" Habitica be accommodatin' ta all reinforcement and punishment styles: positive, negative, predictable, and random.",
"marketing2Header": "Compete With Mates, Join Interest Groups",
- "marketing2Lead1Title": "Social Productivity",
+ "marketing2Lead1Title": "Social Produck-tivity",
"marketing2Lead1": "While ye kin play Habitica solo, th' lights really come on when ye start collaboratin', competin', an' 'olding each other accountable. Th' mos' effective part o' any self-improvement program be social accountability, and what better environment fer accountability and competition than a viddy-yo game?",
"marketing2Lead2Title": "Fight Beasts",
- "marketing2Lead2": "What's a Role Playing Game without battles? Fight monsters with your party. Monsters are \"super accountability mode\" - a day you miss the gym is a day the monster hurts *everyone!*",
- "marketing2Lead3Title": "Challenge Each Other",
- "marketing2Lead3": "Challenges let you compete with friends and strangers. Whoever does the best at the end of a challenge wins special prizes.",
- "marketing3Header": "Apps and Extensions",
- "marketing3Lead1": "The **iPhone & Android** apps let you take care of business on the go. We realize that logging into the website to click buttons can be a drag.",
- "marketing3Lead2Title": "Integrations",
- "marketing3Lead2": "Other **3rd Party Tools** tie Habitica into various aspects of your life. Our API provides easy integration for things like the [Chrome Extension](https://chrome.google.com/webstore/detail/habitica/pidkmpibnnnhneohdgjclfdjpijggmjj?hl=en-US), for which you lose points when browsing unproductive websites, and gain points when on productive ones. [See more here](http://habitica.fandom.com/wiki/Extensions,_Add-Ons,_and_Customizations).",
- "marketing4Header": "Organizational Use",
- "marketing4Lead1": "Education is one of the best sectors for gamification. We all know how glued to phones and games students are these days; harness that power! Pit your students against each other in friendly competition. Reward good behavior with rare prizes. Watch their grades and behavior soar.",
- "marketing4Lead1Title": "Gamification In Education",
+ "marketing2Lead2": "What be a Role Playing Game wivout battlin'? Fight monsters with yer crew. Monsters be \"super accounter-bility mode\" - a day ye pass up yer workout be a day th' monster hurts *ever'one!*",
+ "marketing2Lead3Title": "Challenge One Anudder",
+ "marketing2Lead3": "Challenges let ye compete wit' friends n' strangers. Iffen ye do th' best of all at th' end o' a challenge ye kin win special prizes.",
+ "marketing3Header": "Apps n' Extensions",
+ "marketing3Lead1": "Th' **iPhone & Android** apps let ye take care of business on th' go. We realize that loggin' inta th' website ta click buttons kin be a drag.",
+ "marketing3Lead2Title": "Inter-grations",
+ "marketing3Lead2": "Other **3rd Party Tools** tie Habitica inta vary-us aspects o' yer life. Our API pervides easy inter-gration fer things like th' [Chrome Extension](https://chrome.google.com/webstore/detail/habitica/pidkmpibnnnhneohdgjclfdjpijggmjj?hl=en-US), fer which ye take hits iffen yer browsin' unperductive websites, an' gain points fer bein' on perductive ones. [See more 'ere](http://habitica.fandom.com/wiki/Extensions,_Add-Ons,_and_Customizations).",
+ "marketing4Header": "Orginny-sational Use",
+ "marketing4Lead1": "Education be one o' th' best sectors fer gamification. Ever'one knows how glued ta phones and games yon students be these days; 'arness that power! Pit yer students agin each other in friendly compertition. Reward good behavior wit' rare prizes. Watch their grades n' behavior get better an' better.",
+ "marketing4Lead1Title": "Gamification In Edgercation",
"marketing4Lead2": "Health care costs be on th' rise, 'n somethin''s gotta gift. Hundreds 'o programs be built to reduce costs 'n improve wellness. We believe Habitica can pave a substantial path towards healthy lifestyles.",
"marketing4Lead2Title": "Gamification In Health an' Wellness",
"marketing4Lead3-1": "Want t' gamify yer life?",
"marketing4Lead3-2": "Interested in runnin' a group in education, wellness, 'n more?",
"marketing4Lead3-3": "Want t' learn more?",
- "marketing4Lead3Title": "Gamify Everything",
+ "marketing4Lead3Title": "Gamify Ever'thin'",
"mobileAndroid": "Android",
"mobileIOS": "iOS",
"motivate": "Motivate yerself and yer crew!",
- "motivate1": "Motivate yourself to do anything.",
+ "motivate1": "Motivate yerself ta do anythin'.",
"motivate2": "Get Organized. Get Motivated. Get Dubloons.",
- "oldNews": "News",
- "newsArchive": "News archive on Wikia (multilingual)",
+ "oldNews": "Th' Latest",
+ "newsArchive": "News archive on yon Wikia (multilingual)",
"passConfirm": "Confirm Passcode",
"setNewPass": "Set New Password",
- "passMan": "In case you are using a password manager (like 1Password) and have problems logging in, try typing your username and password manually.",
+ "passMan": "Iffen ye be usin' a password manager (like 1Password) an' be havin' problems loggin' in, try typin' yer username n' password by 'and.",
"password": "Passcode",
"playButton": "Set Sail",
- "playButtonFull": "Enter Habitica",
- "presskit": "Press Kit",
- "presskitDownload": "Download all images:",
- "presskitText": "Thanks for your interest in Habitica! The following images can be used for articles or videos about Habitica. For more information, please contact us at <%= pressEnquiryEmail %>.",
- "pkQuestion1": "What inspired Habitica? How did it start?",
- "pkAnswer1": "If you’ve ever invested time in leveling up a character in a game, it’s hard not to wonder how great your life would be if you put all of that effort into improving your real-life self instead of your avatar. We starting building Habitica to address that question. Habitica officially launched with a Kickstarter in 2013, and the idea really took off. Since then, it’s grown into a huge project, supported by our awesome open-source volunteers and our generous users.",
- "pkQuestion2": "Why does Habitica work?",
- "pkAnswer2": "Forming a new habit is hard because people really need that obvious, instant reward. For example, it’s tough to start flossing, because even though our dentist tells us that it's healthier in the long run, in the immediate moment it just makes your gums hurt. Habitica's gamification adds a sense of instant gratification to everyday objectives by rewarding a tough task with experience, gold… and maybe even a random prize, like a dragon egg! This helps keep people motivated even when the task itself doesn't have an intrinsic reward, and we've seen people turn their lives around as a result. You can check out success stories here: https://habitversary.tumblr.com",
- "pkQuestion3": "Why did you add social features?",
+ "playButtonFull": "Board Habitica",
+ "presskit": "Yon Press Kit",
+ "presskitDownload": "Download all yon images:",
+ "presskitText": "Thanks fer yer int'rest in Habitica! Th' followin' images kin be used fer articles or viddy-yos about Habitica. Fer more infermation, ye kin contact us at <%= pressEnquiryEmail %>.",
+ "pkQuestion1": "What was th' insper-ation fer Habitica? How'd it start?",
+ "pkAnswer1": "If ye’ve ever invested time in levelin' up a character in a game, it be hard not ta wonder how great yer life would be iffen ye put all o' that effort inta improving yer real-life self instead of yer avatar. We started buildin' Habitica t' address that question. Habitica officially launched wit' a Kickstarter in 2013, an' th' idea really took off. Since then, it be grown inta a huge project, supported by our awesome open-source volunteers and our generous users.",
+ "pkQuestion2": "Why's Habitica workin'?",
+ "pkAnswer2": "Formin' a new 'abit be 'ard cuz people really need th' obvious, instant reward. Fer example, it be tough ta start flossin', cuz even though our den-tist be tellin' us that it be healthier in th' long run, at th' time it just makes yer gums hurt. Habitica's gamification be addin' a sense o' instant gratification t' ever'day objectives by rewardin' a tough task wit' experience, gold… and mebbe even a random prize, like a dragon egg! This helps ta keep people motivated e'en when th' task itself don't have a built-in reward, and we be seein' people been turnin' their lives around as a result. Ye kin check out success stories here: https://habitversary.tumblr.com",
+ "pkQuestion3": "Why did ye add social features?",
"pkAnswer3": "Social pressure is a huge motivating factor for a lot of people, so we knew that we wanted to have a strong community that would hold each other accountable for their goals and cheer for their successes. Luckily, one of the things that multiplayer video games do best is foster a sense of community among their users! Habitica’s community structure borrows from these types of games; you can form a small Party of close friends, but you can also join a larger, shared-interest groups known as a Guild. Although some users choose to play solo, most decide to form a support network that encourages social accountability through features such as Quests, where Party members pool their productivity to battle monsters together.",
"pkQuestion4": "Why does skipping tasks remove your avatar’s health?",
"pkAnswer4": "If you skip one of your daily goals, your avatar will lose health the following day. This serves as an important motivating factor to encourage people to follow through with their goals because people really hate hurting their little avatar! Plus, the social accountability is critical for a lot of people: if you’re fighting a monster with your friends, skipping your tasks hurts their avatars, too.",
diff --git a/website/common/locales/en@pirate/questscontent.json b/website/common/locales/en@pirate/questscontent.json
index 094bd0b48f..fb75d1dca7 100644
--- a/website/common/locales/en@pirate/questscontent.json
+++ b/website/common/locales/en@pirate/questscontent.json
@@ -15,49 +15,49 @@
"questGryphonCompletion": "Defeated, th' mighty beast ashamedly slinks back t' its master. \"My word! Well done, adventurers!\" baconsaur exclaims, \"Please, have some of the gryphon's eggs. I am sure you will raise these young ones well!\"",
"questGryphonBoss": "Fiery Gryph'n",
"questGryphonDropGryphonEgg": "Gryph'n (Egg)",
- "questGryphonUnlockText": "Unlocks purchasable Gryph'n eggs in the Market",
+ "questGryphonUnlockText": "Unlocks yon Gryphon Eggs ye kin purchase in th' Market",
"questHedgehogText": "Th' Hedgebeast",
"questHedgehogNotes": "Hedgehogs are a funny group o' animals. They be some o' th' most affectionate pets a Habiteer could owns. But rumor has it, if ye feed them milk aft midnight, they grow quite irritable. 'n fifty times thar size. 'n InspectorCaracal did jus' that. Oops.",
"questHedgehogCompletion": "Ye crew successfully calmed below th' hedgehog! After shrinkin' below to a normal size, she hobbles away to her eggs. She returns squeakin' 'n nudgin' some 'o her eggs along towards ye crew. woefully, these hedgehogs like spiced rum better!",
"questHedgehogBoss": "Hedgebeast",
"questHedgehogDropHedgehogEgg": "Hedgehog (Egg)",
- "questHedgehogUnlockText": "Unlocks purchasable Hedgehog eggs in th' Market",
+ "questHedgehogUnlockText": "Unlocks Hedgehog Eggs ye kin purchase in th' Market",
"questGhostStagText": "Th' Spirit o' Spring",
"questGhostStagNotes": "Shiver me timbers, Sprin'. Th' time o' year when color once again begins t' fill th' landscape. Gone are th' cold, snowy mounds o' winter. Where frost once stood, vibrant plant life loots its ship. Luscious green leaves fill in th' trees, grass returns t' its former vivid hue, a rainbow o' flowers rise along th' plains, 'n a white mystical fog covers th' land! ... Belay that. Mystical fog? \"Oh no,\" InspectorCaracal says apprehensively, \"'twould appear that some kind o' spirit be th' cause o' this fog. Oh, 'n 'tis chargin' right at ye.\"",
"questGhostStagCompletion": "Th' devil's henchman, seemin'ly unwounded, lowers its nose to th' ground. A calmin' voice envelops ye crew. \"I apologize fer me behavior. I have only just awoken from me slumber, 'n it would appear me wits have not completely returned to me. Please take these as a token 'o me apology.\" A cluster 'o eggs materialize on th' grass before th' devil's henchman. Without another word, th' devil's henchman runs off into th' forest wit' flowers fallin' in his wake.",
"questGhostStagBoss": "Ghost Stag",
"questGhostStagDropDeerEgg": "Deer (Egg)",
- "questGhostStagUnlockText": "Unlocks purchasable Deer eggs in th' Market",
+ "questGhostStagUnlockText": "Unlocks Deer Eggs ye kin purchase in th' Market",
"questRatText": "Th' Rat Captain",
"questRatNotes": "Garbage! Massive piles o' unchecked Dailies be lyin' all across Habitica. Th' problem has become so serious that hordes of rats now be seen everywhere. Ye notice @Pandah pettin' one o' th' beasts lovingly. She explains that rats be gentle creatures that feed on unchecked Dailies. The real problem be that th' Dailies have fallen into th' sewer, creatin' a dangerous pit that must be cleared. As ye descend into th' sewers, a massive rat, with blood red eyes an' mangled yellow teeth, attacks ye, defending its horde. Will ye cower in fear or face th' fabled Rat King?",
"questRatCompletion": "Yer final strike saps the gargantuan rat's strength, his eyes fadin' t' a dull grey. Th' beast splits into many tiny rats, which scurry off in fright. Ye notice @Pandah standing behind ye, lookin' at th' once mighty creature. She explains that th' citizens o' Habitica have been inspired by ye r courage an' be quickly completin' all their unchecked Dailies. She warns ye that we must be vigilant, for should we let down our guard, th' Rat King will return. As payment, @Pandah offers ye several rat eggs. Noticing your uneasy expression, she smiles, \"They make wonderful pets.\"",
"questRatBoss": "Rat Captain",
"questRatDropRatEgg": "Rat (Egg)",
- "questRatUnlockText": "Unlocks purchasable Rat eggs in th' Market",
+ "questRatUnlockText": "Unlocks Rat Eggs ye kin purchase in th' Market",
"questOctopusText": "Th' Call o' Octothulu",
"questOctopusNotes": "@Urse, a wild-eyed young scribe, has asked fer ye help explorin' a mysterious cave by th' sea shore. Among th' twilight tidepools stands a massive gate 'o stalactites 'n stalagmites. As ye near th' gate, a dark whirlpool begins to spin at its base. ye stare in awe as a squid-like dragon rises through th' maw. \"th' sticky spawn 'o th' stars has awakened,\" roars @Urse madly. \"After vigintillions 'o years, th' great Octothulu be loose again, 'n ravenin' fer delight!\"",
"questOctopusCompletion": "With a final blow, th' creature slips away into th' whirlpool from which it came. Ye cannot tell if @Urse is happy with yer victory or saddened t' see th' beast go. Wordlessly, yer companion points t' three slimy, gargantuan eggs in a nearby tidepool, set in a nest o' Doubloons. \"Prob'ly just octopus eggs,\" ye say nervously. As ye return home, @Urse frantically scribbles in a journal an' ye suspect this not be th' last time ye'll be hearin' o' th' great Octothulu.",
"questOctopusBoss": "Octothulu",
"questOctopusDropOctopusEgg": "Octopus (Egg)",
- "questOctopusUnlockText": "Unlocks purchasable Octopus eggs in th' Market",
+ "questOctopusUnlockText": "Unlocks Octopus Eggs ye kin purchase in th' Market",
"questHarpyText": "Help! Harpy!",
"questHarpyNotes": "Th' brave adventurer @UncommonCriminal has disappeared into th' forest, followin' th' trail 'o a win'ed monster that was sighted several days ago. ye be 'bout to begin a search when a wounded trusty parrot lands on ye arm, an ugly scar marrin' its beautiful plumage. Attached to its pegleg be a scrawled note explainin' that while defendin' th' parrots, @UncommonCriminal was captured by a vicious Harpy, 'n desperately needs ye help to escape. gunna ye follow th' bird, defeat th' Harpy, 'n save @UncommonCriminal?",
"questHarpyCompletion": "A final blow to th' Harpy brin's it below, feathers sailin' in all directions. After a quick climb to its nest ye find @UncommonCriminal, surrounded by trusty parrot eggs. As a team, ye quickly place th' eggs back in th' broadside nests. th' scarred trusty parrot who found ye caws loudly, droppin' several eggs in ye arms. \"th' Harpy attack has left some eggs in need 'o protection,\" explains @UncommonCriminal. \"It seems ye have be made an honorary trusty parrot.\"",
"questHarpyBoss": "Harpy",
"questHarpyDropParrotEgg": "Parrot (Egg)",
- "questHarpyUnlockText": "Unlocks purchasable Parrot eggs in th' Market",
+ "questHarpyUnlockText": "Unlocks Parrot Eggs ye kin purchase in th' Market",
"questRoosterText": "Roost'r Rampage",
"questRoosterNotes": "Fer years th' farmer @extrajordanary has used Roost'rs as an alarm clock. But now a giant Roost'r has appeared, crowin' louder than any before – 'n wakin' up all ye pirates in Habitica! th' sliumber-deprived Habiticans struggle through their daily tasks. @Pandoro decides th' time has come to put a stop to 'tis. \"Please, be thar anyone who can teach that Roost'r to crow quietly?\" ye volunteer, approachin' th' Roost'r early one mornin' – but it turns, flappin' its giant win's 'n showin' its sharp claws, 'n crows a battle cry.",
"questRoosterCompletion": "Wit' finesse 'n strength, ye have tamed th' wild beast. Its ears, once filled wit' feathers 'n half-remembered tasks, be now clear as day. It crows at ye quietly, snugglin' its beak into ye shoulder. th' next day ye're set to take ye leave, but @EmeraldOx runs up to ye wit' a covered basket. \"Wait! When I went into th' farmhouse 'tis mornin', th' Roost'r had pushed these against th' door whar ye slept. i reckon he wants ye to have them.\" ye uncover th' basket to spy wit' ye eye three delicate eggs.",
"questRoosterBoss": "Roost'r",
"questRoosterDropRoosterEgg": "Roost'r (Egg)",
- "questRoosterUnlockText": "Unlocks purchasable Roost'r eggs in th' Market",
+ "questRoosterUnlockText": "Unlocks Roost'r Eggs ye kin purchase in th' Market",
"questSpiderText": "Th' Icy Arachnid",
"questSpiderNotes": "As th' the seven seas starts coolin' below, delicate frost begins appearin' on Habiticans' windowpanes in lacy webs... except fer @Arcosine, whose windows be frozen completely shut by th' Frost Spid'r currently takin' up residence in his home. Oh dear.",
"questSpiderCompletion": "Th' Frost Spid'r collapses, leavin' behind a small pile 'o frost 'n a few 'o her enchanted egg sacs. @Arcosine rather hurriedly offers them to ye as a reward--perhaps ye could raise some non-threatenin' spid'rs as pets 'o ye own?",
"questSpiderBoss": "Spid'r",
"questSpiderDropSpiderEgg": "Spid'r (Egg)",
- "questSpiderUnlockText": "Unlocks purchasable Spid'r eggs in th' Market",
+ "questSpiderUnlockText": "Unlocks Spidey Eggs ye kin purchasein th' Market",
"questGroupVice": "Vice th' Shadow Wyrm",
"questVice1Text": "Vice, Part 1: Free Yourself o' th' Dragon's Influence",
"questVice1Notes": "
There be tales o' a terrible evil in the caverns o' Mt. Habitica. A monster whose presence twists t' wills o' the lubbers o' the land, turnin' them towards bad habits and laziness! The beast is a grand dragon o' immense power and comprised o' the shadows themselves: Vice, the treacherous Shadow Wyrm. Brave Habiteers, send this beast t' Davy Jones' locker, but only if ye believe ye can stand against its immense power.
Vice Part 1:
How can ye expect t' fight the beast if it already has control o'er ye? Don't fall victim t' laziness and vice! Work hard to fight against the dragon's dark influence and dispel his hold on ye!
",
@@ -102,22 +102,22 @@
"questGoldenknight2Text": "Th' Golden Knight, Part 2: Gold Knight",
"questGoldenknight2Notes": "Armed wit' dozens o' Habiticans' testimonies, ye finally confront th' Golden Knight. Ye begin t' recite th' Habitcans' complaints t' her, one by one. \"'n @Pfeffernusse says that yer constant braggin'-\" Th' knight raises her hand t' silence ye 'n scoffs, \", these scallywags are merely jealous o' me success. Instead o' complainin', they should simply work as hard as I! Perhaps I shall show ye th' power ye can attain through diligence such as mine!\" She raises her morningstar 'n prepares t' attack ye!",
"questGoldenknight2Boss": "Gold Knight",
- "questGoldenknight2Completion": "The Golden Knight lowers her Morningstar in consternation. “I apologize for my rash outburst,” she says. “The truth is, it’s painful to think that I’ve been inadvertently hurting others, and it made me lash out in defense… but perhaps I can still apologize?”",
- "questGoldenknight2DropGoldenknight3Quest": "The Golden Knight Part 3: The Iron Knight (Scroll)",
+ "questGoldenknight2Completion": "Th' Golden Knight lowers 'er Mornin'star in consternation. “I apologize for my rash outburst,” she says. “The truth is, it’s painful to think that I’ve been inadvertently hurting others, and it made me lash out in defense… but perhaps I can still apologize?”",
+ "questGoldenknight2DropGoldenknight3Quest": "Th' Golden Knight Part 3: Th' Iron Knight (Scroll)",
"questGoldenknight3Text": "Th' Golden Knight, Part 3: Th' Iron Knight",
- "questGoldenknight3Notes": "@Jon Arinbjorn cries out to you to get your attention. In the aftermath of your battle, a new figure has appeared. A knight coated in stained-black iron slowly approaches you with sword in hand. The Golden Knight shouts to the figure, \"Father, no!\" but the knight shows no signs of stopping. She turns to you and says, \"I am sorry. I have been a fool, with a head too big to see how cruel I have been. But my father is crueler than I could ever be. If he isn't stopped he'll destroy us all. Here, use my morningstar and halt the Iron Knight!\"",
- "questGoldenknight3Completion": "With a satisfying clang, the Iron Knight falls to his knees and slumps over. \"You are quite strong,\" he pants. \"I have been humbled, today.\" The Golden Knight approaches you and says, \"Thank you. I believe we have gained some humility from our encounter with you. I will speak with my father and explain the complaints against us. Perhaps, we should begin apologizing to the other Habiticans.\" She mulls over in thought before turning back to you. \"Here: as our gift to you, I want you to keep my morningstar. It is yours now.\"",
- "questGoldenknight3Boss": "The Iron Knight",
+ "questGoldenknight3Notes": "@Jon Arinbjorn cries out t'ye ta get yer attention. In the aftermath o' yer battle, a new figure 'as appeared. A knight wearin' stained-black iron slowly comes toward ye wit' sword in 'and. Th' Golden Knight shouts t' th' figure, \"Father, no!\" but th' knight shows no signs o' stoppin'. She turns t' ye an' says, \"I am sorry. I have been a fool, with a head too big to see how cruel I have been. But my father is crueler than I could ever be. If he isn't stopped he'll destroy us all. Here, use my morningstar and halt the Iron Knight!\"",
+ "questGoldenknight3Completion": "Wiv a satisfyin' clang, th' Iron Knight falls t' 'is knees an' slumps o'er. \"You are quite strong,\" 'e pants. \"I have been humbled, today.\" Th' Golden Knight approaches ye an' says, \"Thank you. I believe we have gained some humility from our encounter with you. I will speak with my father and explain the complaints against us. Perhaps, we should begin apologizing to the other Habiticans.\" She mulls o'er in thought afore turning back t' ye. \"Here: as our gift to you, I want you to keep my morningstar. It is yours now.\"",
+ "questGoldenknight3Boss": "Th' Iron Knight",
"questGoldenknight3DropHoney": "Honey (Foodstuffs)",
- "questGoldenknight3DropGoldenPotion": "Golden Hatching Potion",
- "questGoldenknight3DropWeapon": "Mustaine's Milestone Mashing Morning Star (Off-hand Weapon)",
+ "questGoldenknight3DropGoldenPotion": "Golden Hatchin' Potion",
+ "questGoldenknight3DropWeapon": "Mustaine's Milestone Mashin' Mornin' Star (Off-hand Weapon)",
"questGroupEarnable": "Earnable Adventures",
- "questBasilistText": "The Basi-List",
+ "questBasilistText": "Th' Basi-List",
"questBasilistNotes": "There be a commotion in th' marketplace--th' kind that should make ye run away. Bein' a courageous adventurer, ye run towards it instead, an' discover a Basi-list, coalescing from a clump o' incomplete T'-Dos! Nearby Habiticans be paralyzed with fear at th' length o' th' Basi-list, unable t' start working. From somewhere in th' vicinity, ye hear @Arcosine shout: \"Quick! Complete your To-Dos and Dailies to defang the monster, before someone gets a paper cut!\" Strike fast, adventurer, an' check something off - but beware! If ye leave any Dailies undone, th' Basi-list will attack ye an' yer crew!",
"questBasilistCompletion": "The Basi-list has scattered into paper scraps, which shimmer gently in rainbow colors. \"Whew!\" says @Arcosine. \"Good thing you guys were here!\" Feeling more experienced than before, ye gather up some fallen gold from among th' papers.",
"questBasilistBoss": "Th' Basi-List",
"questEggHuntText": "Egg Hunt",
- "questEggHuntNotes": "Overnight, strange plain eggs have appeared everywhere: in Matt's stables, behind the counter at the Tavern, and even among the pet eggs at the Marketplace! What a nuisance! \"Nobody knows where they came from, or what they might hatch into,\" says Megan, \"but we can't just leave them laying around! Work hard and search hard to help me gather up these mysterious eggs. Maybe if you collect enough, there will be some extras left over for you...\"",
+ "questEggHuntNotes": "O'ernight, strange plain eggs 'ave appeared ever'where: in Matt's stables, behind th' counter at th' Tavern, an' e'en among th' pet eggs at th' Marketplace! How agger-vatin'! \"Nobody knows where they came from, or what they might hatch into,\" says Megan, \"but we can't just leave them laying around! Work hard and search hard to help me gather up these mysterious eggs. Maybe if you collect enough, there will be some extras left over for you...\"",
"questEggHuntCompletion": "Ye did it! In gratitude, Megan gives ye ten of the eggs. \"I bet the hatching potions will dye them beautiful colors! And I wonder what will happen when they turn into mounts....\"",
"questEggHuntCollectPlainEgg": "Plain Eggs",
"questEggHuntDropPlainEgg": "Plain Egg",
@@ -137,38 +137,38 @@
"questSeahorseCompletion": "Th' now-tame Sea Stallion swims docilely to ye side. \"Oh, look!\" Kiwibot says. \"He wants us to take care 'o his children.\" She gives ye three eggs. \"Raise them well,\" she says. \"ye're welcome at th' Dilatory Derby any day!\"",
"questSeahorseBoss": "Sea Stallion",
"questSeahorseDropSeahorseEgg": "Seahorse (Egg)",
- "questSeahorseUnlockText": "Unlocks purchasable Seahorse eggs in th' Market",
+ "questSeahorseUnlockText": "Unlocks Seahorse Eggs ye kin purchase in th' Market",
"questGroupAtom": "Attack of the Mundane",
"questAtom1Text": "Attack o' th' Mundane, Part 1: Dish Disaster!",
"questAtom1Notes": "Ye reach th' shores 'o Washed-Up Lake fer some well-earned relaxation... But th' lake be polluted wit' unwashed dishes! How did 'tis happen? Well, ye simply cannot allow th' lake to be in 'tis state. thar be only one thin' ye can do: spit shine th' dishes 'n save ye vacation spot! Better find some soap to spit shine up 'tis mess. A lot 'o soap...",
"questAtom1CollectSoapBars": "Bars o' Soap",
- "questAtom1Drop": "The SnackLess Monster (Scroll)",
- "questAtom1Completion": "After some thorough scrubbing, all the dishes are stacked safely on the shore! You stand back and proudly survey your hard work.",
+ "questAtom1Drop": "Th' SnackLess Monster (Scroll)",
+ "questAtom1Completion": "After some 'eavy scrubbin', all th' dishes er stacked safe n' sound on th' shore! Ye stand back an' proudly survey yer 'ard work.",
"questAtom2Text": "Attack o' th' Mundane, Part 2: Th' SnackLess Monster",
"questAtom2Notes": "Arr, it be lookin' a lot nicer here with all them dishes cleaned up. Maybe ye can finally have yerself a bit o' fun now. Ahoy - there seems to be a pizza box floatin' in the lake there. Well, what's one more thin' to spit shine really? But alas, it be no mere pizza box! With a sudden rush the box lifts from the rum 'n reveals itself to be the head o' a monster. It can't be! The fabled SnackLess Monster?! It be said it's lurked hidden in the lake since times o' yore: a creature spawned from the leftover grub 'n trash 'o the ancient Habiticans. Argh!",
"questAtom2Boss": "Th' SnackLess Monster",
- "questAtom2Drop": "The Laundromancer (Scroll)",
- "questAtom2Completion": "With a deafening cry, and five delicious types of cheese bursting from its mouth, the Snackless Monster falls to pieces. Well done, brave adventurer! But wait... is there something else wrong with the lake?",
+ "questAtom2Drop": "Th' Laundromancer (Scroll)",
+ "questAtom2Completion": "Wi' a deafenin' cry, an' five delicious types o' cheese burstin' from its mouth, th' Snackless Monster falls ta pieces. Well done, brave adventurer! But wait... is there summat else wrong wi' th' lake?",
"questAtom3Text": "Attack o' th' Mundane, Part 3: Th' Laundromancer",
- "questAtom3Notes": "Just when you thought that your trials had ended, Washed-Up Lake begins to froth violently. “HOW DARE YOU!” booms a voice from beneath the water's surface. A robed, blue figure emerges from the water, wielding a magic toilet brush. Filthy laundry begins to bubble up to the surface of the lake. \"I am the Laundromancer!\" he angrily announces. \"You have some nerve - washing my delightfully dirty dishes, destroying my pet, and entering my domain with such clean clothes. Prepare to feel the soggy wrath of my anti-laundry magic!\"",
+ "questAtom3Notes": "Jus' when ye thought that yer trials 'ad ended, Washed-Up Lake begins ta froth vio-lently. “HOW DARE YOU!” booms a voice from 'neath th' water's surface. A berobed, blue figure comes out o' th' water, wieldin' a magic toilet brush. Filthy laundry begins ta bubble up t' th' surface o' th' lake. \"I am the Laundromancer!\" 'e angrily announces. \"You have some nerve - washing my delightfully dirty dishes, destroying my pet, and entering my domain with such clean clothes. Prepare to feel the soggy wrath of my anti-laundry magic!\"",
"questAtom3Completion": "Th' wicked Laundromancer has be defeated! spit shine laundry fightin' falls in piles all around ye. Thin's be lookin' much better around here. As ye begin to wade through th' freshly pressed armor, a glint 'o metal catches ye eye, 'n ye gaze falls upon a gleamin' helm. th' original owner 'o 'tis shinin' item may be unknown, but as ye put it on, ye feel th' warmin' presence 'o a generous devil's henchman. Too bad they didn't sew on a nametag.",
"questAtom3Boss": "Th' Laundromancer",
"questAtom3DropPotion": "Simple Potion o' Hatchin'",
- "questOwlText": "The Night-Owl",
- "questOwlNotes": "The Tavern light is lit 'til dawn Until one eve the glow is gone! How can we see for our all-nighters? @Twitching cries, \"I need some fighters! See that Night-Owl, starry foe? Fight with haste and do not slow! We'll drive its shadow from our door, And make the night shine bright once more!\"",
- "questOwlCompletion": "The Night-Owl fades before the dawn, But even so, you feel a yawn. Perhaps it's time to get some rest? Then on your bed, you see a nest! A Night-Owl knows it can be great To finish work and stay up late, But your new pets will softly peep To tell you when it's time to sleep.",
- "questOwlBoss": "The Night-Owl",
+ "questOwlText": "Th' Night-Owl",
+ "questOwlNotes": "The Tavern light be lit 'til dawn Until one eve th' glow be gone! 'Ow kin we see fer our all-nighters? @Twitching cries, \"I need some fighters! See that Night-Owl, starry foe? Fight with haste and do not slow! We'll drive its shadow from our door, And make the night shine bright once more!\"",
+ "questOwlCompletion": "The Night-Owl fades afore th' dawn, But even so, ye feel a yawn. P'rhaps it be time fer yer rest? Then on yer bunk, ye see a nest! A Night-Owl kens it kin be great Ta finish work an' stay up late, But yer new pets will softly peep To tell ye when it's time t' sleep.",
+ "questOwlBoss": "Th' Night-Owl",
"questOwlDropOwlEgg": "Owl (Egg)",
- "questOwlUnlockText": "Unlocks purchasable Owl eggs in th' Market",
- "questPenguinText": "The Fowl Frost",
+ "questOwlUnlockText": "Unlocks Owl Eggs ye kin purchase in th' Market",
+ "questPenguinText": "Th' Fowl Frost",
"questPenguinNotes": "Though it be a hot summer day in th' southernmost tip o' Habitica, an unnatural chill has fallen upon Lively Lake. Strong, frigid winds rush around as th' shore begins t' freeze over. Ice spikes jut up from th' ground, pushing grass an' dirt away. @Melynnrose an' @Breadstrings run up to you.
\"Help!\" says @Melynnrose. \"We brought a giant penguin in to freeze the lake so we could all go ice skating, but we ran out of fish to feed him!\"
\"He got angry and is using his freeze breath on everything he sees!\" says @Breadstrings. \"Please, you have to subdue him before all of us are covered in ice!\" Looks like ye need this penguin t'... cool down.",
"questPenguinCompletion": "Upon th' penguin's defeat, th' ice melts away. Th' giant penguin settles down in th' sunshine, slurping up an extra bucket o' fish you found. He skates off 'cross th' lake, blowing gently downwards t' create smooth, sparkling ice. What an odd bird! \"It appears he left behind a few eggs, as well,\" says @Painter de Cluster.
@Rattify laughs. \"Maybe these penguins will be a little more... chill?\"",
"questPenguinBoss": "Frost Penguin",
"questPenguinDropPenguinEgg": "Penguin (Egg)",
- "questPenguinUnlockText": "Unlocks purchasable Penguin eggs in th' Market",
+ "questPenguinUnlockText": "Unlocks Penguin Eggs ye kin purchase in th' Market",
"questStressbeastText": "Th' Abominable Stressbeast o' th' Stoïkalm Steppes",
"questStressbeastNotes": "Complete Dailies an' T'-Dos t' damage th' World Boss! Incomplete Dailies fill th' Stress Strike Bar. When th' Stress Strike bar be full, th' World Boss will attack an NPC. A World Boss will never damage individual players or accounts in any way. Only active accounts who not be restin' in th' inn will have their incomplete Dailies tallied.
~*~
Th' first thing we hear are th' footsteps, slower an' more thunderin' than th' stampede. One by one, Habiticans look outside their doors, an' words fail us.
We've all seen Stressbeasts before, o' course - tiny vicious creatures that attack durin' difficult times. But this? This towers taller than th' buildings, with paws that could crush a dragon with ease. Frost swings from its stinkin' fur, an' as it roars, th' icy blast rips th' roofs off our houses. A monster o' this magnitude has never been mentioned outside o' distant legend.
\"Beware, Habiticans!\" SabreCat cries. \"Barricade yourselves indoors - this is the Abominable Stressbeast itself!\"
\"That thing must be made of centuries of stress!\" Kiwibot says, lockin' the Tavern door tightly an' shuttering th' windows.
\"The Stoïkalm Steppes,\" Lemoness says, face grim. \"All this time, we thought they were placid and untroubled, but they must have been secretly hiding their stress somewhere. Over generations, it grew into this, and now it's broken free and attacked them - and us!\"
There be only one way t' drive away a Stressbeast, Abominable or otherwise, an' that's t' attack it with completed Dailies an' T'-Dos! Let's all band together an' fight off this fearsome foe - but be sure not t' slack on yer tasks, or our undone Dailies may enrage it so much that it lashes out...",
- "questStressbeastBoss": "The Abominable Stressbeast",
+ "questStressbeastBoss": "Th' Abominable Stressbeast",
"questStressbeastBossRageTitle": "Stress Strike",
"questStressbeastBossRageDescription": "When this gauge fills, th' Abominable Stressbeast will unleash its Stress Strike on Habitica!",
"questStressbeastDropMammothPet": "Mammoth (Pet)",
@@ -179,55 +179,55 @@
"questStressbeastDesperation": "`Abominable Stressbeast reaches 500K health! Abominable Stressbeast uses Desperate Defense!`\n\nWe be nearly there, Habiticians! With hard work 'n Dailies, we've carved the Stressbeast's health down to only 500K! The beast roars 'n flails with its last strength, becomin' more fearsome by the second. Bailey and Matt yell in terror as it begins to swing 'em around at a terrifyin' speed, raisin' a blindin' blizzard that makes it harder to hit.\n\nPut yer backs into it, me hearties, 'n never fear - this is a sign that the Stressbeast knows it'll soon sink beneath the waves. Don't give up, heave!",
"questStressbeastCompletion": "The Abominable Stressbeast be DEFEATED!
We've done it! With a final bellow, th' Abominable Stressbeast dissipates into a cloud o' snow. The flakes twinkle down through th' air as cheering Habiticans embrace their pets and mounts. Our animals an' our NPCs be safe once more!
Stoïkalm is Saved!
SabreCat speaks gently t' a small sabertooth. \"Please find the citizens of the Stoïkalm Steppes and bring them to us,\" he says. Several hours later, the sabertooth returns, with a herd o' mammoth riders following slowly behind. You recognize th' head rider as Lady Glaciate, the leader of Stoïkalm.
\"Mighty Habiticans,\" she says, \"My citizens and I owe you the deepest thanks, and the deepest apologies. In an effort to protect our Steppes from turmoil, we began to secretly banish all of our stress into the icy mountains. We had no idea that it would build up over generations into the Stressbeast that you saw! When it broke loose, it trapped all of us in the mountains in its stead and went on a rampage against our beloved animals.\" Her sad gaze follows th' falling snow. \"We put everyone at risk with our foolishness. Rest assured that in the future, we will come to you with our problems before our problems come to you.\"
She turns t' where @Baconsaur be snugglin' with some o' th' baby mammoths. \"We have brought your animals an offering of food to apologize for frightening them, and as a symbol of trust, we will leave some of our pets and mounts with you. We know that you will all take care good care of them.\"",
"questStressbeastCompletionChat": "`The Abominable Stressbeast be DEFEATED!`\n\nWe've done it! With a final bellow, th' Abominable Stressbeast dissipates into a cloud o' snow. The flakes twinkle down through th' air as cheerin' Habiticans embrace their pets an' mounts. Our animals an' our NPCs be safe once more!\n\n`Stoïkalm is Saved!`\n\nSabreCat speaks gently t' a small sabertooth. \"Please find the citizens of the Stoïkalm Steppes and bring them to us,\" he says. Several hours later, th' sabertooth returns, with a herd o' mammoth riders following slowly behind. Ye recognize th' head rider as Lady Glaciate, th' leader o' Stoïkalm.\n\n\"Mighty Habiticans,\" she says, \"My citizens and I owe you the deepest thanks, and the deepest apologies. In an effort to protect our Steppes from turmoil, we began to secretly banish all of our stress into the icy mountains. We had no idea that it would build up over generations into the Stressbeast that you saw! When it broke loose, it trapped all of us in the mountains in its stead and went on a rampage against our beloved animals.\" Her sad gaze follows th' falling snow. \"We put everyone at risk with our foolishness. Rest assured that in the future, we will come to you with our problems before our problems come to you.\"\n\nShe turns t' where @Baconsaur be snugglin' with some o' th' baby mammoths. \"We have brought your animals an offering of food to apologize for frightening them, and as a symbol of trust, we will leave some of our pets and mounts with you. We know that you will all take care good care of them.\"",
- "questTRexText": "King of the Dinosaurs",
+ "questTRexText": "King o' th' Dinosaurs",
"questTRexNotes": "Now that ancient creatures from th' Stoïkalm Steppes be roamin' throughout all o' Habitica, @Urse has decided t' adopt a full-grown Tyrannosa'r. What could go wrong?
Everything.",
"questTRexCompletion": "Th' wild dinosa'r finally stops its rampage and settles down t' make friends with th' giant roosters. @Urse beams down at it. \"They're not such terrible pets, after all! They just need a little discipline. Here, take some Tyrannosa'r eggs for yourself.\"",
"questTRexBoss": "Flesh Tyrannosa'r",
- "questTRexUndeadText": "The Dinosaur Unearthed",
+ "questTRexUndeadText": "Th' Dinosarrr Unearthed",
"questTRexUndeadNotes": "As th' ancient dinosaurs from th' Stoïkalm Steppes roam through Habit City, a cry o' terror emanates from th' Grand Museum. @Baconsaur shouts, \"The Tyrannosa'r skeleton in the museum is stirring! It must have sensed its kin!\" Th' bony beast bares its teeth an' clatters towards ye. How can ye defeat a creature that already be dead? You'll have t' strike fast before it heals itself!",
"questTRexUndeadCompletion": "Th'â Tyrannosar's glowin' eyes grow dark, n' it settles back onto its familiar pedestal. Everyone sighs wit' relief. \"Look!\" @Baconsaur says. \"Some o' th' fossilized eggs are shiny 'n new! Maybe they'll hatch fer ye.\"",
"questTRexUndeadBoss": "Skeletal Tyrannosa'r",
- "questTRexUndeadRageTitle": "Skeleton Healing",
+ "questTRexUndeadRageTitle": "Skeleton Healin'",
"questTRexUndeadRageDescription": "This bar fills when ye don't complete yer Dailies. When it be full, th' Skeletal Tyrannosa'r will heal 30% o' its remaining health!",
"questTRexUndeadRageEffect": "`Skeletal Tyrannosa'r uses SKELETON HEALING!`\n\nThe monster lets forth an unearthly roar, n' some o' its damaged bones knit back together!",
"questTRexDropTRexEgg": "Tyrannosa'r (Egg)",
- "questTRexUnlockText": "Unlocks purchasable Tyrannosa'r eggs in th' Market",
+ "questTRexUnlockText": "Unlocks Tyrannosarrr Eggs ye kin purchase in th' Market",
"questRockText": "Escape th' Cave Creature",
"questRockNotes": "Crossin' Habitica's Meandering Mountains with some friends, ye make camp one night in a beautiful cave laced with shining minerals. But when ye wake up th' next morning, the entrance has disappeared, an' th' floor o' th' cave be shiftin' underneath you.
\"The mountain's alive!\" shouts yer companion @pfeffernusse. \"These aren't crystals - these are teeth!\"
@Painter de Cluster grabs yer hand. \"We'll have to find another way out - stay with me and don't get distracted, or we could be trapped in here forever!\"",
"questRockBoss": "Crystal Colossus",
"questRockCompletion": "Yer diligence has allowed ye t' find a safe path through th' living mountain. Standin' in th' sunshine, yer friend @intune notices something glinting on th' ground by th' cave's exit. You stoop to pick it up, an' see that it be a small rock with a vein o' gold running through it. Beside it be a number o' other rocks with rather peculiar shapes. They almost look like... eggs?",
"questRockDropRockEgg": "Rock (Egg)",
- "questRockUnlockText": "Unlocks purchasable Rock eggs in th' Market",
+ "questRockUnlockText": "Unlocks Rock Eggs ye kin purchase in th' Market",
"questBunnyText": "Th' Killer Bunny",
"questBunnyNotes": "After many difficult days, ye reach th' peak o' Mount Procrastination an' stand before th' imposing doors o' th' Fortress o' Neglect. Ye read th' inscription in th' stone. \"Inside resides the creature that embodies your greatest fears, the reason for your inaction. Knock and face your demon!\" Ye tremble, imaginin' th' horror within an' feel th' urge t' flee as ye have done so many times before. @Draayder holds ye back. \"Steady, my friend! The time has come at last. You must do this!\"
Ye knock an' the doors swing inward. From within th' gloom ye hear a deafenin' roar, an' ye draw yer weapon.",
"questBunnyBoss": "Killer Bunny",
"questBunnyCompletion": "With one final blow th' killer rabbit sinks t' th' ground. A sparkly mist rises from her body as she shrinks down into a tiny bunny... nothing like th' cruel beast ye faced a moment before. Her nose twitches adorably an' she hops away, leaving some eggs behind. @Gully laughs. \"Mount Procrastination has a way of making even the smallest challenges seem insurmountable. Let's gather these eggs and head for home.\"",
"questBunnyDropBunnyEgg": "Bunny (Egg)",
- "questBunnyUnlockText": "Unlocks purchasable Bunny eggs in th' Market",
+ "questBunnyUnlockText": "Unlocks Bunny Eggs ye kin purchase in th' Market",
"questSlimeText": "Th' Jelly Regent",
"questSlimeNotes": "As ye work on yer tasks, ye notice ye be movin' slower an' slower. \"It's like walking through molasses,\" @Leephon grumbles. \"No, like walking through jelly!\" @starsystemic says. \"That slimy Jelly Regent has slathered his stuff all over Habitica. It's gumming up the works. Everybody is slowing down.\" Ye look around. Th' streets be slowly fillin' with clear, colorful ooze, an' Habiticans be strugglin' t' get anything done. As others flee th' area, ye grab a mop an' prepare fer battle!",
"questSlimeBoss": "Jelly Regent",
"questSlimeCompletion": "With a final jab, ye trap th' Jelly Regent in an over-sized donut, rushed in by @Overomega, @LordDarkly, an' @Shaner, th' quick-thinking leaders o' th' pastry club. As everyone be pattin' ye on th' back, you feel someone slip somethin' into yer pocket. It be th' reward for yer sweet success: three Marshmallow Slime eggs.",
"questSlimeDropSlimeEgg": "Marshmallow Slime (Egg)",
- "questSlimeUnlockText": "Unlocks purchasable Slime eggs in th' Market",
+ "questSlimeUnlockText": "Unlocks Slime Eggs ye kin purchase in th' Market",
"questSheepText": "Th' Thunder Ram",
"questSheepNotes": "As ye wander th' rural Taskan countryside with friends, takin' a \"quick break\" from yer obligations, ye find a cozy yarn shop. Ye be so absorbed in yer procrastination that ye hardly notice th' ominous clouds creep over th' horizon. \"I've got a ba-a-a-ad feeling about this weather,\" mutters @Misceo, and ye look up. Th' stormy clouds be swirlin' together, an' they look a lot like a... \"We don't have time for cloud-gazing!\" @starsystemic shouts. \"It's attacking!\" Th' Thunder Ram hurtles forward, slingin' bolts o' lightning right at ye!",
"questSheepBoss": "Thunder Ram",
"questSheepCompletion": "Impressed by yer diligence, th' Thunder Ram be drained o' its fury. It launches three huge hailstones in yer direction, an' then fades away with a low rumble. Upon closer inspection, ye discover that th' hailstones actually be three fluffy eggs. Ye gather 'em up, an' then stroll home under a blue sky.",
"questSheepDropSheepEgg": "Sheep (Egg)",
- "questSheepUnlockText": "Unlocks purchasable Sheep eggs in th' Market",
+ "questSheepUnlockText": "Unlocks Sheep Eggs ye kin purchase in th' Market",
"questKrakenText": "The Kraken o' Inkomplete",
"questKrakenNotes": "It be a warm, sunny day as ye sail across th' Inkomplete Bay, but yer thoughts are clouded with worries about everything that ye still need t' do. It seems that as soon as ye finish one task, another crops up, an' then another...
Suddenly, th' boat gives a horrible jolt, an' slimy tentacles burst out o' th' water on all sides! \"We're being attacked by the Kraken of Inkomplete!\" Wolvenhalo cries.
\"Quickly!\" Lemoness calls to you. \"Strike down as many tentacles and tasks as you can, before new ones can rise up to take their place!\"",
"questKrakenBoss": "Th' Kraken o' Inkomplete",
"questKrakenCompletion": "As th' Kraken flees, several eggs float t' th' surface o' th' water. Lemoness examines 'em, an' her suspicion turns t' delight. \"Cuttlefish eggs!\" she says. \"Here, take them as a reward for everything you've completed.\"",
"questKrakenDropCuttlefishEgg": "Cuttlefish (Egg)",
- "questKrakenUnlockText": "Unlocks purchasable Cuttlefish eggs in th' Market",
- "questWhaleText": "Wail of the Whale",
+ "questKrakenUnlockText": "Unlocks Cuttlefish Eggs ye kin purchase in th' Market",
+ "questWhaleText": "Wail o' th' Whale",
"questWhaleNotes": "Ye arrive at th' Diligent Docks, hopin' t' take a submarine t' watch th' Dilatory Derby. Suddenly, a deafening bellow forces ye t' stop an' cover yer ears. \"Thar she blows!\" cries Captain @krazjega, pointin' t' a huge, wailing whale. \"It's not safe to send out the submarines while she's thrashing around!\"
\"Quick,\" calls @UncommonCriminal. \"Help me calm the poor creature so we can figure out why she's making all this noise!\"",
- "questWhaleBoss": "Wailing Whale",
+ "questWhaleBoss": "Wailin' Whale",
"questWhaleCompletion": "After much hard work, th' whale finally ceases her thunderous cry. \"Looks like she was drowning in waves of negative habits,\" @zoebeagle explains. \"Thanks to your consistent effort, we were able to turn the tides!\" As ye step into th' submarine, several whale eggs bob towards you, an' ye scoop 'em up.",
"questWhaleDropWhaleEgg": "Whale (Egg)",
- "questWhaleUnlockText": "Unlocks purchasable Whale eggs in th' Market",
+ "questWhaleUnlockText": "Unlocks Whale Eggs ye kin purchase in th' Market",
"questGroupDilatoryDistress": "Dilatory Distress",
"questDilatoryDistress1Text": "Dilatory Distress, Part 1: Message in a Bottle",
"questDilatoryDistress1Notes": "A message in a bottle arrived from th' newly rebuilt city of Dilatory! It reads: \"Dear Habiticans, we need your help once again. Our princess has disappeared and the city is under siege by some unknown watery demons! The mantis shrimps are holding the attackers at bay. Please aid us!\" To make the long journey to the sunken city, one must be able to breathe water. Fortunately, th' alchemists @Benga and @hazel can make it all possible! Ye only have t' find th' proper ingredients.",
@@ -242,28 +242,28 @@
"questDilatoryDistress2RageTitle": "Swarm Respawn",
"questDilatoryDistress2RageDescription": "Swarm Respawn: This bar fills when ye don't complete yer Dailies. When it be full, th' Water Skull Swarm will heal 30% o' its remaining health!",
"questDilatoryDistress2RageEffect": "`Water Skull Swarm uses SWARM RESPAWN!`\n\nEmboldened by their victories, more skulls pour forth from th' crevasse, bolstering th' swarm!",
- "questDilatoryDistress2DropSkeletonPotion": "Skeleton Hatching Potion",
- "questDilatoryDistress2DropCottonCandyBluePotion": "Cotton Candy Blue Hatching Potion",
+ "questDilatoryDistress2DropSkeletonPotion": "Skeleton Hatchin' Potion",
+ "questDilatoryDistress2DropCottonCandyBluePotion": "Cotton Candy Blue Hatchin' Potion",
"questDilatoryDistress2DropHeadgear": "Fire Coral Circlet (Headgear)",
- "questDilatoryDistress3Text": "Dilatory Distress, Part 3: Not a Mere Maid",
+ "questDilatoryDistress3Text": "Dilatory Distress, Part 3: Nor a Mere Maid",
"questDilatoryDistress3Notes": "Ye follow th' mantis shrimps deep into th' Crevasse, an' discover an underwater fortress. Princess Adva, escorted by more watery skulls, awaits ye inside th' main hall. \"My father has sent you, has he not? Tell him I refuse to return. I am content to stay here and practice my sorcery. Leave now, or you shall feel the wrath of the ocean's new queen!\" Adva seems very adamant, but as she speaks ye notice a strange, ruby pendant on her neck glowing ominously... Perhaps her delusions would cease should ye break it?",
"questDilatoryDistress3Completion": "Finally, ye manage t' pull th' bewitched pendant from Adva's neck an' throw it away. Adva clutches her head. \"Where am I? What happened here?\" After hearin' your story, she frowns. \"This necklace was given to me by a strange ambassador - a lady called 'Tzina'. I don't remember anything after that!\"
Back at Dilatory, Manta be overjoyed by yer success. \"Allow me to reward you with this trident and shield! I ordered them from @aiseant and @starsystemic as a gift for Adva, but... I'd rather not put weapons in her hands any time soon.\"",
- "questDilatoryDistress3Boss": "Adva, the Usurping Mermaid",
+ "questDilatoryDistress3Boss": "Adva, th' Usurping Mermaid",
"questDilatoryDistress3DropFish": "Fish (Food)",
- "questDilatoryDistress3DropWeapon": "Trident of Crashing Tides (Weapon)",
+ "questDilatoryDistress3DropWeapon": "Trident o' Crashin' Tides (Weapon)",
"questDilatoryDistress3DropShield": "Moonpearl Shield (Off-Hand Item)",
"questCheetahText": "Such a Cheetah",
"questCheetahNotes": "As ye hike across th' Sloensteadi Savannah with yer mates @PainterProphet, @tivaquinn, @Unruly Hyena, an' @Crawford, ye be startled t' see a Cheetah screeching past with a new Habitican clamped in its jaws. Under th' Cheetah's scorching paws, tasks burn away as though complete -- before anyone has th' chance t' actually finish them! Th' Habitican sees ye an' yells, \"Please help me! This Cheetah is making me level too quickly, but I'm not getting anything done. I want to slow down and enjoy the game. Make it stop!\" Ye fondly remember yer own fledgling days, an' know that ye have t' help th' newbie by stopping th' Cheetah!",
"questCheetahCompletion": "Th' new Habitican is breathin' heavily after th' wild ride, but thanks ye an' yer friends for yer help. \"I'm glad that Cheetah won't be able to grab anyone else. It did leave some Cheetah eggs for us, so maybe we can raise them into more trustworthy pets!\"",
"questCheetahBoss": "Cheetah",
"questCheetahDropCheetahEgg": "Cheetah (Egg)",
- "questCheetahUnlockText": "Unlocks purchasable Cheetah eggs in th' Market",
+ "questCheetahUnlockText": "Unlocks Cheetah Eggs ye kin purchase in th' Market",
"questHorseText": "Ride th' Night-Mare",
"questHorseNotes": "While relaxin' in th' Pub with @beffymaroo an' @JessicaChase, th' talk turns t' good-natured boasting about yer adventurin' accomplishments. Proud o' yer deeds, an' perhaps gettin' a bit carried away, ye brag that ye can tame any task around. A nearby stranger turns toward ye an' smiles. One eye twinkles as he invites ye t' prove yer claim by ridin' his horse.\nAs ye all head for th' stables, @UncommonCriminal whispers, \"You may have bitten off more than ye can chew. That's no horse - that's a Night-Mare!\" Looking at its stamping hooves, ye begin t' regret yer words...",
"questHorseCompletion": "It takes all yer skill, but finally th' horse stamps a couple o' hooves an' nuzzles you in th' shoulder before allowin' ye t' mount. Ye ride briefly but proudly around th' Pub grounds while yer friends cheer. Th' stranger breaks into a broad grin.\n\"I can see that was no idle boast! Yer determination truly be impressive. Take these eggs t' raise horses o' yer own, an' perhaps we'll meet again one day.\" Ye take th' eggs, th' stranger tips his hat... an' vanishes.",
"questHorseBoss": "Night-Mare",
"questHorseDropHorseEgg": "Horse (Egg)",
- "questHorseUnlockText": "Unlocks purchasable Horse eggs in th' Market",
+ "questHorseUnlockText": "Unlocks Horse Eggs ye kin purchase in th' Market",
"questBurnoutText": "Burnout an' th' Exhaust Spirits",
"questBurnoutNotes": "It be well past midnight, still an' stiflingly hot, when Redphoenix an' scout captain Kiwibot abruptly burst through th' city gates. \"We need t' evacuate all th' wooden buildings!\" Redphoenix shouts. \"Hurry!\"
Kiwibot grips th' wall as she catches her breath. \"It's draining people an' turnin' them into Exhaust Spirits! That's why everything was delayed. That's where th' missing people have gone. It's been stealing their energy!\"
\"'It'?'\" asks Lemoness.
And then th' heat takes form.
It rises from th' earth in a billowin', twistin' mass, an' th' air chokes with th' scent o' smoke an' sulphur. Flames lick 'cross th' molten ground an' contort into limbs, writhing t' horrific heights. Smoldering eyes snap open, an' th' creature lets out a deep an' crackling cackle.
Kiwibot whispers a single word.
\"Burnout.\"",
"questBurnoutCompletion": "Burnout be DEFEATED!
With a great, soft sigh, Burnout slowly releases th' ardent energy that was fueling its fire. As the monster curls quietly into ashes, its stolen energy shimmers through the air, rejuvenating th' Exhaust Spirits an' returnin' them t' their true forms.
Ian, Daniel, an' th' Seasonal Sorceress cheer as Habiticans rush t' greet them, an' all th' missin' citizens o' th' Flourishing Fields embrace their friends an' families. Th' final Exhaust Spirit transforms into th' Joyful Reaper herself!
\"Look!\" whispers @Baconsaur, as th' ashes begin t' glitter. Slowly, they resolve into hundreds o' shining phoenixes!
One o' the glowin' birds alights on th' Joyful Reaper's skeletal arm, an' she grins at it. \"It has been a long time since I've had th' exquisite privilege t' behold a phoenix in th' Flourishing Fields,\" she says. \"Although given recent occurrences, I must say, this be highly thematically appropriate!\"
Her tone sobers, although (naturally) her grin remains. \"We're known for being hard-working here, but we are also known for our feasts an' festivities. Rather ironic, I suppose, that as we strove to plan a spectacular party, we refused t' permit ourselves any time for fun. We certainly won't make th' same mistake twice!\"
She claps her hands. \"Now - let's celebrate!\"",
@@ -281,19 +281,19 @@
"questFrogCompletion": "The frog cowers back into the muck, defeated. As it slinks away, the blue slime fades, leaving the way ahead clear.
Sitting in the middle of the path are three pristine eggs. \"You can even see the tiny tadpoles through the clear casing!\" @Breadstrings says. \"Here, you should take them.\"",
"questFrogBoss": "Clutter Frog",
"questFrogDropFrogEgg": "Frog (Egg)",
- "questFrogUnlockText": "Unlocks purchasable Frog eggs in t' Market",
+ "questFrogUnlockText": "Unlocks Frog Eggs ye kin purchase in t' Market",
"questSnakeText": "Th' Serp'nt o' Distraction",
"questSnakeNotes": "It loots a hardy soul t' live in th' Sand Dunes o' Distraction. Th' arid desert be hardly a productive ship, 'n th' shimmerin' dunes 'ave led many a traveler astray. However, somethin' has even th' locals spooked. Th' sands 'ave been shiftin' 'n upturnin' entire villages. Residents claim a monster wit' an enormous serpentine body lies in wait under th' sands, 'n they 'ave all pooled together a reward fer whomever will help them find 'n stop it. Th' much-lauded snake charmers @EmeraldOx 'n @PainterProphet 'ave agreed t' help ye summon th' beast. Can ye stop th' Serp'nt o' Distraction?",
"questSnakeCompletion": "Wit' assistance from th' charmers, ye banish th' Serp'nt o' Distraction. Though ye were happy t' help th' inhabitants o' th' Dunes, ye can nah help but feel a wee sad fer yer fallen foe. While ye contemplate th' sights, @LordDarkly approaches ye. \"Thank ye! 'tis nah much, but I hope this can express our gratitude properly.\" He hands ye some Gold 'n... some Snake eggs! Ye will see that majestic animal again aft all.",
"questSnakeBoss": "Serp'nt o' Distraction",
"questSnakeDropSnakeEgg": "Snake (Egg)",
- "questSnakeUnlockText": "Unlocks purchasable Snake eggs in th' Market",
+ "questSnakeUnlockText": "Unlocks Snake Eggs ye kin purchase in th' Market",
"questUnicornText": "Convincing th' Unicorn Queen",
- "questUnicornNotes": "Conquest Creek has become muddied, destroying Habit City's fresh water supply! Luckily, @Lukreja knows an old legend that claims that a unicorn's horn can purify the foulest of waters. Together with your intrepid guide @UncommonCriminal, you hike through the frozen peaks of the Meandering Mountains. Finally, at the icy summit of Mount Habitica itself, you find the Unicorn Queen amid the glittering snows. \"Your pleas are compelling,\" she tells you. \"But first you must prove that you are worthy of my aid!\"",
- "questUnicornCompletion": "Impressed by your diligence and strength, the Unicorn Queen at last agrees that your cause is worthy. She allows you to ride on her back as she soars to the source of Conquest Creek. As she lowers her golden horn to the befouled waters, a brilliant blue light rises from the water’s surface. It is so blinding that you are forced to close your eyes. When you open them a moment later, the unicorn is gone. However, @rosiesully lets out a cry of delight: the water is now clear, and three shining eggs rest at the creek’s edge.",
+ "questUnicornNotes": "Conquest Creek 'as become muddied, destroyin' Habit City's fresh water supply! Luckily, @Lukreja knows an ol' legend what claims a unicorn's 'orn kin purify th' foulest o' waters. Together wi' yer able guide @UncommonCriminal, ye hike through th' frozen peaks o' th' Meanderin' Mountains. Finally, at th' icy summit o' Mount Habitica itself, ye find th' Unicorn Queen amid th' glitterin' snows. \"Your pleas are compelling,\" she tells ye. \"But first you must prove that you are worthy of my aid!\"",
+ "questUnicornCompletion": "Impressed by yer diligence an' strength, th' Unicorn Queen at last agrees that yer cause be worthy. She allows ye t' ride on 'er back as she soars t' th' source o' Conquest Creek. As she lowers 'er golden horn t' th' befouled waters, a brigh' blue light rises from th' water’s surface. It be so blindin' that ye be forced ta close yer eyes. When ye open 'em a moment later, th' unicorn be gone. 'Owever, @rosiesully lets out a cry o' delight: th' water now be clear, an' three shinin' eggs rest at th' creek’s edge.",
"questUnicornBoss": "Th' Unicorn Queen",
"questUnicornDropUnicornEgg": "Unicorn (Egg)",
- "questUnicornUnlockText": "Unlocks purchasable Unicorn eggs in th' Market",
+ "questUnicornUnlockText": "Unlocks Unicorn Eggs ye kin purchase in th' Market",
"questSabretoothText": "Th' Sabre Cat",
"questSabretoothNotes": "A roaring monster is terrorizing Habitica! The creature stalks through the wilds and woods, then bursts forth to attack before vanishing again. It's been hunting innocent pandas and frightening the flying pigs into fleeing their pens to roost in the trees. @InspectorCaracal and @icefelis explain that the Zombie Sabre Cat was set free while they were excavating in the ancient, untouched ice-fields of the Stoïkalm Steppes. \"It was perfectly friendly at first – I don't know what happened. Please, you have to help us recapture it! Only a champion of Habitica can subdue this prehistoric beast!\"",
"questSabretoothCompletion": "After a long and tiring battle, you wrestle the Zombie Sabre Cat to the ground. As you are finally able to approach, you notice a nasty cavity in one of its sabre teeth. Realising the true cause of the cat's wrath, you're able to get the cavity filled by @Fandekasp, and advise everyone to avoid feeding their friend sweets in future. The Sabre Cat flourishes, and in gratitude, its tamers send you a generous reward – a clutch of sabretooth eggs!",
diff --git a/website/common/locales/en@pirate/settings.json b/website/common/locales/en@pirate/settings.json
index 17b227a9e8..71456c513a 100644
--- a/website/common/locales/en@pirate/settings.json
+++ b/website/common/locales/en@pirate/settings.json
@@ -205,5 +205,6 @@
"usernameNotVerified": "Please confirm yer seaname.",
"changeUsernameDisclaimer": "We shall be transitionin' login names t' unique, public seanames soon. This seaname will be used fer invitations, @mentions in chat, 'n messagin'.",
"verifyUsernameVeteranPet": "One o' these Veteran Pets will be waitin' fer ye after ye've finish'd confirmin'!",
- "subscriptionReminders": "Don' ferget about yer Subscriptions"
+ "subscriptionReminders": "Don' ferget about yer Subscriptions",
+ "newPMNotificationTitle": "New Message from <%= name %>"
}
diff --git a/website/common/locales/es/achievements.json b/website/common/locales/es/achievements.json
index e95a8967c8..3fd11d9e87 100644
--- a/website/common/locales/es/achievements.json
+++ b/website/common/locales/es/achievements.json
@@ -14,9 +14,17 @@
"achievementJustAddWaterText": "Ha completado las misiones del Pulpo, el Caballito de Mar, la Ballena, la Tortuga, el Nudibranquio, la Serpiente Marina, y el Delfín.",
"achievementJustAddWaterModalText": "¡Completaste las misiones del Pulpo, el Caballito de Mar, la Ballena, la Tortuga, el Nudibranquio, la Serpiente Marina, y el Delfín!",
"achievementBackToBasics": "Volver a lo Básico",
- "achievementBackToBasicsText": "Ha coleccionado todas las Mascotas Básicas.",
- "achievementBackToBasicsModalText": "¡Coleccionaste todas las Mascotas Básicas!",
+ "achievementBackToBasicsText": "Ha conseguido todas las Mascotas Básicas.",
+ "achievementBackToBasicsModalText": "¡Conseguiste todas las Mascotas Básicas!",
"achievementAllYourBase": "Toda tu Base",
- "achievementAllYourBaseText": "Ha domado todos los Montes Básicos.",
- "achievementAllYourBaseModalText": "¡Domaste todos los Montes Básicos!"
+ "achievementAllYourBaseText": "Ha domado todas las Monturas Básicas.",
+ "achievementAllYourBaseModalText": "¡Domaste todas las Monturas Básicas!",
+ "achievementKickstarter2019Text": "Apoyó el Proyecto de Kickstarter de Imperdibles de 2019",
+ "achievementKickstarter2019": "Sponsor Imperdibles de Kickstarter",
+ "achievementAridAuthorityModalText": "¡Domaste todas las Monturas Desérticas!",
+ "achievementAridAuthorityText": "Ha domado todas las Monturas Desérticas.",
+ "achievementAridAuthority": "Autoridad Árida",
+ "achievementDustDevilModalText": "¡Conseguiste todas las Mascotas Desérticas!",
+ "achievementDustDevilText": "Ha conseguido todas las Mascotas Desérticas.",
+ "achievementDustDevil": "Remolino de Polvo"
}
diff --git a/website/common/locales/es/backgrounds.json b/website/common/locales/es/backgrounds.json
index bebb973eff..bbd9aa08ce 100644
--- a/website/common/locales/es/backgrounds.json
+++ b/website/common/locales/es/backgrounds.json
@@ -430,28 +430,28 @@
"backgroundHalflingsHouseNotes": "Visita un encantador Hogar de Mestizo.",
"backgroundBlossomingDesertText": "Desierto Floreciente",
"backgroundBlossomingDesertNotes": "Presencia una extraordinaria floración en el Desierto Floreciente.",
- "backgrounds052019": "60.º: mayo de 2019",
+ "backgrounds052019": "60.ª serie: mayo de 2019",
"backgroundDojoText": "Dojo",
"backgroundDojoNotes": "Aprende nuevos movimientos en un Dojo.",
"backgroundParkWithStatueText": "Parque con Estatua",
"backgroundParkWithStatueNotes": "Sigue un camino forrado con flores por un Parque con una Estatua.",
"backgroundRainbowMeadowText": "Campo Arco Iris",
"backgroundRainbowMeadowNotes": "Encuentra la olla de ora donde el Arco Iris termina en un Campo.",
- "backgrounds062019": "61.º serie: junio de 2019",
+ "backgrounds062019": "61.ª serie: junio de 2019",
"backgroundSchoolOfFishText": "Cardumen",
"backgroundSchoolOfFishNotes": "Nada en un Cardumen.",
"backgroundSeasideCliffsText": "Precipicios Costeros",
"backgroundSeasideCliffsNotes": "Quédate en una playa con la belleza de las Precipicios Costeros arriba.",
"backgroundUnderwaterVentsText": "Ventilaciónes Submarinas",
"backgroundUnderwaterVentsNotes": "Zambúllete abajo a las Ventilaciones Submarinas.",
- "backgrounds072019": "62.º: julio de 2019",
+ "backgrounds072019": "62.ª serie: julio de 2019",
"backgroundLakeWithFloatingLanternsText": "Lago con Linternas Flotantes",
"backgroundLakeWithFloatingLanternsNotes": "Mira las estrellas de la atmósfera festiva de una Lago con Linternas Flotantes.",
"backgroundFlyingOverTropicalIslandsText": "Volando sobre Islas Tropicales",
"backgroundFlyingOverTropicalIslandsNotes": "Deja que la vista te quite el aliento mientras Vuelas sobre Islas Tropicales.",
"backgroundAmongGiantAnemonesText": "Entre Anémonas Gigantes",
"backgroundAmongGiantAnemonesNotes": "Explora la vida del arrecife, protegido de depredadores Entre Anémonas Gigantes.",
- "backgrounds082019": "63.º serie: agosto de 2019",
+ "backgrounds082019": "63.ª serie: agosto de 2019",
"backgroundAmidAncientRuinsText": "Entre Ruinas Antiguas",
"backgroundAmidAncientRuinsNotes": "Quédate en reverencia del pasado misterioso Entre Ruinas Antiguas.",
"backgroundGiantDandelionsText": "Dientes de León Gigantes",
@@ -464,5 +464,12 @@
"backgroundInAClassroomText": "Clase",
"backgroundInAnAncientTombText": "Tumba antigua",
"backgroundAutumnFlowerGardenText": "Jardín de flores de otoño",
- "backgrounds092019": "SET 64: Lanzado en septiembre de 2019"
+ "backgrounds092019": "64.ª serie: septiembre de 2019",
+ "backgroundMonsterMakersWorkshopNotes": "Experimenta con ciencias desacreditadas en el Taller del Creador de Monstruos.",
+ "backgroundMonsterMakersWorkshopText": "Taller del Creador de Monstruos",
+ "backgroundPumpkinCarriageNotes": "Móntate en una Carroza de Calabaza antes de que el reloj marque la medianoche.",
+ "backgroundPumpkinCarriageText": "Carroza de Calabaza",
+ "backgroundFoggyMoorNotes": "Cuida tus pasos al atravesar un Páramo Brumoso.",
+ "backgroundFoggyMoorText": "Páramo Brumoso",
+ "backgrounds102019": "65.ª serie: octubre de 2019"
}
diff --git a/website/common/locales/es/content.json b/website/common/locales/es/content.json
index 487a7731cf..2bce38d18f 100644
--- a/website/common/locales/es/content.json
+++ b/website/common/locales/es/content.json
@@ -212,7 +212,7 @@
"hatchingPotionFrost": "Escarcha",
"hatchingPotionIcySnow": "Nieve Glacial",
"hatchingPotionNotes": "Vierte esto en un huevo y eclosionará como una mascota <%= potText(locale) %>.",
- "premiumPotionAddlNotes": "No puede usarse en huevos de mascota de misión.",
+ "premiumPotionAddlNotes": "No puede usarse en huevos de Mascotas de Misiones. Disponible para su compra hasta <%= date(locale) %>.",
"foodMeat": "Carne",
"foodMeatThe": "La Carne",
"foodMeatA": "Carne",
@@ -346,5 +346,9 @@
"hatchingPotionSunshine": "Solar",
"hatchingPotionBronze": "Bronce",
"hatchingPotionWatery": "Aguado",
- "hatchingPotionSilver": "Plata"
+ "hatchingPotionSilver": "Plata",
+ "hatchingPotionShadow": "Sombrío",
+ "questEggRobotAdjective": "un futurista",
+ "questEggRobotMountText": "Robot",
+ "questEggRobotText": "Robot"
}
diff --git a/website/common/locales/es/death.json b/website/common/locales/es/death.json
index 4aeae14d46..8fd72a6c1f 100644
--- a/website/common/locales/es/death.json
+++ b/website/common/locales/es/death.json
@@ -2,16 +2,16 @@
"lostAllHealth": "¡Te quedaste sin Salud!",
"dontDespair": "¡No te desesperes!",
"deathPenaltyDetails": "Has perdido un Nivel, tu Oro y una pieza de equipamiento, ¡pero puedes recuperarlos todos con trabajo duro! Buena suerte--lo harás genial.",
- "refillHealthTryAgain": "Rellena la salud y vuelve a intentarlo",
+ "refillHealthTryAgain": "Rellenar la salud y volver a intentarlo",
"dyingOftenTips": "¿Pasa esto a menudo? ¡Aqui tienes ayuda!",
"losingHealthWarning": "¡Cuidado, estás perdiendo salud!",
"losingHealthWarning2": "¡No dejes que tu salud baje a cero! Si lo haces, perderás un nivel, tu oro y una pieza de equipamiento.",
"toRegainHealth": "Para recuperar salud:",
- "lowHealthTips1": "Sube de nivel y te curarás del todo.",
+ "lowHealthTips1": "Sube de nivel y te curarás del todo",
"lowHealthTips2": "Compra una Poción de Salud en la columna Recompensas para recuperar 15 puntos de salud.",
"losingHealthQuickly": "¿Estás perdiendo salud muy rápido?",
"lowHealthTips3": "Las tareas diarias que no cumples te dañan por la noche: no añadas demasiadas al principio.",
"lowHealthTips4": "Si tienes alguna tarea diaria que no sea necesario realizar un día concreto, haz clic en el icono del lápiz y desactiva ese día.",
"goodLuck": "¡Buena suerte!",
"cannotRevive": "No puedes revivir si no has muerto"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/es/defaulttasks.json b/website/common/locales/es/defaulttasks.json
index 7f39004756..6aedfe386a 100644
--- a/website/common/locales/es/defaulttasks.json
+++ b/website/common/locales/es/defaulttasks.json
@@ -24,5 +24,42 @@
"defaultTag4": "Estudios",
"defaultTag5": "Equipos",
"defaultTag6": "Tareas de casa",
- "defaultTag7": "Creatividad"
-}
\ No newline at end of file
+ "defaultTag7": "Creatividad",
+ "defaultHabitNotes": "O elimínalo en la pantalla de edición",
+ "defaultHabitText": "Pulsa aquí para cambiar esto por un mal hábito que te gustaría abandonar",
+ "creativityTodoNotes": "Toca para especificar el nombre de tu proyecto",
+ "creativityTodoText": "Terminar proyecto creativo",
+ "creativityDailyNotes": "¡Toca para especificar el nombre de tu proyecto actual + definir el programa!",
+ "creativityDailyText": "Trabaja en un proyecto creativo",
+ "creativityHabit": "Estudiar a un maestro del arte >> + Practicar una nueva técnica creativa",
+ "choresTodoNotes": "¡Toca para especificar el área ordenada!",
+ "choresTodoText": "Organizar placard >> Organizar el desorden",
+ "choresDailyNotes": "¡Toca para elegir tu programa!",
+ "choresDailyText": "Lavar los platos",
+ "choresHabit": "Limpiar durante 10 minutos",
+ "selfCareTodoNotes": "¡Toca para especificar qué planeas hacer!",
+ "selfCareTodoText": "Involucrarse en una actividad divertida",
+ "selfCareDailyNotes": "¡Toca para elegir tu programa!",
+ "selfCareDailyText": "5 minutos de respiración silenciosa",
+ "selfCareHabit": "Tomar un breve descanso",
+ "schoolTodoNotes": "¡Toca para nombrar al trabajo y elegir una fecha límite!",
+ "schoolTodoText": "Terminar trabajo para la clase",
+ "schoolDailyNotes": "¡Toca para elegir tu programa de tareas!",
+ "schoolDailyText": "Terminar la tarea",
+ "schoolHabit": "Estudiar/Procrastinar",
+ "healthTodoNotes": "¡Toca para añadir listas de tareas!",
+ "healthTodoText": "Revisión de programa >> Piensa en un cambio saludable",
+ "healthDailyNotes": "¡Toca para realizar cambios!",
+ "healthDailyText": "Usar hilo dental",
+ "healthHabit": "Comer comida Saludable/Chatarra",
+ "exerciseTodoNotes": "¡Toca para añadir una lista de tareas!",
+ "exerciseTodoText": "Organizar programa de ejercicio",
+ "exerciseDailyNotes": "¡Toca para definir tu programa y especificar ejercicios!",
+ "exerciseDailyText": "Estirar >> Rutina de ejercicio diario",
+ "exerciseHabit": "10 min cardio >> + 10 minutos de cardio",
+ "workTodoProjectNotes": "Toca para especificar el nombre de tu proyecto actual + determinar una fecha límite",
+ "workTodoProject": "Proyecto de trabajo >> Completar proyecto de trabajo",
+ "workDailyImportantTaskNotes": "Toca para especificar tu tarea más importante",
+ "workDailyImportantTask": "Tarea más importante >> Trabajé en la tarea más importante de hoy",
+ "workHabitMail": "Leer emails"
+}
diff --git a/website/common/locales/es/front.json b/website/common/locales/es/front.json
index ded8867296..0d258ffc04 100644
--- a/website/common/locales/es/front.json
+++ b/website/common/locales/es/front.json
@@ -35,10 +35,10 @@
"companyPrivacy": "Privacidad",
"companyTerms": "Condiciones",
"companyVideos": "Vídeos",
- "contribUse": "Los colaboradores de Habitica utilizan:",
+ "contribUse": "Los colaboradores de Habitica utilizan",
"dragonsilverQuote": "Ya no sé cuánto tiempo ni cuántos sistemas para guardar tareas he probado a lo largo de décadas... [Habitica] es el único que me ayuda realmente a terminar mis tareas y no solo apuntarlas.",
"dreimQuote": "Cuando descubrí [Habitica] el verano pasado, acababa de suspender la mitad de mis exámenes. Gracias a las tareas diarias, conseguí organizarme y tener disciplina y, hace un mes, aprobé todo.",
- "elmiQuote": "Todas las mañanas me apetece levantarme para ganar un poco de oro.",
+ "elmiQuote": "¡Todas las mañanas me apetece levantarme para ganar un poco de oro!",
"forgotPassword": "¿Has olvidado la contraseña?",
"emailNewPass": "Enviar un link de cambio de contraseña",
"forgotPasswordSteps": "Introduce la dirección de correo electrónico que utilizaste para registrarte en Habitica.",
@@ -47,7 +47,7 @@
"examplesHeading": "Los jugadores usan Habitica para gestionar...",
"featureAchievementByline": "¿Has hecho algo increíble? ¡Consigue una insignia y exhíbela!",
"featureAchievementHeading": "Insignias de logros",
- "featureEquipByline": "Compra ediciones limitadas de equipo, pociones y otros objetos virtuales en nuestro Mercado, gracias a las recompensas que obtienes por cumplir tus tareas.",
+ "featureEquipByline": "¡Compra ediciones limitadas de equipo, pociones y otros objetos virtuales en nuestro Mercado, con las recompensas que obtienes por cumplir tus tareas!",
"featureEquipHeading": "Equipo y extras",
"featurePetByline": "Cuando completas tus tareas, aparecen huevos y artículos. Para coleccionar mascotas y monturas, ¡sé tan productivo como puedas!",
"featurePetHeading": "Mascotas y monturas",
@@ -61,9 +61,9 @@
"footerMobile": "Móvil",
"footerSocial": "Social",
"forgotPass": "Olvidé mi contraseña",
- "frabjabulousQuote": "[Habitica] es la razón por la que conseguí un trabajo genial y bien pagado... y algo más milagroso todavía: ahora no me olvido ni un solo día de usar hilo dental.",
+ "frabjabulousQuote": "[Habitica] es la razón por la que conseguí un trabajo genial y bien pagado... y algo más milagroso todavía: ¡ahora no me olvido ni un solo día de usar hilo dental!",
"free": "Únete gratis",
- "gamifyButton": "Convierte tu vida en un juego",
+ "gamifyButton": "¡Convierte tu vida en un juego!",
"goalSample1": "Practicar piano 1 hora",
"goalSample2": "Trabajar en un artículo para publicar",
"goalSample3": "Escribir entrada del blog",
@@ -128,7 +128,7 @@
"mobileIOS": "iOS",
"motivate": "¡Motívate a ti mismo y a tu equipo!",
"motivate1": "Motívate para hacer cualquier cosa.",
- "motivate2": "Organízate. Motívate. Obtén Oro",
+ "motivate2": "Organízate. Motívate. Obtén Oro.",
"oldNews": "Noticias",
"newsArchive": "Archivo de noticias en Wikia (multilingüe)",
"passConfirm": "Confirmar Contraseña",
@@ -188,14 +188,14 @@
"schoolSample4": "Notas para Capitulo 1",
"schoolSample5": "Leer 1 Capítulo",
"sixteenBitFilQuote": "Estoy finalizando mis tareas y trabajos en tiempo record gracias a [Habitica]. ¡Siempre estoy deseando alcanzar mi siguiente nivel!",
- "skysailorQuote": "Mi equipo y nuestras misiones me mantienen comprometido con el juego, lo que me mantiene motivado a hacer las cosas y cambiar mi vida para mejor.",
+ "skysailorQuote": "Mi equipo y nuestras misiones me mantienen comprometido con el juego, lo que me mantiene motivado a hacer las cosas y cambiar mi vida para mejor",
"socialTitle": "Habitica - Tu Vida, Un Juego",
"supermouse35Quote": "¡Estoy haciendo más ejercicio y no he olvidado tomar mis medicinas en meses! Gracias, Habitica. :D",
"sync": "Sincronizar",
"tasks": "Tareas",
"teamSample1": "Borrador del Plan de la Reunión del Martes",
"teamSample2": "Hacks de crecimiento de lluvia de ideas",
- "teamSample3": " Habla sobre los KPI de esta semana",
+ "teamSample3": "Habla sobre los KPI de esta semana",
"teams": "Equipos",
"terms": "Términos y Condiciones",
"testimonialHeading": "Lo que dice la gente...",
@@ -215,13 +215,13 @@
"emailOrUsername": "Correo electrónico o Nombre de usuario (distingue mayúsculas y minúsculas)",
"watchVideos": "Ver Vídeos",
"work": "Trabajar",
- "zelahQuote": "Con [Habitica], Puedo irme a la cama a tiempo pensando en ganar puntos por acostarme pronto o perder salud por hacerlo tarde.",
+ "zelahQuote": "Con [Habitica], puedo irme a la cama a tiempo pensando en ganar puntos por acostarme pronto o perder salud por hacerlo tarde.",
"reportAccountProblems": "Informar de problemas de Cuenta",
"reportCommunityIssues": "Informar de problemas de la Comunidad",
- "subscriptionPaymentIssues": "Problemas en la suscripción o en los pagos.",
+ "subscriptionPaymentIssues": "Problemas en la suscripción o en los pagos",
"generalQuestionsSite": "Preguntas Generales sobre la Web",
"businessInquiries": "Consultas de Empresas/Marketing",
- "merchandiseInquiries": "Consultas de material de merchandasing (camisetas, pegatinas) ",
+ "merchandiseInquiries": "Consultas de material de merchandasing (camisetas, pegatinas)",
"marketingInquiries": "Consultas de Marketing/Social Media",
"tweet": "Tuitear",
"apps": "Aplicaciones",
@@ -238,7 +238,7 @@
"altAttrFastCompany": "Fast Company",
"altAttrKickstarter": "Kickstarter",
"altAttrDiscover": "Discover Magazine",
- "altAttrFrabjabulous": "Frabjabulous:",
+ "altAttrFrabjabulous": "Frabjabulous: ",
"altAttrAlexandraSo": "_AlexandraSo_:",
"altAttrEvaGantz": "EvaGantz:",
"altAttrSupermouse35": "supermouse35:",
@@ -257,8 +257,8 @@
"altAttrGithub": "GitHub",
"altAttrTrello": "Trello",
"altAttrSlack": "Slack",
- "missingAuthHeaders": "Faltan los encabezados de autentificación. ",
- "missingAuthParams": "Faltan los parámetros de autentificación. ",
+ "missingAuthHeaders": "Faltan los encabezados de autentificación.",
+ "missingAuthParams": "Faltan los parámetros de autentificación.",
"missingUsernameEmail": "Falta el nombre de usuario o correo electrónico.",
"missingEmail": "Falta el correo electrónico.",
"missingUsername": "Falta el nombre de usuario.",
@@ -278,7 +278,7 @@
"invalidLoginCredentials": "El nombre de usuario y/o correo electrónico y/o conseña no son correctos.",
"passwordResetPage": "Restablecer Contraseña",
"passwordReset": "Si tenemos constancia de tu correo electrónico, te hemos enviado un mensaje con las instrucciones a seguir para establecer una nueva contraseña.",
- "passwordResetEmailSubject": "Restablecer contraseña para Habitica.",
+ "passwordResetEmailSubject": "Restablecer contraseña para Habitica",
"passwordResetEmailText": "Si has solicitado restablecer la contraseña del usuario <%= username %> en Habitica, entra en <%= passwordResetLink %> para establecer una nueva. El enlace expira tras 24 horas. Si no has solicitado restablecer una contraseña, por favor ignora este mensaje.",
"passwordResetEmailHtml": "Si has solicitado restablecer la contraseña del usuario <%= username %> en Habitica, \">haz clic aquí para establecer una nueva. El enlace expira tras 24 horas.
Si no has solicitado restablecer una contraseña, por favor ignora este mensaje.",
"invalidLoginCredentialsLong": "Oh-oh - tu dirección de correo electrónico o contraseña son incorrectos.\n- Asegúrate de que están escritos correctamente. Tu nombre de inicio de sesión y contraseña distinguen entre mayúsculas y minúsculas.\n- Puede que te hayas registrado con tu cuenta de Google o Facebook en lugar de tu correo electrónico, intenta iniciar sesión con alguna de ellas.\n- Si has olvidado tu contraseña, pulsa sobre \"¿Has olvidado la contraseña?\".",
@@ -287,9 +287,9 @@
"accountSuspendedTitle": "Esta cuenta ha sido suspendida",
"unsupportedNetwork": "La red no está en servicio.",
"cantDetachSocial": "La cuenta carece de otro método de autenticación; no se puede separar de este método de autenticación.",
- "onlySocialAttachLocal": "Solo se puede añadir autenticación local a una cuenta social. ",
- "invalidReqParams": "Parámetros de solicitud no válidos. ",
- "memberIdRequired": "\"member\" debe ser una UUID válida. ",
+ "onlySocialAttachLocal": "Solo se puede añadir autenticación local a una cuenta social.",
+ "invalidReqParams": "Parámetros de solicitud no válidos.",
+ "memberIdRequired": "\"member\" debe ser una UUID válida.",
"heroIdRequired": "\"herold\" debe ser una UUID válida.",
"cannotFulfillReq": "Tu petición no puede ser cumplida. Mánda un email a admin@habitica.com si el error persiste.",
"modelNotFound": "Este modelo no existe.",
@@ -310,15 +310,15 @@
"or": "O",
"gamifyYourLife": "Convierte tu vida en un juego",
"aboutHabitica": "Habitica es una app gratuita de construcción de hábitos y productividad que se toma tu vida real como un juego. Con recompensas y castigos en el juego para motivarte y una fuerte red social para inspirarte, Habitica puede ayudarte a conseguir tus metas para ser saludable, trabajador y feliz.",
- "trackYourGoals": "Registra tus Hábitos y Objetivos.",
- "trackYourGoalsDesc": "Mantente responsable siguiendo y manteniendo tus Hábitos, Tareas Diarias y Tareas Pendientes con las apps para móvil de habitica y la página web, ambas fáciles de usar. ",
+ "trackYourGoals": "Registra tus Hábitos y Objetivos",
+ "trackYourGoalsDesc": "Mantente responsable siguiendo y manteniendo tus Hábitos, Tareas Diarias y Tareas Pendientes con las apps para móvil de habitica y la página web, ambas fáciles de usar.",
"earnRewards": "Consigue Recompensas por tus Objetivos",
"earnRewardsDesc": "¡Tacha las tareas para subir el nivel de tu Avatar, y desbloquea características dentro del juego como armaduras de batalla, mascotas misteriosas, habilidades mágicas e incluso misiones!",
"battleMonsters": "Lucha contra monstruos con tus amigos",
"battleMonstersDesc": "¡Lucha contra monstruos con otros usuarios de Habitica! Utiliza el Oro que ganes para comprar recompensas del juego o personalizadas, como ver un capítulo de tu serie de televisión favorita.",
"playersUseToImprove": "Los jugadores utilizan Habitica para mejorar",
"healthAndFitness": "Salud y Bienestar",
- "healthAndFitnessDesc": "¿Nunca te motiva enjuagarte la boca? ¿No hay manera de que vayas al gimnasio? ¡Habitica por fin hace que mantenerse sano sea divertido!",
+ "healthAndFitnessDesc": "¿Sin motivación para usar hilo dental? ¿No hay manera de que vayas al gimnasio? Habitica por fin hace que mantenerse sano sea divertido.",
"schoolAndWork": "Estudios y Trabajo",
"schoolAndWorkDesc": "Si estás preparando un informe para tu profesor o para tu jefe, es sencillo mantenerte al día con tu progreso abordando tus tareas más complicadas.",
"muchmuchMore": "¡Y mucho, mucho más!",
diff --git a/website/common/locales/es/gear.json b/website/common/locales/es/gear.json
index ed8ced2045..0e360afbc7 100644
--- a/website/common/locales/es/gear.json
+++ b/website/common/locales/es/gear.json
@@ -25,9 +25,9 @@
"weaponWarrior0Text": "Espada de entrenamiento",
"weaponWarrior0Notes": "Arma de práctica. No otorga ningún beneficio.",
"weaponWarrior1Text": "Espada",
- "weaponWarrior1Notes": "Espada común de un soldado. Incrementa la Fuerza en <%= str %>.",
+ "weaponWarrior1Notes": "Espada común de un soldado. Aumenta la Fuerza en <%= str %>.",
"weaponWarrior2Text": "Hacha",
- "weaponWarrior2Notes": "Arma cortante de doble filo. Incrementa la fuerza en <%= str %>",
+ "weaponWarrior2Notes": "Arma cortante de doble filo. Aumenta la fuerza en <%= str %>",
"weaponWarrior3Text": "Lucero del alba",
"weaponWarrior3Notes": "Maza pesada con brutales espinas . Incrementa la Fuerza en <%= str %>.",
"weaponWarrior4Text": "Espada de Zafiro",
@@ -61,9 +61,9 @@
"weaponWizard4Text": "Báculo de latón",
"weaponWizard4Notes": "Tan fuerte como pesado. Aumenta la Inteligencia por <%= int %> y la Percepción por <%= per %>.",
"weaponWizard5Text": "Báculo de archimago",
- "weaponWizard5Notes": "Ayuda a lanzar los hechizos más complejos. Incrementa Inteligencia en <%= int %> y Percepción en <%= per %>.",
+ "weaponWizard5Notes": "Ayuda a lanzar los hechizos más complejos. Aumenta la Inteligencia por <%= int %> y la Percepción por <%= per %>.",
"weaponWizard6Text": "Báculo dorado",
- "weaponWizard6Notes": "Hecho de oricalco, el oro alquímico más fuerte y raro. Incrementa Inteligencia en <%= int %> y Percepción en <%= per %>.",
+ "weaponWizard6Notes": "Hecho de oricalco, el oro alquímico más fuerte y raro. Aumenta la Inteligencia por <%= int %> y la Percepción por <%= per %>.",
"weaponHealer0Text": "Vara de novato",
"weaponHealer0Notes": "Para sanadores en entrenamiento. No aporta ningún beneficio.",
"weaponHealer1Text": "Vara de acólito",
@@ -93,13 +93,13 @@
"weaponSpecialTridentOfCrashingTidesText": "Tridente de Poderosas Mareas",
"weaponSpecialTridentOfCrashingTidesNotes": "Te da la habilidad de pedir pescado, y también repartir algunas poderosas puñaladas a tus tareas. Aumenta la Inteligencia en <%= int %>.",
"weaponSpecialTaskwoodsLanternText": "Linterna del Bosque-tarea",
- "weaponSpecialTaskwoodsLanternNotes": "Dado al amanecer al guardián fantasma de los Huertos de Bosquetarea, esta linterna puede iluminar la más profunda oscuridad y urdir poderosos conjuros. Aumenta la Percepción y la Inteligencia en <%= attrs %>cada una.",
+ "weaponSpecialTaskwoodsLanternNotes": "Dado al amanecer al guardián fantasma de los Huertos de Bosquetarea, esta linterna puede iluminar la más profunda oscuridad y urdir poderosos conjuros. Aumenta la Percepción y la Inteligencia por <%= attrs %> cada una.",
"weaponSpecialBardInstrumentText": "Laúd de bardo",
- "weaponSpecialBardInstrumentNotes": "¡Toca una alegre melodía con este laúd mágico! Suma <%= attrs %> de inteligencia y <%= attrs %> de percepción.",
+ "weaponSpecialBardInstrumentNotes": "¡Toca una alegre melodía con este laúd mágico! Aumenta la Inteligencia por <%= attrs %> y la Percepción por <%= attrs %>.",
"weaponSpecialLunarScytheText": "Guadaña lunar",
- "weaponSpecialLunarScytheNotes": "Encera esta guadaña a menudo o perderá su poder. Suma <%= attrs %> de fuerza y <%= attrs %> de percepción.",
+ "weaponSpecialLunarScytheNotes": "Encera esta guadaña a menudo o perderá su poder. Aumenta la Fuerza por <%= attrs %> y la Percepción por <%= attrs %>.",
"weaponSpecialMammothRiderSpearText": "Arpón de jinete de mamut",
- "weaponSpecialMammothRiderSpearNotes": "Este arpón con punta de cuarzo rosa te envolverá en sus milenarios poderes hechizantes. Suma <%= int %> de inteligencia.",
+ "weaponSpecialMammothRiderSpearNotes": "Este arpón con punta de cuarzo rosa te envolverá en sus milenarios poderes hechizantes. Aumenta la Inteligencia en <%= int %>.",
"weaponSpecialPageBannerText": "Estandarte de Paje",
"weaponSpecialPageBannerNotes": "¡Ondea bien alto tu estandarte para inspirar confianza! Aumenta la Fuerza en <%= str %>.",
"weaponSpecialRoguishRainbowMessageText": "Mensaje arco iris pícaro",
@@ -1773,5 +1773,9 @@
"weaponSpecialSpring2019MageText": "Vara de Ambar",
"weaponSpecialSpring2019HealerNotes": "Tu canción sobre las flores y la lluvia calmará los espíritus de todos los que la oigan. Mejora la inteligencia en <%= int %>. Lote de edición limitada de la primavera de 2019.",
"weaponSpecialSpring2019HealerText": "Canto primaveral",
- "weaponSpecialSpring2019MageNotes": "¡Hay un mosquito atrapado en la piedra al final de esta vara! Puede (o puede que no) tenga ADN de dinosaurio. Mejora la inteligencia en <%= int %> y la percepción en <%= per %>. Lote de Edición Limitada de la primavera de 2019."
+ "weaponSpecialSpring2019MageNotes": "¡Hay un mosquito atrapado en la piedra al final de esta vara! Puede (o puede que no) tenga ADN de dinosaurio. Mejora la inteligencia en <%= int %> y la percepción en <%= per %>. Lote de Edición Limitada de la primavera de 2019.",
+ "weaponArmoireAstronomersTelescopeText": "Telescopio de Astronomo",
+ "weaponSpecialSummer2019HealerText": "Varita de Burbujas",
+ "weaponSpecialSummer2019RogueText": "Ancla Anticuada",
+ "weaponSpecialSummer2019WarriorText": "Coral Rojo"
}
diff --git a/website/common/locales/es/generic.json b/website/common/locales/es/generic.json
index bae759dd2e..d4015db882 100644
--- a/website/common/locales/es/generic.json
+++ b/website/common/locales/es/generic.json
@@ -293,5 +293,6 @@
"contactForm": "Contacta al Equipo de Moderadores",
"options": "Opciones",
"demo": "Demo",
- "loadEarlierMessages": "Cargar Mensajes Anteriores"
+ "loadEarlierMessages": "Cargar Mensajes Anteriores",
+ "finish": "Terminar"
}
diff --git a/website/common/locales/es/groups.json b/website/common/locales/es/groups.json
index 64969e48ce..e114f55f04 100644
--- a/website/common/locales/es/groups.json
+++ b/website/common/locales/es/groups.json
@@ -250,19 +250,19 @@
"onlyGroupLeaderCanEditTasks": "¡No estás autorizado para manejar las tareas!",
"onlyGroupTasksCanBeAssigned": "Sólo pueden ser asignadas tareas del grupo.",
"assignedTo": "Asignado a",
- "assignedToUser": "Asignado a <%= userName %>",
- "assignedToMembers": "Asignado a <%= userCount %> miembros",
- "assignedToYouAndMembers": "Asignado a <%= userCount %> miembros y a ti",
+ "assignedToUser": "Asignado a <%= userName %>",
+ "assignedToMembers": "Asignado a <%= userCount %> members",
+ "assignedToYouAndMembers": "Asignado a <%= userCount %> members miembros y a ti",
"youAreAssigned": "Estás asignado a esta tarea",
"taskIsUnassigned": "Esta tarea está sin asignar",
"confirmClaim": "¿Estás seguro de querer reclamar esta tarea?",
"confirmUnClaim": "¿Estás seguro de querer cancelar esta tarea?",
"confirmApproval": "¿Estás seguro de querer aprobar esta tarea?",
"confirmNeedsWork": "¿Estás seguro de querer marcar esta tarea como trabajo necesario?",
- "userRequestsApproval": "<%= userName %>requieren aprobación",
- "userCountRequestsApproval": "<%= userCount %> miembros requieren aprobación",
+ "userRequestsApproval": "<%= userName %> requieren aprobación",
+ "userCountRequestsApproval": "<%= userCount %> members miembros requieren aprobación",
"youAreRequestingApproval": "Estás solicitando aprobación",
- "chatPrivilegesRevoked": "No puedes hacer eso porque tus privilegios para chatear han sido revocados.",
+ "chatPrivilegesRevoked": "No puedes hacer esto porque tus privilegios de chat han sido removidos. Para obtener detalles o preguntar si tus privilegios pueden ser devueltos, por favor envía un correo a nuestro Community Manager vía admin@habitica.com o pide a tus padres o tutor que lo hagan. Por favor incluye tu @NombreDeUsuario en el correo. Si un moderador ya te ha dicho que tu exclusión del chat es temporal, no necesitas mandar un correo.",
"cannotCreatePublicGuildWhenMuted": "No puedes crear un gremio público porque tus privilegios para chatear han sido revocados.",
"cannotInviteWhenMuted": "No puedes invitar a nadie a un gremio o equipo porque tus privilegios para chatear han sido revocados.",
"newChatMessagePlainNotification": "Nuevo mensaje en <%= groupName %> de <%= authorName %>. ¡Haz click aquí para abrir la pagina de chat!",
@@ -277,10 +277,10 @@
"confirmRemoveTag": "¿De verdad quieres eliminar \"<%= tag %>\"?",
"groupHomeTitle": "Inicio",
"assignTask": "Asignar Tarea",
- "claim": "Reclama",
+ "claim": "Reclamar Tarea",
"removeClaim": "Eliminar Reclamación",
"onlyGroupLeaderCanManageSubscription": "Solo el lider de grupo puede manejar las subscripciones de grupo",
- "yourTaskHasBeenApproved": "Tu tarea <%= taskText %> ha sido aprobada.",
+ "yourTaskHasBeenApproved": "Tu tarea <%= taskText %> ha sido aprobada.",
"taskNeedsWork": "<%= managerName %> ha marcado <%= taskText %> ya que necesita trabajo adicional.",
"userHasRequestedTaskApproval": "<%= user %> pide aprobación para <%= taskName %>",
"approve": "Aprobar",
@@ -341,8 +341,8 @@
"leaderCannotLeaveGroupWithActiveGroup": "Un líder no puede abandonar un grupo mientras el grupo tenga un plan activo",
"youHaveGroupPlan": "Tienes una suscripción gratuita ya que eres miembro de un grupo que tiene un Plan de Grupo. Acabará cuando dejes de estar en el grupo que tiene un Plan de Grupo. Cualquier saldo mensual de suscripción adicional será aplicado al terminar el Plan de Grupo.",
"cancelGroupSub": "Cancelar plan de grupo",
- "confirmCancelGroupPlan": "¿Estás seguro de que quieres cancelar el plan de grupo y eliminar los beneficios de todos los miembros, incluyendo sus suscripciones gratuitas?",
- "canceledGroupPlan": "Plan de grupo cancelado",
+ "confirmCancelGroupPlan": "¿Estás seguro de que quieres cancelar tu Plan de Grupo? Todos los miembros del Grupo perderán sus suscripciones y beneficios.",
+ "canceledGroupPlan": "Plan de Grupo Cancelado",
"groupPlanCanceled": "El plan de grupo se volverá inactivo el",
"purchasedGroupPlanPlanExtraMonths": "Tienes <%= months %> meses de saldo extra de plan de grupo.",
"addManager": "Asignar Administrador",
@@ -480,5 +480,9 @@
"recurringCompletion": "Ninguno - La tarea de grupo no ha sido completada",
"singleCompletion": "Único - Se completa cuando cualquiera de los usuarios a los que haya sido asignada la termina",
"allAssignedCompletion": "Todos - Se completa cuando todos los usuarios a los que ha sido asignada la terminan",
- "pmReported": "Gracias por reportar este mensaje."
+ "pmReported": "Gracias por reportar este mensaje.",
+ "groupActivityNotificationTitle": "<%= user %> publicó en <%= group %>",
+ "suggestedGroup": "Sugerido porque eres nuevo en Habitica.",
+ "taskClaimed": "<%= userName %> ha reclamado la tarea <%= taskText %>.",
+ "youHaveBeenAssignedTask": "<%= managerName %> te ha asignado la tarea <%= taskText %>."
}
diff --git a/website/common/locales/es/limited.json b/website/common/locales/es/limited.json
index a540727151..f6b3af0a33 100644
--- a/website/common/locales/es/limited.json
+++ b/website/common/locales/es/limited.json
@@ -155,5 +155,17 @@
"spring2019OrchidWarriorSet": "Orquídea (Guerrero)",
"spring2019AmberMageSet": "Ámbar (Mago)",
"spring2019RobinHealerSet": "Petirrojo (Sanador)",
- "spring2019CloudRogueSet": "Nube (Pícaro)"
+ "spring2019CloudRogueSet": "Nube (Pícaro)",
+ "september2018": "Septiembre del 2018",
+ "september2017": "Septiembre del 2017",
+ "june2018": "Junio 2018",
+ "eventAvailabilityReturning": "Disponible para su compra hasta <%= availableDate(locale) %>. Esta poción estuvo disponible por última vez el <%= previousDate(locale) %>.",
+ "fall2019RavenSet": "Cuervo (Guerrero)",
+ "fall2019LichSet": "Liche (Sanador)",
+ "fall2019CyclopsSet": "Cíclope (Mago)",
+ "fall2019OperaticSpecterSet": "Espectro Operístico (Pícaro)",
+ "summer2019HammerheadRogueSet": "Cabeza de Martillo (Pícaro)",
+ "summer2019ConchHealerSet": "Caracola (Sanador)",
+ "summer2019WaterLilyMageSet": "Nenúfar (Mago)",
+ "summer2019SeaTurtleWarriorSet": "Tortuga Marina (Guerrero)"
}
diff --git a/website/common/locales/es/loadingscreentips.json b/website/common/locales/es/loadingscreentips.json
index b1755849f7..b07c64b925 100644
--- a/website/common/locales/es/loadingscreentips.json
+++ b/website/common/locales/es/loadingscreentips.json
@@ -10,7 +10,7 @@
"tip8": "¡Envía un mensaje a alguien pulsando su nombre en el chat y luego el icono del sobre sobre su perfil!",
"tip9": "Usa los filtros + la barra de búsqueda en inventarios, tiendas, Gremios y retos para encontrar rápidamente lo que quieres.",
"tip10": "Puedes ganar gemas participando en desafíos. ¡Todos los días se añaden nuevos!",
- "tip11": "¡Tener más de cuatro miembros en tu Equipo incrementa la responsabilidad!",
+ "tip11": "¡Tener más de cuatro miembros en tu Equipo aumenta la responsabilidad!",
"tip12": "¡Añade listas a tus Tareas Pendientes para multiplicar tus recompensas!",
"tip13": "¡Haz click en \"Etiquetas\" en tu página de tareas para hacer una lista de tareas poco manejable en algo que puedas manejar!",
"tip14": "Puedes añadir títulos de sección o frases inspiradoras a tu lista: añádelos como hábitos y quítales los signos + y -.",
diff --git a/website/common/locales/es/npc.json b/website/common/locales/es/npc.json
index d949ae8969..ad096b34fa 100644
--- a/website/common/locales/es/npc.json
+++ b/website/common/locales/es/npc.json
@@ -94,7 +94,7 @@
"invalidQuantity": "La cantidad a comprar tiene que ser un número.",
"USD": "(USD)",
"newStuff": "Cosas Nuevas de Bailey",
- "newBaileyUpdate": "¡Nueva Actualización de Bailey!",
+ "newBaileyUpdate": "¡Nuevas Novedades de Bailey!",
"tellMeLater": "Dímelo más tarde",
"dismissAlert": "Descartar este aviso",
"donateText1": "Añade 20 Gemas a tu cuenta. Las Gemas se usan para comprar objetos especiales en el juego, como camisetas y peinados.",
diff --git a/website/common/locales/es/pets.json b/website/common/locales/es/pets.json
index 1d9e5b703c..0391630217 100644
--- a/website/common/locales/es/pets.json
+++ b/website/common/locales/es/pets.json
@@ -56,18 +56,18 @@
"premiumPotionNoDropExplanation": "Las pociones de eclosión mágicas no se pueden usar en los huevos recibidos por completar misiones. La única forma de conseguir estas pociones es comprándolas más abajo: nunca aparecen al azar como botín.",
"beastMasterProgress": "Progreso como domador de bestias",
"stableBeastMasterProgress": "Progreso como domador de bestias: <%= number %> mascotas encontradas",
- "beastAchievement": "¡Has ganado el logro \"Maestro de Bestias\" por conseguir todas las mascotas!",
- "beastMasterName": "Domador de bestias",
+ "beastAchievement": "¡Has conseguido el logro \"Domador de Bestias\" por conseguir todas las mascotas!",
+ "beastMasterName": "Domador de Bestias",
"beastMasterText": "Ha encontrado las 90 mascotas. (Increíblemente difícil, ¡felicita a este usuario!)",
"beastMasterText2": "y ha soltado sus mascotas un total de <%= count %> vez(/veces)",
"mountMasterProgress": "Progreso como maestro de monturas",
"stableMountMasterProgress": "Progreso como maestro de monturas: <%= number %> monturas domadas",
"mountAchievement": "¡Has obtenido el logro «Maestro de monturas» por domar a todas las monturas!",
- "mountMasterName": "Maestro de monturas",
+ "mountMasterName": "Maestro de Monturas",
"mountMasterText": "Has domado a las 90 monturas. (Aún más difícil, ¡felicita a este usuario!)",
"mountMasterText2": "y ha soltado todas las 90 monturas un total de <%= count %> vez(/veces)",
- "beastMountMasterName": "Domador de bestias y Maestro de monturas",
- "triadBingoName": "Bingo tríada",
+ "beastMountMasterName": "Domador de Bestias y Maestro de Monturas",
+ "triadBingoName": "Triple Bingo",
"triadBingoText": "Ha encontrado a las 90 mascotas, las 90 monturas y las 90 mascotas una vez más. (¡¿Cómo es posible?!)",
"triadBingoText2": "y ha liberado a todo el establo <%= count %> vez(/veces) en total",
"triadBingoAchievement": "¡Has obtenido el logro «Bingo tríada» por haber encontrado a todas las mascotas, domado a todas las monturas y encontrado a todas las mascotas otra vez!",
@@ -144,5 +144,6 @@
"notEnoughMounts": "No has reunido suficientes monturas",
"notEnoughPetsMounts": "No has reunido suficientes mascotas ni monturas",
"wackyPets": "Mascotas Chifladas",
- "filterByWacky": "Chiflado"
+ "filterByWacky": "Chiflado",
+ "gryphatrice": "Grifotriz"
}
diff --git a/website/common/locales/es/quests.json b/website/common/locales/es/quests.json
index 8bf771b590..a33dc0fc45 100644
--- a/website/common/locales/es/quests.json
+++ b/website/common/locales/es/quests.json
@@ -126,5 +126,16 @@
"bossHealth": "<%= currentHealth %> / <%= maxHealth %> Salud",
"rageAttack": "Ataque de Ira:",
"bossRage": "<%= currentRage %> / <%= maxRage %> Ira",
- "rageStrikes": "Golpes de Ira"
+ "rageStrikes": "Golpes de Ira",
+ "tavernBossTired": "<%= bossName %> intenta lanzar <%= rageName %> pero se encuentra demasiado cansado.",
+ "chatQuestCancelled": "<%= username %> canceló la misión <%= questName %>.",
+ "chatQuestAborted": "<%= username %> abortó la misión <%= questName %>.",
+ "chatItemQuestFinish": "¡Todos los objetos encontrados! El equipo ha recibido su recompensa.",
+ "chatFindItems": "<%= username %> encontró <%= items %>.",
+ "chatBossDefeated": "¡Derrotásteis a <%= bossName %>! Los miembros del equipo que participaron de la misión reciben las recompensas de la victoria.",
+ "chatBossDontAttack": "<%= username %> ataca a <%= bossName %> por <%= userDamage %> puntos de daño. <%= bossName %> no ataca, porque tiene en cuenta el hecho de que hay algunos problemas post-mantenimiento, y no quiere herir a nadie de manera injusta. ¡Continuará su devastación pronto!",
+ "chatBossDamage": "<%= username %> ataca a <%= bossName %> por <%= userDamage %> puntos de daño. <%= bossName %> ataca al equipo por <%= bossDamage %> puntos de daño.",
+ "chatQuestStarted": "Tu misión, <%= questName %>, ha comenzado.",
+ "questInvitationNotificationInfo": "Fuiste invitado a unirte a una misión",
+ "hatchingPotionQuests": "Misiones de Pociones de Eclosión Mágicas"
}
diff --git a/website/common/locales/es/settings.json b/website/common/locales/es/settings.json
index bae37a3253..00a908ef98 100644
--- a/website/common/locales/es/settings.json
+++ b/website/common/locales/es/settings.json
@@ -119,8 +119,8 @@
"giftedSubscriptionInfo": "<%= name %> te ha regalado una suscripción de <%= months %> meses",
"giftedSubscriptionFull": "¡Hola <%= username %>, <%= sender %> te ha enviado <%= monthCount %> meses de suscripción!",
"giftedSubscriptionWinterPromo": "¡Hola <%= username %>, recibiste <%= monthCount %> meses de suscripción como parte de nuestra promoción de regalos festivos!",
- "invitedParty": "Invitado al Equipo",
- "invitedGuild": "Invitado al Gremio",
+ "invitedParty": "Has sido invitado a un Equipo",
+ "invitedGuild": "Has sido invitado a un Gremio",
"importantAnnouncements": "Recordatorios para entrar en Habitica, completar tareas y recibir premios",
"weeklyRecaps": "Resumen de la actividad de tu cuenta durante la última semana. (Nota: Esta función está deshabilitada en estos momentos por problemas de rendimiento, pero esperamos poder restablecerla y enviar correos de nuevo muy pronto).",
"onboarding": "Pautas para configurar tu cuenta de Habitica",
@@ -204,5 +204,7 @@
"usernameVerifiedConfirmation": "¡Tu nombre de usuario, <%= username %>, está confirmado!",
"usernameNotVerified": "Por favor, confirma tu nombre de usuario.",
"changeUsernameDisclaimer": "Pronto estaremos haciendo el cambio de nombres de inicio de sesión a nombres de usuario públicos únicos. Este nombre de usuario se usará para invitaciones, @menciones en los chats, y mensajes.",
- "verifyUsernameVeteranPet": "¡Una de estas Mascotas Veteranas te estará esperando cuando hayas terminado de confirmar!"
+ "verifyUsernameVeteranPet": "¡Una de estas Mascotas Veteranas te estará esperando cuando hayas terminado de confirmar!",
+ "subscriptionReminders": "Recordatorios de Suscripciones",
+ "newPMNotificationTitle": "Nuevo mensaje de <%= name %>"
}
diff --git a/website/common/locales/es/subscriber.json b/website/common/locales/es/subscriber.json
index 91d758e598..1b90eaf938 100644
--- a/website/common/locales/es/subscriber.json
+++ b/website/common/locales/es/subscriber.json
@@ -152,7 +152,7 @@
"mysterySet201810": "Conjunto del Bosque Oscuro",
"mysterySet201811": "Conjunto de Hechicero Espléndido",
"mysterySet201812": "Conjunto Zorro Ártico",
- "mysterySet201901": "Polaris Set",
+ "mysterySet201901": "Conjunto Polaris",
"mysterySet301404": "El Conjunto Steampunk",
"mysterySet301405": "Accesorios Steampunk",
"mysterySet301703": "Conjunto de Pavo real Steampunk",
@@ -219,10 +219,11 @@
"subCanceledTitle": "Suscripción cancelada",
"mysterySet201908": "Conjunto de Fauno Footloose",
"mysterySet201907": "Conjunto de Colega Playero",
- "mysterySet201906": "Conjunto de Amable Koi",
+ "mysterySet201906": "Conjunto Koi Bondadoso",
"mysterySet201905": "Conjunto de Dragón Deslumbrante",
"mysterySet201904": "Conjunto Ópalo Opulento",
"mysterySet201903": "Conjunto Egg-quisito",
"subWillBecomeInactive": "Dejará de estar activa",
- "confirmCancelSub": "¿Seguro que quieres cancelar tu suscripción? Perderás todos los beneficios asociados a ella."
+ "confirmCancelSub": "¿Seguro que quieres cancelar tu suscripción? Perderás todos los beneficios asociados a ella.",
+ "mysterySet201909": "Conjunto Bellota Adorable"
}
diff --git a/website/common/locales/es_419/content.json b/website/common/locales/es_419/content.json
index c47cdcfb81..780bbca39f 100644
--- a/website/common/locales/es_419/content.json
+++ b/website/common/locales/es_419/content.json
@@ -207,12 +207,12 @@
"hatchingPotionFairy": "Hadas",
"hatchingPotionStarryNight": "Noche Estrellada",
"hatchingPotionRainbow": "Arcoíris",
- "hatchingPotionGlass": "Glass",
- "hatchingPotionGlow": "Glow-in-the-Dark",
- "hatchingPotionFrost": "Frost",
- "hatchingPotionIcySnow": "Icy Snow",
+ "hatchingPotionGlass": "Cristal",
+ "hatchingPotionGlow": "Fosforescente",
+ "hatchingPotionFrost": "Escarcha",
+ "hatchingPotionIcySnow": "Nieve helada",
"hatchingPotionNotes": "Vierte esto sobre un huevo, y nacerá una mascota <%= potText(locale) %>.",
- "premiumPotionAddlNotes": "No se puede usar con huevos de mascotas de misión.",
+ "premiumPotionAddlNotes": "No se puede usar con huevos de mascotas de misión. Disponible para comprar hasta <%= date(locale) %>.",
"foodMeat": "Carne",
"foodMeatThe": "la Carne",
"foodMeatA": "Carne",
@@ -274,51 +274,81 @@
"foodCakeRedThe": "el Pastel de Fresa",
"foodCakeRedA": "un Pastel de Fresa",
"foodCandySkeleton": "Caramelo de Huesos",
- "foodCandySkeletonThe": "el Dulce de Huesos",
- "foodCandySkeletonA": "Dulce de Huesos",
+ "foodCandySkeletonThe": "el Caramelo de Huesos",
+ "foodCandySkeletonA": "Caramelo de Huesos",
"foodCandyBase": "Caramelo Básico",
- "foodCandyBaseThe": "el Dulce Básico",
- "foodCandyBaseA": "Dulce básico",
+ "foodCandyBaseThe": "el Caramelo Básico",
+ "foodCandyBaseA": "Caramelo Básico",
"foodCandyCottonCandyBlue": "Caramelo Azul Agrio",
- "foodCandyCottonCandyBlueThe": "el Dulce Agrio Azul",
- "foodCandyCottonCandyBlueA": "Dulce Agrio Azul",
+ "foodCandyCottonCandyBlueThe": "el Caramelo Agrio Azul",
+ "foodCandyCottonCandyBlueA": "Caramelo Azul Agrio",
"foodCandyCottonCandyPink": "Caramelo Rosa Agrio",
- "foodCandyCottonCandyPinkThe": "el Dulce Agrio Rosa",
- "foodCandyCottonCandyPinkA": "Dulce Agrio Rosa",
+ "foodCandyCottonCandyPinkThe": "el Caramelo Agrio Rosa",
+ "foodCandyCottonCandyPinkA": "Caramelo Rosa Agrio",
"foodCandyShade": "Caramelo de Chocolate",
- "foodCandyShadeThe": "el Dulce de Chocolate",
- "foodCandyShadeA": "Dulce de Chocolate",
+ "foodCandyShadeThe": "el Caramelo de Chocolate",
+ "foodCandyShadeA": "Caramelo de Chocolate",
"foodCandyWhite": "Caramelo de Vainilla",
- "foodCandyWhiteThe": "un Dulce de Vainilla",
- "foodCandyWhiteA": "Dulce de Vainilla",
+ "foodCandyWhiteThe": "el Caramelo de Vainilla",
+ "foodCandyWhiteA": "Caramelo de Vainilla",
"foodCandyGolden": "Caramelo de Miel",
- "foodCandyGoldenThe": "el Dulce de Miel",
- "foodCandyGoldenA": "Dulce de Miel",
+ "foodCandyGoldenThe": "el Caramelo de Miel",
+ "foodCandyGoldenA": "Caramelo de Miel",
"foodCandyZombie": "Caramelo Podrido",
- "foodCandyZombieThe": "el Dulce Podrido",
- "foodCandyZombieA": "Dulce Podrido",
+ "foodCandyZombieThe": "el Caramelo Podrido",
+ "foodCandyZombieA": "Caramelo Podrido",
"foodCandyDesert": "Caramelo de Arena",
- "foodCandyDesertThe": "el Dulce de Arena",
- "foodCandyDesertA": "Dulce de Arena",
+ "foodCandyDesertThe": "el Caramelo de Arena",
+ "foodCandyDesertA": "Caramelo de Arena",
"foodCandyRed": "Caramelo de Canela",
- "foodCandyRedThe": "el Dulce de Canela",
- "foodCandyRedA": "Dulce de Canela",
+ "foodCandyRedThe": "el Caramelo de Canela",
+ "foodCandyRedA": "Caramelo de Canela",
"foodSaddleText": "Silla de Montar",
"foodSaddleNotes": "Convierte instantáneamente a una de tus mascotas en una montura.",
- "foodSaddleSellWarningNote": "¡Hey! ¡Este es un artículo bastante util! ¿Estas familiarizado con como usar una Silla de montar con tus mascotas?",
+ "foodSaddleSellWarningNote": "¡Hey! ¡Este es un artículo bastante util! ¿Estás familiarizado con cómo usar una Silla de Montar con tus mascotas?",
"foodNotes": "Dale esto a una mascota y podrá convertirse en un corcel robusto.",
"foodPieSkeleton": "Pastel de médula ósea",
- "foodPieSkeletonA": "una rebanada de pastel de olla de médula ósea",
+ "foodPieSkeletonA": "una rebanada de pastel de médula ósea",
"foodPieBase": "Pastel de manzana básico",
"foodPieBaseThe": "el pastel de manzana básico",
"foodPieBaseA": "una rebanada de pastel de manzana básico",
"foodPieCottonCandyBlue": "Pastel de arándanos",
"foodPieCottonCandyBlueThe": "el pastel de arándanos",
"foodPieCottonCandyBlueA": "una rebanada de pastel de arándanos",
- "foodPieCottonCandyPink": "Pastel de ruibarbo rosa",
- "foodPieCottonCandyPinkThe": "el pastel de ruibarbo rosa",
- "foodPieCottonCandyPinkA": "una rebanada de pastel de ruibarbo rosa",
+ "foodPieCottonCandyPink": "Pastel de ruibarbo rosado",
+ "foodPieCottonCandyPinkThe": "el pastel de ruibarbo rosado",
+ "foodPieCottonCandyPinkA": "una rebanada de pastel de ruibarbo rosado",
"hatchingPotionRoseQuartz": "Cuarzo rosado",
"hatchingPotionCelestial": "Celestial",
- "hatchingPotionVeggie": "Jardín"
+ "hatchingPotionVeggie": "Jardín",
+ "hatchingPotionBronze": "Bronce",
+ "hatchingPotionSunshine": "Luz de sol",
+ "questEggRobotAdjective": "un futurista",
+ "questEggRobotMountText": "Robot",
+ "questEggRobotText": "Robot",
+ "questEggDolphinAdjective": "un alegre",
+ "questEggDolphinMountText": "Delfín",
+ "questEggDolphinText": "Delfín",
+ "foodPieRedA": "una rebanada de pastel de cereza roja",
+ "foodPieRedThe": "el pastel de cereza roja",
+ "foodPieRed": "Pastel de cereza roja",
+ "foodPieDesertA": "una rebanada de pastel de postre del desierto",
+ "foodPieDesertThe": "el pastel de postre del desierto",
+ "foodPieDesert": "Pastel de postre del desierto",
+ "foodPieZombieA": "una rebanada de pastel podrido",
+ "foodPieZombieThe": "el pastel podrido",
+ "foodPieZombie": "Pastel podrido",
+ "foodPieGoldenA": "una rebanada de pastel de crema de banana dorado",
+ "foodPieGoldenThe": "el pastel de crema de banana dorado",
+ "foodPieGolden": "Pastel de crema de banana dorado",
+ "foodPieWhiteA": "una rebanada de pastel de pudín de vainilla",
+ "foodPieWhiteThe": "el pastel de pudín de vainilla",
+ "foodPieWhite": "Pastel de pudín de vainilla",
+ "foodPieShadeA": "una rebanada de pastel de chocolate oscuro",
+ "foodPieShadeThe": "el pastel de chocolate oscuro",
+ "foodPieShade": "Pastel de chocolate oscuro",
+ "foodPieSkeletonThe": "el Pastel de médula ósea",
+ "hatchingPotionShadow": "Sombra",
+ "hatchingPotionSilver": "Plata",
+ "hatchingPotionWatery": "Aguado"
}
diff --git a/website/common/locales/eu/achievements.json b/website/common/locales/eu/achievements.json
index 4f5dcd77c1..85e929d6cc 100755
--- a/website/common/locales/eu/achievements.json
+++ b/website/common/locales/eu/achievements.json
@@ -1,9 +1,9 @@
{
- "achievement": "Achievement",
- "share": "Share",
- "onwards": "Onwards!",
- "levelup": "By accomplishing your real life goals, you leveled up and are now fully healed!",
- "reachedLevel": "You Reached Level <%= level %>",
- "achievementLostMasterclasser": "Quest Completionist: Masterclasser Series",
- "achievementLostMasterclasserText": "Completed all sixteen quests in the Masterclasser Quest Series and solved the mystery of the Lost Masterclasser!"
+ "achievement": "",
+ "share": "",
+ "onwards": "",
+ "levelup": "",
+ "reachedLevel": "",
+ "achievementLostMasterclasser": "",
+ "achievementLostMasterclasserText": ""
}
diff --git a/website/common/locales/eu/backgrounds.json b/website/common/locales/eu/backgrounds.json
index 5fb78cf9cd..b557e9ae92 100755
--- a/website/common/locales/eu/backgrounds.json
+++ b/website/common/locales/eu/backgrounds.json
@@ -1,412 +1,412 @@
{
- "backgrounds": "Backgrounds",
- "background": "Background",
- "backgroundShop": "Background Shop",
- "backgroundShopText": "Background Shop",
- "noBackground": "No Background Selected",
- "backgrounds062014": "SET 1: Released June 2014",
- "backgroundBeachText": "Beach",
- "backgroundBeachNotes": "Lounge upon a warm beach.",
- "backgroundFairyRingText": "Fairy Ring",
- "backgroundFairyRingNotes": "Dance in a fairy ring.",
- "backgroundForestText": "Forest",
- "backgroundForestNotes": "Stroll through a summer forest.",
- "backgrounds072014": "SET 2: Released July 2014",
- "backgroundCoralReefText": "Coral Reef",
- "backgroundCoralReefNotes": "Swim in a coral reef.",
- "backgroundOpenWatersText": "Open Waters",
- "backgroundOpenWatersNotes": "Enjoy the open waters.",
- "backgroundSeafarerShipText": "Seafarer Ship",
- "backgroundSeafarerShipNotes": "Sail aboard a Seafarer Ship.",
- "backgrounds082014": "SET 3: Released August 2014",
- "backgroundCloudsText": "Clouds",
- "backgroundCloudsNotes": "Soar through the Clouds.",
- "backgroundDustyCanyonsText": "Dusty Canyon",
- "backgroundDustyCanyonsNotes": "Wander through a Dusty Canyon.",
- "backgroundVolcanoText": "Volcano",
- "backgroundVolcanoNotes": "Heat up inside a Volcano.",
- "backgrounds092014": "SET 4: Released September 2014",
- "backgroundThunderstormText": "Thunderstorm",
- "backgroundThunderstormNotes": "Conduct lightning in a Thunderstorm.",
- "backgroundAutumnForestText": "Autumn Forest",
- "backgroundAutumnForestNotes": "Stroll through an Autumn Forest.",
- "backgroundHarvestFieldsText": "Harvest Fields",
- "backgroundHarvestFieldsNotes": "Cultivate your Harvest Fields.",
- "backgrounds102014": "SET 5: Released October 2014",
- "backgroundGraveyardText": "Graveyard",
- "backgroundGraveyardNotes": "Visit a Creepy Graveyard.",
- "backgroundHauntedHouseText": "Haunted House",
- "backgroundHauntedHouseNotes": "Sneak through a Haunted House.",
- "backgroundPumpkinPatchText": "Pumpkin Patch",
- "backgroundPumpkinPatchNotes": "Carve jack-o-lanterns in a Pumpkin Patch.",
- "backgrounds112014": "SET 6: Released November 2014",
- "backgroundHarvestFeastText": "Harvest Feast",
- "backgroundHarvestFeastNotes": "Enjoy a Harvest Feast.",
- "backgroundStarrySkiesText": "Starry Skies",
- "backgroundStarrySkiesNotes": "Gaze at the Starry Skies.",
- "backgroundSunsetMeadowText": "Sunset Meadow",
- "backgroundSunsetMeadowNotes": "Admire a Sunset Meadow.",
- "backgrounds122014": "SET 7: Released December 2014",
- "backgroundIcebergText": "Iceberg",
- "backgroundIcebergNotes": "Drift upon an Iceberg.",
- "backgroundTwinklyLightsText": "Winter Twinkly Lights",
- "backgroundTwinklyLightsNotes": "Stroll between trees bedecked in festive lights.",
- "backgroundSouthPoleText": "South Pole",
- "backgroundSouthPoleNotes": "Visit the icy South Pole.",
- "backgrounds012015": "SET 8: Released January 2015",
- "backgroundIceCaveText": "Ice Cave",
- "backgroundIceCaveNotes": "Descend into an Ice Cave.",
- "backgroundFrigidPeakText": "Frigid Peak",
- "backgroundFrigidPeakNotes": "Summit a Frigid Peak.",
- "backgroundSnowyPinesText": "Snowy Pines",
- "backgroundSnowyPinesNotes": "Shelter amid Snowy Pines.",
- "backgrounds022015": "SET 9: Released February 2015",
- "backgroundBlacksmithyText": "Blacksmithy",
- "backgroundBlacksmithyNotes": "Labor in the Blacksmithy.",
- "backgroundCrystalCaveText": "Crystal Cave",
- "backgroundCrystalCaveNotes": "Explore a Crystal Cave.",
- "backgroundDistantCastleText": "Distant Castle",
- "backgroundDistantCastleNotes": "Defend a Distant Castle.",
- "backgrounds032015": "SET 10: Released March 2015",
- "backgroundSpringRainText": "Spring Rain",
- "backgroundSpringRainNotes": "Dance in the Spring Rain.",
- "backgroundStainedGlassText": "Stained Glass",
- "backgroundStainedGlassNotes": "Admire some Stained Glass.",
- "backgroundRollingHillsText": "Rolling Hills",
- "backgroundRollingHillsNotes": "Frolic through the Rolling Hills.",
- "backgrounds042015": "SET 11: Released April 2015",
- "backgroundCherryTreesText": "Cherry Trees",
- "backgroundCherryTreesNotes": "Admire the Cherry Trees in blossom.",
- "backgroundFloralMeadowText": "Flowering Meadow",
- "backgroundFloralMeadowNotes": "Picnic in a Flowering Meadow.",
- "backgroundGumdropLandText": "Gumdrop Land",
- "backgroundGumdropLandNotes": "Nibble the scenery of Gumdrop Land.",
- "backgrounds052015": "SET 12: Released May 2015",
- "backgroundMarbleTempleText": "Marble Temple",
- "backgroundMarbleTempleNotes": "Pose in front of a Marble Temple.",
- "backgroundMountainLakeText": "Mountain Lake",
- "backgroundMountainLakeNotes": "Dip your toes in a Mountain Lake.",
- "backgroundPagodasText": "Pagodas",
- "backgroundPagodasNotes": "Climb to the top of Pagodas.",
- "backgrounds062015": "SET 13: Released June 2015",
- "backgroundDriftingRaftText": "Drifting Raft",
- "backgroundDriftingRaftNotes": "Paddle a Drifting Raft.",
- "backgroundShimmeryBubblesText": "Shimmery Bubbles",
- "backgroundShimmeryBubblesNotes": "Float through a sea of Shimmery Bubbles.",
- "backgroundIslandWaterfallsText": "Island Waterfalls",
- "backgroundIslandWaterfallsNotes": "Picnic near Island Waterfalls.",
- "backgrounds072015": "SET 14: Released July 2015",
- "backgroundDilatoryRuinsText": "Ruins of Dilatory",
- "backgroundDilatoryRuinsNotes": "Dive to the Ruins of Dilatory.",
- "backgroundGiantWaveText": "Giant Wave",
- "backgroundGiantWaveNotes": "Surf a Giant Wave!",
- "backgroundSunkenShipText": "Sunken Ship",
- "backgroundSunkenShipNotes": "Explore a Sunken Ship.",
- "backgrounds082015": "SET 15: Released August 2015",
- "backgroundPyramidsText": "Pyramids",
- "backgroundPyramidsNotes": "Admire the Pyramids.",
- "backgroundSunsetSavannahText": "Sunset Savannah",
- "backgroundSunsetSavannahNotes": "Stalk across the Sunset Savannah.",
- "backgroundTwinklyPartyLightsText": "Twinkly Party Lights",
- "backgroundTwinklyPartyLightsNotes": "Dance under Twinkly Party Lights!",
- "backgrounds092015": "SET 16: Released September 2015",
- "backgroundMarketText": "Habitica Market",
- "backgroundMarketNotes": "Shop in the Habitica Market.",
- "backgroundStableText": "Habitica Stable",
- "backgroundStableNotes": "Tend mounts in the Habitica Stable.",
- "backgroundTavernText": "Habitica Tavern",
- "backgroundTavernNotes": "Visit the Habitica Tavern.",
- "backgrounds102015": "SET 17: Released October 2015",
- "backgroundHarvestMoonText": "Harvest Moon",
- "backgroundHarvestMoonNotes": "Cackle under the Harvest Moon.",
- "backgroundSlimySwampText": "Slimy Swamp",
- "backgroundSlimySwampNotes": "Slog through a Slimy Swamp.",
- "backgroundSwarmingDarknessText": "Swarming Darkness",
- "backgroundSwarmingDarknessNotes": "Shiver in the Swarming Darkness.",
- "backgrounds112015": "SET 18: Released November 2015",
- "backgroundFloatingIslandsText": "Floating Islands",
- "backgroundFloatingIslandsNotes": "Hop across the Floating Islands.",
- "backgroundNightDunesText": "Night Dunes",
- "backgroundNightDunesNotes": "Walk peacefully through the Night Dunes.",
- "backgroundSunsetOasisText": "Sunset Oasis",
- "backgroundSunsetOasisNotes": "Bask in the Sunset Oasis.",
- "backgrounds122015": "SET 19: Released December 2015",
- "backgroundAlpineSlopesText": "Alpine Slopes",
- "backgroundAlpineSlopesNotes": "Ski on the Alpine Slopes.",
- "backgroundSnowySunriseText": "Snowy Sunrise",
- "backgroundSnowySunriseNotes": "Gaze at the Snowy Sunrise.",
- "backgroundWinterTownText": "Winter Town",
- "backgroundWinterTownNotes": "Bustle through a Winter Town.",
- "backgrounds012016": "SET 20: Released January 2016",
- "backgroundFrozenLakeText": "Frozen Lake",
- "backgroundFrozenLakeNotes": "Skate on a Frozen Lake.",
- "backgroundSnowmanArmyText": "Snowman Army",
- "backgroundSnowmanArmyNotes": "Lead a Snowman Army.",
- "backgroundWinterNightText": "Winter Night",
- "backgroundWinterNightNotes": "Look at the stars of a Winter Night.",
- "backgrounds022016": "SET 21: Released February 2016",
- "backgroundBambooForestText": "Bamboo Forest",
- "backgroundBambooForestNotes": "Stroll through the Bamboo Forest.",
- "backgroundCozyLibraryText": "Cozy Library",
- "backgroundCozyLibraryNotes": "Read in the Cozy Library.",
- "backgroundGrandStaircaseText": "Grand Staircase",
- "backgroundGrandStaircaseNotes": "Stride down the Grand Staircase.",
- "backgrounds032016": "SET 22: Released March 2016",
- "backgroundDeepMineText": "Deep Mine",
- "backgroundDeepMineNotes": "Find precious metals in a Deep Mine.",
- "backgroundRainforestText": "Rainforest",
- "backgroundRainforestNotes": "Venture into a Rainforest.",
- "backgroundStoneCircleText": "Circle of Stones",
- "backgroundStoneCircleNotes": "Cast spells in a Circle of Stones.",
- "backgrounds042016": "SET 23: Released April 2016",
- "backgroundArcheryRangeText": "Archery Range",
- "backgroundArcheryRangeNotes": "Practice on the Archery Range.",
- "backgroundGiantFlowersText": "Giant Flowers",
- "backgroundGiantFlowersNotes": "Frolic atop Giant Flowers.",
- "backgroundRainbowsEndText": "End of the Rainbow",
- "backgroundRainbowsEndNotes": "Discover gold at the End of the Rainbow.",
- "backgrounds052016": "SET 24: Released May 2016",
- "backgroundBeehiveText": "Beehive",
- "backgroundBeehiveNotes": "Buzz and dance in a Beehive.",
- "backgroundGazeboText": "Gazebo",
- "backgroundGazeboNotes": "Battle a Gazebo.",
- "backgroundTreeRootsText": "Tree Roots",
- "backgroundTreeRootsNotes": "Explore the Tree Roots.",
- "backgrounds062016": "SET 25: Released June 2016",
- "backgroundLighthouseShoreText": "Lighthouse Shore",
- "backgroundLighthouseShoreNotes": "Stroll down the Lighthouse Shore.",
- "backgroundLilypadText": "Lilypad",
- "backgroundLilypadNotes": "Hop on a Lilypad.",
- "backgroundWaterfallRockText": "Waterfall Rock",
- "backgroundWaterfallRockNotes": "Splash on a Waterfall Rock.",
- "backgrounds072016": "SET 26: Released July 2016",
- "backgroundAquariumText": "Aquarium",
- "backgroundAquariumNotes": "Bob in an Aquarium.",
- "backgroundDeepSeaText": "Deep Sea",
- "backgroundDeepSeaNotes": "Dive to the Deep Sea.",
- "backgroundDilatoryCastleText": "Castle of Dilatory",
- "backgroundDilatoryCastleNotes": "Swim past the Castle of Dilatory.",
- "backgrounds082016": "SET 27: Released August 2016",
- "backgroundIdyllicCabinText": "Idyllic Cabin",
- "backgroundIdyllicCabinNotes": "Retreat to an Idyllic Cabin.",
- "backgroundMountainPyramidText": "Mountain Pyramid",
- "backgroundMountainPyramidNotes": "Climb the many steps of a Mountain Pyramid.",
- "backgroundStormyShipText": "Stormy Ship",
- "backgroundStormyShipNotes": "Hold steady against wind and wave aboard a Stormy Ship.",
- "backgrounds092016": "SET 28: Released September 2016",
- "backgroundCornfieldsText": "Cornfields",
- "backgroundCornfieldsNotes": "Enjoy a beautiful day out in the Cornfields.",
- "backgroundFarmhouseText": "Farmhouse",
- "backgroundFarmhouseNotes": "Say hello to the animals on your way to the Farmhouse.",
- "backgroundOrchardText": "Orchard",
- "backgroundOrchardNotes": "Pick ripe fruit in an Orchard.",
- "backgrounds102016": "SET 29: Released October 2016",
- "backgroundSpiderWebText": "Spider Web",
- "backgroundSpiderWebNotes": "Get snagged in a Spider Web.",
- "backgroundStrangeSewersText": "Strange Sewers",
- "backgroundStrangeSewersNotes": "Slither through the Strange Sewers.",
- "backgroundRainyCityText": "Rainy City",
- "backgroundRainyCityNotes": "Splash through a Rainy City.",
- "backgrounds112016": "SET 30: Released November 2016",
- "backgroundMidnightCloudsText": "Midnight Clouds",
- "backgroundMidnightCloudsNotes": "Fly through the Midnight Clouds.",
- "backgroundStormyRooftopsText": "Stormy Rooftops",
- "backgroundStormyRooftopsNotes": "Creep across Stormy Rooftops.",
- "backgroundWindyAutumnText": "Windy Autumn",
- "backgroundWindyAutumnNotes": "Chase leaves during a Windy Autumn.",
- "incentiveBackgrounds": "Plain Background Set",
- "backgroundVioletText": "Violet",
- "backgroundVioletNotes": "A vibrant violet backdrop.",
- "backgroundBlueText": "Blue",
- "backgroundBlueNotes": "A basic blue backdrop.",
- "backgroundGreenText": "Green",
- "backgroundGreenNotes": "A great green backdrop.",
- "backgroundPurpleText": "Purple",
- "backgroundPurpleNotes": "A pleasant purple backdrop.",
- "backgroundRedText": "Red",
- "backgroundRedNotes": "A rad red backdrop.",
- "backgroundYellowText": "Yellow",
- "backgroundYellowNotes": "A yummy yellow backdrop.",
- "backgrounds122016": "SET 31: Released December 2016",
- "backgroundShimmeringIcePrismText": "Shimmering Ice Prisms",
- "backgroundShimmeringIcePrismNotes": "Dance through the Shimmering Ice Prisms.",
- "backgroundWinterFireworksText": "Winter Fireworks",
- "backgroundWinterFireworksNotes": "Set off Winter Fireworks.",
- "backgroundWinterStorefrontText": "Winter Shop",
- "backgroundWinterStorefrontNotes": "Purchase presents from a Winter Shop.",
- "backgrounds012017": "SET 32: Released January 2017",
- "backgroundBlizzardText": "Blizzard",
- "backgroundBlizzardNotes": "Brave a fierce Blizzard.",
- "backgroundSparklingSnowflakeText": "Sparkling Snowflake",
- "backgroundSparklingSnowflakeNotes": "Glide on a Sparkling Snowflake.",
- "backgroundStoikalmVolcanoesText": "Stoïkalm Volcanoes",
- "backgroundStoikalmVolcanoesNotes": "Explore the Stoïkalm Volcanoes.",
- "backgrounds022017": "SET 33: Released February 2017",
- "backgroundBellTowerText": "Bell Tower",
- "backgroundBellTowerNotes": "Climb to the Bell Tower.",
- "backgroundTreasureRoomText": "Treasure Room",
- "backgroundTreasureRoomNotes": "Bask in the wealth of a Treasure Room.",
- "backgroundWeddingArchText": "Wedding Arch",
- "backgroundWeddingArchNotes": "Pose under the Wedding Arch.",
- "backgrounds032017": "SET 34: Released March 2017",
- "backgroundMagicBeanstalkText": "Magic Beanstalk",
- "backgroundMagicBeanstalkNotes": "Ascend a Magic Beanstalk.",
- "backgroundMeanderingCaveText": "Meandering Cave",
- "backgroundMeanderingCaveNotes": "Explore the Meandering Cave.",
- "backgroundMistiflyingCircusText": "Mistiflying Circus",
- "backgroundMistiflyingCircusNotes": "Carouse in the Mistiflying Circus.",
- "backgrounds042017": "SET 35: Released April 2017",
- "backgroundBugCoveredLogText": "Bug-Covered Log",
- "backgroundBugCoveredLogNotes": "Investigate a Bug-Covered Log.",
- "backgroundGiantBirdhouseText": "Giant Birdhouse",
- "backgroundGiantBirdhouseNotes": "Perch in a Giant Birdhouse.",
- "backgroundMistShroudedMountainText": "Mist-Shrouded Mountain",
- "backgroundMistShroudedMountainNotes": "Summit a Mist-Shrouded Mountain.",
- "backgrounds052017": "SET 36: Released May 2017",
- "backgroundGuardianStatuesText": "Guardian Statues",
- "backgroundGuardianStatuesNotes": "Stand vigil in front of Guardian Statues.",
- "backgroundHabitCityStreetsText": "Habit City Streets",
- "backgroundHabitCityStreetsNotes": "Explore the Streets of Habit City.",
- "backgroundOnATreeBranchText": "On a Tree Branch",
- "backgroundOnATreeBranchNotes": "Perch On a Tree Branch.",
- "backgrounds062017": "SET 37: Released June 2017",
- "backgroundBuriedTreasureText": "Buried Treasure",
- "backgroundBuriedTreasureNotes": "Unearth Buried Treasure.",
- "backgroundOceanSunriseText": "Ocean Sunrise",
- "backgroundOceanSunriseNotes": "Admire an Ocean Sunrise.",
- "backgroundSandcastleText": "Sandcastle",
- "backgroundSandcastleNotes": "Rule over a Sandcastle.",
- "backgrounds072017": "SET 38: Released July 2017",
- "backgroundGiantSeashellText": "Giant Seashell",
- "backgroundGiantSeashellNotes": "Lounge in a Giant Seashell.",
- "backgroundKelpForestText": "Kelp Forest",
- "backgroundKelpForestNotes": "Swim through a Kelp Forest.",
- "backgroundMidnightLakeText": "Midnight Lake",
- "backgroundMidnightLakeNotes": "Rest by a Midnight Lake.",
- "backgrounds082017": "SET 39: Released August 2017",
- "backgroundBackOfGiantBeastText": "Back of a Giant Beast",
- "backgroundBackOfGiantBeastNotes": "Ride on the Back of a Giant Beast.",
- "backgroundDesertDunesText": "Desert Dunes",
- "backgroundDesertDunesNotes": "Boldly explore the Desert Dunes.",
- "backgroundSummerFireworksText": "Summer Fireworks",
- "backgroundSummerFireworksNotes": "Celebrate Habitica's Naming Day with Summer Fireworks!",
- "backgrounds092017": "SET 40: Released September 2017",
- "backgroundBesideWellText": "Beside a Well",
- "backgroundBesideWellNotes": "Stroll Beside a Well.",
- "backgroundGardenShedText": "Garden Shed",
- "backgroundGardenShedNotes": "Work in a Garden Shed.",
- "backgroundPixelistsWorkshopText": "Pixelist's Workshop",
- "backgroundPixelistsWorkshopNotes": "Create masterpieces in the Pixelist's Workshop.",
- "backgrounds102017": "SET 41: Released October 2017",
- "backgroundMagicalCandlesText": "Magical Candles",
- "backgroundMagicalCandlesNotes": "Bask in the glow of Magical Candles.",
- "backgroundSpookyHotelText": "Spooky Hotel",
- "backgroundSpookyHotelNotes": "Sneak down the hall of a Spooky Hotel.",
- "backgroundTarPitsText": "Tar Pits",
- "backgroundTarPitsNotes": "Tiptoe through the Tar Pits.",
- "backgrounds112017": "SET 42: Released November 2017",
- "backgroundFiberArtsRoomText": "Fiber Arts Room",
- "backgroundFiberArtsRoomNotes": "Spin thread in a Fiber Arts Room.",
- "backgroundMidnightCastleText": "Midnight Castle",
- "backgroundMidnightCastleNotes": "Stroll by the Midnight Castle.",
- "backgroundTornadoText": "Tornado",
- "backgroundTornadoNotes": "Fly through a Tornado.",
- "backgrounds122017": "SET 43: Released December 2017",
- "backgroundCrosscountrySkiTrailText": "Cross-Country Ski Trail",
- "backgroundCrosscountrySkiTrailNotes": "Glide along a Cross-Country Ski Trail.",
- "backgroundStarryWinterNightText": "Starry Winter Night",
- "backgroundStarryWinterNightNotes": "Admire a Starry Winter Night.",
- "backgroundToymakersWorkshopText": "Toymaker's Workshop",
- "backgroundToymakersWorkshopNotes": "Bask in the wonder of a Toymaker's Workshop.",
- "backgrounds012018": "SET 44: Released January 2018",
- "backgroundAuroraText": "Aurora",
- "backgroundAuroraNotes": "Bask in the wintry glow of an Aurora.",
- "backgroundDrivingASleighText": "Sleigh",
- "backgroundDrivingASleighNotes": "Drive a Sleigh over snow-covered fields.",
- "backgroundFlyingOverIcySteppesText": "Icy Steppes",
- "backgroundFlyingOverIcySteppesNotes": "Fly over Icy Steppes.",
- "backgrounds022018": "SET 45: Released February 2018",
- "backgroundChessboardLandText": "Chessboard Land",
- "backgroundChessboardLandNotes": "Play a game in Chessboard Land.",
- "backgroundMagicalMuseumText": "Magical Museum",
- "backgroundMagicalMuseumNotes": "Tour a Magical Museum.",
- "backgroundRoseGardenText": "Rose Garden",
- "backgroundRoseGardenNotes": "Dally in a fragrant Rose Garden.",
- "backgrounds032018": "SET 46: Released March 2018",
- "backgroundGorgeousGreenhouseText": "Gorgeous Greenhouse",
- "backgroundGorgeousGreenhouseNotes": "Walk among the flora kept in a Gorgeous Greenhouse.",
- "backgroundElegantBalconyText": "Elegant Balcony",
- "backgroundElegantBalconyNotes": "Look out over the landscape from an Elegant Balcony.",
- "backgroundDrivingACoachText": "Driving a Coach",
- "backgroundDrivingACoachNotes": "Enjoy Driving a Coach past fields of flowers.",
- "backgrounds042018": "SET 47: Released April 2018",
- "backgroundTulipGardenText": "Tulip Garden",
- "backgroundTulipGardenNotes": "Tiptoe through a Tulip Garden.",
- "backgroundFlyingOverWildflowerFieldText": "Field of Wildflowers",
- "backgroundFlyingOverWildflowerFieldNotes": "Soar above a Field of Wildflowers.",
- "backgroundFlyingOverAncientForestText": "Ancient Forest",
- "backgroundFlyingOverAncientForestNotes": "Fly over the canopy of an Ancient Forest.",
- "backgrounds052018": "SET 48: Released May 2018",
- "backgroundTerracedRiceFieldText": "Terraced Rice Field",
- "backgroundTerracedRiceFieldNotes": "Enjoy a Terraced Rice Field in the growing season.",
- "backgroundFantasticalShoeStoreText": "Fantastical Shoe Store",
- "backgroundFantasticalShoeStoreNotes": "Look for fun new footwear in the Fantastical Shoe Store.",
- "backgroundChampionsColosseumText": "Champions' Colosseum",
- "backgroundChampionsColosseumNotes": "Bask in the glory of the Champions' Colosseum.",
- "backgrounds062018": "SET 49: Released June 2018",
- "backgroundDocksText": "Docks",
- "backgroundDocksNotes": "Fish from atop the Docks.",
- "backgroundRowboatText": "Rowboat",
- "backgroundRowboatNotes": "Sing rounds in a Rowboat.",
- "backgroundPirateFlagText": "Pirate Flag",
- "backgroundPirateFlagNotes": "Fly a fearsome Pirate Flag.",
- "backgrounds072018": "SET 50: Released July 2018",
- "backgroundDarkDeepText": "Dark Deep",
- "backgroundDarkDeepNotes": "Swim in the Dark Deep among bioluminescent critters.",
- "backgroundDilatoryCityText": "City of Dilatory",
- "backgroundDilatoryCityNotes": "Meander through the undersea City of Dilatory.",
- "backgroundTidePoolText": "Tide Pool",
- "backgroundTidePoolNotes": "Observe the ocean life near a Tide Pool.",
- "backgrounds082018": "SET 51: Released August 2018",
- "backgroundTrainingGroundsText": "Training Grounds",
- "backgroundTrainingGroundsNotes": "Spar on the Training Grounds.",
- "backgroundFlyingOverRockyCanyonText": "Rocky Canyon",
- "backgroundFlyingOverRockyCanyonNotes": "Look down into a breathtaking scene as you fly over a Rocky Canyon.",
- "backgroundBridgeText": "Bridge",
- "backgroundBridgeNotes": "Cross a charming Bridge.",
- "backgrounds092018": "SET 52: Released September 2018",
- "backgroundApplePickingText": "Apple Picking",
- "backgroundApplePickingNotes": "Go Apple Picking and bring home a bushel.",
- "backgroundGiantBookText": "Giant Book",
- "backgroundGiantBookNotes": "Read as you walk through the pages of a Giant Book.",
- "backgroundCozyBarnText": "Cozy Barn",
- "backgroundCozyBarnNotes": "Relax with your pets and mounts in their Cozy Barn.",
- "backgrounds102018": "SET 53: Released October 2018",
- "backgroundBayouText": "Bayou",
- "backgroundBayouNotes": "Bask in the fireflies' glow on the misty Bayou.",
- "backgroundCreepyCastleText": "Creepy Castle",
- "backgroundCreepyCastleNotes": "Dare to approach a Creepy Castle.",
- "backgroundDungeonText": "Dungeon",
- "backgroundDungeonNotes": "Rescue the prisoners of a spooky Dungeon.",
- "backgrounds112018": "SET 54: Released November 2018",
- "backgroundBackAlleyText": "Back Alley",
- "backgroundBackAlleyNotes": "Look shady loitering in a Back Alley.",
- "backgroundGlowingMushroomCaveText": "Glowing Mushroom Cave",
- "backgroundGlowingMushroomCaveNotes": "Stare in awe at a Glowing Mushroom Cave.",
- "backgroundCozyBedroomText": "Cozy Bedroom",
- "backgroundCozyBedroomNotes": "Curl up in a Cozy Bedroom.",
- "backgrounds122018": "SET 55: Released December 2018",
- "backgroundFlyingOverSnowyMountainsText": "Snowy Mountains",
- "backgroundFlyingOverSnowyMountainsNotes": "Soar over Snowy Mountains at night.",
- "backgroundFrostyForestText": "Frosty Forest",
- "backgroundFrostyForestNotes": "Bundle up to hike through a Frosty Forest.",
- "backgroundSnowyDayFireplaceText": "Snowy Day Fireplace",
- "backgroundSnowyDayFireplaceNotes": "Snuggle up next to a Fireplace on a Snowy Day.",
- "backgrounds012019": "SET 56: Released January 2019",
- "backgroundAvalancheText": "Avalanche",
- "backgroundAvalancheNotes": "Flee the thundering might of an Avalanche.",
- "backgroundArchaeologicalDigText": "Archaeological Dig",
- "backgroundArchaeologicalDigNotes": "Unearth secrets of the ancient past at an Archaeological Dig.",
- "backgroundScribesWorkshopText": "Scribe's Workshop",
- "backgroundScribesWorkshopNotes": "Write your next great scroll in a Scribe's Workshop."
-}
\ No newline at end of file
+ "backgrounds": "",
+ "background": "",
+ "backgroundShop": "",
+ "backgroundShopText": "",
+ "noBackground": "",
+ "backgrounds062014": "",
+ "backgroundBeachText": "",
+ "backgroundBeachNotes": "",
+ "backgroundFairyRingText": "",
+ "backgroundFairyRingNotes": "",
+ "backgroundForestText": "",
+ "backgroundForestNotes": "",
+ "backgrounds072014": "",
+ "backgroundCoralReefText": "",
+ "backgroundCoralReefNotes": "",
+ "backgroundOpenWatersText": "",
+ "backgroundOpenWatersNotes": "",
+ "backgroundSeafarerShipText": "",
+ "backgroundSeafarerShipNotes": "",
+ "backgrounds082014": "",
+ "backgroundCloudsText": "",
+ "backgroundCloudsNotes": "",
+ "backgroundDustyCanyonsText": "",
+ "backgroundDustyCanyonsNotes": "",
+ "backgroundVolcanoText": "",
+ "backgroundVolcanoNotes": "",
+ "backgrounds092014": "",
+ "backgroundThunderstormText": "",
+ "backgroundThunderstormNotes": "",
+ "backgroundAutumnForestText": "",
+ "backgroundAutumnForestNotes": "",
+ "backgroundHarvestFieldsText": "",
+ "backgroundHarvestFieldsNotes": "",
+ "backgrounds102014": "",
+ "backgroundGraveyardText": "",
+ "backgroundGraveyardNotes": "",
+ "backgroundHauntedHouseText": "",
+ "backgroundHauntedHouseNotes": "",
+ "backgroundPumpkinPatchText": "",
+ "backgroundPumpkinPatchNotes": "",
+ "backgrounds112014": "",
+ "backgroundHarvestFeastText": "",
+ "backgroundHarvestFeastNotes": "",
+ "backgroundStarrySkiesText": "",
+ "backgroundStarrySkiesNotes": "",
+ "backgroundSunsetMeadowText": "",
+ "backgroundSunsetMeadowNotes": "",
+ "backgrounds122014": "",
+ "backgroundIcebergText": "",
+ "backgroundIcebergNotes": "",
+ "backgroundTwinklyLightsText": "",
+ "backgroundTwinklyLightsNotes": "",
+ "backgroundSouthPoleText": "",
+ "backgroundSouthPoleNotes": "",
+ "backgrounds012015": "",
+ "backgroundIceCaveText": "",
+ "backgroundIceCaveNotes": "",
+ "backgroundFrigidPeakText": "",
+ "backgroundFrigidPeakNotes": "",
+ "backgroundSnowyPinesText": "",
+ "backgroundSnowyPinesNotes": "",
+ "backgrounds022015": "",
+ "backgroundBlacksmithyText": "",
+ "backgroundBlacksmithyNotes": "",
+ "backgroundCrystalCaveText": "",
+ "backgroundCrystalCaveNotes": "",
+ "backgroundDistantCastleText": "",
+ "backgroundDistantCastleNotes": "",
+ "backgrounds032015": "",
+ "backgroundSpringRainText": "",
+ "backgroundSpringRainNotes": "",
+ "backgroundStainedGlassText": "",
+ "backgroundStainedGlassNotes": "",
+ "backgroundRollingHillsText": "",
+ "backgroundRollingHillsNotes": "",
+ "backgrounds042015": "",
+ "backgroundCherryTreesText": "",
+ "backgroundCherryTreesNotes": "",
+ "backgroundFloralMeadowText": "",
+ "backgroundFloralMeadowNotes": "",
+ "backgroundGumdropLandText": "",
+ "backgroundGumdropLandNotes": "",
+ "backgrounds052015": "",
+ "backgroundMarbleTempleText": "",
+ "backgroundMarbleTempleNotes": "",
+ "backgroundMountainLakeText": "",
+ "backgroundMountainLakeNotes": "",
+ "backgroundPagodasText": "",
+ "backgroundPagodasNotes": "",
+ "backgrounds062015": "",
+ "backgroundDriftingRaftText": "",
+ "backgroundDriftingRaftNotes": "",
+ "backgroundShimmeryBubblesText": "",
+ "backgroundShimmeryBubblesNotes": "",
+ "backgroundIslandWaterfallsText": "",
+ "backgroundIslandWaterfallsNotes": "",
+ "backgrounds072015": "",
+ "backgroundDilatoryRuinsText": "",
+ "backgroundDilatoryRuinsNotes": "",
+ "backgroundGiantWaveText": "",
+ "backgroundGiantWaveNotes": "",
+ "backgroundSunkenShipText": "",
+ "backgroundSunkenShipNotes": "",
+ "backgrounds082015": "",
+ "backgroundPyramidsText": "",
+ "backgroundPyramidsNotes": "",
+ "backgroundSunsetSavannahText": "",
+ "backgroundSunsetSavannahNotes": "",
+ "backgroundTwinklyPartyLightsText": "",
+ "backgroundTwinklyPartyLightsNotes": "",
+ "backgrounds092015": "",
+ "backgroundMarketText": "",
+ "backgroundMarketNotes": "",
+ "backgroundStableText": "",
+ "backgroundStableNotes": "",
+ "backgroundTavernText": "",
+ "backgroundTavernNotes": "",
+ "backgrounds102015": "",
+ "backgroundHarvestMoonText": "",
+ "backgroundHarvestMoonNotes": "",
+ "backgroundSlimySwampText": "",
+ "backgroundSlimySwampNotes": "",
+ "backgroundSwarmingDarknessText": "",
+ "backgroundSwarmingDarknessNotes": "",
+ "backgrounds112015": "",
+ "backgroundFloatingIslandsText": "",
+ "backgroundFloatingIslandsNotes": "",
+ "backgroundNightDunesText": "",
+ "backgroundNightDunesNotes": "",
+ "backgroundSunsetOasisText": "",
+ "backgroundSunsetOasisNotes": "",
+ "backgrounds122015": "",
+ "backgroundAlpineSlopesText": "",
+ "backgroundAlpineSlopesNotes": "",
+ "backgroundSnowySunriseText": "",
+ "backgroundSnowySunriseNotes": "",
+ "backgroundWinterTownText": "",
+ "backgroundWinterTownNotes": "",
+ "backgrounds012016": "",
+ "backgroundFrozenLakeText": "",
+ "backgroundFrozenLakeNotes": "",
+ "backgroundSnowmanArmyText": "",
+ "backgroundSnowmanArmyNotes": "",
+ "backgroundWinterNightText": "",
+ "backgroundWinterNightNotes": "",
+ "backgrounds022016": "",
+ "backgroundBambooForestText": "",
+ "backgroundBambooForestNotes": "",
+ "backgroundCozyLibraryText": "",
+ "backgroundCozyLibraryNotes": "",
+ "backgroundGrandStaircaseText": "",
+ "backgroundGrandStaircaseNotes": "",
+ "backgrounds032016": "",
+ "backgroundDeepMineText": "",
+ "backgroundDeepMineNotes": "",
+ "backgroundRainforestText": "",
+ "backgroundRainforestNotes": "",
+ "backgroundStoneCircleText": "",
+ "backgroundStoneCircleNotes": "",
+ "backgrounds042016": "",
+ "backgroundArcheryRangeText": "",
+ "backgroundArcheryRangeNotes": "",
+ "backgroundGiantFlowersText": "",
+ "backgroundGiantFlowersNotes": "",
+ "backgroundRainbowsEndText": "",
+ "backgroundRainbowsEndNotes": "",
+ "backgrounds052016": "",
+ "backgroundBeehiveText": "",
+ "backgroundBeehiveNotes": "",
+ "backgroundGazeboText": "",
+ "backgroundGazeboNotes": "",
+ "backgroundTreeRootsText": "",
+ "backgroundTreeRootsNotes": "",
+ "backgrounds062016": "",
+ "backgroundLighthouseShoreText": "",
+ "backgroundLighthouseShoreNotes": "",
+ "backgroundLilypadText": "",
+ "backgroundLilypadNotes": "",
+ "backgroundWaterfallRockText": "",
+ "backgroundWaterfallRockNotes": "",
+ "backgrounds072016": "",
+ "backgroundAquariumText": "",
+ "backgroundAquariumNotes": "",
+ "backgroundDeepSeaText": "",
+ "backgroundDeepSeaNotes": "",
+ "backgroundDilatoryCastleText": "",
+ "backgroundDilatoryCastleNotes": "",
+ "backgrounds082016": "",
+ "backgroundIdyllicCabinText": "",
+ "backgroundIdyllicCabinNotes": "",
+ "backgroundMountainPyramidText": "",
+ "backgroundMountainPyramidNotes": "",
+ "backgroundStormyShipText": "",
+ "backgroundStormyShipNotes": "",
+ "backgrounds092016": "",
+ "backgroundCornfieldsText": "",
+ "backgroundCornfieldsNotes": "",
+ "backgroundFarmhouseText": "",
+ "backgroundFarmhouseNotes": "",
+ "backgroundOrchardText": "",
+ "backgroundOrchardNotes": "",
+ "backgrounds102016": "",
+ "backgroundSpiderWebText": "",
+ "backgroundSpiderWebNotes": "",
+ "backgroundStrangeSewersText": "",
+ "backgroundStrangeSewersNotes": "",
+ "backgroundRainyCityText": "",
+ "backgroundRainyCityNotes": "",
+ "backgrounds112016": "",
+ "backgroundMidnightCloudsText": "",
+ "backgroundMidnightCloudsNotes": "",
+ "backgroundStormyRooftopsText": "",
+ "backgroundStormyRooftopsNotes": "",
+ "backgroundWindyAutumnText": "",
+ "backgroundWindyAutumnNotes": "",
+ "incentiveBackgrounds": "",
+ "backgroundVioletText": "",
+ "backgroundVioletNotes": "",
+ "backgroundBlueText": "",
+ "backgroundBlueNotes": "",
+ "backgroundGreenText": "",
+ "backgroundGreenNotes": "",
+ "backgroundPurpleText": "",
+ "backgroundPurpleNotes": "",
+ "backgroundRedText": "",
+ "backgroundRedNotes": "",
+ "backgroundYellowText": "",
+ "backgroundYellowNotes": "",
+ "backgrounds122016": "",
+ "backgroundShimmeringIcePrismText": "",
+ "backgroundShimmeringIcePrismNotes": "",
+ "backgroundWinterFireworksText": "",
+ "backgroundWinterFireworksNotes": "",
+ "backgroundWinterStorefrontText": "",
+ "backgroundWinterStorefrontNotes": "",
+ "backgrounds012017": "",
+ "backgroundBlizzardText": "",
+ "backgroundBlizzardNotes": "",
+ "backgroundSparklingSnowflakeText": "",
+ "backgroundSparklingSnowflakeNotes": "",
+ "backgroundStoikalmVolcanoesText": "",
+ "backgroundStoikalmVolcanoesNotes": "",
+ "backgrounds022017": "",
+ "backgroundBellTowerText": "",
+ "backgroundBellTowerNotes": "",
+ "backgroundTreasureRoomText": "",
+ "backgroundTreasureRoomNotes": "",
+ "backgroundWeddingArchText": "",
+ "backgroundWeddingArchNotes": "",
+ "backgrounds032017": "",
+ "backgroundMagicBeanstalkText": "",
+ "backgroundMagicBeanstalkNotes": "",
+ "backgroundMeanderingCaveText": "",
+ "backgroundMeanderingCaveNotes": "",
+ "backgroundMistiflyingCircusText": "",
+ "backgroundMistiflyingCircusNotes": "",
+ "backgrounds042017": "",
+ "backgroundBugCoveredLogText": "",
+ "backgroundBugCoveredLogNotes": "",
+ "backgroundGiantBirdhouseText": "",
+ "backgroundGiantBirdhouseNotes": "",
+ "backgroundMistShroudedMountainText": "",
+ "backgroundMistShroudedMountainNotes": "",
+ "backgrounds052017": "",
+ "backgroundGuardianStatuesText": "",
+ "backgroundGuardianStatuesNotes": "",
+ "backgroundHabitCityStreetsText": "",
+ "backgroundHabitCityStreetsNotes": "",
+ "backgroundOnATreeBranchText": "",
+ "backgroundOnATreeBranchNotes": "",
+ "backgrounds062017": "",
+ "backgroundBuriedTreasureText": "",
+ "backgroundBuriedTreasureNotes": "",
+ "backgroundOceanSunriseText": "",
+ "backgroundOceanSunriseNotes": "",
+ "backgroundSandcastleText": "",
+ "backgroundSandcastleNotes": "",
+ "backgrounds072017": "",
+ "backgroundGiantSeashellText": "",
+ "backgroundGiantSeashellNotes": "",
+ "backgroundKelpForestText": "",
+ "backgroundKelpForestNotes": "",
+ "backgroundMidnightLakeText": "",
+ "backgroundMidnightLakeNotes": "",
+ "backgrounds082017": "",
+ "backgroundBackOfGiantBeastText": "",
+ "backgroundBackOfGiantBeastNotes": "",
+ "backgroundDesertDunesText": "",
+ "backgroundDesertDunesNotes": "",
+ "backgroundSummerFireworksText": "",
+ "backgroundSummerFireworksNotes": "",
+ "backgrounds092017": "",
+ "backgroundBesideWellText": "",
+ "backgroundBesideWellNotes": "",
+ "backgroundGardenShedText": "",
+ "backgroundGardenShedNotes": "",
+ "backgroundPixelistsWorkshopText": "",
+ "backgroundPixelistsWorkshopNotes": "",
+ "backgrounds102017": "",
+ "backgroundMagicalCandlesText": "",
+ "backgroundMagicalCandlesNotes": "",
+ "backgroundSpookyHotelText": "",
+ "backgroundSpookyHotelNotes": "",
+ "backgroundTarPitsText": "",
+ "backgroundTarPitsNotes": "",
+ "backgrounds112017": "",
+ "backgroundFiberArtsRoomText": "",
+ "backgroundFiberArtsRoomNotes": "",
+ "backgroundMidnightCastleText": "",
+ "backgroundMidnightCastleNotes": "",
+ "backgroundTornadoText": "",
+ "backgroundTornadoNotes": "",
+ "backgrounds122017": "",
+ "backgroundCrosscountrySkiTrailText": "",
+ "backgroundCrosscountrySkiTrailNotes": "",
+ "backgroundStarryWinterNightText": "",
+ "backgroundStarryWinterNightNotes": "",
+ "backgroundToymakersWorkshopText": "",
+ "backgroundToymakersWorkshopNotes": "",
+ "backgrounds012018": "",
+ "backgroundAuroraText": "",
+ "backgroundAuroraNotes": "",
+ "backgroundDrivingASleighText": "",
+ "backgroundDrivingASleighNotes": "",
+ "backgroundFlyingOverIcySteppesText": "",
+ "backgroundFlyingOverIcySteppesNotes": "",
+ "backgrounds022018": "",
+ "backgroundChessboardLandText": "",
+ "backgroundChessboardLandNotes": "",
+ "backgroundMagicalMuseumText": "",
+ "backgroundMagicalMuseumNotes": "",
+ "backgroundRoseGardenText": "",
+ "backgroundRoseGardenNotes": "",
+ "backgrounds032018": "",
+ "backgroundGorgeousGreenhouseText": "",
+ "backgroundGorgeousGreenhouseNotes": "",
+ "backgroundElegantBalconyText": "",
+ "backgroundElegantBalconyNotes": "",
+ "backgroundDrivingACoachText": "",
+ "backgroundDrivingACoachNotes": "",
+ "backgrounds042018": "",
+ "backgroundTulipGardenText": "",
+ "backgroundTulipGardenNotes": "",
+ "backgroundFlyingOverWildflowerFieldText": "",
+ "backgroundFlyingOverWildflowerFieldNotes": "",
+ "backgroundFlyingOverAncientForestText": "",
+ "backgroundFlyingOverAncientForestNotes": "",
+ "backgrounds052018": "",
+ "backgroundTerracedRiceFieldText": "",
+ "backgroundTerracedRiceFieldNotes": "",
+ "backgroundFantasticalShoeStoreText": "",
+ "backgroundFantasticalShoeStoreNotes": "",
+ "backgroundChampionsColosseumText": "",
+ "backgroundChampionsColosseumNotes": "",
+ "backgrounds062018": "",
+ "backgroundDocksText": "",
+ "backgroundDocksNotes": "",
+ "backgroundRowboatText": "",
+ "backgroundRowboatNotes": "",
+ "backgroundPirateFlagText": "",
+ "backgroundPirateFlagNotes": "",
+ "backgrounds072018": "",
+ "backgroundDarkDeepText": "",
+ "backgroundDarkDeepNotes": "",
+ "backgroundDilatoryCityText": "",
+ "backgroundDilatoryCityNotes": "",
+ "backgroundTidePoolText": "",
+ "backgroundTidePoolNotes": "",
+ "backgrounds082018": "",
+ "backgroundTrainingGroundsText": "",
+ "backgroundTrainingGroundsNotes": "",
+ "backgroundFlyingOverRockyCanyonText": "",
+ "backgroundFlyingOverRockyCanyonNotes": "",
+ "backgroundBridgeText": "",
+ "backgroundBridgeNotes": "",
+ "backgrounds092018": "",
+ "backgroundApplePickingText": "",
+ "backgroundApplePickingNotes": "",
+ "backgroundGiantBookText": "",
+ "backgroundGiantBookNotes": "",
+ "backgroundCozyBarnText": "",
+ "backgroundCozyBarnNotes": "",
+ "backgrounds102018": "",
+ "backgroundBayouText": "",
+ "backgroundBayouNotes": "",
+ "backgroundCreepyCastleText": "",
+ "backgroundCreepyCastleNotes": "",
+ "backgroundDungeonText": "",
+ "backgroundDungeonNotes": "",
+ "backgrounds112018": "",
+ "backgroundBackAlleyText": "",
+ "backgroundBackAlleyNotes": "",
+ "backgroundGlowingMushroomCaveText": "",
+ "backgroundGlowingMushroomCaveNotes": "",
+ "backgroundCozyBedroomText": "",
+ "backgroundCozyBedroomNotes": "",
+ "backgrounds122018": "",
+ "backgroundFlyingOverSnowyMountainsText": "",
+ "backgroundFlyingOverSnowyMountainsNotes": "",
+ "backgroundFrostyForestText": "",
+ "backgroundFrostyForestNotes": "",
+ "backgroundSnowyDayFireplaceText": "",
+ "backgroundSnowyDayFireplaceNotes": "",
+ "backgrounds012019": "",
+ "backgroundAvalancheText": "",
+ "backgroundAvalancheNotes": "",
+ "backgroundArchaeologicalDigText": "",
+ "backgroundArchaeologicalDigNotes": "",
+ "backgroundScribesWorkshopText": "",
+ "backgroundScribesWorkshopNotes": ""
+}
diff --git a/website/common/locales/eu/challenge.json b/website/common/locales/eu/challenge.json
index 0fcf913145..2c800f4918 100755
--- a/website/common/locales/eu/challenge.json
+++ b/website/common/locales/eu/challenge.json
@@ -1,139 +1,139 @@
{
- "challenge": "Challenge",
- "challengeDetails": "Challenges are community events in which players compete and earn prizes by completing a group of related tasks.",
- "brokenChaLink": "Broken Challenge Link",
- "brokenTask": "Broken Challenge Link: this task was part of a challenge, but has been removed from it. What would you like to do?",
- "keepIt": "Keep It",
- "removeIt": "Remove It",
- "brokenChallenge": "Broken Challenge Link: this task was part of a challenge, but the challenge (or group) has been deleted. What to do with the orphan tasks?",
- "keepThem": "Keep Tasks",
- "removeThem": "Remove Tasks",
- "challengeCompleted": "This challenge has been completed, and the winner was <%= user %>! What to do with the orphan tasks?",
- "unsubChallenge": "Broken Challenge Link: this task was part of a challenge, but you have unsubscribed from the challenge. What to do with the orphan tasks?",
- "challengeWinner": "Was the winner in the following challenges",
- "challenges": "Challenges",
- "challengesLink": "Challenges",
- "challengePrize": "Challenge Prize",
- "endDate": "Ends",
- "noChallenges": "No challenges yet, visit",
- "toCreate": "to create one.",
- "selectWinner": "Select a winner and close the challenge:",
- "deleteOrSelect": "Delete or select winner",
- "endChallenge": "End Challenge",
- "challengeDiscription": "These are the Challenge's tasks that will be added to your task dashboard when you join this Challenge. The sample Challenge tasks below will change color and gain graphs to show you the overall progress of the group.",
- "hows": "How's Everyone Doing?",
- "filter": "Filter",
- "groups": "Groups",
- "noNone": "None",
- "category": "Category",
- "membership": "Membership",
- "ownership": "Ownership",
- "participating": "Participating",
- "notParticipating": "Not Participating",
- "either": "Either",
- "createChallenge": "Create Challenge",
- "createChallengeAddTasks": "Add Challenge Tasks",
- "createChallengeCloneTasks": "Clone Challenge Tasks",
- "addTaskToChallenge": "Add Task",
- "discard": "Discard",
- "challengeTitle": "Challenge Title",
- "challengeTag": "Tag Name",
- "challengeTagPop": "Challenges appear on tag-lists & task-tooltips. So while you'll want a descriptive title above, you'll also need a 'short name'. Eg, 'Lose 10 pounds in 3 months' might become '-10lb' (Click for more info).",
- "challengeDescr": "Description",
- "prize": "Prize",
- "prizePop": "If someone can 'win' your challenge, you can optionally award that winner a Gem prize. The maximum number you can award is the number of gems you own (plus the number of guild gems, if you created this challenge's guild). Note: This prize can't be changed later.",
- "prizePopTavern": "If someone can 'win' your challenge, you can award that winner a Gem prize. Max = number of gems you own. Note: This prize can't be changed later and Tavern challenges will not be refunded if the challenge is cancelled.",
- "publicChallenges": "Minimum 1 Gem for public challenges (helps prevent spam, it really does).",
- "publicChallengesTitle": "Public Challenges",
- "officialChallenge": "Official Habitica Challenge",
- "by": "by",
- "participants": "<%= membercount %> Participants",
- "join": "Join",
- "exportChallengeCSV": "Export to CSV",
- "selectGroup": "Please select group",
- "challengeCreated": "Challenge created",
- "sureDelCha": "Are you sure you want to delete this challenge?",
- "sureDelChaTavern": "Are you sure you want to delete this challenge? Your gems will not be refunded.",
- "removeTasks": "Remove Tasks",
- "keepTasks": "Keep Tasks",
- "closeCha": "Close challenge and...",
- "leaveCha": "Leave challenge and...",
- "challengedOwnedFilterHeader": "Ownership",
- "challengedOwnedFilter": "Owned",
- "owned": "Owned",
- "challengedNotOwnedFilter": "Not Owned",
- "not_owned": "Not Owned",
- "not_participating": "Not Participating",
- "challengedEitherOwnedFilter": "Either",
- "backToChallenges": "Back to all challenges",
- "prizeValue": "<%= gemcount %> <%= gemicon %> Prize",
- "clone": "Clone",
- "challengeNotEnoughGems": "You do not have enough gems to post this challenge.",
- "noPermissionEditChallenge": "You don't have permissions to edit this challenge",
- "noPermissionDeleteChallenge": "You don't have permissions to delete this challenge",
- "noPermissionCloseChallenge": "You don't have permissions to close this challenge",
- "congratulations": "Congratulations!",
- "hurray": "Hurray!",
- "noChallengeOwner": "no owner",
- "noChallengeOwnerPopover": "This challenge does not have an owner because the person who created the challenge deleted their account.",
- "challengeMemberNotFound": "User not found among challenge's members",
- "onlyGroupLeaderChal": "Only the group leader can create challenges",
- "tavChalsMinPrize": "Prize must be at least 1 Gem for Public Challenges.",
- "cantAfford": "You can't afford this prize. Purchase more gems or lower the prize amount.",
- "challengeIdRequired": "\"challengeId\" must be a valid UUID.",
- "winnerIdRequired": "\"winnerId\" must be a valid UUID.",
- "challengeNotFound": "Challenge not found or you don't have access.",
- "onlyLeaderDeleteChal": "Only the challenge leader can delete it.",
- "onlyLeaderUpdateChal": "Only the challenge leader can update it.",
- "winnerNotFound": "Winner with id \"<%= userId %>\" not found or not part of the challenge.",
- "noCompletedTodosChallenge": "\"includeCompletedTodos\" is not supported when fetching challenge tasks.",
- "userTasksNoChallengeId": "When \"tasksOwner\" is \"user\" \"challengeId\" can't be passed.",
- "onlyChalLeaderEditTasks": "Tasks belonging to a challenge can only be edited by the leader.",
- "userAlreadyInChallenge": "User is already participating in this challenge.",
- "cantOnlyUnlinkChalTask": "Only broken challenges tasks can be unlinked.",
- "shortNameTooShort": "Tag Name must have at least 3 characters.",
- "joinedChallenge": "Joined a Challenge",
- "joinedChallengeText": "This user put themselves to the test by joining a Challenge!",
- "myChallenges": "My Challenges",
- "findChallenges": "Discover Challenges",
- "noChallengeTitle": "You don't have any Challenges.",
- "challengeDescription1": "Challenges are community events in which players compete and earn prizes by completing a group of related tasks.",
- "challengeDescription2": "Find recommended Challenges based on your interests, browse Habitica's public Challenges, or create your own Challenges.",
- "noChallengeMatchFilters": "We couldn't find any matching Challenges.",
- "createdBy": "Created By",
- "joinChallenge": "Join Challenge",
- "leaveChallenge": "Leave Challenge",
- "addTask": "Add Task",
- "editChallenge": "Edit Challenge",
- "challengeDescription": "Challenge Description",
- "selectChallengeWinnersDescription": "Select a winner from the Challenge participants",
- "awardWinners": "Award Winner",
- "doYouWantedToDeleteChallenge": "Do you want to delete this Challenge?",
- "deleteChallenge": "Delete Challenge",
- "challengeNamePlaceholder": "What is your Challenge name?",
- "challengeSummary": "Summary",
- "challengeSummaryPlaceholder": "Write a short description advertising your Challenge to other Habiticans. What is the main purpose of your Challenge and why should people join it? Try to include useful keywords in the description so that Habiticans can easily find it when they search!",
- "challengeDescriptionPlaceholder": "Use this section to go into more detail about everything that Challenge participants should know about your Challenge.",
- "challengeGuild": "Add to",
- "challengeMinimum": "Minimum 1 Gem for public Challenges (helps prevent spam, it really does).",
- "participantsTitle": "Participants",
- "shortName": "Short Name",
- "shortNamePlaceholder": "What short tag should be used to identify your Challenge?",
- "updateChallenge": "Update Challenge",
- "haveNoChallenges": "This group has no Challenges",
- "loadMore": "Load More",
- "exportChallengeCsv": "Export Challenge",
- "editingChallenge": "Editing Challenge",
- "nameRequired": "Name is required",
- "tagTooShort": "Tag name is too short",
- "summaryRequired": "Summary is required",
- "summaryTooLong": "Summary is too long",
- "descriptionRequired": "Description is required",
- "locationRequired": "Location of challenge is required ('Add to')",
- "categoiresRequired": "One or more categories must be selected",
- "viewProgressOf": "View Progress Of",
- "viewProgress": "View Progress",
- "selectMember": "Select Member",
- "confirmKeepChallengeTasks": "Do you want to keep challenge tasks?",
- "selectParticipant": "Select a Participant"
-}
\ No newline at end of file
+ "challenge": "",
+ "challengeDetails": "",
+ "brokenChaLink": "",
+ "brokenTask": "",
+ "keepIt": "",
+ "removeIt": "",
+ "brokenChallenge": "",
+ "keepThem": "",
+ "removeThem": "",
+ "challengeCompleted": "",
+ "unsubChallenge": "",
+ "challengeWinner": "",
+ "challenges": "",
+ "challengesLink": "",
+ "challengePrize": "",
+ "endDate": "",
+ "noChallenges": "",
+ "toCreate": "",
+ "selectWinner": "",
+ "deleteOrSelect": "",
+ "endChallenge": "",
+ "challengeDiscription": "",
+ "hows": "",
+ "filter": "",
+ "groups": "",
+ "noNone": "",
+ "category": "",
+ "membership": "",
+ "ownership": "",
+ "participating": "",
+ "notParticipating": "",
+ "either": "",
+ "createChallenge": "",
+ "createChallengeAddTasks": "",
+ "createChallengeCloneTasks": "",
+ "addTaskToChallenge": "",
+ "discard": "",
+ "challengeTitle": "",
+ "challengeTag": "",
+ "challengeTagPop": "",
+ "challengeDescr": "",
+ "prize": "",
+ "prizePop": "",
+ "prizePopTavern": "",
+ "publicChallenges": "",
+ "publicChallengesTitle": "",
+ "officialChallenge": "",
+ "by": "",
+ "participants": "",
+ "join": "",
+ "exportChallengeCSV": "",
+ "selectGroup": "",
+ "challengeCreated": "",
+ "sureDelCha": "",
+ "sureDelChaTavern": "",
+ "removeTasks": "",
+ "keepTasks": "",
+ "closeCha": "",
+ "leaveCha": "",
+ "challengedOwnedFilterHeader": "",
+ "challengedOwnedFilter": "",
+ "owned": "",
+ "challengedNotOwnedFilter": "",
+ "not_owned": "",
+ "not_participating": "",
+ "challengedEitherOwnedFilter": "",
+ "backToChallenges": "",
+ "prizeValue": "",
+ "clone": "",
+ "challengeNotEnoughGems": "",
+ "noPermissionEditChallenge": "",
+ "noPermissionDeleteChallenge": "",
+ "noPermissionCloseChallenge": "",
+ "congratulations": "",
+ "hurray": "",
+ "noChallengeOwner": "",
+ "noChallengeOwnerPopover": "",
+ "challengeMemberNotFound": "",
+ "onlyGroupLeaderChal": "",
+ "tavChalsMinPrize": "",
+ "cantAfford": "",
+ "challengeIdRequired": "",
+ "winnerIdRequired": "",
+ "challengeNotFound": "",
+ "onlyLeaderDeleteChal": "",
+ "onlyLeaderUpdateChal": "",
+ "winnerNotFound": "",
+ "noCompletedTodosChallenge": "",
+ "userTasksNoChallengeId": "",
+ "onlyChalLeaderEditTasks": "",
+ "userAlreadyInChallenge": "",
+ "cantOnlyUnlinkChalTask": "",
+ "shortNameTooShort": "",
+ "joinedChallenge": "",
+ "joinedChallengeText": "",
+ "myChallenges": "",
+ "findChallenges": "",
+ "noChallengeTitle": "",
+ "challengeDescription1": "",
+ "challengeDescription2": "",
+ "noChallengeMatchFilters": "",
+ "createdBy": "",
+ "joinChallenge": "",
+ "leaveChallenge": "",
+ "addTask": "",
+ "editChallenge": "",
+ "challengeDescription": "",
+ "selectChallengeWinnersDescription": "",
+ "awardWinners": "",
+ "doYouWantedToDeleteChallenge": "",
+ "deleteChallenge": "",
+ "challengeNamePlaceholder": "",
+ "challengeSummary": "",
+ "challengeSummaryPlaceholder": "",
+ "challengeDescriptionPlaceholder": "",
+ "challengeGuild": "",
+ "challengeMinimum": "",
+ "participantsTitle": "",
+ "shortName": "",
+ "shortNamePlaceholder": "",
+ "updateChallenge": "",
+ "haveNoChallenges": "",
+ "loadMore": "",
+ "exportChallengeCsv": "",
+ "editingChallenge": "",
+ "nameRequired": "",
+ "tagTooShort": "",
+ "summaryRequired": "",
+ "summaryTooLong": "",
+ "descriptionRequired": "",
+ "locationRequired": "",
+ "categoiresRequired": "",
+ "viewProgressOf": "",
+ "viewProgress": "",
+ "selectMember": "",
+ "confirmKeepChallengeTasks": "",
+ "selectParticipant": ""
+}
diff --git a/website/common/locales/eu/character.json b/website/common/locales/eu/character.json
index 67d30253e9..15f7a1b4fa 100755
--- a/website/common/locales/eu/character.json
+++ b/website/common/locales/eu/character.json
@@ -1,228 +1,228 @@
{
- "communityGuidelinesWarning": "Please keep in mind that your Display Name, profile photo, and blurb must comply with the Community Guidelines (e.g. no profanity, no adult topics, no insults, etc). If you have any questions about whether or not something is appropriate, feel free to email <%= hrefBlankCommunityManagerEmail %>!",
- "profile": "Profile",
- "avatar": "Customize Avatar",
- "editAvatar": "Edit Avatar",
- "noDescription": "This Habitican hasn't added a description.",
- "noPhoto": "This Habitican hasn't added a photo.",
- "other": "Other",
- "fullName": "Full Name",
- "displayName": "Display name",
- "changeDisplayName": "Change Display Name",
- "newDisplayName": "New Display Name",
- "displayPhoto": "Photo",
- "displayBlurb": "Blurb",
- "displayBlurbPlaceholder": "Please introduce yourself",
- "photoUrl": "Photo Url",
- "imageUrl": "Image Url",
- "inventory": "Inventory",
- "social": "Social",
- "lvl": "Lvl",
- "buffed": "Buffed",
- "bodyBody": "Body",
- "bodySize": "Size",
- "size": "Size",
- "bodySlim": "Slim",
- "bodyBroad": "Broad",
- "unlockSet": "Unlock Set - <%= cost %>",
- "locked": "locked",
- "shirts": "Shirts",
- "shirt": "Shirt",
- "specialShirts": "Special Shirts",
- "bodyHead": "Hairstyles and Hair Colors",
- "bodySkin": "Skin",
- "skin": "Skin",
- "color": "Color",
- "bodyHair": "Hair",
- "hair": "Hair",
- "bangs": "Bangs",
- "hairBangs": "Bangs",
- "ponytail": "Ponytail",
- "glasses": "Glasses",
- "hairBase": "Base",
- "hairSet1": "Hairstyle Set 1",
- "hairSet2": "Hairstyle Set 2",
- "hairSet3": "Hairstyle Set 3",
- "bodyFacialHair": "Facial Hair",
- "beard": "Beard",
- "mustache": "Mustache",
- "flower": "Flower",
- "accent": "Accent",
- "headband": "Headband",
- "wheelchair": "Wheelchair",
- "extra": "Extra",
- "basicSkins": "Basic Skins",
- "rainbowSkins": "Rainbow Skins",
- "pastelSkins": "Pastel Skins",
- "spookySkins": "Spooky Skins",
- "supernaturalSkins": "Supernatural Skins",
- "splashySkins": "Splashy Skins",
- "winterySkins": "Wintery Skins",
- "rainbowColors": "Rainbow Colors",
- "shimmerColors": "Shimmer Colors",
- "hauntedColors": "Haunted Colors",
- "winteryColors": "Wintery Colors",
- "equipment": "Equipment",
- "equipmentBonus": "Equipment",
- "equipmentBonusText": "Stat bonuses provided by your equipped battle gear. See the Equipment tab under Inventory to select your battle gear.",
- "classBonusText": "Your class (Warrior, if you haven't unlocked or selected another class) uses its own equipment more effectively than gear from other classes. Equipped gear from your current class gets a 50% boost to the Stat bonus it grants.",
- "classEquipBonus": "Class Bonus",
- "battleGear": "Battle Gear",
- "gear": "Gear",
- "battleGearText": "This is the gear you wear into battle; it affects numbers when interacting with your tasks.",
- "autoEquipBattleGear": "Auto-equip new gear",
- "costume": "Costume",
- "costumeText": "If you prefer the look of other gear to what you have equipped, check the \"Use Costume\" box to visually don a costume while wearing your battle gear underneath.",
- "useCostume": "Use Costume",
- "useCostumeInfo1": "Click \"Use Costume\" to equip items to your avatar without affecting the Stats from your Battle Gear! This means that you can equip for the best Stats on the left, and dress up your avatar with your equipment on the right.",
- "useCostumeInfo2": "Once you click \"Use Costume\" your avatar will look pretty basic... but don't worry! If you look on the left, you'll see that your Battle Gear is still equipped. Next, you can make things fancy! Anything you equip on the right won't affect your Stats, but can make you look super awesome. Try out different combos, mixing sets, and coordinating your Costume with your pets, mounts, and backgrounds.
Got more questions? Check out the Costume page on the wiki. Find the perfect ensemble? Show it off in the Costume Carnival guild or brag in the Tavern!",
- "costumePopoverText": "Select \"Use Costume\" to equip items to your avatar without affecting the Stats from your Battle Gear! This means that you can dress up your avatar in whatever outfit you like while still having your best Battle Gear equipped.",
- "autoEquipPopoverText": "Select this option to automatically equip gear as soon as you purchase it.",
- "costumeDisabled": "You have disabled your costume.",
- "gearAchievement": "You have earned the \"Ultimate Gear\" Achievement for upgrading to the maximum gear set for a class! You have attained the following complete sets:",
- "gearAchievementNotification": "You have earned the \"Ultimate Gear\" Achievement for upgrading to the maximum gear set for a class!",
- "moreGearAchievements": "To attain more Ultimate Gear badges, change classes on the Settings > Site page and buy your new class's gear!",
- "armoireUnlocked": "For more equipment, check out the Enchanted Armoire! Click on the Enchanted Armoire Reward for a random chance at special Equipment! It may also give you random XP or food items.",
- "ultimGearName": "Ultimate Gear - <%= ultClass %>",
- "ultimGearText": "Has upgraded to the maximum weapon and armor set for the <%= ultClass %> class.",
- "level": "Level",
- "levelUp": "Level Up!",
- "gainedLevel": "You gained a level!",
- "leveledUp": "By accomplishing your real-life goals, you've grown to Level <%= level %>!",
- "fullyHealed": "You have been fully healed!",
- "huzzah": "Huzzah!",
- "mana": "Mana",
- "hp": "HP",
- "mp": "MP",
- "xp": "XP",
- "health": "Health",
- "allocateStr": "Points allocated to Strength:",
- "allocateStrPop": "Add a Point to Strength",
- "allocateCon": "Points allocated to Constitution:",
- "allocateConPop": "Add a Point to Constitution",
- "allocatePer": "Points allocated to Perception:",
- "allocatePerPop": "Add a Point to Perception",
- "allocateInt": "Points allocated to Intelligence:",
- "allocateIntPop": "Add a Point to Intelligence",
- "noMoreAllocate": "Now that you've hit level 100, you won't gain any more Stat Points. You can continue leveling up, or start a new adventure at level 1 by using the Orb of Rebirth, now available for free in the Market.",
- "stats": "Stats",
- "achievs": "Achievements",
- "strength": "Strength",
- "strText": "Strength increases the chance of random \"critical hits\" and the Gold, Experience, and drop chance boost from them. It also helps deal damage to boss monsters.",
- "constitution": "Constitution",
- "conText": "Constitution reduces the damage you take from negative Habits and missed Dailies.",
- "perception": "Perception",
- "perText": "Perception increases how much Gold you earn, and once you've unlocked the Market, increases the chance of finding items when scoring tasks.",
- "intelligence": "Intelligence",
- "intText": "Intelligence increases how much Experience you earn, and once you've unlocked Classes, determines your maximum Mana available for class abilities.",
- "levelBonus": "Level Bonus",
- "levelBonusText": "Each Stat gets a bonus equal to half of (your Level minus 1).",
- "allocatedPoints": "Allocated Points",
- "allocatedPointsText": "Stat Points you've earned and assigned. Assign Points using the Character Build column.",
- "allocated": "Allocated",
- "buffs": "Buffs",
- "buffsText": "Temporary Stat bonuses from abilities and achievements. These wear off at the end of your day. The abilities you've unlocked appear in the Rewards list of your Tasks page.",
- "characterBuild": "Character Build",
- "class": "Class",
- "experience": "Experience",
- "warrior": "Warrior",
- "healer": "Healer",
- "rogue": "Rogue",
- "mage": "Mage",
- "wizard": "Mage",
- "mystery": "Mystery",
- "changeClass": "Change Class, Refund Stat Points",
- "lvl10ChangeClass": "To change class you must be at least level 10.",
- "changeClassConfirmCost": "Are you sure you want to change your class for 3 Gems?",
- "invalidClass": "Invalid class. Please specify 'warrior', 'rogue', 'wizard', or 'healer'.",
- "levelPopover": "Each level earns you one Point to assign to a Stat of your choice. You can do so manually, or let the game decide for you using one of the Automatic Allocation options.",
- "unallocated": "Unallocated Stat Points",
- "haveUnallocated": "You have <%= points %> unallocated Stat Point(s)",
- "autoAllocation": "Automatic Allocation",
- "autoAllocationPop": "Places Points into Stats according to your preferences, when you level up.",
- "evenAllocation": "Distribute Stat Points evenly",
- "evenAllocationPop": "Assigns the same number of Points to each Stat.",
- "classAllocation": "Distribute Points based on Class",
- "classAllocationPop": "Assigns more Points to the Stats important to your Class.",
- "taskAllocation": "Distribute Points based on task activity",
- "taskAllocationPop": "Assigns Points based on the Strength, Intelligence, Constitution, and Perception categories associated with the tasks you complete.",
- "distributePoints": "Distribute Unallocated Points",
- "distributePointsPop": "Assigns all unallocated Stat Points according to the selected allocation scheme.",
- "warriorText": "Warriors score more and better \"critical hits\", which randomly give bonus Gold, Experience, and drop chance for scoring a task. They also deal heavy damage to boss monsters. Play a Warrior if you find motivation from unpredictable jackpot-style rewards, or want to dish out the hurt in boss Quests!",
- "wizardText": "Mages learn swiftly, gaining Experience and Levels faster than other classes. They also get a great deal of Mana for using special abilities. Play a Mage if you enjoy the tactical game aspects of Habitica, or if you are strongly motivated by leveling up and unlocking advanced features!",
- "mageText": "Mages learn swiftly, gaining Experience and Levels faster than other classes. They also get a great deal of Mana for using special abilities. Play a Mage if you enjoy the tactical game aspects of Habitica, or if you are strongly motivated by leveling up and unlocking advanced features!",
- "rogueText": "Rogues love to accumulate wealth, gaining more Gold than anyone else, and are adept at finding random items. Their iconic Stealth ability lets them duck the consequences of missed Dailies. Play a Rogue if you find strong motivation from Rewards and Achievements, striving for loot and badges!",
- "healerText": "Healers stand impervious against harm, and extend that protection to others. Missed Dailies and bad Habits don't faze them much, and they have ways to recover Health from failure. Play a Healer if you enjoy assisting others in your Party, or if the idea of cheating Death through hard work inspires you!",
- "optOutOfClasses": "Opt Out",
- "optOutOfPMs": "Opt Out",
- "chooseClass": "Choose your Class",
- "chooseClassLearnMarkdown": "[Learn more about Habitica's class system](http://habitica.wikia.com/wiki/Class_System)",
- "optOutOfClassesText": "Can't be bothered with classes? Want to choose later? Opt out - you'll be a warrior with no special abilities. You can read about the class system later on the wiki and enable classes at any time under User Icon > Settings.",
- "selectClass": "Select <%= heroClass %>",
- "select": "Select",
- "stealth": "Stealth",
- "stealthNewDay": "When a new day begins, you will avoid damage from this many missed Dailies.",
- "streaksFrozen": "Streaks Frozen",
- "streaksFrozenText": "Streaks on missed Dailies will not reset at the end of the day.",
- "respawn": "Respawn!",
- "youDied": "You Died!",
- "dieText": "You've lost a Level, all your Gold, and a random piece of Equipment. Arise, Habiteer, and try again! Curb those negative Habits, be vigilant in completion of Dailies, and hold death at arm's length with a Health Potion if you falter!",
- "sureReset": "Are you sure? This will reset your character's class and allocated Stat Points (you'll get them all back to re-allocate), and costs 3 Gems.",
- "purchaseFor": "Purchase for <%= cost %> Gems?",
- "purchaseForHourglasses": "Purchase for <%= cost %> Hourglasses?",
- "notEnoughMana": "Not enough mana.",
- "invalidTarget": "You can't cast a skill on that.",
- "youCast": "You cast <%= spell %>.",
- "youCastTarget": "You cast <%= spell %> on <%= target %>.",
- "youCastParty": "You cast <%= spell %> for the party.",
- "critBonus": "Critical Hit! Bonus:",
- "gainedGold": "You gained some Gold",
- "gainedMana": "You gained some Mana",
- "gainedHealth": "You gained some Health",
- "gainedExperience": "You gained some Experience",
- "lostGold": "You spent some Gold",
- "lostMana": "You used some Mana",
- "lostHealth": "You lost some Health",
- "lostExperience": "You lost some Experience",
- "displayNameDescription1": "This is what appears in messages you post in the Tavern, guilds, and party chat, along with what is displayed on your avatar. To change it, click the Edit button above. If instead you want to change your username, go to",
- "displayNameDescription2": "Settings->Site",
- "displayNameDescription3": "and look in the Registration section.",
- "unequipBattleGear": "Unequip Battle Gear",
- "unequipCostume": "Unequip Costume",
- "equip": "Equip",
- "unequip": "Unequip",
- "unequipPetMountBackground": "Unequip Pet, Mount, Background",
- "animalSkins": "Animal Skins",
- "chooseClassHeading": "Choose your Class! Or opt out to choose later.",
- "warriorWiki": "Warrior",
- "mageWiki": "Mage",
- "rogueWiki": "Rogue",
- "healerWiki": "Healer",
- "chooseClassLearn": "Learn more about classes",
- "str": "STR",
- "con": "CON",
- "per": "PER",
- "int": "INT",
- "showQuickAllocation": "Show Stat Allocation",
- "hideQuickAllocation": "Hide Stat Allocation",
- "quickAllocationLevelPopover": "Each level earns you one Point to assign to a Stat of your choice. You can do so manually, or let the game decide for you using one of the Automatic Allocation options found in User Icon > Stats.",
- "notEnoughAttrPoints": "You don't have enough Stat Points.",
- "classNotSelected": "You must select Class before you can assign Stat Points.",
- "style": "Style",
- "facialhair": "Facial",
- "photo": "Photo",
- "info": "Info",
- "joined": "Joined",
- "totalLogins": "Total Check Ins",
- "latestCheckin": "Latest Check In",
- "editProfile": "Edit Profile",
- "challengesWon": "Challenges Won",
- "questsCompleted": "Quests Completed",
- "headAccess": "Head Access.",
- "backAccess": "Back Access.",
- "bodyAccess": "Body Access.",
- "mainHand": "Main-Hand",
- "offHand": "Off-Hand",
- "statPoints": "Stat Points",
- "pts": "pts"
-}
\ No newline at end of file
+ "communityGuidelinesWarning": "",
+ "profile": "",
+ "avatar": "",
+ "editAvatar": "",
+ "noDescription": "",
+ "noPhoto": "",
+ "other": "",
+ "fullName": "",
+ "displayName": "",
+ "changeDisplayName": "",
+ "newDisplayName": "",
+ "displayPhoto": "",
+ "displayBlurb": "",
+ "displayBlurbPlaceholder": "",
+ "photoUrl": "",
+ "imageUrl": "",
+ "inventory": "",
+ "social": "",
+ "lvl": "",
+ "buffed": "",
+ "bodyBody": "",
+ "bodySize": "",
+ "size": "",
+ "bodySlim": "",
+ "bodyBroad": "",
+ "unlockSet": "",
+ "locked": "",
+ "shirts": "",
+ "shirt": "",
+ "specialShirts": "",
+ "bodyHead": "",
+ "bodySkin": "",
+ "skin": "",
+ "color": "",
+ "bodyHair": "",
+ "hair": "",
+ "bangs": "",
+ "hairBangs": "",
+ "ponytail": "",
+ "glasses": "",
+ "hairBase": "",
+ "hairSet1": "",
+ "hairSet2": "",
+ "hairSet3": "",
+ "bodyFacialHair": "",
+ "beard": "",
+ "mustache": "",
+ "flower": "",
+ "accent": "",
+ "headband": "",
+ "wheelchair": "",
+ "extra": "",
+ "basicSkins": "",
+ "rainbowSkins": "",
+ "pastelSkins": "",
+ "spookySkins": "",
+ "supernaturalSkins": "",
+ "splashySkins": "",
+ "winterySkins": "",
+ "rainbowColors": "",
+ "shimmerColors": "",
+ "hauntedColors": "",
+ "winteryColors": "",
+ "equipment": "",
+ "equipmentBonus": "",
+ "equipmentBonusText": "",
+ "classBonusText": "",
+ "classEquipBonus": "",
+ "battleGear": "",
+ "gear": "",
+ "battleGearText": "",
+ "autoEquipBattleGear": "",
+ "costume": "",
+ "costumeText": "",
+ "useCostume": "",
+ "useCostumeInfo1": "",
+ "useCostumeInfo2": "",
+ "costumePopoverText": "",
+ "autoEquipPopoverText": "",
+ "costumeDisabled": "",
+ "gearAchievement": "",
+ "gearAchievementNotification": "",
+ "moreGearAchievements": "",
+ "armoireUnlocked": "",
+ "ultimGearName": "",
+ "ultimGearText": "",
+ "level": "",
+ "levelUp": "",
+ "gainedLevel": "",
+ "leveledUp": "",
+ "fullyHealed": "",
+ "huzzah": "",
+ "mana": "",
+ "hp": "",
+ "mp": "",
+ "xp": "",
+ "health": "",
+ "allocateStr": "",
+ "allocateStrPop": "",
+ "allocateCon": "",
+ "allocateConPop": "",
+ "allocatePer": "",
+ "allocatePerPop": "",
+ "allocateInt": "",
+ "allocateIntPop": "",
+ "noMoreAllocate": "",
+ "stats": "",
+ "achievs": "",
+ "strength": "",
+ "strText": "",
+ "constitution": "",
+ "conText": "",
+ "perception": "",
+ "perText": "",
+ "intelligence": "",
+ "intText": "",
+ "levelBonus": "",
+ "levelBonusText": "",
+ "allocatedPoints": "",
+ "allocatedPointsText": "",
+ "allocated": "",
+ "buffs": "",
+ "buffsText": "",
+ "characterBuild": "",
+ "class": "",
+ "experience": "",
+ "warrior": "",
+ "healer": "",
+ "rogue": "",
+ "mage": "",
+ "wizard": "",
+ "mystery": "",
+ "changeClass": "",
+ "lvl10ChangeClass": "",
+ "changeClassConfirmCost": "",
+ "invalidClass": "",
+ "levelPopover": "",
+ "unallocated": "",
+ "haveUnallocated": "",
+ "autoAllocation": "",
+ "autoAllocationPop": "",
+ "evenAllocation": "",
+ "evenAllocationPop": "",
+ "classAllocation": "",
+ "classAllocationPop": "",
+ "taskAllocation": "",
+ "taskAllocationPop": "",
+ "distributePoints": "",
+ "distributePointsPop": "",
+ "warriorText": "",
+ "wizardText": "",
+ "mageText": "",
+ "rogueText": "",
+ "healerText": "",
+ "optOutOfClasses": "",
+ "optOutOfPMs": "",
+ "chooseClass": "",
+ "chooseClassLearnMarkdown": "",
+ "optOutOfClassesText": "",
+ "selectClass": "",
+ "select": "",
+ "stealth": "",
+ "stealthNewDay": "",
+ "streaksFrozen": "",
+ "streaksFrozenText": "",
+ "respawn": "",
+ "youDied": "",
+ "dieText": "",
+ "sureReset": "",
+ "purchaseFor": "",
+ "purchaseForHourglasses": "",
+ "notEnoughMana": "",
+ "invalidTarget": "",
+ "youCast": "",
+ "youCastTarget": "",
+ "youCastParty": "",
+ "critBonus": "",
+ "gainedGold": "",
+ "gainedMana": "",
+ "gainedHealth": "",
+ "gainedExperience": "",
+ "lostGold": "",
+ "lostMana": "",
+ "lostHealth": "",
+ "lostExperience": "",
+ "displayNameDescription1": "",
+ "displayNameDescription2": "",
+ "displayNameDescription3": "",
+ "unequipBattleGear": "",
+ "unequipCostume": "",
+ "equip": "",
+ "unequip": "",
+ "unequipPetMountBackground": "",
+ "animalSkins": "",
+ "chooseClassHeading": "",
+ "warriorWiki": "",
+ "mageWiki": "",
+ "rogueWiki": "",
+ "healerWiki": "",
+ "chooseClassLearn": "",
+ "str": "",
+ "con": "",
+ "per": "",
+ "int": "",
+ "showQuickAllocation": "",
+ "hideQuickAllocation": "",
+ "quickAllocationLevelPopover": "",
+ "notEnoughAttrPoints": "",
+ "classNotSelected": "",
+ "style": "",
+ "facialhair": "",
+ "photo": "",
+ "info": "",
+ "joined": "",
+ "totalLogins": "",
+ "latestCheckin": "",
+ "editProfile": "",
+ "challengesWon": "",
+ "questsCompleted": "",
+ "headAccess": "",
+ "backAccess": "",
+ "bodyAccess": "",
+ "mainHand": "",
+ "offHand": "",
+ "statPoints": "",
+ "pts": ""
+}
diff --git a/website/common/locales/eu/communityguidelines.json b/website/common/locales/eu/communityguidelines.json
index 301ed05ebc..5770676386 100755
--- a/website/common/locales/eu/communityguidelines.json
+++ b/website/common/locales/eu/communityguidelines.json
@@ -1,128 +1,128 @@
{
- "iAcceptCommunityGuidelines": "I agree to abide by the Community Guidelines",
- "tavernCommunityGuidelinesPlaceholder": "Friendly reminder: this is an all-ages chat, so please keep content and language appropriate! Consult the Community Guidelines in the sidebar if you have questions.",
- "lastUpdated": "Last updated:",
- "commGuideHeadingWelcome": "Welcome to Habitica!",
- "commGuidePara001": "Greetings, adventurer! Welcome to Habitica, the land of productivity, healthy living, and the occasional rampaging gryphon. We have a cheerful community full of helpful people supporting each other on their way to self-improvement. To fit in, all it takes is a positive attitude, a respectful manner, and the understanding that everyone has different skills and limitations -- including you! Habiticans are patient with one another and try to help whenever they can.",
- "commGuidePara002": "To help keep everyone safe, happy, and productive in the community, we do have some guidelines. We have carefully crafted them to make them as friendly and easy-to-read as possible. Please take the time to read them before you start chatting.",
- "commGuidePara003": "These rules apply to all of the social spaces we use, including (but not necessarily limited to) Trello, GitHub, Transifex, and the Wikia (aka wiki). Sometimes, unforeseen situations will arise, like a new source of conflict or a vicious necromancer. When this happens, the mods may respond by editing these guidelines to keep the community safe from new threats. Fear not: you will be notified by an announcement from Bailey if the guidelines change.",
- "commGuidePara004": "Now ready your quills and scrolls for note-taking, and let's get started!",
- "commGuideHeadingInteractions": "Interactions in Habitica",
- "commGuidePara015": "Habitica has two kinds of social spaces: public, and private. Public spaces include the Tavern, Public Guilds, GitHub, Trello, and the Wiki. Private spaces are Private Guilds, Party chat, and Private Messages. All Display Names must comply with the public space guidelines. To change your Display Name, go on the website to User > Profile and click on the \"Edit\" button.",
- "commGuidePara016": "When navigating the public spaces in Habitica, there are some general rules to keep everyone safe and happy. These should be easy for adventurers like you!",
- "commGuideList02A": "Respect each other. Be courteous, kind, friendly, and helpful. Remember: Habiticans come from all backgrounds and have had wildly divergent experiences. This is part of what makes Habitica so cool! Building a community means respecting and celebrating our differences as well as our similarities. Here are some easy ways to respect each other:",
- "commGuideList02B": "Obey all of the Terms and Conditions.",
- "commGuideList02C": "Do not post images or text that are violent, threatening, or sexually explicit/suggestive, or that promote discrimination, bigotry, racism, sexism, hatred, harassment or harm against any individual or group. Not even as a joke. This includes slurs as well as statements. Not everyone has the same sense of humor, and so something that you consider a joke may be hurtful to another. Attack your Dailies, not each other.",
- "commGuideList02D": "Keep discussions appropriate for all ages. We have many young Habiticans who use the site! Let's not tarnish any innocents or hinder any Habiticans in their goals.",
- "commGuideList02E": "Avoid profanity. This includes milder, religious-based oaths that may be acceptable elsewhere. We have people from all religious and cultural backgrounds, and we want to make sure that all of them feel comfortable in public spaces. If a moderator or staff member tells you that a term is disallowed on Habitica, even if it is a term that you did not realize was problematic, that decision is final. Additionally, slurs will be dealt with very severely, as they are also a violation of the Terms of Service.",
- "commGuideList02F": "Avoid extended discussions of divisive topics in the Tavern and where it would be off-topic. If you feel that someone has said something rude or hurtful, do not engage them. If someone mentions something that is allowed by the guidelines but which is hurtful to you, it’s okay to politely let someone know that. If it is against the guidelines or the Terms of Service, you should flag it and let a mod respond. When in doubt, flag the post.",
- "commGuideList02G": "Comply immediately with any Mod request. This could include, but is not limited to, requesting you limit your posts in a particular space, editing your profile to remove unsuitable content, asking you to move your discussion to a more suitable space, etc.",
- "commGuideList02H": "Take time to reflect instead of responding in anger if someone tells you that something you said or did made them uncomfortable. There is great strength in being able to sincerely apologize to someone. If you feel that the way they responded to you was inappropriate, contact a mod rather than calling them out on it publicly.",
- "commGuideList02I": "Divisive/contentious conversations should be reported to mods by flagging the messages involved or using the Moderator Contact Form. If you feel that a conversation is getting heated, overly emotional, or hurtful, cease to engage. Instead, report the posts to let us know about it. Moderators will respond as quickly as possible. It's our job to keep you safe. If you feel that more context is required, you can report the problem using the Moderator Contact Form.",
- "commGuideList02J": "Do not spam. Spamming may include, but is not limited to: posting the same comment or query in multiple places, posting links without explanation or context, posting nonsensical messages, posting multiple promotional messages about a Guild, Party or Challenge, or posting many messages in a row. Asking for gems or a subscription in any of the chat spaces or via Private Message is also considered spamming. If people clicking on a link will result in any benefit to you, you need to disclose that in the text of your message or that will also be considered spam.
It is up to the mods to decide if something constitutes spam or might lead to spam, even if you don’t feel that you have been spamming. For example, advertising a Guild is acceptable once or twice, but multiple posts in one day would probably constitute spam, no matter how useful the Guild is!",
- "commGuideList02K": "Avoid posting large header text in the public chat spaces, particularly the Tavern. Much like ALL CAPS, it reads as if you were yelling, and interferes with the comfortable atmosphere.",
- "commGuideList02L": "We highly discourage the exchange of personal information -- particularly information that can be used to identify you -- in public chat spaces. Identifying information can include but is not limited to: your address, your email address, and your API token/password. This is for your safety! Staff or moderators may remove such posts at their discretion. If you are asked for personal information in a private Guild, Party, or PM, we highly recommend that you politely refuse and alert the staff and moderators by either 1) flagging the message if it is in a Party or private Guild, or 2) filling out the Moderator Contact Form and including screenshots.",
- "commGuidePara019": "In private spaces, users have more freedom to discuss whatever topics they would like, but they still may not violate the Terms and Conditions, including posting slurs or any discriminatory, violent, or threatening content. Note that, because Challenge names appear in the winner's public profile, ALL Challenge names must obey the public space guidelines, even if they appear in a private space.",
- "commGuidePara020": "Private Messages (PMs) have some additional guidelines. If someone has blocked you, do not contact them elsewhere to ask them to unblock you. Additionally, you should not send PMs to someone asking for support (since public answers to support questions are helpful to the community). Finally, do not send anyone PMs begging for a gift of gems or a subscription, as this can be considered spamming.",
- "commGuidePara020A": "If you see a post that you believe is in violation of the public space guidelines outlined above, or if you see a post that concerns you or makes you uncomfortable, you can bring it to the attention of Moderators and Staff by clicking the flag icon to report it. A Staff member or Moderator will respond to the situation as soon as possible. Please note that intentionally reporting innocent posts is an infraction of these Guidelines (see below in “Infractions”). PMs cannot be flagged at this time, so if you need to report a PM, please contact the Mods via the form on the “Contact Us” page, which you can also access via the help menu by clicking “Contact the Moderation Team.” You may want to do this if there are multiple problematic posts by the same person in different Guilds, or if the situation requires some explanation. You may contact us in your native language if that is easier for you: we may have to use Google Translate, but we want you to feel comfortable about contacting us if you have a problem.",
- "commGuidePara021": "Furthermore, some public spaces in Habitica have additional guidelines.",
- "commGuideHeadingTavern": "The Tavern",
- "commGuidePara022": "The Tavern is the main spot for Habiticans to mingle. Daniel the Innkeeper keeps the place spic-and-span, and Lemoness will happily conjure up some lemonade while you sit and chat. Just keep in mind…",
- "commGuidePara023": "Conversation tends to revolve around casual chatting and productivity or life improvement tips. Because the Tavern chat can only hold 200 messages, it isn't a good place for prolonged conversations on topics, especially sensitive ones (ex. politics, religion, depression, whether or not goblin-hunting should be banned, etc.). These conversations should be taken to an applicable Guild. A Mod may direct you to a suitable Guild, but it is ultimately your responsibility to find and post in the appropriate place.",
- "commGuidePara024": "Don't discuss anything addictive in the Tavern. Many people use Habitica to try to quit their bad Habits. Hearing people talk about addictive/illegal substances may make this much harder for them! Respect your fellow Tavern-goers and take this into consideration. This includes, but is not exclusive to: smoking, alcohol, pornography, gambling, and drug use/abuse.",
- "commGuidePara027": "When a moderator directs you to take a conversation elsewhere, if there is no relevant Guild, they may suggest you use the Back Corner. The Back Corner Guild is a free public space to discuss potentially sensitive subjects that should only be used when directed there by a moderator. It is carefully monitored by the moderation team. It is not a place for general discussions or conversations, and you will be directed there by a mod only when it is appropriate.",
- "commGuideHeadingPublicGuilds": "Public Guilds",
- "commGuidePara029": "Public Guilds are much like the Tavern, except that instead of being centered around general conversation, they have a focused theme. Public Guild chat should focus on this theme. For example, members of the Wordsmiths Guild might be cross if the conversation is suddenly focusing on gardening instead of writing, and a Dragon-Fanciers Guild might not have any interest in deciphering ancient runes. Some Guilds are more lax about this than others, but in general, try to stay on topic!",
- "commGuidePara031": "Some public Guilds will contain sensitive topics such as depression, religion, politics, etc. This is fine as long as the conversations therein do not violate any of the Terms and Conditions or Public Space Rules, and as long as they stay on topic.",
- "commGuidePara033": "Public Guilds may NOT contain 18+ content. If they plan to regularly discuss sensitive content, they should say so in the Guild description. This is to keep Habitica safe and comfortable for everyone.",
- "commGuidePara035": "If the Guild in question has different kinds of sensitive issues, it is respectful to your fellow Habiticans to place your comment behind a warning (ex. \"Warning: references self-harm\"). These may be characterized as trigger warnings and/or content notes, and Guilds may have their own rules in addition to those given here. If possible, please use markdown to hide the potentially sensitive content below line breaks so that those who may wish to avoid reading it can scroll past it without seeing the content. Habitica staff and moderators may still remove this material at their discretion.",
- "commGuidePara036": "Additionally, the sensitive material should be topical -- bringing up self-harm in a Guild focused on fighting depression may make sense, but is probably less appropriate in a music Guild. If you see someone who is repeatedly violating this guideline, especially after several requests, please flag the posts and notify the moderators via the Moderator Contact Form.",
- "commGuidePara037": "No Guilds, Public or Private, should be created for the purpose of attacking any group or individual. Creating such a Guild is grounds for an instant ban. Fight bad habits, not your fellow adventurers!",
- "commGuidePara038": "All Tavern Challenges and Public Guild Challenges must comply with these rules as well.",
- "commGuideHeadingInfractionsEtc": "Infractions, Consequences, and Restoration",
- "commGuideHeadingInfractions": "Infractions",
- "commGuidePara050": "Overwhelmingly, Habiticans assist each other, are respectful, and work to make the whole community fun and friendly. However, once in a blue moon, something that a Habitican does may violate one of the above guidelines. When this happens, the Mods will take whatever actions they deem necessary to keep Habitica safe and comfortable for everyone.",
- "commGuidePara051": "There are a variety of infractions, and they are dealt with depending on their severity. These are not comprehensive lists, and the Mods can make decisions on topics not covered here at their own discretion. The Mods will take context into account when evaluating infractions.",
- "commGuideHeadingSevereInfractions": "Severe Infractions",
- "commGuidePara052": "Severe infractions greatly harm the safety of Habitica's community and users, and therefore have severe consequences as a result.",
- "commGuidePara053": "The following are examples of some severe infractions. This is not a comprehensive list.",
- "commGuideList05A": "Violation of Terms and Conditions",
- "commGuideList05B": "Hate Speech/Images, Harassment/Stalking, Cyber-Bullying, Flaming, and Trolling",
- "commGuideList05C": "Violation of Probation",
- "commGuideList05D": "Impersonation of Staff or Moderators",
- "commGuideList05E": "Repeated Moderate Infractions",
- "commGuideList05F": "Creation of a duplicate account to avoid consequences (for example, making a new account to chat after having chat privileges revoked)",
- "commGuideList05G": "Intentional deception of Staff or Moderators in order to avoid consequences or to get another user in trouble",
- "commGuideHeadingModerateInfractions": "Moderate Infractions",
- "commGuidePara054": "Moderate infractions do not make our community unsafe, but they do make it unpleasant. These infractions will have moderate consequences. When in conjunction with multiple infractions, the consequences may grow more severe.",
- "commGuidePara055": "The following are some examples of Moderate Infractions. This is not a comprehensive list.",
- "commGuideList06A": "Ignoring, disrespecting or arguing with a Mod. This includes publicly complaining about moderators or other users, publicly glorifying or defending banned users, or debating whether or not a moderator action was appropriate. If you are concerned about one of the rules or the behaviour of the Mods, please contact the staff via email (admin@habitica.com).",
- "commGuideList06B": "Backseat Modding. To quickly clarify a relevant point: A friendly mention of the rules is fine. Backseat modding consists of telling, demanding, and/or strongly implying that someone must take an action that you describe to correct a mistake. You can alert someone to the fact that they have committed a transgression, but please do not demand an action -- for example, saying, \"Just so you know, profanity is discouraged in the Tavern, so you may want to delete that,\" would be better than saying, \"I'm going to have to ask you to delete that post.\"",
- "commGuideList06C": "Intentionally flagging innocent posts.",
- "commGuideList06D": "Repeatedly Violating Public Space Guidelines",
- "commGuideList06E": "Repeatedly Committing Minor Infractions",
- "commGuideHeadingMinorInfractions": "Minor Infractions",
- "commGuidePara056": "Minor Infractions, while discouraged, still have minor consequences. If they continue to occur, they can lead to more severe consequences over time.",
- "commGuidePara057": "The following are some examples of Minor Infractions. This is not a comprehensive list.",
- "commGuideList07A": "First-time violation of Public Space Guidelines",
- "commGuideList07B": "Any statements or actions that trigger a \"Please Don't\". When a Mod has to say \"Please don't do this\" to a user, it can count as a very minor infraction for that user. An example might be \"Please don't keep arguing in favor of this feature idea after we've told you several times that it isn't feasible.\" In many cases, the Please Don't will be the minor consequence as well, but if Mods have to say \"Please Don't\" to the same user enough times, the triggering Minor Infractions will start to count as Moderate Infractions.",
- "commGuidePara057A": "Some posts may be hidden because they contain sensitive information or might give people the wrong idea. Typically this does not count as an infraction, particularly not the first time it happens!",
- "commGuideHeadingConsequences": "Consequences",
- "commGuidePara058": "In Habitica -- as in real life -- every action has a consequence, whether it is getting fit because you've been running, getting cavities because you've been eating too much sugar, or passing a class because you've been studying.",
- "commGuidePara059": "Similarly, all infractions have direct consequences. Some sample consequences are outlined below.",
- "commGuidePara060": "If your infraction has a moderate or severe consequence, there will be a post from a staff member or moderator in the forum in which the infraction occurred explaining:",
- "commGuideList08A": "what your infraction was",
- "commGuideList08B": "what the consequence is",
- "commGuideList08C": "what to do to correct the situation and restore your status, if possible.",
- "commGuidePara060A": "If the situation calls for it, you may receive a PM or email as well as a post in the forum in which the infraction occurred. In some cases you may not be reprimanded in public at all.",
- "commGuidePara060B": "If your account is banned (a severe consequence), you will not be able to log into Habitica and will receive an error message upon attempting to log in. If you wish to apologize or make a plea for reinstatement, please email the staff at admin@habitica.com with your UUID (which will be given in the error message). It is your responsibility to reach out if you desire reconsideration or reinstatement.",
- "commGuideHeadingSevereConsequences": "Examples of Severe Consequences",
- "commGuideList09A": "Account bans (see above)",
- "commGuideList09C": "Permanently disabling (\"freezing\") progression through Contributor Tiers",
- "commGuideHeadingModerateConsequences": "Examples of Moderate Consequences",
- "commGuideList10A": "Restricted public and/or private chat privileges",
- "commGuideList10A1": "If your actions result in revocation of your chat privileges, a Moderator or Staff member will PM you and/or post in the forum in which you were muted to notify you of the reason for your muting and the length of time for which you will be muted. At the end of that period, you will receive your chat privileges back, provided you are willing to correct the behavior for which you were muted and comply with the Community Guidelines.",
- "commGuideList10C": "Restricted Guild/Challenge creation privileges",
- "commGuideList10D": "Temporarily disabling (\"freezing\") progression through Contributor Tiers",
- "commGuideList10E": "Demotion of Contributor Tiers",
- "commGuideList10F": "Putting users on \"Probation\"",
- "commGuideHeadingMinorConsequences": "Examples of Minor Consequences",
- "commGuideList11A": "Reminders of Public Space Guidelines",
- "commGuideList11B": "Warnings",
- "commGuideList11C": "Requests",
- "commGuideList11D": "Deletions (Mods/Staff may delete problematic content)",
- "commGuideList11E": "Edits (Mods/Staff may edit problematic content)",
- "commGuideHeadingRestoration": "Restoration",
- "commGuidePara061": "Habitica is a land devoted to self-improvement, and we believe in second chances. If you commit an infraction and receive a consequence, view it as a chance to evaluate your actions and strive to be a better member of the community.",
- "commGuidePara062": "The announcement, message, and/or email that you receive explaining the consequences of your actions is a good source of information. Cooperate with any restrictions which have been imposed, and endeavor to meet the requirements to have any penalties lifted.",
- "commGuidePara063": "If you do not understand your consequences, or the nature of your infraction, ask the Staff/Moderators for help so you can avoid committing infractions in the future. If you feel a particular decision was unfair, you can contact the staff to discuss it at admin@habitica.com.",
- "commGuideHeadingMeet": "Meet the Staff and Mods!",
- "commGuidePara006": "Habitica has some tireless knights-errant who join forces with the staff members to keep the community calm, contented, and free of trolls. Each has a specific domain, but will sometimes be called to serve in other social spheres.",
- "commGuidePara007": "Staff have purple tags marked with crowns. Their title is \"Heroic\".",
- "commGuidePara008": "Mods have dark blue tags marked with stars. Their title is \"Guardian\". The only exception is Bailey, who, as an NPC, has a black and green tag marked with a star.",
- "commGuidePara009": "The current Staff Members are (from left to right):",
- "commGuideAKA": "<%= habitName %> aka <%= realName %>",
- "commGuideOnTrello": "<%= trelloName %> on Trello",
- "commGuideOnGitHub": "<%= gitHubName %> on GitHub",
- "commGuidePara010": "There are also several Moderators who assist the staff members. They were selected carefully, so please give them your respect and listen to their suggestions.",
- "commGuidePara011": "The current Moderators are (from left to right):",
- "commGuidePara011a": "in Tavern chat",
- "commGuidePara011b": "on GitHub/Wikia",
- "commGuidePara011c": "on Wikia",
- "commGuidePara011d": "on GitHub",
- "commGuidePara012": "If you have an issue or concern about a particular Mod, please send an email to our Staff (admin@habitica.com).",
- "commGuidePara013": "In a community as big as Habitica, users come and go, and sometimes a staff member or moderator needs to lay down their noble mantle and relax. The following are Staff and Moderators Emeritus. They no longer act with the power of a Staff member or Moderator, but we would still like to honor their work!",
- "commGuidePara014": "Staff and Moderators Emeritus:",
- "commGuideHeadingFinal": "The Final Section",
- "commGuidePara067": "So there you have it, brave Habitican -- the Community Guidelines! Wipe that sweat off of your brow and give yourself some XP for reading it all. If you have any questions or concerns about these Community Guidelines, please reach out to us via the Moderator Contact Form and we will be happy to help clarify things.",
- "commGuidePara068": "Now go forth, brave adventurer, and slay some Dailies!",
- "commGuideHeadingLinks": "Useful Links",
- "commGuideLink01": "Habitica Help: Ask a Question: a Guild for users to ask questions!",
- "commGuideLink02": "The Wiki: the biggest collection of information about Habitica.",
- "commGuideLink03": "GitHub: for bug reports or helping with code!",
- "commGuideLink04": "The Main Trello: for site feature requests.",
- "commGuideLink05": "The Mobile Trello: for mobile feature requests.",
- "commGuideLink06": "The Art Trello: for submitting pixel art.",
- "commGuideLink07": "The Quest Trello: for submitting quest writing.",
- "commGuidePara069": "The following talented artists contributed to these illustrations:"
-}
\ No newline at end of file
+ "iAcceptCommunityGuidelines": "",
+ "tavernCommunityGuidelinesPlaceholder": "",
+ "lastUpdated": "",
+ "commGuideHeadingWelcome": "",
+ "commGuidePara001": "",
+ "commGuidePara002": "",
+ "commGuidePara003": "",
+ "commGuidePara004": "",
+ "commGuideHeadingInteractions": "",
+ "commGuidePara015": "",
+ "commGuidePara016": "",
+ "commGuideList02A": "",
+ "commGuideList02B": "",
+ "commGuideList02C": "",
+ "commGuideList02D": "",
+ "commGuideList02E": "",
+ "commGuideList02F": "",
+ "commGuideList02G": "",
+ "commGuideList02H": "",
+ "commGuideList02I": "",
+ "commGuideList02J": "",
+ "commGuideList02K": "",
+ "commGuideList02L": "",
+ "commGuidePara019": "",
+ "commGuidePara020": "",
+ "commGuidePara020A": "",
+ "commGuidePara021": "",
+ "commGuideHeadingTavern": "",
+ "commGuidePara022": "",
+ "commGuidePara023": "",
+ "commGuidePara024": "",
+ "commGuidePara027": "",
+ "commGuideHeadingPublicGuilds": "",
+ "commGuidePara029": "",
+ "commGuidePara031": "",
+ "commGuidePara033": "",
+ "commGuidePara035": "",
+ "commGuidePara036": "",
+ "commGuidePara037": "",
+ "commGuidePara038": "",
+ "commGuideHeadingInfractionsEtc": "",
+ "commGuideHeadingInfractions": "",
+ "commGuidePara050": "",
+ "commGuidePara051": "",
+ "commGuideHeadingSevereInfractions": "",
+ "commGuidePara052": "",
+ "commGuidePara053": "",
+ "commGuideList05A": "",
+ "commGuideList05B": "",
+ "commGuideList05C": "",
+ "commGuideList05D": "",
+ "commGuideList05E": "",
+ "commGuideList05F": "",
+ "commGuideList05G": "",
+ "commGuideHeadingModerateInfractions": "",
+ "commGuidePara054": "",
+ "commGuidePara055": "",
+ "commGuideList06A": "",
+ "commGuideList06B": "",
+ "commGuideList06C": "",
+ "commGuideList06D": "",
+ "commGuideList06E": "",
+ "commGuideHeadingMinorInfractions": "",
+ "commGuidePara056": "",
+ "commGuidePara057": "",
+ "commGuideList07A": "",
+ "commGuideList07B": "",
+ "commGuidePara057A": "",
+ "commGuideHeadingConsequences": "",
+ "commGuidePara058": "",
+ "commGuidePara059": "",
+ "commGuidePara060": "",
+ "commGuideList08A": "",
+ "commGuideList08B": "",
+ "commGuideList08C": "",
+ "commGuidePara060A": "",
+ "commGuidePara060B": "",
+ "commGuideHeadingSevereConsequences": "",
+ "commGuideList09A": "",
+ "commGuideList09C": "",
+ "commGuideHeadingModerateConsequences": "",
+ "commGuideList10A": "",
+ "commGuideList10A1": "",
+ "commGuideList10C": "",
+ "commGuideList10D": "",
+ "commGuideList10E": "",
+ "commGuideList10F": "",
+ "commGuideHeadingMinorConsequences": "",
+ "commGuideList11A": "",
+ "commGuideList11B": "",
+ "commGuideList11C": "",
+ "commGuideList11D": "",
+ "commGuideList11E": "",
+ "commGuideHeadingRestoration": "",
+ "commGuidePara061": "",
+ "commGuidePara062": "",
+ "commGuidePara063": "",
+ "commGuideHeadingMeet": "",
+ "commGuidePara006": "",
+ "commGuidePara007": "",
+ "commGuidePara008": "",
+ "commGuidePara009": "",
+ "commGuideAKA": "",
+ "commGuideOnTrello": "",
+ "commGuideOnGitHub": "",
+ "commGuidePara010": "",
+ "commGuidePara011": "",
+ "commGuidePara011a": "",
+ "commGuidePara011b": "",
+ "commGuidePara011c": "",
+ "commGuidePara011d": "",
+ "commGuidePara012": "",
+ "commGuidePara013": "",
+ "commGuidePara014": "",
+ "commGuideHeadingFinal": "",
+ "commGuidePara067": "",
+ "commGuidePara068": "",
+ "commGuideHeadingLinks": "",
+ "commGuideLink01": "",
+ "commGuideLink02": "",
+ "commGuideLink03": "",
+ "commGuideLink04": "",
+ "commGuideLink05": "",
+ "commGuideLink06": "",
+ "commGuideLink07": "",
+ "commGuidePara069": ""
+}
diff --git a/website/common/locales/eu/content.json b/website/common/locales/eu/content.json
index 3f17e549a0..1e1ae9635f 100755
--- a/website/common/locales/eu/content.json
+++ b/website/common/locales/eu/content.json
@@ -1,310 +1,310 @@
{
- "potionText": "Health Potion",
- "potionNotes": "Recover 15 Health (Instant Use)",
- "armoireText": "Enchanted Armoire",
- "armoireNotesFull": "Open the Armoire to randomly receive special Equipment, Experience, or food! Equipment pieces remaining:",
- "armoireLastItem": "You've found the last piece of rare Equipment in the Enchanted Armoire.",
- "armoireNotesEmpty": "The Armoire will have new Equipment in the first week of every month. Until then, keep clicking for Experience and Food!",
- "dropEggWolfText": "Wolf",
- "dropEggWolfMountText": "Wolf",
- "dropEggWolfAdjective": "a loyal",
- "dropEggTigerCubText": "Tiger Cub",
- "dropEggTigerCubMountText": "Tiger",
- "dropEggTigerCubAdjective": "a fierce",
- "dropEggPandaCubText": "Panda Cub",
- "dropEggPandaCubMountText": "Panda",
- "dropEggPandaCubAdjective": "a gentle",
- "dropEggLionCubText": "Lion Cub",
- "dropEggLionCubMountText": "Lion",
- "dropEggLionCubAdjective": "a regal",
- "dropEggFoxText": "Fox",
- "dropEggFoxMountText": "Fox",
- "dropEggFoxAdjective": "a wily",
- "dropEggFlyingPigText": "Flying Pig",
- "dropEggFlyingPigMountText": "Flying Pig",
- "dropEggFlyingPigAdjective": "a whimsical",
- "dropEggDragonText": "Dragon",
- "dropEggDragonMountText": "Dragon",
- "dropEggDragonAdjective": "a mighty",
- "dropEggCactusText": "Cactus",
- "dropEggCactusMountText": "Cactus",
- "dropEggCactusAdjective": "a prickly",
- "dropEggBearCubText": "Bear Cub",
- "dropEggBearCubMountText": "Bear",
- "dropEggBearCubAdjective": "a brave",
- "questEggGryphonText": "Gryphon",
- "questEggGryphonMountText": "Gryphon",
- "questEggGryphonAdjective": "a proud",
- "questEggHedgehogText": "Hedgehog",
- "questEggHedgehogMountText": "Hedgehog",
- "questEggHedgehogAdjective": "a spiky",
- "questEggDeerText": "Deer",
- "questEggDeerMountText": "Deer",
- "questEggDeerAdjective": "an elegant",
- "questEggEggText": "Egg",
- "questEggEggMountText": "Egg Basket",
- "questEggEggAdjective": "a colorful",
- "questEggRatText": "Rat",
- "questEggRatMountText": "Rat",
- "questEggRatAdjective": "a sociable",
- "questEggOctopusText": "Octopus",
- "questEggOctopusMountText": "Octopus",
- "questEggOctopusAdjective": "a slippery",
- "questEggSeahorseText": "Seahorse",
- "questEggSeahorseMountText": "Seahorse",
- "questEggSeahorseAdjective": "a prize",
- "questEggParrotText": "Parrot",
- "questEggParrotMountText": "Parrot",
- "questEggParrotAdjective": "a vibrant",
- "questEggRoosterText": "Rooster",
- "questEggRoosterMountText": "Rooster",
- "questEggRoosterAdjective": "a strutting",
- "questEggSpiderText": "Spider",
- "questEggSpiderMountText": "Spider",
- "questEggSpiderAdjective": "an artistic",
- "questEggOwlText": "Owl",
- "questEggOwlMountText": "Owl",
- "questEggOwlAdjective": "a wise",
- "questEggPenguinText": "Penguin",
- "questEggPenguinMountText": "Penguin",
- "questEggPenguinAdjective": "a perspicacious",
- "questEggTRexText": "Tyrannosaur",
- "questEggTRexMountText": "Tyrannosaur",
- "questEggTRexAdjective": "a tiny-armed",
- "questEggRockText": "Rock",
- "questEggRockMountText": "Rock",
- "questEggRockAdjective": "a lively",
- "questEggBunnyText": "Bunny",
- "questEggBunnyMountText": "Bunny",
- "questEggBunnyAdjective": "a snuggly",
- "questEggSlimeText": "Marshmallow Slime",
- "questEggSlimeMountText": "Marshmallow Slime",
- "questEggSlimeAdjective": "a sweet",
- "questEggSheepText": "Sheep",
- "questEggSheepMountText": "Sheep",
- "questEggSheepAdjective": "a woolly",
- "questEggCuttlefishText": "Cuttlefish",
- "questEggCuttlefishMountText": "Cuttlefish",
- "questEggCuttlefishAdjective": "a cuddly",
- "questEggWhaleText": "Whale",
- "questEggWhaleMountText": "Whale",
- "questEggWhaleAdjective": "a splashy",
- "questEggCheetahText": "Cheetah",
- "questEggCheetahMountText": "Cheetah",
- "questEggCheetahAdjective": "an honest",
- "questEggHorseText": "Horse",
- "questEggHorseMountText": "Horse",
- "questEggHorseAdjective": "a galloping",
- "questEggFrogText": "Frog",
- "questEggFrogMountText": "Frog",
- "questEggFrogAdjective": "a princely",
- "questEggSnakeText": "Snake",
- "questEggSnakeMountText": "Snake",
- "questEggSnakeAdjective": "a slithering",
- "questEggUnicornText": "Unicorn",
- "questEggUnicornMountText": "Winged Unicorn",
- "questEggUnicornAdjective": "a magical",
- "questEggSabretoothText": "Sabretooth Tiger",
- "questEggSabretoothMountText": "Sabretooth Tiger",
- "questEggSabretoothAdjective": "a ferocious",
- "questEggMonkeyText": "Monkey",
- "questEggMonkeyMountText": "Monkey",
- "questEggMonkeyAdjective": "a mischievous",
- "questEggSnailText": "Snail",
- "questEggSnailMountText": "Snail",
- "questEggSnailAdjective": "a slow but steady",
- "questEggFalconText": "Falcon",
- "questEggFalconMountText": "Falcon",
- "questEggFalconAdjective": "a swift",
- "questEggTreelingText": "Treeling",
- "questEggTreelingMountText": "Treeling",
- "questEggTreelingAdjective": "a leafy",
- "questEggAxolotlText": "Axolotl",
- "questEggAxolotlMountText": "Axolotl",
- "questEggAxolotlAdjective": "a little",
- "questEggTurtleText": "Sea Turtle",
- "questEggTurtleMountText": "Giant Sea Turtle",
- "questEggTurtleAdjective": "a peaceful",
- "questEggArmadilloText": "Armadillo",
- "questEggArmadilloMountText": "Armadillo",
- "questEggArmadilloAdjective": "an armored",
- "questEggCowText": "Cow",
- "questEggCowMountText": "Cow",
- "questEggCowAdjective": "a mooing",
- "questEggBeetleText": "Beetle",
- "questEggBeetleMountText": "Beetle",
- "questEggBeetleAdjective": "an unbeatable",
- "questEggFerretText": "Ferret",
- "questEggFerretMountText": "Ferret",
- "questEggFerretAdjective": "a furry",
- "questEggSlothText": "Sloth",
- "questEggSlothMountText": "Sloth",
- "questEggSlothAdjective": "a speedy",
- "questEggTriceratopsText": "Triceratops",
- "questEggTriceratopsMountText": "Triceratops",
- "questEggTriceratopsAdjective": "a tricky",
- "questEggGuineaPigText": "Guinea Pig",
- "questEggGuineaPigMountText": "Guinea Pig",
- "questEggGuineaPigAdjective": "a giddy",
- "questEggPeacockText": "Peacock",
- "questEggPeacockMountText": "Peacock",
- "questEggPeacockAdjective": "a prancing",
- "questEggButterflyText": "Caterpillar",
- "questEggButterflyMountText": "Butterfly",
- "questEggButterflyAdjective": "a cute",
- "questEggNudibranchText": "Nudibranch",
- "questEggNudibranchMountText": "Nudibranch",
- "questEggNudibranchAdjective": "a nifty",
- "questEggHippoText": "Hippo",
- "questEggHippoMountText": "Hippo",
- "questEggHippoAdjective": "a happy",
- "questEggYarnText": "Yarn",
- "questEggYarnMountText": "Flying Carpet",
- "questEggYarnAdjective": "woolen",
- "questEggPterodactylText": "Pterodactyl",
- "questEggPterodactylMountText": "Pterodactyl",
- "questEggPterodactylAdjective": "a trusting",
- "questEggBadgerText": "Badger",
- "questEggBadgerMountText": "Badger",
- "questEggBadgerAdjective": "a bustling",
- "questEggSquirrelText": "Squirrel",
- "questEggSquirrelMountText": "Squirrel",
- "questEggSquirrelAdjective": "a bushy-tailed",
- "questEggSeaSerpentText": "Sea Serpent",
- "questEggSeaSerpentMountText": "Sea Serpent",
- "questEggSeaSerpentAdjective": "a shimmering",
- "questEggKangarooText": "Kangaroo",
- "questEggKangarooMountText": "Kangaroo",
- "questEggKangarooAdjective": "a keen",
- "questEggAlligatorText": "Alligator",
- "questEggAlligatorMountText": "Alligator",
- "questEggAlligatorAdjective": "a cunning",
- "questEggVelociraptorText": "Velociraptor",
- "questEggVelociraptorMountText": "Velociraptor",
- "questEggVelociraptorAdjective": "a clever",
- "eggNotes": "Find a hatching potion to pour on this egg, and it will hatch into <%= eggAdjective(locale) %> <%= eggText(locale) %>.",
- "hatchingPotionBase": "Base",
- "hatchingPotionWhite": "White",
- "hatchingPotionDesert": "Desert",
- "hatchingPotionRed": "Red",
- "hatchingPotionShade": "Shade",
- "hatchingPotionSkeleton": "Skeleton",
- "hatchingPotionZombie": "Zombie",
- "hatchingPotionCottonCandyPink": "Cotton Candy Pink",
- "hatchingPotionCottonCandyBlue": "Cotton Candy Blue",
- "hatchingPotionGolden": "Golden",
- "hatchingPotionSpooky": "Spooky",
- "hatchingPotionPeppermint": "Peppermint",
- "hatchingPotionFloral": "Floral",
- "hatchingPotionAquatic": "Aquatic",
- "hatchingPotionEmber": "Ember",
- "hatchingPotionThunderstorm": "Thunderstorm",
- "hatchingPotionGhost": "Ghost",
- "hatchingPotionRoyalPurple": "Royal Purple",
- "hatchingPotionHolly": "Holly",
- "hatchingPotionCupid": "Cupid",
- "hatchingPotionShimmer": "Shimmer",
- "hatchingPotionFairy": "Fairy",
- "hatchingPotionStarryNight": "Starry Night",
- "hatchingPotionRainbow": "Rainbow",
- "hatchingPotionGlass": "Glass",
- "hatchingPotionGlow": "Glow-in-the-Dark",
- "hatchingPotionFrost": "Frost",
- "hatchingPotionIcySnow": "Icy Snow",
- "hatchingPotionNotes": "Pour this on an egg, and it will hatch as a <%= potText(locale) %> pet.",
- "premiumPotionAddlNotes": "Not usable on quest pet eggs.",
- "foodMeat": "Meat",
- "foodMeatThe": "the Meat",
- "foodMeatA": "Meat",
- "foodMilk": "Milk",
- "foodMilkThe": "the Milk",
- "foodMilkA": "Milk",
- "foodPotatoe": "Potato",
- "foodPotatoeThe": "the Potato",
- "foodPotatoeA": "a Potato",
- "foodStrawberry": "Strawberry",
- "foodStrawberryThe": "the Strawberry",
- "foodStrawberryA": "a Strawberry",
- "foodChocolate": "Chocolate",
- "foodChocolateThe": "the Chocolate",
- "foodChocolateA": "Chocolate",
- "foodFish": "Fish",
- "foodFishThe": "the Fish",
- "foodFishA": "a Fish",
- "foodRottenMeat": "Rotten Meat",
- "foodRottenMeatThe": "the Rotten Meat",
- "foodRottenMeatA": "Rotten Meat",
- "foodCottonCandyPink": "Pink Cotton Candy",
- "foodCottonCandyPinkThe": "the Pink Cotton Candy",
- "foodCottonCandyPinkA": "Pink Cotton Candy",
- "foodCottonCandyBlue": "Blue Cotton Candy",
- "foodCottonCandyBlueThe": "the Blue Cotton Candy",
- "foodCottonCandyBlueA": "Blue Cotton Candy",
- "foodHoney": "Honey",
- "foodHoneyThe": "the Honey",
- "foodHoneyA": "Honey",
- "foodCakeSkeleton": "Bare Bones Cake",
- "foodCakeSkeletonThe": "the Bare Bones Cake",
- "foodCakeSkeletonA": "a Bare Bones Cake",
- "foodCakeBase": "Basic Cake",
- "foodCakeBaseThe": "the Basic Cake",
- "foodCakeBaseA": "a Basic Cake",
- "foodCakeCottonCandyBlue": "Candy Blue Cake",
- "foodCakeCottonCandyBlueThe": "the Candy Blue Cake",
- "foodCakeCottonCandyBlueA": "a Candy Blue Cake",
- "foodCakeCottonCandyPink": "Candy Pink Cake",
- "foodCakeCottonCandyPinkThe": "the Candy Pink Cake",
- "foodCakeCottonCandyPinkA": "a Candy Pink Cake",
- "foodCakeShade": "Chocolate Cake",
- "foodCakeShadeThe": "the Chocolate Cake",
- "foodCakeShadeA": "a Chocolate Cake",
- "foodCakeWhite": "Cream Cake",
- "foodCakeWhiteThe": "the Cream Cake",
- "foodCakeWhiteA": "a Cream Cake",
- "foodCakeGolden": "Honey Cake",
- "foodCakeGoldenThe": "the Honey Cake",
- "foodCakeGoldenA": "a Honey Cake",
- "foodCakeZombie": "Rotten Cake",
- "foodCakeZombieThe": "the Rotten Cake",
- "foodCakeZombieA": "a Rotten Cake",
- "foodCakeDesert": "Sand Cake",
- "foodCakeDesertThe": "the Sand Cake",
- "foodCakeDesertA": "a Sand Cake",
- "foodCakeRed": "Strawberry Cake",
- "foodCakeRedThe": "the Strawberry Cake",
- "foodCakeRedA": "a Strawberry Cake",
- "foodCandySkeleton": "Bare Bones Candy",
- "foodCandySkeletonThe": "the Bare Bones Candy",
- "foodCandySkeletonA": "Bare Bones Candy",
- "foodCandyBase": "Basic Candy",
- "foodCandyBaseThe": "the Basic Candy",
- "foodCandyBaseA": "Basic Candy",
- "foodCandyCottonCandyBlue": "Sour Blue Candy",
- "foodCandyCottonCandyBlueThe": "the Sour Blue Candy",
- "foodCandyCottonCandyBlueA": "Sour Blue Candy",
- "foodCandyCottonCandyPink": "Sour Pink Candy",
- "foodCandyCottonCandyPinkThe": "the Sour Pink Candy",
- "foodCandyCottonCandyPinkA": "Sour Pink Candy",
- "foodCandyShade": "Chocolate Candy",
- "foodCandyShadeThe": "the Chocolate Candy",
- "foodCandyShadeA": "Chocolate Candy",
- "foodCandyWhite": "Vanilla Candy",
- "foodCandyWhiteThe": "the Vanilla Candy",
- "foodCandyWhiteA": "Vanilla Candy",
- "foodCandyGolden": "Honey Candy",
- "foodCandyGoldenThe": "the Honey Candy",
- "foodCandyGoldenA": "Honey Candy",
- "foodCandyZombie": "Rotten Candy",
- "foodCandyZombieThe": "the Rotten Candy",
- "foodCandyZombieA": "Rotten Candy",
- "foodCandyDesert": "Sand Candy",
- "foodCandyDesertThe": "the Sand Candy",
- "foodCandyDesertA": "Sand Candy",
- "foodCandyRed": "Cinnamon Candy",
- "foodCandyRedThe": "the Cinnamon Candy",
- "foodCandyRedA": "Cinnamon Candy",
- "foodSaddleText": "Saddle",
- "foodSaddleNotes": "Instantly raises one of your pets into a mount.",
- "foodSaddleSellWarningNote": "Hey! This is a pretty useful item! Are you familiar with how to use a Saddle with your Pets?",
- "foodNotes": "Feed this to a pet and it may grow into a sturdy steed."
-}
\ No newline at end of file
+ "potionText": "",
+ "potionNotes": "",
+ "armoireText": "",
+ "armoireNotesFull": "",
+ "armoireLastItem": "",
+ "armoireNotesEmpty": "",
+ "dropEggWolfText": "",
+ "dropEggWolfMountText": "",
+ "dropEggWolfAdjective": "",
+ "dropEggTigerCubText": "",
+ "dropEggTigerCubMountText": "",
+ "dropEggTigerCubAdjective": "",
+ "dropEggPandaCubText": "",
+ "dropEggPandaCubMountText": "",
+ "dropEggPandaCubAdjective": "",
+ "dropEggLionCubText": "",
+ "dropEggLionCubMountText": "",
+ "dropEggLionCubAdjective": "",
+ "dropEggFoxText": "",
+ "dropEggFoxMountText": "",
+ "dropEggFoxAdjective": "",
+ "dropEggFlyingPigText": "",
+ "dropEggFlyingPigMountText": "",
+ "dropEggFlyingPigAdjective": "",
+ "dropEggDragonText": "",
+ "dropEggDragonMountText": "",
+ "dropEggDragonAdjective": "",
+ "dropEggCactusText": "",
+ "dropEggCactusMountText": "",
+ "dropEggCactusAdjective": "",
+ "dropEggBearCubText": "",
+ "dropEggBearCubMountText": "",
+ "dropEggBearCubAdjective": "",
+ "questEggGryphonText": "",
+ "questEggGryphonMountText": "",
+ "questEggGryphonAdjective": "",
+ "questEggHedgehogText": "",
+ "questEggHedgehogMountText": "",
+ "questEggHedgehogAdjective": "",
+ "questEggDeerText": "",
+ "questEggDeerMountText": "",
+ "questEggDeerAdjective": "",
+ "questEggEggText": "",
+ "questEggEggMountText": "",
+ "questEggEggAdjective": "",
+ "questEggRatText": "",
+ "questEggRatMountText": "",
+ "questEggRatAdjective": "",
+ "questEggOctopusText": "",
+ "questEggOctopusMountText": "",
+ "questEggOctopusAdjective": "",
+ "questEggSeahorseText": "",
+ "questEggSeahorseMountText": "",
+ "questEggSeahorseAdjective": "",
+ "questEggParrotText": "",
+ "questEggParrotMountText": "",
+ "questEggParrotAdjective": "",
+ "questEggRoosterText": "",
+ "questEggRoosterMountText": "",
+ "questEggRoosterAdjective": "",
+ "questEggSpiderText": "",
+ "questEggSpiderMountText": "",
+ "questEggSpiderAdjective": "",
+ "questEggOwlText": "",
+ "questEggOwlMountText": "",
+ "questEggOwlAdjective": "",
+ "questEggPenguinText": "",
+ "questEggPenguinMountText": "",
+ "questEggPenguinAdjective": "",
+ "questEggTRexText": "",
+ "questEggTRexMountText": "",
+ "questEggTRexAdjective": "",
+ "questEggRockText": "",
+ "questEggRockMountText": "",
+ "questEggRockAdjective": "",
+ "questEggBunnyText": "",
+ "questEggBunnyMountText": "",
+ "questEggBunnyAdjective": "",
+ "questEggSlimeText": "",
+ "questEggSlimeMountText": "",
+ "questEggSlimeAdjective": "",
+ "questEggSheepText": "",
+ "questEggSheepMountText": "",
+ "questEggSheepAdjective": "",
+ "questEggCuttlefishText": "",
+ "questEggCuttlefishMountText": "",
+ "questEggCuttlefishAdjective": "",
+ "questEggWhaleText": "",
+ "questEggWhaleMountText": "",
+ "questEggWhaleAdjective": "",
+ "questEggCheetahText": "",
+ "questEggCheetahMountText": "",
+ "questEggCheetahAdjective": "",
+ "questEggHorseText": "",
+ "questEggHorseMountText": "",
+ "questEggHorseAdjective": "",
+ "questEggFrogText": "",
+ "questEggFrogMountText": "",
+ "questEggFrogAdjective": "",
+ "questEggSnakeText": "",
+ "questEggSnakeMountText": "",
+ "questEggSnakeAdjective": "",
+ "questEggUnicornText": "",
+ "questEggUnicornMountText": "",
+ "questEggUnicornAdjective": "",
+ "questEggSabretoothText": "",
+ "questEggSabretoothMountText": "",
+ "questEggSabretoothAdjective": "",
+ "questEggMonkeyText": "",
+ "questEggMonkeyMountText": "",
+ "questEggMonkeyAdjective": "",
+ "questEggSnailText": "",
+ "questEggSnailMountText": "",
+ "questEggSnailAdjective": "",
+ "questEggFalconText": "",
+ "questEggFalconMountText": "",
+ "questEggFalconAdjective": "",
+ "questEggTreelingText": "",
+ "questEggTreelingMountText": "",
+ "questEggTreelingAdjective": "",
+ "questEggAxolotlText": "",
+ "questEggAxolotlMountText": "",
+ "questEggAxolotlAdjective": "",
+ "questEggTurtleText": "",
+ "questEggTurtleMountText": "",
+ "questEggTurtleAdjective": "",
+ "questEggArmadilloText": "",
+ "questEggArmadilloMountText": "",
+ "questEggArmadilloAdjective": "",
+ "questEggCowText": "",
+ "questEggCowMountText": "",
+ "questEggCowAdjective": "",
+ "questEggBeetleText": "",
+ "questEggBeetleMountText": "",
+ "questEggBeetleAdjective": "",
+ "questEggFerretText": "",
+ "questEggFerretMountText": "",
+ "questEggFerretAdjective": "",
+ "questEggSlothText": "",
+ "questEggSlothMountText": "",
+ "questEggSlothAdjective": "",
+ "questEggTriceratopsText": "",
+ "questEggTriceratopsMountText": "",
+ "questEggTriceratopsAdjective": "",
+ "questEggGuineaPigText": "",
+ "questEggGuineaPigMountText": "",
+ "questEggGuineaPigAdjective": "",
+ "questEggPeacockText": "",
+ "questEggPeacockMountText": "",
+ "questEggPeacockAdjective": "",
+ "questEggButterflyText": "",
+ "questEggButterflyMountText": "",
+ "questEggButterflyAdjective": "",
+ "questEggNudibranchText": "",
+ "questEggNudibranchMountText": "",
+ "questEggNudibranchAdjective": "",
+ "questEggHippoText": "",
+ "questEggHippoMountText": "",
+ "questEggHippoAdjective": "",
+ "questEggYarnText": "",
+ "questEggYarnMountText": "",
+ "questEggYarnAdjective": "",
+ "questEggPterodactylText": "",
+ "questEggPterodactylMountText": "",
+ "questEggPterodactylAdjective": "",
+ "questEggBadgerText": "",
+ "questEggBadgerMountText": "",
+ "questEggBadgerAdjective": "",
+ "questEggSquirrelText": "",
+ "questEggSquirrelMountText": "",
+ "questEggSquirrelAdjective": "",
+ "questEggSeaSerpentText": "",
+ "questEggSeaSerpentMountText": "",
+ "questEggSeaSerpentAdjective": "",
+ "questEggKangarooText": "",
+ "questEggKangarooMountText": "",
+ "questEggKangarooAdjective": "",
+ "questEggAlligatorText": "",
+ "questEggAlligatorMountText": "",
+ "questEggAlligatorAdjective": "",
+ "questEggVelociraptorText": "",
+ "questEggVelociraptorMountText": "",
+ "questEggVelociraptorAdjective": "",
+ "eggNotes": "",
+ "hatchingPotionBase": "",
+ "hatchingPotionWhite": "",
+ "hatchingPotionDesert": "",
+ "hatchingPotionRed": "",
+ "hatchingPotionShade": "",
+ "hatchingPotionSkeleton": "",
+ "hatchingPotionZombie": "",
+ "hatchingPotionCottonCandyPink": "",
+ "hatchingPotionCottonCandyBlue": "",
+ "hatchingPotionGolden": "",
+ "hatchingPotionSpooky": "",
+ "hatchingPotionPeppermint": "",
+ "hatchingPotionFloral": "",
+ "hatchingPotionAquatic": "",
+ "hatchingPotionEmber": "",
+ "hatchingPotionThunderstorm": "",
+ "hatchingPotionGhost": "",
+ "hatchingPotionRoyalPurple": "",
+ "hatchingPotionHolly": "",
+ "hatchingPotionCupid": "",
+ "hatchingPotionShimmer": "",
+ "hatchingPotionFairy": "",
+ "hatchingPotionStarryNight": "",
+ "hatchingPotionRainbow": "",
+ "hatchingPotionGlass": "",
+ "hatchingPotionGlow": "",
+ "hatchingPotionFrost": "",
+ "hatchingPotionIcySnow": "",
+ "hatchingPotionNotes": "",
+ "premiumPotionAddlNotes": "",
+ "foodMeat": "",
+ "foodMeatThe": "",
+ "foodMeatA": "",
+ "foodMilk": "",
+ "foodMilkThe": "",
+ "foodMilkA": "",
+ "foodPotatoe": "",
+ "foodPotatoeThe": "",
+ "foodPotatoeA": "",
+ "foodStrawberry": "",
+ "foodStrawberryThe": "",
+ "foodStrawberryA": "",
+ "foodChocolate": "",
+ "foodChocolateThe": "",
+ "foodChocolateA": "",
+ "foodFish": "",
+ "foodFishThe": "",
+ "foodFishA": "",
+ "foodRottenMeat": "",
+ "foodRottenMeatThe": "",
+ "foodRottenMeatA": "",
+ "foodCottonCandyPink": "",
+ "foodCottonCandyPinkThe": "",
+ "foodCottonCandyPinkA": "",
+ "foodCottonCandyBlue": "",
+ "foodCottonCandyBlueThe": "",
+ "foodCottonCandyBlueA": "",
+ "foodHoney": "",
+ "foodHoneyThe": "",
+ "foodHoneyA": "",
+ "foodCakeSkeleton": "",
+ "foodCakeSkeletonThe": "",
+ "foodCakeSkeletonA": "",
+ "foodCakeBase": "",
+ "foodCakeBaseThe": "",
+ "foodCakeBaseA": "",
+ "foodCakeCottonCandyBlue": "",
+ "foodCakeCottonCandyBlueThe": "",
+ "foodCakeCottonCandyBlueA": "",
+ "foodCakeCottonCandyPink": "",
+ "foodCakeCottonCandyPinkThe": "",
+ "foodCakeCottonCandyPinkA": "",
+ "foodCakeShade": "",
+ "foodCakeShadeThe": "",
+ "foodCakeShadeA": "",
+ "foodCakeWhite": "",
+ "foodCakeWhiteThe": "",
+ "foodCakeWhiteA": "",
+ "foodCakeGolden": "",
+ "foodCakeGoldenThe": "",
+ "foodCakeGoldenA": "",
+ "foodCakeZombie": "",
+ "foodCakeZombieThe": "",
+ "foodCakeZombieA": "",
+ "foodCakeDesert": "",
+ "foodCakeDesertThe": "",
+ "foodCakeDesertA": "",
+ "foodCakeRed": "",
+ "foodCakeRedThe": "",
+ "foodCakeRedA": "",
+ "foodCandySkeleton": "",
+ "foodCandySkeletonThe": "",
+ "foodCandySkeletonA": "",
+ "foodCandyBase": "",
+ "foodCandyBaseThe": "",
+ "foodCandyBaseA": "",
+ "foodCandyCottonCandyBlue": "",
+ "foodCandyCottonCandyBlueThe": "",
+ "foodCandyCottonCandyBlueA": "",
+ "foodCandyCottonCandyPink": "",
+ "foodCandyCottonCandyPinkThe": "",
+ "foodCandyCottonCandyPinkA": "",
+ "foodCandyShade": "",
+ "foodCandyShadeThe": "",
+ "foodCandyShadeA": "",
+ "foodCandyWhite": "",
+ "foodCandyWhiteThe": "",
+ "foodCandyWhiteA": "",
+ "foodCandyGolden": "",
+ "foodCandyGoldenThe": "",
+ "foodCandyGoldenA": "",
+ "foodCandyZombie": "",
+ "foodCandyZombieThe": "",
+ "foodCandyZombieA": "",
+ "foodCandyDesert": "",
+ "foodCandyDesertThe": "",
+ "foodCandyDesertA": "",
+ "foodCandyRed": "",
+ "foodCandyRedThe": "",
+ "foodCandyRedA": "",
+ "foodSaddleText": "",
+ "foodSaddleNotes": "",
+ "foodSaddleSellWarningNote": "",
+ "foodNotes": ""
+}
diff --git a/website/common/locales/eu/contrib.json b/website/common/locales/eu/contrib.json
index c1abb6c920..b6151ae84b 100755
--- a/website/common/locales/eu/contrib.json
+++ b/website/common/locales/eu/contrib.json
@@ -1,80 +1,80 @@
{
- "playerTiersDesc": "The colored usernames you see in chat represent a person's contributor tier. The higher the tier, the more the person has contributed to habitica through art, code, the community, or more!",
- "tier1": "Tier 1 (Friend)",
- "tier2": "Tier 2 (Friend)",
- "tier3": "Tier 3 (Elite)",
- "tier4": "Tier 4 (Elite)",
- "tier5": "Tier 5 (Champion)",
- "tier6": "Tier 6 (Champion)",
- "tier7": "Tier 7 (Legendary)",
- "tierModerator": "Moderator (Guardian)",
- "tierStaff": "Staff (Heroic)",
- "tierNPC": "NPC",
- "friend": "Friend",
- "friendFirst": "When your first set of submissions is deployed, you will receive the Habitica Contributor's badge. Your name in Tavern chat will proudly display that you are a contributor. As a bounty for your work, you will also receive 3 Gems.",
- "friendSecond": "When your second set of submissions is deployed, the Crystal Armor will be available for purchase in the Rewards shop. As a bounty for your continued work, you will also receive 3 Gems.",
- "elite": "Elite",
- "eliteThird": "When your third set of submissions is deployed, the Crystal Helmet will be available for purchase in the Rewards shop. As a bounty for your continued work, you will also receive 3 Gems.",
- "eliteFourth": "When your fourth set of submissions is deployed, the Crystal Sword will be available for purchase in the Rewards shop. As a bounty for your continued work, you will also receive 4 Gems.",
- "champion": "Champion",
- "championFifth": "When your fifth set of submissions is deployed, the Crystal Shield will be available for purchase in the Rewards shop. As a bounty for your continued work, you will also receive 4 Gems.",
- "championSixth": "When your sixth set of submissions is deployed, you will receive a Hydra Pet. You will also receive 4 Gems.",
- "legendary": "Legendary",
- "legSeventh": "When your seventh set of submissions is deployed, you will receive 4 Gems and become a member of the honored Contributor's Guild and be privy to the behind-the-scenes details of Habitica! Further contributions do not increase your tier, but you may continue to earn Gem bounties and titles.",
- "moderator": "Moderator",
- "guardian": "Guardian",
- "guardianText": "Moderators were selected carefully from high tier contributors, so please give them your respect and listen to their suggestions.",
- "staff": "Staff",
- "heroic": "Heroic",
- "heroicText": "The Heroic tier contains Habitica staff and staff-level contributors. If you have this title, you were appointed to it (or hired!).",
- "npcText": "NPCs backed Habitica's Kickstarter at the highest tier. You can find their avatars watching over site features!",
- "modalContribAchievement": "Contributor Achievement!",
- "contribModal": "<%= name %>, you awesome person! You're now a tier <%= level %> contributor for helping Habitica.",
- "contribLink": "See what prizes you've earned for your contribution!",
- "contribName": "Contributor",
- "contribText": "Has contributed to Habitica, whether via code, art, music, writing, or other methods. To learn more, join the Aspiring Legends Guild!",
- "readMore": "Read More",
- "kickstartName": "Kickstarter Backer - $<%= key %> Tier",
- "kickstartText": "Backed the Kickstarter Project",
- "helped": "Helped Habitica Grow",
- "helpedText1": "Helped Habitica grow by filling out",
- "helpedText2": "this survey.",
- "hall": "Hall of Heroes",
+ "playerTiersDesc": "",
+ "tier1": "",
+ "tier2": "",
+ "tier3": "",
+ "tier4": "",
+ "tier5": "",
+ "tier6": "",
+ "tier7": "",
+ "tierModerator": "",
+ "tierStaff": "",
+ "tierNPC": "",
+ "friend": "",
+ "friendFirst": "",
+ "friendSecond": "",
+ "elite": "",
+ "eliteThird": "",
+ "eliteFourth": "",
+ "champion": "",
+ "championFifth": "",
+ "championSixth": "",
+ "legendary": "",
+ "legSeventh": "",
+ "moderator": "",
+ "guardian": "",
+ "guardianText": "",
+ "staff": "",
+ "heroic": "",
+ "heroicText": "",
+ "npcText": "",
+ "modalContribAchievement": "",
+ "contribModal": "",
+ "contribLink": "",
+ "contribName": "",
+ "contribText": "",
+ "readMore": "",
+ "kickstartName": "",
+ "kickstartText": "",
+ "helped": "",
+ "helpedText1": "",
+ "helpedText2": "",
+ "hall": "",
"contribTitle": "Contributor Title (eg, \"Blacksmith\")",
- "contribLevel": "Contrib Tier",
+ "contribLevel": "",
"contribHallText": "1-7 for normal contributors, 8 for moderators, 9 for staff. This determines which items, pets, and mounts are available. Also determines name-tag coloring. Tiers 8 and 9 are automatically given admin status.",
- "hallContributors": "Hall of Contributors",
- "hallPatrons": "Hall of Patrons",
+ "hallContributors": "",
+ "hallPatrons": "",
"rewardUser": "Reward User",
- "UUID": "User ID",
+ "UUID": "",
"loadUser": "Load User",
- "noAdminAccess": "You don't have admin access.",
- "userNotFound": "User not found.",
- "invalidUUID": "UUID must be valid",
- "title": "Title",
+ "noAdminAccess": "",
+ "userNotFound": "",
+ "invalidUUID": "",
+ "title": "",
"moreDetails": "More details (1-7)",
"moreDetails2": "more details (8-9)",
- "contributions": "Contributions",
- "admin": "Admin",
+ "contributions": "",
+ "admin": "",
"notGems": "is in USD, not in Gems. Aka, if this number is 1, it means 4 gems. Only use this option when manually granting gems to players, don't use it when granting contributor tiers. Contrib tiers will automatically add gems.",
- "gamemaster": "Game Master (staff/moderator)",
- "backerTier": "Backer Tier",
+ "gamemaster": "",
+ "backerTier": "",
"balance": "Balance",
- "tierPop": "Click tier labels for details.",
- "playerTiers": "Player Tiers",
- "tier": "Tier",
- "visitHeroes": "Visit the Hall of Heroes (contributors and backers)",
- "conLearn": "Learn more about contributor rewards",
- "conLearnHow": "Learn how to contribute to Habitica",
- "conLearnURL": "http://habitica.wikia.com/wiki/Contributing_to_Habitica",
- "conRewardsURL": "http://habitica.wikia.com/wiki/Contributor_Rewards",
- "surveysSingle": "Helped Habitica grow, either by filling out a survey or helping with a major testing effort. Thank you!",
- "surveysMultiple": "Helped Habitica grow on <%= count %> occasions, either by filling out a survey or helping with a major testing effort. Thank you!",
- "currentSurvey": "Current Survey",
- "surveyWhen": "The badge will be awarded to all participants when surveys have been processed, in late March.",
- "blurbInbox": "This is where your private messages are stored! You can send someone a message by clicking on the envelope icon next to their name in Tavern, Party, or Guild Chat. If you've received an inappropriate PM, you should email a screenshot of it to Lemoness (<%= hrefCommunityManagerEmail %>)",
- "blurbGuildsPage": "Guilds are common-interest chat groups created by the players, for players. Browse through the list and join the Guilds that interest you!",
- "blurbChallenges": "Challenges are created by your fellow players. Joining a Challenge will add its tasks to your task dashboard, and winning a Challenge will give you an achievement and often a gem prize!",
- "blurbHallPatrons": "This is the Hall of Patrons, where we honor the noble adventurers who backed Habitica's original Kickstarter. We thank them for helping us bring Habitica to life!",
- "blurbHallContributors": "This is the Hall of Contributors, where open-source contributors to Habitica are honored. Whether through code, art, music, writing, or even just helpfulness, they have earned gems, exclusive equipment, and prestigious titles. You can contribute to Habitica, too! Find out more here. "
-}
\ No newline at end of file
+ "tierPop": "",
+ "playerTiers": "",
+ "tier": "",
+ "visitHeroes": "",
+ "conLearn": "",
+ "conLearnHow": "",
+ "conLearnURL": "",
+ "conRewardsURL": "",
+ "surveysSingle": "",
+ "surveysMultiple": "",
+ "currentSurvey": "",
+ "surveyWhen": "",
+ "blurbInbox": "",
+ "blurbGuildsPage": "",
+ "blurbChallenges": "",
+ "blurbHallPatrons": "",
+ "blurbHallContributors": ""
+}
diff --git a/website/common/locales/eu/death.json b/website/common/locales/eu/death.json
index ffdde6730e..b1b4f0a1e4 100755
--- a/website/common/locales/eu/death.json
+++ b/website/common/locales/eu/death.json
@@ -1,17 +1,17 @@
{
- "lostAllHealth": "You ran out of Health!",
- "dontDespair": "Don't despair!",
- "deathPenaltyDetails": "You lost a Level, your Gold, and a piece of Equipment, but you can get them all back with hard work! Good luck--you'll do great.",
- "refillHealthTryAgain": "Refill Health & Try Again",
- "dyingOftenTips": "Is this happening often? Here are some tips!",
- "losingHealthWarning": "Careful - You're Losing Health!",
- "losingHealthWarning2": "Don't let your Health drop to zero! If you do, you'll lose a level, your Gold, and a piece of equipment.",
- "toRegainHealth": "To regain Health:",
- "lowHealthTips1": "Level up to fully heal!",
- "lowHealthTips2": "Buy a Health Potion from the Rewards column to restore 15 Health Points.",
- "losingHealthQuickly": "Losing Health quickly?",
- "lowHealthTips3": "Incomplete Dailies hurt you overnight, so be careful not to add too many at first!",
- "lowHealthTips4": "If a Daily isn't due on a certain day, you can disable it by clicking the pencil icon.",
- "goodLuck": "Good luck!",
- "cannotRevive": "Cannot revive if not dead"
-}
\ No newline at end of file
+ "lostAllHealth": "",
+ "dontDespair": "",
+ "deathPenaltyDetails": "",
+ "refillHealthTryAgain": "",
+ "dyingOftenTips": "",
+ "losingHealthWarning": "",
+ "losingHealthWarning2": "",
+ "toRegainHealth": "",
+ "lowHealthTips1": "",
+ "lowHealthTips2": "",
+ "losingHealthQuickly": "",
+ "lowHealthTips3": "",
+ "lowHealthTips4": "",
+ "goodLuck": "",
+ "cannotRevive": ""
+}
diff --git a/website/common/locales/eu/defaulttasks.json b/website/common/locales/eu/defaulttasks.json
index 85539142d0..b1a6e6d355 100755
--- a/website/common/locales/eu/defaulttasks.json
+++ b/website/common/locales/eu/defaulttasks.json
@@ -1,28 +1,28 @@
{
- "defaultHabit1Text": "Productive Work (Click the pencil to edit)",
- "defaultHabit1Notes": "Sample Good Habits: + Eat a vegetable + 15 minutes productive work",
- "defaultHabit2Text": "Eat Junk Food (Click the pencil to edit)",
- "defaultHabit2Notes": "Sample Bad Habits: - Smoke - Procrastinate",
- "defaultHabit3Text": "Take the Stairs/Elevator (Click the pencil to edit)",
- "defaultHabit3Notes": "Sample Good or Bad Habits: +/- Took Stairs/Elevator ; +/- Drank Water/Soda",
- "defaultHabit4Text": "Add a task to Habitica",
- "defaultHabit4Notes": "Either a Habit, a Daily, or a To-Do",
- "defaultHabit5Text": "Tap here to edit this into a bad habit you'd like to quit",
- "defaultHabit5Notes": "Or delete from the edit screen",
- "defaultDaily1Text": "Use Habitica to keep track of your tasks",
- "defaultTodo1Text": "Join Habitica (Check me off!)",
- "defaultTodoNotes": "You can either complete this To-Do, edit it, or remove it.",
- "defaultTodo2Text": "Finish Justin's task walkthrough",
- "defaultTodo2Notes": "Visit all the sections of the bottom bar",
- "defaultReward1Text": "15 minute break",
- "defaultReward1Notes": "Custom rewards can come in many forms. Some people will hold off watching their favorite show unless they have the gold to pay for it.",
- "defaultReward2Text": "Reward yourself",
- "defaultReward2Notes": "Watch TV, play a game, eat a treat, it's up to you!",
- "defaultTag1": "Work",
- "defaultTag2": "Exercise",
- "defaultTag3": "Health + Wellness",
- "defaultTag4": "School",
- "defaultTag5": "Teams",
- "defaultTag6": "Chores",
- "defaultTag7": "Creativity"
-}
\ No newline at end of file
+ "defaultHabit1Text": "",
+ "defaultHabit1Notes": "",
+ "defaultHabit2Text": "",
+ "defaultHabit2Notes": "",
+ "defaultHabit3Text": "",
+ "defaultHabit3Notes": "",
+ "defaultHabit4Text": "",
+ "defaultHabit4Notes": "",
+ "defaultHabit5Text": "",
+ "defaultHabit5Notes": "",
+ "defaultDaily1Text": "",
+ "defaultTodo1Text": "",
+ "defaultTodoNotes": "",
+ "defaultTodo2Text": "",
+ "defaultTodo2Notes": "",
+ "defaultReward1Text": "",
+ "defaultReward1Notes": "",
+ "defaultReward2Text": "",
+ "defaultReward2Notes": "",
+ "defaultTag1": "",
+ "defaultTag2": "",
+ "defaultTag3": "",
+ "defaultTag4": "",
+ "defaultTag5": "",
+ "defaultTag6": "",
+ "defaultTag7": ""
+}
diff --git a/website/common/locales/eu/faq.json b/website/common/locales/eu/faq.json
index 545fb45c8a..a4da00f2cb 100755
--- a/website/common/locales/eu/faq.json
+++ b/website/common/locales/eu/faq.json
@@ -1,58 +1,58 @@
{
- "frequentlyAskedQuestions": "Frequently Asked Questions",
- "faqQuestion0": "I'm confused. Where do I get an overview?",
- "iosFaqAnswer0": "First, you'll set up tasks that you want to do in your everyday life. Then, as you complete the tasks in real life and check them off, you'll earn experience and gold. Gold is used to buy equipment and some items, as well as custom rewards. Experience causes your character to level up and unlock content such as Pets, Skills, and Quests! You can customize your character under Menu > Customize Avatar.\n\n Some basic ways to interact: click the (+) in the upper-right-hand corner to add a new task. Tap on an existing task to edit it, and swipe left on a task to delete it. You can sort tasks using Tags in the upper-left-hand corner, and expand and contract checklists by clicking on the checklist bubble.",
- "androidFaqAnswer0": "First, you'll set up tasks that you want to do in your everyday life. Then, as you complete the tasks in real life and check them off, you'll earn experience and gold. Gold is used to buy equipment and some items, as well as custom rewards. Experience causes your character to level up and unlock content such as Pets, Skills, and Quests! You can customize your character under Menu > [Inventory >] Avatar.\n\n Some basic ways to interact: click the (+) in the lower-right-hand corner to add a new task. Tap on an existing task to edit it, and swipe left on a task to delete it. You can sort tasks using Tags in the upper-right-hand corner, and expand and contract checklists by clicking on the checklist count box.",
- "webFaqAnswer0": "First, you'll set up tasks that you want to do in your everyday life. Then, as you complete the tasks in real life and check them off, you'll earn Experience and Gold. Gold is used to buy equipment and some items, as well as custom rewards. Experience causes your character to level up and unlock content such as pets, skills, and quests! For more detail, check out a step-by-step overview of the game at [Help -> Overview for New Users](https://habitica.com/static/overview).",
- "faqQuestion1": "How do I set up my tasks?",
- "iosFaqAnswer1": "Good Habits (the ones with a +) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a -) are tasks that you should avoid, like biting nails. Habits with a + and a - have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award experience and gold. Bad Habits subtract health.\n\n Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by tapping to edit it. If you skip a Daily that is due, your avatar will take damage overnight. Be careful not to add too many Dailies at once!\n\n To-Dos are your To-Do list. Completing a To-Do earns you gold and experience. You never lose health from To-Dos. You can add a due date to a To-Do by tapping to edit.",
- "androidFaqAnswer1": "Good Habits (the ones with a +) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a -) are tasks that you should avoid, like biting nails. Habits with a + and a - have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award experience and gold. Bad Habits subtract health.\n\n Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by tapping to edit it. If you skip a Daily that is due, your character will take damage overnight. Be careful not to add too many Dailies at once!\n\n To-Dos are your To-Do list. Completing a To-Do earns you gold and experience. You never lose health from To-Dos. You can add a due date to a To-Do by tapping to edit.",
- "webFaqAnswer1": "* Good Habits (the ones with a :heavy_plus_sign:) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a :heavy_minus_sign:) are tasks that you should avoid, like biting nails. Habits with a :heavy_plus_sign: and a :heavy_minus_sign: have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award Experience and Gold. Bad Habits subtract Health.\n* Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by clicking the pencil item to edit it. If you skip a Daily that is due, your avatar will take damage overnight. Be careful not to add too many Dailies at once!\n* To-Dos are your To-Do list. Completing a To-Do earns you Gold and Experience. You never lose Health from To-Dos. You can add a due date to a To-Do by clicking the pencil icon to edit.",
- "faqQuestion2": "What are some sample tasks?",
- "iosFaqAnswer2": "The wiki has four lists of sample tasks to use as inspiration:\n
\n * [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits)\n * [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies)\n * [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos)\n * [Sample Custom Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards)",
- "androidFaqAnswer2": "The wiki has four lists of sample tasks to use as inspiration:\n
\n * [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits)\n * [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies)\n * [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos)\n * [Sample Custom Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards)",
- "webFaqAnswer2": "The wiki has four lists of sample tasks to use as inspiration:\n * [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits)\n * [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies)\n * [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos)\n * [Sample Custom Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards)",
- "faqQuestion3": "Why do my tasks change color?",
- "iosFaqAnswer3": "Your tasks change color based on how well you are currently accomplishing them! Each new task starts out as a neutral yellow. Perform Dailies or positive Habits more frequently and they move toward blue. Miss a Daily or give in to a bad Habit and the task moves toward red. The redder a task, the more rewards it will give you, but if it's a Daily or bad Habit, the more it will hurt you! This helps motivate you to complete the tasks that are giving you trouble.",
- "androidFaqAnswer3": "Your tasks change color based on how well you are currently accomplishing them! Each new task starts out as a neutral yellow. Perform Dailies or positive Habits more frequently and they move toward blue. Miss a Daily or give in to a bad Habit and the task moves toward red. The redder a task, the more rewards it will give you, but if it's a Daily or bad Habit, the more it will hurt you! This helps motivate you to complete the tasks that are giving you trouble.",
- "webFaqAnswer3": "Your tasks change color based on how well you are currently accomplishing them! Each new task starts out as a neutral yellow. Perform Dailies or positive Habits more frequently and they move toward blue. Miss a Daily or give in to a bad Habit and the task moves toward red. The redder a task, the more rewards it will give you, but if it’s a Daily or bad Habit, the more it will hurt you! This helps motivate you to complete the tasks that are giving you trouble.",
- "faqQuestion4": "Why did my avatar lose health, and how do I regain it?",
- "iosFaqAnswer4": "There are several things that can cause you to take damage. First, if you left Dailies incomplete overnight and didn't check them off in the screen that popped up the next morning, those unfinished Dailies will damage you. Second, if you tap a bad Habit, it will damage you. Finally, if you are in a Boss Battle with your Party and one of your Party mates did not complete all their Dailies, the Boss will attack you.\n\n The main way to heal is to gain a level, which restores all your health. You can also buy a Health Potion with gold from the Rewards column. Plus, at level 10 or above, you can choose to become a Healer, and then you will learn healing skills. If you are in a Party with a Healer, they can heal you as well.",
- "androidFaqAnswer4": "There are several things that can cause you to take damage. First, if you left Dailies incomplete overnight and didn't check them off in the screen that popped up the next morning, those unfinished Dailies will damage you. Second, if you tap a bad Habit, it will damage you. Finally, if you are in a Boss Battle with your Party and one of your Party mates did not complete all their Dailies, the Boss will attack you.\n\n The main way to heal is to gain a level, which restores all your health. You can also buy a Health Potion with gold from the Rewards tab on the Tasks page. Plus, at level 10 or above, you can choose to become a Healer, and then you will learn healing skills. If you are in a Party with a Healer, they can heal you as well.",
- "webFaqAnswer4": "There are several things that can cause you to take damage. First, if you left Dailies incomplete overnight and didn't check them off in the screen that popped up the next morning, those unfinished Dailies will damage you. Second, if you click a bad Habit, it will damage you. Finally, if you are in a Boss Battle with your party and one of your party mates did not complete all their Dailies, the Boss will attack you. The main way to heal is to gain a level, which restores all your Health. You can also buy a Health Potion with Gold from the Rewards column. Plus, at level 10 or above, you can choose to become a Healer, and then you will learn healing skills. Other Healers can heal you as well if you are in a Party with them. Learn more by clicking \"Party\" in the navigation bar.",
- "faqQuestion5": "How do I play Habitica with my friends?",
- "iosFaqAnswer5": "The best way is to invite them to a Party with you! Parties can go on quests, battle monsters, and cast skills to support each other. Go to Menu > Party and click \"Create New Party\" if you don't already have a Party. Then tap on the Members list, and tap Invite in the upper right-hand corner to invite your friends by entering their User ID (a string of numbers and letters that they can find under Settings > Account Details on the app, and Settings > API on the website). On the website, you can also invite friends via email, which we will add to the app in a future update.\n\nOn the website, you and your friends can also join Guilds, which are public chat rooms. Guilds will be added to the app in a future update!",
- "androidFaqAnswer5": "The best way is to invite them to a Party with you! Parties can go on quests, battle monsters, and cast skills to support each other. Go to the [website](https://habitica.com/) to create one if you don't already have a Party. You can also join guilds together (Social > Guilds). Guilds are chat rooms focusing on a shared interest or the pursuit of a common goal, and can be public or private. You can join as many guilds as you'd like, but only one party.\n\n For more detailed info, check out the wiki pages on [Parties](http://habitica.wikia.com/wiki/Party) and [Guilds](http://habitica.wikia.com/wiki/Guilds).",
- "webFaqAnswer5": "The best way is to invite them to a Party with you by clicking \"Party\" in the navigation bar! Parties can go on quests, battle monsters, and cast skills to support each other. You can also join Guilds together (click on \"Guilds\" in the navigation bar). Guilds are chat rooms focusing on a shared interest or the pursuit of a common goal, and can be public or private. You can join as many Guilds as you'd like, but only one Party. For more detailed info, check out the wiki pages on [Parties](http://habitica.wikia.com/wiki/Party) and [Guilds](http://habitica.wikia.com/wiki/Guilds).",
- "faqQuestion6": "How do I get a Pet or Mount?",
- "iosFaqAnswer6": "At level 3, you will unlock the Drop System. Every time you complete a task, you'll have a random chance at receiving an egg, a hatching potion, or a piece of food. They will be stored in Menu > Items.\n\n To hatch a Pet, you'll need an egg and a hatching potion. Tap on the egg to determine the species you want to hatch, and select \"Hatch Egg.\" Then choose a hatching potion to determine its color! Go to Menu > Pets to equip your new Pet to your avatar by clicking on it. \n\n You can also grow your Pets into Mounts by feeding them under Menu > Pets. Tap on a Pet, and then select \"Feed Pet\"! You'll have to feed a pet many times before it becomes a Mount, but if you can figure out its favorite food, it will grow more quickly. Use trial and error, or [see the spoilers here](http://habitica.wikia.com/wiki/Food#Food_Preferences). Once you have a Mount, go to Menu > Mounts and tap on it to equip it to your avatar.\n\n You can also get eggs for Quest Pets by completing certain Quests. (See below to learn more about Quests.)",
- "androidFaqAnswer6": "At level 3, you will unlock the Drop System. Every time you complete a task, you'll have a random chance at receiving an egg, a hatching potion, or a piece of food. They will be stored in Menu > Items.\n\n To hatch a Pet, you'll need an egg and a hatching potion. Tap on the egg to determine the species you want to hatch, and select \"Hatch with potion.\" Then choose a hatching potion to determine its color! To equip your new Pet, go to Menu > Stable > Pets, select a species, click on the desired Pet, and select \"Use\"(Your avatar doesn't update to reflect the change). \n\n You can also grow your Pets into Mounts by feeding them under Menu > Stable [ > Pets ]. Tap on a Pet, and then select \"Feed\"! You'll have to feed a pet many times before it becomes a Mount, but if you can figure out its favorite food, it will grow more quickly. Use trial and error, or [see the spoilers here](http://habitica.wikia.com/wiki/Food#Food_Preferences). To equip your Mount, go to Menu > Stable > Mounts, select a species, click on the desired Mount, and select \"Use\"(Your avatar doesn't update to reflect the change).\n\n You can also get eggs for Quest Pets by completing certain Quests. (See below to learn more about Quests.)",
- "webFaqAnswer6": "At level 3, you will unlock the Drop System. Every time you complete a task, you'll have a random chance at receiving an egg, a hatching potion, or a piece of food. They will be stored under Inventory > Items. To hatch a Pet, you'll need an egg and a hatching potion. Once you have both an egg and a potion, go to Inventory > Stable to hatch your pet by clicking on its image. Once you've hatched a pet, you can equip it by clicking on it. You can also grow your Pets into Mounts by feeding them under Inventory > Stable. Drag a piece of food from the action bar at the bottom of the screen and drop it on a pet to feed it! You'll have to feed a Pet many times before it becomes a Mount, but if you can figure out its favorite food, it will grow more quickly. Use trial and error, or [see the spoilers here](http://habitica.wikia.com/wiki/Food#Food_Preferences). Once you have a Mount, click on it to equip it to your avatar. You can also get eggs for Quest Pets by completing certain Quests. (See below to learn more about Quests.)",
- "faqQuestion7": "How do I become a Warrior, Mage, Rogue, or Healer?",
- "iosFaqAnswer7": "At level 10, you can choose to become a Warrior, Mage, Rogue, or Healer. (All players start as Warriors by default.) Each Class has different equipment options, different Skills that they can cast after level 11, and different advantages. Warriors can easily damage Bosses, withstand more damage from their tasks, and help make their Party tougher. Mages can also easily damage Bosses, as well as level up quickly and restore Mana for their party. Rogues earn the most gold and find the most item drops, and they can help their Party do the same. Finally, Healers can heal themselves and their Party members.\n\n If you don't want to choose a Class immediately -- for example, if you are still working to buy all the gear of your current class -- you can click “Decide Later” and choose later under Menu > Choose Class.",
- "androidFaqAnswer7": "At level 10, you can choose to become a Warrior, Mage, Rogue, or Healer. (All players start as Warriors by default.) Each Class has different equipment options, different Skills that they can cast after level 11, and different advantages. Warriors can easily damage Bosses, withstand more damage from their tasks, and help make their Party tougher. Mages can also easily damage Bosses, as well as level up quickly and restore Mana for their party. Rogues earn the most gold and find the most item drops, and they can help their Party do the same. Finally, Healers can heal themselves and their Party members.\n\n If you don't want to choose a Class immediately -- for example, if you are still working to buy all the gear of your current class -- you can click “Opt Out” and choose later under Menu > Choose Class.",
- "webFaqAnswer7": "At level 10, you can choose to become a Warrior, Mage, Rogue, or Healer. (All players start as Warriors by default.) Each Class has different equipment options, different Skills that they can cast after level 11, and different advantages. Warriors can easily damage Bosses, withstand more damage from their tasks, and help make their party tougher. Mages can also easily damage Bosses, as well as level up quickly and restore Mana for their party. Rogues earn the most Gold and find the most item drops, and they can help their party do the same. Finally, Healers can heal themselves and their party members. If you don't want to choose a Class immediately -- for example, if you are still working to buy all the gear of your current class -- you can click \"Opt Out\" and re-enable it later under Settings.",
- "faqQuestion8": "What is the blue Stat bar that appears in the Header after level 10?",
- "iosFaqAnswer8": "The blue bar that appeared when you hit level 10 and chose a Class is your Mana bar. As you continue to level up, you will unlock special Skills that cost Mana to use. Each Class has different Skills, which appear after level 11 under Menu > Use Skills. Unlike your health bar, your Mana bar does not reset when you gain a level. Instead, Mana is gained when you complete Good Habits, Dailies, and To-Dos, and lost when you indulge bad Habits. You'll also regain some Mana overnight -- the more Dailies you completed, the more you will gain.",
- "androidFaqAnswer8": "The blue bar that appeared when you hit level 10 and chose a Class is your Mana bar. As you continue to level up, you will unlock special Skills that cost Mana to use. Each Class has different Skills, which appear after level 11 under Menu > Skills. Unlike your health bar, your Mana bar does not reset when you gain a level. Instead, Mana is gained when you complete Good Habits, Dailies, and To-Dos, and lost when you indulge bad Habits. You'll also regain some Mana overnight -- the more Dailies you completed, the more you will gain.",
- "webFaqAnswer8": "The blue bar that appeared when you hit level 10 and chose a Class is your Mana bar. As you continue to level up, you will unlock special Skills that cost Mana to use. Each Class has different Skills, which appear after level 11 in the action bar at the bottom of the screen. Unlike your Health bar, your Mana bar does not reset when you gain a level. Instead, Mana is gained when you complete good Habits, Dailies, and To-Dos, and lost when you indulge bad Habits. You'll also regain some Mana overnight -- the more Dailies you completed, the more you will gain.",
- "faqQuestion9": "How do I fight monsters and go on Quests?",
- "iosFaqAnswer9": "First, you need to join or start a Party (see above). Although you can battle monsters alone, we recommend playing in a group, because this will make Quests much easier. Plus, having a friend to cheer you on as you accomplish your tasks is very motivating!\n\n Next, you need a Quest Scroll, which are stored under Menu > Items. There are three ways to get a scroll:\n\n - At level 15, you get a Quest-line, aka three linked quests. More Quest-lines unlock at levels 30, 40, and 60 respectively. \n - When you invite people to your Party, you'll be rewarded with the Basi-List Scroll!\n - You can buy Quests from the Quests Shop for Gold and Gems.\n\n To battle the Boss or collect items for a Collection Quest, simply complete your tasks normally, and they will be tallied into damage overnight. (Reloading by pulling down on the screen may be required to see the Boss's health bar go down.) If you are fighting a Boss and you missed any Dailies, the Boss will damage your Party at the same time that you damage the Boss. \n\n After level 11 Mages and Warriors will gain Skills that allow them to deal additional damage to the Boss, so these are excellent classes to choose at level 10 if you want to be a heavy hitter.",
- "androidFaqAnswer9": "First, you need to join or start a Party (see above). Although you can battle monsters alone, we recommend playing in a group, because this will make Quests much easier. Plus, having a friend to cheer you on as you accomplish your tasks is very motivating!\n\n Next, you need a Quest Scroll, which are stored under Menu > Items. There are three ways to get a scroll:\n\n - At level 15, you get a Quest-line, aka three linked quests. More Quest-lines unlock at levels 30, 40, and 60 respectively. \n - When you invite people to your Party, you'll be rewarded with the Basi-List Scroll!\n - You can buy Quests from the Quests Shop for Gold and Gems.\n\n To battle the Boss or collect items for a Collection Quest, simply complete your tasks normally, and they will be tallied into damage overnight. (Reloading by pulling down on the screen may be required to see the Boss's health bar go down.) If you are fighting a Boss and you missed any Dailies, the Boss will damage your Party at the same time that you damage the Boss. \n\n After level 11 Mages and Warriors will gain Skills that allow them to deal additional damage to the Boss, so these are excellent classes to choose at level 10 if you want to be a heavy hitter.",
- "webFaqAnswer9": "First, you need to join or start a Party by clicking \"Party\" in the navigation bar. Although you can battle monsters alone, we recommend playing in a group, because this will make quests much easier. Plus, having a friend to cheer you on as you accomplish your tasks is very motivating! Next, you need a Quest Scroll, which are stored under Inventory > Quests. There are four ways to get a scroll:\n * When you invite people to your Party, you'll be rewarded with the Basi-List Scroll!\n * At level 15, you get a Quest-line, i.e., three linked quests. More Quest-lines unlock at levels 30, 40, and 60 respectively.\n * You can buy Quests from the Quests Shop (Shops > Quests) for Gold and Gems.\n * When you check in to Habitica a certain number of times, you'll be rewarded with Quest Scrolls. You earn a Scroll during your 1st, 7th, 22nd, and 40th check-ins.\n To battle the Boss or collect items for a Collection Quest, simply complete your tasks normally, and they will be tallied into damage overnight. (Reloading may be required to see the Boss's Health bar go down.) If you are fighting a Boss and you missed any Dailies, the Boss will damage your Party at the same time that you damage the Boss. After level 11 Mages and Warriors will gain Skills that allow them to deal additional damage to the Boss, so these are excellent classes to choose at level 10 if you want to be a heavy hitter.",
- "faqQuestion10": "What are Gems, and how do I get them?",
- "iosFaqAnswer10": "Gems are purchased with real money by tapping on the Gem icon in the header. When people buy Gems, they are helping us to keep the site running. We're very grateful for their support!\n\n In addition to buying Gems directly, there are three other ways players can gain Gems:\n\n * Win a Challenge that has been set up by another player. Go to Social > Challenges to join some.\n * Subscribe and unlock the ability to buy a certain number of Gems per month.\n * Contribute your skills to the Habitica project. See this wiki page for more details: [Contributing to Habitica](http://habitica.wikia.com/wiki/Contributing_to_Habitica).\n\n Keep in mind that items purchased with Gems do not offer any statistical advantages, so players can still make use of the app without them!",
- "androidFaqAnswer10": "Gems are purchased with real money by tapping on the Gem icon in the header. When people buy Gems, they are helping us to keep the site running. We're very grateful for their support!\n\n In addition to buying Gems directly, there are three other ways players can gain Gems:\n\n * Win a Challenge that has been set up by another player. Go to Social > Challenges to join some.\n * Subscribe and unlock the ability to buy a certain number of Gems per month.\n * Contribute your skills to the Habitica project. See this wiki page for more details: [Contributing to Habitica](http://habitica.wikia.com/wiki/Contributing_to_Habitica).\n\n Keep in mind that items purchased with Gems do not offer any statistical advantages, so players can still make use of the app without them!",
- "webFaqAnswer10": "Gems are purchased with real money, although [subscribers](https://habitica.com/user/settings/subscription) can purchase them with Gold. When people subscribe or buy Gems, they are helping us to keep the site running. We're very grateful for their support! In addition to buying Gems directly or becoming a subscriber, there are two other ways players can gain Gems:\n* Win a Challenge that has been set up by another player. Go to Challenges > Discover Challenges to join some.\n * Contribute your skills to the Habitica project. See this wiki page for more details: [Contributing to Habitica](http://habitica.wikia.com/wiki/Contributing_to_Habitica). Keep in mind that items purchased with Gems do not offer any statistical advantages, so players can still make use of the site without them!",
- "faqQuestion11": "How do I report a bug or request a feature?",
- "iosFaqAnswer11": "You can report a bug, request a feature, or send feedback under Menu > About > Report a Bug and Menu > About > Send Feedback! We'll do everything we can to assist you.",
- "androidFaqAnswer11": "You can report a bug, request a feature, or send feedback under About > Report a Bug and About > Send us Feedback! We'll do everything we can to assist you.",
- "webFaqAnswer11": "To report a bug, go to [Help > Report a Bug](https://habitica.com/groups/guild/a29da26b-37de-4a71-b0c6-48e72a900dac) and read the points above the chat box. If you're unable to log in to Habitica, send your login details (not your password!) to [<%= techAssistanceEmail %>](<%= wikiTechAssistanceEmail %>). Don't worry, we'll get you fixed up soon! Feature requests are collected on Trello. Go to [Help > Request a Feature](https://trello.com/c/odmhIqyW/440-read-first-table-of-contents) and follow the instructions. Ta-da!",
- "faqQuestion12": "How do I battle a World Boss?",
- "iosFaqAnswer12": "World Bosses are special monsters that appear in the Tavern. All active users are automatically battling the Boss, and their tasks and Skills will damage the Boss as usual.\n\n You can also be in a normal Quest at the same time. Your tasks and Skills will count towards both the World Boss and the Boss/Collection Quest in your party.\n\n A World Boss will never hurt you or your account in any way. Instead, it has a Rage Bar that fills when users skip Dailies. If its Rage bar fills, it will attack one of the Non-Player Characters around the site and their image will change.\n\n You can read more about [past World Bosses](http://habitica.wikia.com/wiki/World_Bosses) on the wiki.",
- "androidFaqAnswer12": "World Bosses are special monsters that appear in the Tavern. All active users are automatically battling the Boss, and their tasks and Skills will damage the Boss as usual.\n\n You can also be in a normal Quest at the same time. Your tasks and Skills will count towards both the World Boss and the Boss/Collection Quest in your party.\n\n A World Boss will never hurt you or your account in any way. Instead, it has a Rage Bar that fills when users skip Dailies. If its Rage bar fills, it will attack one of the Non-Player Characters around the site and their image will change.\n\n You can read more about [past World Bosses](http://habitica.wikia.com/wiki/World_Bosses) on the wiki.",
- "webFaqAnswer12": "World Bosses are special monsters that appear in the Tavern. All active users are automatically battling the Boss, and their tasks and Skills will damage the Boss as usual. You can also be in a normal Quest at the same time. Your tasks and Skills will count towards both the World Boss and the Boss/Collection Quest in your party. A World Boss will never hurt you or your account in any way. Instead, it has a Rage Bar that fills when users skip Dailies. If its Rage bar fills, it will attack one of the Non-Player Characters around the site and their image will change. You can read more about [past World Bosses](http://habitica.wikia.com/wiki/World_Bosses) on the wiki.",
- "iosFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the Tavern chat under Menu > Tavern! We're happy to help.",
- "androidFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the Tavern chat under Menu > Tavern! We're happy to help.",
- "webFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the [Habitica Help guild](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)! We're happy to help."
-}
\ No newline at end of file
+ "frequentlyAskedQuestions": "",
+ "faqQuestion0": "",
+ "iosFaqAnswer0": "",
+ "androidFaqAnswer0": "",
+ "webFaqAnswer0": "",
+ "faqQuestion1": "",
+ "iosFaqAnswer1": "",
+ "androidFaqAnswer1": "",
+ "webFaqAnswer1": "",
+ "faqQuestion2": "",
+ "iosFaqAnswer2": "",
+ "androidFaqAnswer2": "",
+ "webFaqAnswer2": "",
+ "faqQuestion3": "",
+ "iosFaqAnswer3": "",
+ "androidFaqAnswer3": "",
+ "webFaqAnswer3": "",
+ "faqQuestion4": "",
+ "iosFaqAnswer4": "",
+ "androidFaqAnswer4": "",
+ "webFaqAnswer4": "",
+ "faqQuestion5": "",
+ "iosFaqAnswer5": "",
+ "androidFaqAnswer5": "",
+ "webFaqAnswer5": "",
+ "faqQuestion6": "",
+ "iosFaqAnswer6": "",
+ "androidFaqAnswer6": "",
+ "webFaqAnswer6": "",
+ "faqQuestion7": "",
+ "iosFaqAnswer7": "",
+ "androidFaqAnswer7": "",
+ "webFaqAnswer7": "",
+ "faqQuestion8": "",
+ "iosFaqAnswer8": "",
+ "androidFaqAnswer8": "",
+ "webFaqAnswer8": "",
+ "faqQuestion9": "",
+ "iosFaqAnswer9": "",
+ "androidFaqAnswer9": "",
+ "webFaqAnswer9": "",
+ "faqQuestion10": "",
+ "iosFaqAnswer10": "",
+ "androidFaqAnswer10": "",
+ "webFaqAnswer10": "",
+ "faqQuestion11": "",
+ "iosFaqAnswer11": "",
+ "androidFaqAnswer11": "",
+ "webFaqAnswer11": "",
+ "faqQuestion12": "",
+ "iosFaqAnswer12": "",
+ "androidFaqAnswer12": "",
+ "webFaqAnswer12": "",
+ "iosFaqStillNeedHelp": "",
+ "androidFaqStillNeedHelp": "",
+ "webFaqStillNeedHelp": ""
+}
diff --git a/website/common/locales/eu/gear.json b/website/common/locales/eu/gear.json
index 02b63057e5..cd7b66b3b0 100755
--- a/website/common/locales/eu/gear.json
+++ b/website/common/locales/eu/gear.json
@@ -1,1745 +1,1745 @@
{
- "set": "Set",
- "equipmentType": "Type",
- "klass": "Class",
- "groupBy": "Group By <%= type %>",
- "classBonus": "(This item matches your class, so it gets an additional 1.5 Stat multiplier.)",
- "classArmor": "Class Armor",
- "featuredset": "Featured Set <%= name %>",
- "mysterySets": "Mystery Sets",
- "gearNotOwned": "You do not own this item.",
- "noGearItemsOfType": "You don't own any of these.",
- "noGearItemsOfClass": "You already have all your class equipment! More will be released during the Grand Galas, near the solstices and equinoxes.",
- "classLockedItem": "This item is only available to a specific class. Change your class under the User icon > Settings > Character Build!",
- "tierLockedItem": "This item is only available once you've purchased the previous items in sequence. Keep working your way up!",
- "sortByType": "Type",
- "sortByPrice": "Price",
- "sortByCon": "CON",
- "sortByPer": "PER",
- "sortByStr": "STR",
- "sortByInt": "INT",
- "weapon": "weapon",
- "weaponCapitalized": "Main-Hand Item",
- "weaponBase0Text": "No Weapon",
- "weaponBase0Notes": "No Weapon.",
- "weaponWarrior0Text": "Training Sword",
- "weaponWarrior0Notes": "Practice weapon. Confers no benefit.",
- "weaponWarrior1Text": "Sword",
- "weaponWarrior1Notes": "Common soldier's blade. Increases Strength by <%= str %>.",
- "weaponWarrior2Text": "Axe",
- "weaponWarrior2Notes": "Double-bitted chopping weapon. Increases Strength by <%= str %>",
- "weaponWarrior3Text": "Morning Star",
- "weaponWarrior3Notes": "Heavy club with brutal spikes. Increases Strength by <%= str %>.",
- "weaponWarrior4Text": "Sapphire Blade",
- "weaponWarrior4Notes": "Sword whose edge bites like the north wind. Increases Strength by <%= str %>.",
- "weaponWarrior5Text": "Ruby Sword",
- "weaponWarrior5Notes": "Weapon whose forge-glow never fades. Increases Strength by <%= str %>.",
- "weaponWarrior6Text": "Golden Sword",
- "weaponWarrior6Notes": "Bane of creatures of darkness. Increases Strength by <%= str %>.",
- "weaponRogue0Text": "Dagger",
- "weaponRogue0Notes": "A rogue's most basic weapon. Confers no benefit.",
- "weaponRogue1Text": "Short Sword",
- "weaponRogue1Notes": "Light, concealable blade. Increases Strength by <%= str %>.",
- "weaponRogue2Text": "Scimitar",
- "weaponRogue2Notes": "Slashing sword, swift to deliver a killing blow. Increases Strength by <%= str %>.",
- "weaponRogue3Text": "Kukri",
- "weaponRogue3Notes": "Distinctive bush knife, both survival tool and weapon. Increases Strength by <%= str %>.",
- "weaponRogue4Text": "Nunchaku",
- "weaponRogue4Notes": "Heavy batons whirled about on a length of chain. Increases Strength by <%= str %>.",
- "weaponRogue5Text": "Ninja-to",
- "weaponRogue5Notes": "Sleek and deadly as the ninja themselves. Increases Strength by <%= str %>.",
- "weaponRogue6Text": "Hook Sword",
- "weaponRogue6Notes": "Complex weapon adept at ensnaring and disarming opponents. Increases Strength by <%= str %>.",
- "weaponWizard0Text": "Apprentice Staff",
- "weaponWizard0Notes": "Practice staff. Confers no benefit.",
- "weaponWizard1Text": "Wooden Staff",
- "weaponWizard1Notes": "Basic implement of carven wood. Increases Intelligence by <%= int %> and Perception by <%= per %>.",
- "weaponWizard2Text": "Jeweled Staff",
- "weaponWizard2Notes": "Focuses power through a precious stone. Increases Intelligence by <%= int %> and Perception by <%= per %>.",
- "weaponWizard3Text": "Iron Staff",
- "weaponWizard3Notes": "Plated in metal to channel heat, cold, and lightning. Increases Intelligence by <%= int %> and Perception by <%= per %>.",
- "weaponWizard4Text": "Brass Staff",
- "weaponWizard4Notes": "As powerful as it is heavy. Increases Intelligence by <%= int %> and Perception by <%= per %>.",
- "weaponWizard5Text": "Archmage Staff",
- "weaponWizard5Notes": "Assists in weaving the most complex of spells. Increases Intelligence by <%= int %> and Perception by <%= per %>.",
- "weaponWizard6Text": "Golden Staff",
- "weaponWizard6Notes": "Fashioned of orichalcum, the alchemic gold, mighty and rare. Increases Intelligence by <%= int %> and Perception by <%= per %>.",
- "weaponHealer0Text": "Novice Rod",
- "weaponHealer0Notes": "For healers in training. Confers no benefit.",
- "weaponHealer1Text": "Acolyte Rod",
- "weaponHealer1Notes": "Crafted during a healer's initiation. Increases Intelligence by <%= int %>.",
- "weaponHealer2Text": "Quartz Rod",
- "weaponHealer2Notes": "Topped with a gem bearing curative properties. Increases Intelligence by <%= int %>.",
- "weaponHealer3Text": "Amethyst Rod",
- "weaponHealer3Notes": "Purifies poison at a touch. Increases Intelligence by <%= int %>.",
- "weaponHealer4Text": "Physician Rod",
- "weaponHealer4Notes": "As much a badge of office as a healing tool. Increases Intelligence by <%= int %>.",
- "weaponHealer5Text": "Royal Scepter",
- "weaponHealer5Notes": "Fit to grace the hand of a monarch, or of one who stands at a monarch's right hand. Increases Intelligence by <%= int %>.",
- "weaponHealer6Text": "Golden Scepter",
- "weaponHealer6Notes": "Soothes the pain of all who look upon it. Increases Intelligence by <%= int %>.",
- "weaponSpecial0Text": "Dark Souls Blade",
- "weaponSpecial0Notes": "Feasts upon foes' life essence to power its wicked strokes. Increases Strength by <%= str %>.",
- "weaponSpecial1Text": "Crystal Blade",
- "weaponSpecial1Notes": "Its glittering facets tell the tale of a hero. Increases all Stats by <%= attrs %>.",
- "weaponSpecial2Text": "Stephen Weber's Shaft of the Dragon",
- "weaponSpecial2Notes": "Feel the potency of the dragon surge from within! Increases Strength and Perception by <%= attrs %> each.",
- "weaponSpecial3Text": "Mustaine's Milestone Mashing Morning Star",
- "weaponSpecial3Notes": "Meetings, monsters, malaise: managed! Mash! Increases Strength, Intelligence, and Constitution by <%= attrs %> each.",
- "weaponSpecialCriticalText": "Critical Hammer of Bug-Crushing",
- "weaponSpecialCriticalNotes": "This champion slew a critical GitHub foe where many warriors fell. Fashioned from the bones of Bug, this hammer deals a mighty critical hit. Increases Strength and Perception by <%= attrs %> each.",
- "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": "Trident of Crashing Tides",
- "weaponSpecialTridentOfCrashingTidesNotes": "Gives you the ability to command fish, and also deliver some mighty stabs to your tasks. Increases Intelligence by <%= 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",
- "weaponSpecialBardInstrumentNotes": "Strum a merry tune on this magical lute! Increases Intelligence and Perception by <%= attrs %> each.",
- "weaponSpecialLunarScytheText": "Lunar Scythe",
- "weaponSpecialLunarScytheNotes": "Wax this scythe regularly, or its power will wane. Increases Strength and Perception by <%= attrs %> each.",
- "weaponSpecialMammothRiderSpearText": "Mammoth Rider Spear",
- "weaponSpecialMammothRiderSpearNotes": "This rose quartz-tipped spear will imbue you with ancient spell-casting power. Increases Intelligence by <%= int %>.",
- "weaponSpecialPageBannerText": "Page Banner",
- "weaponSpecialPageBannerNotes": "Wave your banner high to inspire confidence! Increases Strength by <%= str %>.",
- "weaponSpecialRoguishRainbowMessageText": "Roguish Rainbow Message",
- "weaponSpecialRoguishRainbowMessageNotes": "This sparkly envelope contains messages of encouragement from Habiticans, and a touch of magic to help speed your deliveries! Increases Perception by <%= per %>.",
- "weaponSpecialSkeletonKeyText": "Skeleton Key",
- "weaponSpecialSkeletonKeyNotes": "All the best Sneakthieves carry a key that can open any lock! Increases Constitution by <%= con %>.",
- "weaponSpecialNomadsScimitarText": "Nomad's Scimitar",
- "weaponSpecialNomadsScimitarNotes": "The curved blade of this Scimitar is perfect for attacking Tasks from the back of a mount! Increases Intelligence by <%= int %>.",
- "weaponSpecialFencingFoilText": "Fencing Foil",
- "weaponSpecialFencingFoilNotes": "Should anyone dare to impugn your honor, you'll be ready with this fine foil! Increases Strength by <%= str %>.",
- "weaponSpecialTachiText": "Tachi",
- "weaponSpecialTachiNotes": "This light and curved sword will shred your tasks to ribbons! Increases Strength by <%= str %>.",
- "weaponSpecialAetherCrystalsText": "Aether Crystals",
- "weaponSpecialAetherCrystalsNotes": "These bracers and crystals once belonged to the Lost Masterclasser herself. Increases all Stats by <%= attrs %>.",
- "weaponSpecialYetiText": "Yeti-Tamer Spear",
- "weaponSpecialYetiNotes": "This spear allows its user to command any yeti. Increases Strength by <%= str %>. Limited Edition 2013-2014 Winter Gear.",
- "weaponSpecialSkiText": "Ski-sassin Pole",
- "weaponSpecialSkiNotes": "A weapon capable of destroying hordes of enemies! It also helps the user make very nice parallel turns. Increases Strength by <%= str %>. Limited Edition 2013-2014 Winter Gear.",
- "weaponSpecialCandycaneText": "Candy Cane Staff",
- "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": "Snowflake Wand",
- "weaponSpecialSnowflakeNotes": "This wand sparkles with unlimited healing power. Increases Intelligence by <%= int %>. Limited Edition 2013-2014 Winter Gear.",
- "weaponSpecialSpringRogueText": "Hook Claws",
- "weaponSpecialSpringRogueNotes": "Great for scaling tall buildings, and also for shredding carpets. Increases Strength by <%= str %>. Limited Edition 2014 Spring Gear.",
- "weaponSpecialSpringWarriorText": "Carrot Sword",
- "weaponSpecialSpringWarriorNotes": "This mighty sword can slice foes with ease! It also makes a delicious mid-battle snack. Increases Strength by <%= str %>. Limited Edition 2014 Spring Gear.",
- "weaponSpecialSpringMageText": "Swiss Cheese Staff",
- "weaponSpecialSpringMageNotes": "Only the most powerful rodents can brave their hunger to wield this potent staff. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2014 Spring Gear.",
- "weaponSpecialSpringHealerText": "Lovely Bone",
- "weaponSpecialSpringHealerNotes": "FETCH! Increases Intelligence by <%= int %>. Limited Edition 2014 Spring Gear.",
- "weaponSpecialSummerRogueText": "Pirate Cutlass",
- "weaponSpecialSummerRogueNotes": "Avast! You'll make those Dailies walk the plank! Increases Strength by <%= str %>. Limited Edition 2014 Summer Gear.",
- "weaponSpecialSummerWarriorText": "Seafaring Slicer",
- "weaponSpecialSummerWarriorNotes": "There isn't a task in any To-Do list willing to tangle with this gnarly knife! Increases Strength by <%= str %>. Limited Edition 2014 Summer Gear.",
- "weaponSpecialSummerMageText": "Kelp Catcher",
- "weaponSpecialSummerMageNotes": "This trident is used to spear seaweed effectively, for extra-productive kelp harvesting! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2014 Summer Gear.",
- "weaponSpecialSummerHealerText": "Wand of the Shallows",
- "weaponSpecialSummerHealerNotes": "This wand, made of aquamarine and live coral, is very attractive to schools of fish. Increases Intelligence by <%= int %>. Limited Edition 2014 Summer Gear.",
- "weaponSpecialFallRogueText": "Silver Stake",
- "weaponSpecialFallRogueNotes": "Dispatches undead. Also grants a bonus against werewolves, because you can never be too careful. Increases Strength by <%= str %>. Limited Edition 2014 Autumn Gear.",
- "weaponSpecialFallWarriorText": "Grabby Claw of Science",
- "weaponSpecialFallWarriorNotes": "This grabby claw is at the very cutting edge of technology. Increases Strength by <%= str %>. Limited Edition 2014 Autumn Gear.",
- "weaponSpecialFallMageText": "Magic Broom",
- "weaponSpecialFallMageNotes": "This enchanted broom flies faster than a dragon! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2014 Autumn Gear.",
- "weaponSpecialFallHealerText": "Scarab Wand",
- "weaponSpecialFallHealerNotes": "The scarab on this wand protects and heals its wielder. Increases Intelligence by <%= int %>. Limited Edition 2014 Autumn Gear.",
- "weaponSpecialWinter2015RogueText": "Ice Spike",
- "weaponSpecialWinter2015RogueNotes": "You truly, definitely, absolutely just picked these up off of the ground. Increases Strength by <%= str %>. Limited Edition 2014-2015 Winter Gear.",
- "weaponSpecialWinter2015WarriorText": "Gumdrop Sword",
- "weaponSpecialWinter2015WarriorNotes": "This delicious sword probably attracts monsters... but you're up for the challenge! Increases Strength by <%= str %>. Limited Edition 2014-2015 Winter Gear.",
- "weaponSpecialWinter2015MageText": "Winter-lit Staff",
- "weaponSpecialWinter2015MageNotes": "The light of this crystal staff fills hearts with cheer. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2014-2015 Winter Gear.",
- "weaponSpecialWinter2015HealerText": "Soothing Scepter",
- "weaponSpecialWinter2015HealerNotes": "This scepter warms sore muscles and soothes away stress. Increases Intelligence by <%= int %>. Limited Edition 2014-2015 Winter Gear.",
- "weaponSpecialSpring2015RogueText": "Exploding Squeak",
- "weaponSpecialSpring2015RogueNotes": "Don't let the sound fool you - these explosives pack a punch. Increases Strength by <%= str %>. Limited Edition 2015 Spring Gear.",
- "weaponSpecialSpring2015WarriorText": "Bone Club",
- "weaponSpecialSpring2015WarriorNotes": "It is a real bone club for real fierce doggies and is definitely not a chew toy that the Seasonal Sorceress gave you because who's a good doggy? Whoooo's a good doggy?? It's you!!! You're a good doggy!!! Increases Strength by <%= str %>. Limited Edition 2015 Spring Gear.",
- "weaponSpecialSpring2015MageText": "Magician's Wand",
- "weaponSpecialSpring2015MageNotes": "Conjure up a carrot for yourself with this fancy wand. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2015 Spring Gear.",
- "weaponSpecialSpring2015HealerText": "Cat Rattle",
- "weaponSpecialSpring2015HealerNotes": "When you wave it, it makes a fascinating clickety noise that would keep ANYONE entertained for hours. Increases Intelligence by <%= int %>. Limited Edition 2015 Spring Gear.",
- "weaponSpecialSummer2015RogueText": "Firing Coral",
- "weaponSpecialSummer2015RogueNotes": "This relative of fire coral has the ability to propel its venom through the water. Increases Strength by <%= str %>. Limited Edition 2015 Summer Gear.",
- "weaponSpecialSummer2015WarriorText": "Sun Swordfish",
- "weaponSpecialSummer2015WarriorNotes": "The Sun Swordfish is a fearsome weapon, provided that it can be induced to stop wriggling. Increases Strength by <%= str %>. Limited Edition 2015 Summer Gear.",
- "weaponSpecialSummer2015MageText": "Soothsayer Staff",
- "weaponSpecialSummer2015MageNotes": "Hidden power glimmers in the jewels of this staff. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2015 Summer Gear.",
- "weaponSpecialSummer2015HealerText": "Wand of the Waves",
- "weaponSpecialSummer2015HealerNotes": "Cures seasickness and sea sickness! Increases Intelligence by <%= int %>. Limited Edition 2015 Summer Gear.",
- "weaponSpecialFall2015RogueText": "Bat-tle Ax",
- "weaponSpecialFall2015RogueNotes": "Fearsome To-Dos cower before the flapping of this ax. Increases Strength by <%= str %>. Limited Edition 2015 Autumn Gear.",
- "weaponSpecialFall2015WarriorText": "Wooden Plank",
- "weaponSpecialFall2015WarriorNotes": "Great for elevating things in cornfields and/or smacking tasks. Increases Strength by <%= str %>. Limited Edition 2015 Autumn Gear.",
- "weaponSpecialFall2015MageText": "Enchanted Thread",
- "weaponSpecialFall2015MageNotes": "A powerful Stitch Witch can control this enchanted thread without even touching it! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2015 Autumn Gear.",
- "weaponSpecialFall2015HealerText": "Swamp-Slime Potion",
- "weaponSpecialFall2015HealerNotes": "Brewed to perfection! Now you just have to convince yourself to drink it. Increases Intelligence by <%= int %>. Limited Edition 2015 Autumn Gear.",
- "weaponSpecialWinter2016RogueText": "Cocoa Mug",
- "weaponSpecialWinter2016RogueNotes": "Warming drink, or boiling projectile? You decide... Increases Strength by <%= str %>. Limited Edition 2015-2016 Winter Gear.",
- "weaponSpecialWinter2016WarriorText": "Sturdy Shovel",
- "weaponSpecialWinter2016WarriorNotes": "Shovel overdue tasks out of the way! Increases Strength by <%= str %>. Limited Edition 2015-2016 Winter Gear.",
- "weaponSpecialWinter2016MageText": "Sorcerous Snowboard",
- "weaponSpecialWinter2016MageNotes": "Your moves are so sick, they must be magic! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2015-2016 Winter Gear.",
- "weaponSpecialWinter2016HealerText": "Confetti Cannon",
- "weaponSpecialWinter2016HealerNotes": "WHEEEEEEEEEE!!!!!!! HAPPY WINTER WONDERLAND!!!!!!!! Increases Intelligence by <%= int %>. Limited Edition 2015-2016 Winter Gear.",
- "weaponSpecialSpring2016RogueText": "Fire Bolas",
- "weaponSpecialSpring2016RogueNotes": "You've mastered the ball, the club, and the knife. Now you advance to juggling fire! Awoo! Increases Strength by <%= str %>. Limited Edition 2016 Spring Gear.",
- "weaponSpecialSpring2016WarriorText": "Cheese Mallet",
- "weaponSpecialSpring2016WarriorNotes": "No one has as many friends as the mouse with tender cheeses. Increases Strength by <%= str %>. Limited Edition 2016 Spring Gear.",
- "weaponSpecialSpring2016MageText": "Staff of Bells",
- "weaponSpecialSpring2016MageNotes": "Abra-cat-abra! So dazzling, you might mesmerize yourself! Ooh... it jingles... Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2016 Spring Gear.",
- "weaponSpecialSpring2016HealerText": "Spring Flower Wand",
- "weaponSpecialSpring2016HealerNotes": "With a wave and a wink, you bring the fields and forests into bloom! Or bop troublesome mice on the head. Increases Intelligence by <%= int %>. Limited Edition 2016 Spring Gear.",
- "weaponSpecialSummer2016RogueText": "Electric Rod",
- "weaponSpecialSummer2016RogueNotes": "Anyone who battles you is in for a shocking surprise... Increases Strength by <%= str %>. Limited Edition 2016 Summer Gear.",
- "weaponSpecialSummer2016WarriorText": "Hooked Sword",
- "weaponSpecialSummer2016WarriorNotes": "Bite those tough tasks with this hooked sword! Increases Strength by <%= str %>. Limited Edition 2016 Summer Gear.",
- "weaponSpecialSummer2016MageText": "Seafoam Staff",
- "weaponSpecialSummer2016MageNotes": "All the power of the seas filters through this staff. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2016 Summer Gear.",
- "weaponSpecialSummer2016HealerText": "Healing Trident",
- "weaponSpecialSummer2016HealerNotes": "One spike harms, the other heals. Increases Intelligence by <%= int %>. Limited Edition 2016 Summer Gear.",
- "weaponSpecialFall2016RogueText": "Spiderbite Dagger",
- "weaponSpecialFall2016RogueNotes": "Feel the sting of the spider's bite! Increases Strength by <%= str %>. Limited Edition 2016 Autumn Gear.",
- "weaponSpecialFall2016WarriorText": "Attacking Roots",
- "weaponSpecialFall2016WarriorNotes": "Attack your tasks with these twisting roots! Increases Strength by <%= str %>. Limited Edition 2016 Autumn Gear.",
- "weaponSpecialFall2016MageText": "Ominous Orb",
- "weaponSpecialFall2016MageNotes": "Don't ask this orb to tell your future... Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2016 Autumn Gear.",
- "weaponSpecialFall2016HealerText": "Venomous Serpent",
- "weaponSpecialFall2016HealerNotes": "One bite harms, and another bite heals. Increases Intelligence by <%= int %>. Limited Edition 2016 Autumn Gear.",
- "weaponSpecialWinter2017RogueText": "Ice Axe",
- "weaponSpecialWinter2017RogueNotes": "This axe is great for attack, defense, and ice-climbing! Increases Strength by <%= str %>. Limited Edition 2016-2017 Winter Gear.",
- "weaponSpecialWinter2017WarriorText": "Stick of Might",
- "weaponSpecialWinter2017WarriorNotes": "Conquer your goals by whacking them with this mighty stick! Increases Strength by <%= str %>. Limited Edition 2016-2017 Winter Gear.",
- "weaponSpecialWinter2017MageText": "Winter Wolf Crystal Staff",
- "weaponSpecialWinter2017MageNotes": "The glowing blue crystal set in the end of this staff is called the Winter Wolf's Eye! It channels magic from snow and ice. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2016-2017 Winter Gear.",
- "weaponSpecialWinter2017HealerText": "Sugar-Spun Wand",
- "weaponSpecialWinter2017HealerNotes": "This wand can reach into your dreams and bring you visions of dancing sugarplums. Increases Intelligence by <%= int %>. Limited Edition 2016-2017 Winter Gear.",
- "weaponSpecialSpring2017RogueText": "Karrotana",
- "weaponSpecialSpring2017RogueNotes": "These blades will make quick work of tasks, but also are handy for slicing vegetables! Yum! Increases Strength by <%= str %>. Limited Edition 2017 Spring Gear.",
- "weaponSpecialSpring2017WarriorText": "Feathery Whip",
- "weaponSpecialSpring2017WarriorNotes": "This mighty whip will tame the unruliest task. But.. It's also… So FUN AND DISTRACTING!! Increases Strength by <%= str %>. Limited Edition 2017 Spring Gear.",
- "weaponSpecialSpring2017MageText": "Magic Fetching Stick",
- "weaponSpecialSpring2017MageNotes": "When you're not crafting spells with it, you can throw it and then bring it back! What fun!! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2017 Spring Gear.",
- "weaponSpecialSpring2017HealerText": "Egg Wand",
- "weaponSpecialSpring2017HealerNotes": "The true magic of this wand is the secret of new life inside the colorful shell. Increases Intelligence by <%= int %>. Limited Edition 2017 Spring Gear.",
- "weaponSpecialSummer2017RogueText": "Sea Dragon Fins",
- "weaponSpecialSummer2017RogueNotes": "The edges of these fins are razor-sharp. Increases Strength by <%= str %>. Limited Edition 2017 Summer Gear.",
- "weaponSpecialSummer2017WarriorText": "The Mightiest Beach Umbrella",
- "weaponSpecialSummer2017WarriorNotes": "All fear it. Increases Strength by <%= str %>. Limited Edition 2017 Summer Gear.",
- "weaponSpecialSummer2017MageText": "Whirlpool Whips",
- "weaponSpecialSummer2017MageNotes": "Summon up magical whips of boiling water to smite your tasks! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2017 Summer Gear.",
- "weaponSpecialSummer2017HealerText": "Pearl Wand",
- "weaponSpecialSummer2017HealerNotes": "A single touch from this pearl-tipped wand soothes away all wounds. Increases Intelligence by <%= int %>. Limited Edition 2017 Summer Gear.",
- "weaponSpecialFall2017RogueText": "Candied Apple Mace",
- "weaponSpecialFall2017RogueNotes": "Defeat your foes with sweetness! Increases Strength by <%= str %>. Limited Edition 2017 Autumn Gear.",
- "weaponSpecialFall2017WarriorText": "Candy Corn Lance",
- "weaponSpecialFall2017WarriorNotes": "All your foes will cower before this tasty-looking lance, regardless of whether they're ghosts, monsters, or red To-Dos. Increases Strength by <%= str %>. Limited Edition 2017 Autumn Gear.",
- "weaponSpecialFall2017MageText": "Spooky Staff",
- "weaponSpecialFall2017MageNotes": "The eyes of the glowing skull on this staff radiate magic and mystery. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2017 Autumn Gear.",
- "weaponSpecialFall2017HealerText": "Creepy Candelabra",
- "weaponSpecialFall2017HealerNotes": "This light dispels fear and lets others know you're here to help. Increases Intelligence by <%= int %>. Limited Edition 2017 Autumn Gear.",
- "weaponSpecialWinter2018RogueText": "Peppermint Hook",
- "weaponSpecialWinter2018RogueNotes": "Perfect for climbing walls or distracting your foes with sweet, sweet candy. Increases Strength by <%= str %>. Limited Edition 2017-2018 Winter Gear.",
- "weaponSpecialWinter2018WarriorText": "Holiday Bow Hammer",
- "weaponSpecialWinter2018WarriorNotes": "The sparkly appearance of this bright weapon will dazzle your enemies as you swing it! Increases Strength by <%= str %>. Limited Edition 2017-2018 Winter Gear.",
- "weaponSpecialWinter2018MageText": "Holiday Confetti",
- "weaponSpecialWinter2018MageNotes": "Magic--and glitter--is in the air! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2017-2018 Winter Gear.",
- "weaponSpecialWinter2018HealerText": "Mistletoe Wand",
- "weaponSpecialWinter2018HealerNotes": "This mistletoe ball is sure to enchant and delight passersby! Increases Intelligence by <%= int %>. Limited Edition 2017-2018 Winter Gear.",
- "weaponSpecialSpring2018RogueText": "Buoyant Bullrush",
- "weaponSpecialSpring2018RogueNotes": "What might appear to be cute cattails are actually quite effective weapons in the right wings. Increases Strength by <%= str %>. Limited Edition 2018 Spring Gear.",
- "weaponSpecialSpring2018WarriorText": "Axe of Daybreak",
- "weaponSpecialSpring2018WarriorNotes": "Made of bright gold, this axe is mighty enough to attack the reddest task! Increases Strength by <%= str %>. Limited Edition 2018 Spring Gear.",
- "weaponSpecialSpring2018MageText": "Tulip Stave",
- "weaponSpecialSpring2018MageNotes": "This magic flower never wilts! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2018 Spring Gear.",
- "weaponSpecialSpring2018HealerText": "Garnet Rod",
- "weaponSpecialSpring2018HealerNotes": "The stones in this staff will focus your power when you cast healing spells! Increases Intelligence by <%= int %>. Limited Edition 2018 Spring Gear.",
- "weaponSpecialSummer2018RogueText": "Fishing Rod",
- "weaponSpecialSummer2018RogueNotes": "This lightweight, practically unbreakable rod and reel can be dual-wielded to maximize your DPS (Dragonfish Per Summer). Increases Strength by <%= str %>. Limited Edition 2018 Summer Gear.",
- "weaponSpecialSummer2018WarriorText": "Betta Fish Spear",
- "weaponSpecialSummer2018WarriorNotes": "Mighty enough for battle, elegant enough for ceremony, this exquisitely crafted spear shows you will protect your home surf no matter what! Increases Strength by <%= str %>. Limited Edition 2018 Summer Gear.",
- "weaponSpecialSummer2018MageText": "Lionfish Fin Rays",
- "weaponSpecialSummer2018MageNotes": "Underwater, magic based on fire, ice, or electricity can prove hazardous to the Mage wielding it. Conjuring poisonous spines, however, works brilliantly! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2018 Summer Gear.",
- "weaponSpecialSummer2018HealerText": "Merfolk Monarch Trident",
- "weaponSpecialSummer2018HealerNotes": "With a benevolent gesture, you command healing water to flow through your dominions in waves. Increases Intelligence by <%= int %>. Limited Edition 2018 Summer Gear.",
- "weaponSpecialFall2018RogueText": "Vial of Clarity",
- "weaponSpecialFall2018RogueNotes": "When you need to come back to your senses, when you need a little boost to make the right decision, take a deep breath and a sip. It'll be OK! Increases Strength by <%= str %>. Limited Edition 2018 Autumn Gear.",
- "weaponSpecialFall2018WarriorText": "Whip of Minos",
- "weaponSpecialFall2018WarriorNotes": "Not quite long enough to unwind behind you for keeping your bearings in a maze. Well, maybe a very small maze. Increases Strength by <%= str %>. Limited Edition 2018 Autumn Gear.",
- "weaponSpecialFall2018MageText": "Staff of Sweetness",
- "weaponSpecialFall2018MageNotes": "This is no ordinary lollipop! The glowing orb of magic sugar atop this staff has the power to make good habits stick to you. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2018 Autumn Gear. Two-handed item.",
- "weaponSpecialFall2018HealerText": "Starving Staff",
- "weaponSpecialFall2018HealerNotes": "Just keep this staff fed, and it will bestow Blessings. If you forget to feed it, keep your fingers out of reach. Increases Intelligence by <%= int %>. Limited Edition 2018 Autumn Gear.",
- "weaponSpecialWinter2019RogueText": "Poinsettia Bouquet",
- "weaponSpecialWinter2019RogueNotes": "Use this festive bouquet to further camouflage yourself, or generously gift it to brighten a friend's day! Increases Strength by <%= str %>. Limited Edition 2018-2019 Winter Gear.",
- "weaponSpecialWinter2019WarriorText": "Snowflake Halberd",
- "weaponSpecialWinter2019WarriorNotes": "This snowflake was grown, ice crystal by ice crystal, into a diamond-hard blade! Increases Strength by <%= str %>. Limited Edition 2018-2019 Winter Gear.",
- "weaponSpecialWinter2019MageText": "Fiery Dragon Staff",
- "weaponSpecialWinter2019MageNotes": "Watch out! This explosive staff is ready to help you take on all comers. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2018-2019 Winter Gear",
- "weaponSpecialWinter2019HealerText": "Wand of Winter",
- "weaponSpecialWinter2019HealerNotes": "Winter can be a time of rest and healing, and so this wand of winter magic can help to soothe the most grievous hurts. Increases Intelligence by <%= int %>. Limited Edition 2018-2019 Winter Gear.",
- "weaponMystery201411Text": "Pitchfork of Feasting",
- "weaponMystery201411Notes": "Stab your enemies or dig in to your favorite foods - this versatile pitchfork does it all! Confers no benefit. November 2014 Subscriber Item.",
- "weaponMystery201502Text": "Shimmery Winged Staff of Love and Also Truth",
- "weaponMystery201502Notes": "For WINGS! For LOVE! For ALSO TRUTH! Confers no benefit. February 2015 Subscriber Item.",
- "weaponMystery201505Text": "Green Knight Lance",
- "weaponMystery201505Notes": "This green and silver lance has unseated many opponents from their mounts. Confers no benefit. May 2015 Subscriber Item.",
- "weaponMystery201611Text": "Copious Cornucopia",
- "weaponMystery201611Notes": "All manner of delicious and wholesome foods spill forth from this horn. Enjoy the feast! Confers no benefit. November 2016 Subscriber Item.",
- "weaponMystery201708Text": "Lava Sword",
- "weaponMystery201708Notes": "The fiery glow of this sword will make quick work of even dark red Tasks! Confers no benefit. August 2017 Subscriber Item.",
- "weaponMystery201811Text": "Splendid Sorcerer's Staff",
- "weaponMystery201811Notes": "This magical stave is as powerful as it is elegant. Confers no benefit. November 2018 Subscriber Item.",
- "weaponMystery301404Text": "Steampunk Cane",
- "weaponMystery301404Notes": "Excellent for taking a turn about town. March 3015 Subscriber Item. Confers no benefit.",
- "weaponArmoireBasicCrossbowText": "Basic Crossbow",
- "weaponArmoireBasicCrossbowNotes": "This crossbow can pierce a task's armor from very far away! Increases Strength by <%= str %>, Perception by <%= per %>, and Constitution by <%= con %>. Enchanted Armoire: Independent Item.",
- "weaponArmoireLunarSceptreText": "Soothing Lunar Sceptre",
- "weaponArmoireLunarSceptreNotes": "The healing power of this wand waxes and wanes. Increases Constitution by <%= con %> and Intelligence by <%= int %>. Enchanted Armoire: Soothing Lunar Set (Item 3 of 3).",
- "weaponArmoireRancherLassoText": "Rancher Lasso",
- "weaponArmoireRancherLassoNotes": "Lassos: the ideal tool for rounding up and wrangling. Increases Strength by <%= str %>, Perception by <%= per %>, and Intelligence by <%= int %>. Enchanted Armoire: Rancher Set (Item 3 of 3).",
- "weaponArmoireMythmakerSwordText": "Mythmaker Sword",
- "weaponArmoireMythmakerSwordNotes": "Though it may seem humble, this sword has made many mythic heroes. Increases Perception and Strength by <%= attrs %> each. Enchanted Armoire: Golden Toga Set (Item 3 of 3).",
- "weaponArmoireIronCrookText": "Iron Crook",
- "weaponArmoireIronCrookNotes": "Fiercely hammered from iron, this iron crook is good at herding sheep. Increases Perception and Strength by <%= attrs %> each. Enchanted Armoire: Horned Iron Set (Item 3 of 3).",
- "weaponArmoireGoldWingStaffText": "Gold Wing Staff",
- "weaponArmoireGoldWingStaffNotes": "The wings on this staff constantly flutter and twist. Increases all Stats by <%= attrs %> each. Enchanted Armoire: Independent Item.",
- "weaponArmoireBatWandText": "Bat Wand",
- "weaponArmoireBatWandNotes": "This wand can turn any task into a bat! Wave it about and watch them fly away. Increases Intelligence by <%= int %> and Perception by <%= per %>. Enchanted Armoire: Independent Item.",
- "weaponArmoireShepherdsCrookText": "Shepherd's Crook",
- "weaponArmoireShepherdsCrookNotes": "Useful for herding gryphons. Increases Constitution by <%= con %>. Enchanted Armoire: Shepherd Set (Item 1 of 3).",
- "weaponArmoireCrystalCrescentStaffText": "Crystal Crescent Staff",
- "weaponArmoireCrystalCrescentStaffNotes": "Summon the power of the crescent moon with this shining staff! Increases Intelligence and Strength by <%= attrs %> each. Enchanted Armoire: Crystal Crescent Set (Item 3 of 3).",
- "weaponArmoireBlueLongbowText": "Blue Longbow",
- "weaponArmoireBlueLongbowNotes": "Ready... Aim... Fire! This bow has great range. Increases Perception by <%= per %>, Constitution by <%= con %>, and Strength by <%= str %>. Enchanted Armoire: Iron Archer Set (Item 3 of 3).",
- "weaponArmoireGlowingSpearText": "Glowing Spear",
- "weaponArmoireGlowingSpearNotes": "This spear hypnotizes wild tasks so you can attack them. Increases Strength by <%= str %>. Enchanted Armoire: Independent Item.",
- "weaponArmoireBarristerGavelText": "Barrister Gavel",
- "weaponArmoireBarristerGavelNotes": "Order! Increases Strength and Constitution by <%= attrs %> each. Enchanted Armoire: Barrister Set (Item 3 of 3).",
- "weaponArmoireJesterBatonText": "Jester Baton",
- "weaponArmoireJesterBatonNotes": "With a wave of your baton and some witty repartee, even the most complicated situations become clear. Increases Intelligence and Perception by <%= attrs %> each. Enchanted Armoire: Jester Set (Item 3 of 3).",
- "weaponArmoireMiningPickaxText": "Mining Pickax",
- "weaponArmoireMiningPickaxNotes": "Mine the maximum amount of gold from your tasks! Increases Perception by <%= per %>. Enchanted Armoire: Miner Set (Item 3 of 3).",
- "weaponArmoireBasicLongbowText": "Basic Longbow",
- "weaponArmoireBasicLongbowNotes": "A serviceable hand-me-down bow. Increases Strength by <%= str %>. Enchanted Armoire: Basic Archer Set (Item 1 of 3).",
- "weaponArmoireHabiticanDiplomaText": "Habitican Diploma",
- "weaponArmoireHabiticanDiplomaNotes": "A certificate of significant achievement -- well done! Increases Intelligence by <%= int %>. Enchanted Armoire: Graduate Set (Item 1 of 3).",
- "weaponArmoireSandySpadeText": "Sandy Spade",
- "weaponArmoireSandySpadeNotes": "A tool for digging, as well as flicking sand into the eyes of enemy monsters. Increases Strength by <%= str %>. Enchanted Armoire: Seaside Set (Item 1 of 3).",
- "weaponArmoireCannonText": "Cannon",
- "weaponArmoireCannonNotes": "Arr! Set your aim with determination. Increases Strength by <%= str %>. Enchanted Armoire: Cannoneer Set (Item 1 of 3).",
- "weaponArmoireVermilionArcherBowText": "Vermilion Archer Bow",
- "weaponArmoireVermilionArcherBowNotes": "Your arrow will fly like a shooting star from this brilliant red bow! Increases Strength by <%= str %>. Enchanted Armoire: Vermilion Archer Set (Item 1 of 3).",
- "weaponArmoireOgreClubText": "Ogre Club",
- "weaponArmoireOgreClubNotes": "This club was salvaged from an actual Ogre's lair. Increases Strength by <%= str %>. Enchanted Armoire: Ogre Outfit (Item 2 of 3).",
- "weaponArmoireWoodElfStaffText": "Wood Elf Staff",
- "weaponArmoireWoodElfStaffNotes": "Made from a fallen limb of an ancient tree, this staff will help you communicate with forest denizens great and small. Increases Intelligence by <%= int %>. Enchanted Armoire: Wood Elf Set (Item 3 of 3).",
- "weaponArmoireWandOfHeartsText": "Wand of Hearts",
- "weaponArmoireWandOfHeartsNotes": "This wand sparkles with a warm red light. It will also grant your heart wisdom. Increases Intelligence by <%= int %>. Enchanted Armoire: Queen of Hearts Set (Item 3 of 3).",
- "weaponArmoireForestFungusStaffText": "Forest Fungus Staff",
- "weaponArmoireForestFungusStaffNotes": "Use this gnarled staff to work mycological magic! Increases Intelligence by <%= int %> and Perception by <%= per %>. Enchanted Armoire: Independent Item.",
- "weaponArmoireFestivalFirecrackerText": "Festival Firecracker",
- "weaponArmoireFestivalFirecrackerNotes": "Enjoy this delightful sparkler responsibly. Increases Perception by <%= per %>. Enchanted Armoire: Festival Attire Set (Item 3 of 3).",
- "weaponArmoireMerchantsDisplayTrayText": "Merchant's Display Tray",
- "weaponArmoireMerchantsDisplayTrayNotes": "Use this lacquered tray to show the fine goods you're offering for sale. Increases Intelligence by <%= int %>. Enchanted Armoire: Merchant Set (Item 3 of 3).",
- "weaponArmoireBattleAxeText": "Ancient Axe",
- "weaponArmoireBattleAxeNotes": "This fine iron axe is well-suited to battling your fiercest foes or your most difficult tasks. Increases Intelligence by <%= int %> and Constitution by <%= con %>. Enchanted Armoire: Independent Item.",
- "weaponArmoireHoofClippersText": "Hoof Clippers",
- "weaponArmoireHoofClippersNotes": "Trim the hooves of your hard-working mounts to help them stay healthy as they carry you to adventure! Increases Strength, Intelligence, and Constitution by <%= attrs %> each. Enchanted Armoire: Farrier Set (Item 1 of 3).",
- "weaponArmoireWeaversCombText": "Weaver's Comb",
- "weaponArmoireWeaversCombNotes": "Use this comb to pack your weft threads together to make a tightly woven fabric. Increases Perception by <%= per %> and Strength by <%= str %>. Enchanted Armoire: Weaver Set (Item 2 of 3).",
- "weaponArmoireLamplighterText": "Lamplighter",
- "weaponArmoireLamplighterNotes": "This long pole has a wick on one end for lighting lamps, and a hook on the other end for putting them out. Increases Constitution by <%= con %> and Perception by <%= per %>. Enchanted Armoire: Lamplighter's Set (Item 1 of 4)",
- "weaponArmoireCoachDriversWhipText": "Coach Driver's Whip",
- "weaponArmoireCoachDriversWhipNotes": "Your steeds know what they're doing, so this whip is just for show (and the neat snapping sound!). Increases Intelligence by <%= int %> and Strength by <%= str %>. Enchanted Armoire: Coach Driver Set (Item 3 of 3).",
- "weaponArmoireScepterOfDiamondsText": "Scepter of Diamonds",
- "weaponArmoireScepterOfDiamondsNotes": "This scepter shines with a warm red glow as it grants you increased willpower. Increases Strength by <%= str %>. Enchanted Armoire: King of Diamonds Set (Item 3 of 4).",
- "weaponArmoireFlutteryArmyText": "Fluttery Army",
- "weaponArmoireFlutteryArmyNotes": "This group of scrappy lepidopterans is ready to flap fiercely and cool down your reddest tasks! Increases Constitution, Intelligence, and Strength by <%= attrs %> each. Enchanted Armoire: Fluttery Frock Set (Item 3 of 4).",
- "weaponArmoireCobblersHammerText": "Cobbler's Hammer",
- "weaponArmoireCobblersHammerNotes": "This hammer is specially made for leatherwork. It can do a real number on a red Daily in a pinch, though. Increases Constitution and Strength by <%= attrs %> each. Enchanted Armoire: Cobbler Set (Item 2 of 3).",
- "weaponArmoireGlassblowersBlowpipeText": "Glassblower's Blowpipe",
- "weaponArmoireGlassblowersBlowpipeNotes": "Use this tube to blow molten glass into beautiful vases, ornaments, and other fancy things. Increases Strength by <%= str %>. Enchanted Armoire: Glassblower Set (Item 1 of 4).",
- "weaponArmoirePoisonedGobletText": "Poisoned Goblet",
- "weaponArmoirePoisonedGobletNotes": "Use this to build your resistance to iocane powder and other inconceivably dangerous poisons. Increases Intelligence by <%= int %>. Enchanted Armoire: Piratical Princess Set (Item 3 of 4).",
- "weaponArmoireJeweledArcherBowText": "Jeweled Archer Bow",
- "weaponArmoireJeweledArcherBowNotes": "This bow of gold and gems will send your arrows to their targets at incredible speed. Increases Intelligence by <%= int %>. Enchanted Armoire: Jeweled Archer Set (Item 3 of 3).",
- "weaponArmoireNeedleOfBookbindingText": "Needle of Bookbinding",
- "weaponArmoireNeedleOfBookbindingNotes": "You'd be surprised at how tough books can be. This needle can pierce right to the heart of your chores. Increases Strength by <%= str %>. Enchanted Armoire: Bookbinder Set (Item 3 of 4).",
- "weaponArmoireSpearOfSpadesText": "Spear of Spades",
- "weaponArmoireSpearOfSpadesNotes": "This knightly lance is perfect for attacking your reddest Habits and Dailies. Increases Constitution by <%= con %>. Enchanted Armoire: Ace of Spades Set (Item 3 of 3).",
- "weaponArmoireArcaneScrollText": "Arcane Scroll",
- "weaponArmoireArcaneScrollNotes": "This ancient To-Do list is filled with strange symbols and spells from a forgotten age. Increases Intelligence by <%= int %>. Enchanted Armoire: Scribe Set (Item 3 of 3).",
- "armor": "armor",
- "armorCapitalized": "Armor",
- "armorBase0Text": "Plain Clothing",
- "armorBase0Notes": "Ordinary clothing. Confers no benefit.",
- "armorWarrior1Text": "Leather Armor",
- "armorWarrior1Notes": "Jerkin of sturdy boiled hide. Increases Constitution by <%= con %>.",
- "armorWarrior2Text": "Chain Mail",
- "armorWarrior2Notes": "Armor of interlocked metal rings. Increases Constitution by <%= con %>.",
- "armorWarrior3Text": "Plate Armor",
- "armorWarrior3Notes": "Suit of all-encasing steel, the pride of knights. Increases Constitution by <%= con %>.",
- "armorWarrior4Text": "Red Armor",
- "armorWarrior4Notes": "Heavy plate glowing with defensive enchantments. Increases Constitution by <%= con %>.",
- "armorWarrior5Text": "Golden Armor",
- "armorWarrior5Notes": "Looks ceremonial, but no known blade can pierce it. Increases Constitution by <%= con %>.",
- "armorRogue1Text": "Oiled Leather",
- "armorRogue1Notes": "Leather armor treated to reduce noise. Increases Perception by <%= per %>.",
- "armorRogue2Text": "Black Leather",
- "armorRogue2Notes": "Colored with dark dye to blend into shadows. Increases Perception by <%= per %>.",
- "armorRogue3Text": "Camouflage Vest",
- "armorRogue3Notes": "Equally discreet in dungeon or wilderness. Increases Perception by <%= per %>.",
- "armorRogue4Text": "Penumbral Armor",
- "armorRogue4Notes": "Wraps the wearer in a veil of twilight. Increases Perception by <%= per %>.",
- "armorRogue5Text": "Umbral Armor",
- "armorRogue5Notes": "Allows stealth in the open in broad daylight. Increases Perception by <%= per %>.",
- "armorWizard1Text": "Magician Robe",
- "armorWizard1Notes": "Hedge-mage's outfit. Increases Intelligence by <%= int %>.",
- "armorWizard2Text": "Wizard Robe",
- "armorWizard2Notes": "Clothes for a wandering wonder-worker. Increases Intelligence by <%= int %>.",
- "armorWizard3Text": "Robe of Mysteries",
- "armorWizard3Notes": "Denotes initiation into elite secrets. Increases Intelligence by <%= int %>.",
- "armorWizard4Text": "Archmage Robe",
- "armorWizard4Notes": "Spirits and elementals bow before it. Increases Intelligence by <%= int %>.",
- "armorWizard5Text": "Royal Magus Robe",
- "armorWizard5Notes": "Symbol of the power behind the throne. Increases Intelligence by <%= int %>.",
- "armorHealer1Text": "Acolyte Robe",
- "armorHealer1Notes": "Garment showing humility and purpose. Increases Constitution by <%= con %>.",
- "armorHealer2Text": "Medic Robe",
- "armorHealer2Notes": "Worn by those dedicated to tending the wounded in battle. Increases Constitution by <%= con %>.",
- "armorHealer3Text": "Defender Mantle",
- "armorHealer3Notes": "Turns the healer's own magics inward to fend off harm. Increases Constitution by <%= con %>.",
- "armorHealer4Text": "Physician Mantle",
- "armorHealer4Notes": "Projects authority and dissipates curses. Increases Constitution by <%= con %>.",
- "armorHealer5Text": "Royal Mantle",
- "armorHealer5Notes": "Attire of those who have saved the lives of kings. Increases Constitution by <%= con %>.",
- "armorSpecial0Text": "Shade Armor",
- "armorSpecial0Notes": "Screams when struck, for it feels pain in its wearer's place. Increases Constitution by <%= con %>.",
- "armorSpecial1Text": "Crystal Armor",
- "armorSpecial1Notes": "Its tireless power inures the wearer to mundane discomfort. Increases all Stats by <%= attrs %>.",
- "armorSpecial2Text": "Jean Chalard's Noble Tunic",
- "armorSpecial2Notes": "Makes you extra fluffy! Increases Constitution and Intelligence by <%= attrs %> each.",
- "armorSpecialTakeThisText": "Take This Armor",
- "armorSpecialTakeThisNotes": "This armor was earned by participating in a sponsored Challenge made by Take This. Congratulations! Increases all Stats by <%= attrs %>.",
- "armorSpecialFinnedOceanicArmorText": "Finned Oceanic Armor",
- "armorSpecialFinnedOceanicArmorNotes": "Although delicate, this armor makes your skin as harmful to the touch as a fire coral. Increases Strength by <%= str %>.",
- "armorSpecialPyromancersRobesText": "Pyromancer's Robes",
- "armorSpecialPyromancersRobesNotes": "These elegant robes bestow each strike and spell with a burst of ethereal fire. Increases Constitution by <%= con %>.",
- "armorSpecialBardRobesText": "Bardic Robes",
- "armorSpecialBardRobesNotes": "These colorful robes may be conspicuous, but you can sing your way out of any situation. Increases Perception by <%= per %>.",
- "armorSpecialLunarWarriorArmorText": "Lunar Warrior Armor",
- "armorSpecialLunarWarriorArmorNotes": "This armor is forged of moonstone and magical steel. Increases Strength and Constitution by <%= attrs %> each.",
- "armorSpecialMammothRiderArmorText": "Mammoth Rider Armor",
- "armorSpecialMammothRiderArmorNotes": "This suit of fur and leather includes a snazzy cape studded with rose quartz gems. It will protect you from bitter winds as you adventure in the coldest climes. Increases Constitution by <%= con %>.",
- "armorSpecialPageArmorText": "Page Armor",
- "armorSpecialPageArmorNotes": "Carry everything you need in your perfect pack! Increases Constitution by <%= con %>.",
- "armorSpecialRoguishRainbowMessengerRobesText": "Roguish Rainbow Messenger Robes",
- "armorSpecialRoguishRainbowMessengerRobesNotes": "These vividly striped robes will allow you to fly through gale-force winds smoothly and safely. Increases Strength by <%= str %>.",
- "armorSpecialSneakthiefRobesText": "Sneakthief Robes",
- "armorSpecialSneakthiefRobesNotes": "These robes will help hide you in the dead of night, but will also allow freedom of movement as you silently sneak about! Increases Intelligence by <%= int %>.",
- "armorSpecialSnowSovereignRobesText": "Snow Sovereign Robes",
- "armorSpecialSnowSovereignRobesNotes": "These robes are elegant enough for court, yet warm enough for the coldest winter day. Increases Perception by <%= per %>.",
- "armorSpecialNomadsCuirassText": "Nomad's Cuirass",
- "armorSpecialNomadsCuirassNotes": "This armor features a strong chest-plate to protect your heart! Increases Constitution by <%= con %>.",
- "armorSpecialDandySuitText": "Dandy Suit",
- "armorSpecialDandySuitNotes": "You're undeniably dressed for success! Increases Perception by <%= per %>.",
- "armorSpecialSamuraiArmorText": "Samurai Armor",
- "armorSpecialSamuraiArmorNotes": "This strong, scaled armor is held together by elegant silk cords. Increases Perception by <%= per %>.",
- "armorSpecialTurkeyArmorBaseText": "Turkey Armor",
- "armorSpecialTurkeyArmorBaseNotes": "Keep your drumsticks warm and cozy in this feathery armor! Confers no benefit.",
- "armorSpecialTurkeyArmorGildedText": "Gilded Turkey Armor",
- "armorSpecialTurkeyArmorGildedNotes": "Strut your stuff in this seasonally shiny armor! Confers no benefit.",
- "armorSpecialYetiText": "Yeti-Tamer Robe",
- "armorSpecialYetiNotes": "Fuzzy and fierce. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.",
- "armorSpecialSkiText": "Ski-sassin Parka",
- "armorSpecialSkiNotes": "Full of secret daggers and ski trail maps. Increases Perception by <%= per %>. Limited Edition 2013-2014 Winter Gear.",
- "armorSpecialCandycaneText": "Candy Cane Robe",
- "armorSpecialCandycaneNotes": "Spun from sugar and silk. Increases Intelligence by <%= int %>. Limited Edition 2013-2014 Winter Gear.",
- "armorSpecialSnowflakeText": "Snowflake Robe",
- "armorSpecialSnowflakeNotes": "A robe to keep you warm, even in a blizzard. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.",
- "armorSpecialBirthdayText": "Absurd Party Robes",
- "armorSpecialBirthdayNotes": "Happy Birthday, Habitica! Wear these Absurd Party Robes to celebrate this wonderful day. Confers no benefit.",
- "armorSpecialBirthday2015Text": "Silly Party Robes",
- "armorSpecialBirthday2015Notes": "Happy Birthday, Habitica! Wear these Silly Party Robes to celebrate this wonderful day. Confers no benefit.",
- "armorSpecialBirthday2016Text": "Ridiculous Party Robes",
- "armorSpecialBirthday2016Notes": "Happy Birthday, Habitica! Wear these Ridiculous Party Robes to celebrate this wonderful day. Confers no benefit.",
- "armorSpecialBirthday2017Text": "Whimsical Party Robes",
- "armorSpecialBirthday2017Notes": "Happy Birthday, Habitica! Wear these Whimsical Party Robes to celebrate this wonderful day. Confers no benefit.",
- "armorSpecialBirthday2018Text": "Fanciful Party Robes",
- "armorSpecialBirthday2018Notes": "Happy Birthday, Habitica! Wear these Fanciful Party Robes to celebrate this wonderful day. Confers no benefit.",
- "armorSpecialGaymerxText": "Rainbow Warrior Armor",
- "armorSpecialGaymerxNotes": "In celebration of the GaymerX Conference, this special armor is decorated with a radiant, colorful rainbow pattern! GaymerX is a game convention celebrating LGTBQ and gaming and is open to everyone.",
- "armorSpecialSpringRogueText": "Sleek Cat Suit",
- "armorSpecialSpringRogueNotes": "Impeccably groomed. Increases Perception by <%= per %>. Limited Edition 2014 Spring Gear.",
- "armorSpecialSpringWarriorText": "Clover-steel Armor",
- "armorSpecialSpringWarriorNotes": "Soft as clover, strong as steel! Increases Constitution by <%= con %>. Limited Edition 2014 Spring Gear.",
- "armorSpecialSpringMageText": "Rodentia Robes",
- "armorSpecialSpringMageNotes": "Mice are nice! Increases Intelligence by <%= int %>. Limited Edition 2014 Spring Gear.",
- "armorSpecialSpringHealerText": "Fuzzy Puppy Robes",
- "armorSpecialSpringHealerNotes": "Warm and snuggly, but protects its owner from harm. Increases Constitution by <%= con %>. Limited Edition 2014 Spring Gear.",
- "armorSpecialSummerRogueText": "Pirate Robes",
- "armorSpecialSummerRogueNotes": "These robes be very cozy, yarrrr! Increases Perception by <%= per %>. Limited Edition 2014 Summer Gear.",
- "armorSpecialSummerWarriorText": "Swashbuckler Robes",
- "armorSpecialSummerWarriorNotes": "Complete with buckle, as well as swash. Increases Constitution by <%= con %>. Limited Edition 2014 Summer Gear.",
- "armorSpecialSummerMageText": "Emerald Tail",
- "armorSpecialSummerMageNotes": "This garment of shimmering scales transforms its wearer into a real Mermage! Increases Intelligence by <%= int %>. Limited Edition 2014 Summer Gear.",
- "armorSpecialSummerHealerText": "Seahealer Tail",
- "armorSpecialSummerHealerNotes": "This garment of shimmering scales transforms its wearer into a real Seahealer! Increases Constitution by <%= con %>. Limited Edition 2014 Summer Gear.",
- "armorSpecialFallRogueText": "Bloodred Robes",
- "armorSpecialFallRogueNotes": "Vivid. Velvet. Vampiric. Increases Perception by <%= per %>. Limited Edition 2014 Autumn Gear.",
- "armorSpecialFallWarriorText": "Lab-coat of Science",
- "armorSpecialFallWarriorNotes": "Protects you from mysterious potion spills. Increases Constitution by <%= con %>. Limited Edition 2014 Autumn Gear.",
- "armorSpecialFallMageText": "Witchy Wizard Robes",
- "armorSpecialFallMageNotes": "This robe has plenty of pockets to hold extra helpings of eye of newt and tongue of frog. Increases Intelligence by <%= int %>. Limited Edition 2014 Autumn Gear.",
- "armorSpecialFallHealerText": "Gauzy Gear",
- "armorSpecialFallHealerNotes": "Charge into battle pre-bandaged! Increases Constitution by <%= con %>. Limited Edition 2014 Autumn Gear.",
- "armorSpecialWinter2015RogueText": "Icicle Drake Armor",
- "armorSpecialWinter2015RogueNotes": "This armor is freezing cold, but it will definitely be worth it when you uncover the untold riches at the center of the Icicle Drake hives. Not that you are looking for any such untold riches, because you are truly, definitely, absolutely a genuine Icicle Drake, okay?! Stop asking questions! Increases Perception by <%= per %>. Limited Edition 2014-2015 Winter Gear.",
- "armorSpecialWinter2015WarriorText": "Gingerbread Armor",
- "armorSpecialWinter2015WarriorNotes": "Cozy and warm, straight from the oven! Increases Constitution by <%= con %>. Limited Edition 2014-2015 Winter Gear.",
- "armorSpecialWinter2015MageText": "Boreal Robe",
- "armorSpecialWinter2015MageNotes": "You can see the glimmering lights of the north in this robe. Increases Intelligence by <%= int %>. Limited Edition 2014-2015 Winter Gear.",
- "armorSpecialWinter2015HealerText": "Skating Outfit",
- "armorSpecialWinter2015HealerNotes": "Ice-skating is very relaxing, but you shouldn't try it without this protective gear in case you get attacked by the icicle drakes. Increases Constitution by <%= con %>. Limited Edition 2014-2015 Winter Gear.",
- "armorSpecialSpring2015RogueText": "Squeaker Robes",
- "armorSpecialSpring2015RogueNotes": "Furry, soft, and definitely not flammable. Increases Perception by <%= per %>. Limited Edition 2015 Spring Gear.",
- "armorSpecialSpring2015WarriorText": "Beware Armor",
- "armorSpecialSpring2015WarriorNotes": "Only the fiercest doggy is allowed to be this fluffy. Increases Constitution by <%= con %>. Limited Edition 2015 Spring Gear.",
- "armorSpecialSpring2015MageText": "Magician's Bunny Suit",
- "armorSpecialSpring2015MageNotes": "Your coattails match your cottontail! Increases Intelligence by <%= int %>. Limited Edition 2015 Spring Gear.",
- "armorSpecialSpring2015HealerText": "Comforting Catsuit",
- "armorSpecialSpring2015HealerNotes": "This soft catsuit is comfortable, and as comforting as mint tea. Increases Constitution by <%= con %>. Limited Edition 2015 Spring Gear.",
- "armorSpecialSummer2015RogueText": "Ruby Tail",
- "armorSpecialSummer2015RogueNotes": "This garment of shimmering scales transforms its wearer into a real Reef Renegade! Increases Perception by <%= per %>. Limited Edition 2015 Summer Gear.",
- "armorSpecialSummer2015WarriorText": "Golden Tail",
- "armorSpecialSummer2015WarriorNotes": "This garment of shimmering scales transforms its wearer into a real Sunfish Warrior! Increases Constitution by <%= con %>. Limited Edition 2015 Summer Gear.",
- "armorSpecialSummer2015MageText": "Soothsayer Robes",
- "armorSpecialSummer2015MageNotes": "Hidden power resides in the puffs of these sleeves. Increases Intelligence by <%= int %>. Limited Edition 2015 Summer Gear.",
- "armorSpecialSummer2015HealerText": "Sailor's Armor",
- "armorSpecialSummer2015HealerNotes": "This armor lets everyone know that you are an honest merchant sailor who would never dream of behaving like a scalawag. Increases Constitution by <%= con %>. Limited Edition 2015 Summer Gear.",
- "armorSpecialFall2015RogueText": "Bat-tle Armor",
- "armorSpecialFall2015RogueNotes": "Fly into bat-tle! Increases Perception by <%= per %>. Limited Edition 2015 Autumn Gear.",
- "armorSpecialFall2015WarriorText": "Scarecrow Armor",
- "armorSpecialFall2015WarriorNotes": "Despite being stuffed with straw, this armor is extremely hefty! Increases Constitution by <%= con %>. Limited Edition 2015 Autumn Gear.",
- "armorSpecialFall2015MageText": "Stitched Robes",
- "armorSpecialFall2015MageNotes": "Every stitch in this armor shimmers with enchantment. Increases Intelligence by <%= int %>. Limited Edition 2015 Autumn Gear.",
- "armorSpecialFall2015HealerText": "Potioner Robes",
- "armorSpecialFall2015HealerNotes": "What? Of course that was a potion of constitution. No, you are definitely not turning into a frog! Don't be ribbiticulous. Increases Constitution by <%= con %>. Limited Edition 2015 Autumn Gear.",
- "armorSpecialWinter2016RogueText": "Cocoa Armor",
- "armorSpecialWinter2016RogueNotes": "This leather armor keeps you nice and toasty. Is it actually made from cocoa? You'll never tell. Increases Perception by <%= per %>. Limited Edition 2015-2016 Winter Gear.",
- "armorSpecialWinter2016WarriorText": "Snowman Suit",
- "armorSpecialWinter2016WarriorNotes": "Brr! This padded armor is truly powerful... until it melts. Increases Constitution by <%= con %>. Limited Edition 2015-2016 Winter Gear.",
- "armorSpecialWinter2016MageText": "Snowboarder Parka",
- "armorSpecialWinter2016MageNotes": "The wisest wizard keeps well-bundled in the winter wind. Increases Intelligence by <%= int %>. Limited Edition 2015-2016 Winter Gear.",
- "armorSpecialWinter2016HealerText": "Festive Fairy Cloak",
- "armorSpecialWinter2016HealerNotes": "Festive Fairies wrap their body wings around themselves for protection as they use their head wings to catch headwinds and fly around Habitica at speeds of up to 100 mph, delivering gifts and spraying everyone with confetti. How droll. Increases Constitution by <%= con %>. Limited Edition 2015-2016 Winter Gear.",
- "armorSpecialSpring2016RogueText": "Canine Camo Suit",
- "armorSpecialSpring2016RogueNotes": "A clever pup knows to choose a brighter guise for concealment when everything is green and vibrant. Increases Perception by <%= per %>. Limited Edition 2016 Spring Gear.",
- "armorSpecialSpring2016WarriorText": "Mighty Mail",
- "armorSpecialSpring2016WarriorNotes": "Though you be but little, you are fierce! Increases Constitution by <%= con %>. Limited Edition 2016 Spring Gear.",
- "armorSpecialSpring2016MageText": "Grand Malkin Robes",
- "armorSpecialSpring2016MageNotes": "Brightly colored, so you won't be mistaken for a necromouser. Increases Intelligence by <%= int %>. Limited Edition 2016 Spring Gear.",
- "armorSpecialSpring2016HealerText": "Fluffy Bunny Breeches",
- "armorSpecialSpring2016HealerNotes": "Hippity hop! Bound from hill to hill, healing those in need. Increases Constitution by <%= con %>. Limited Edition 2016 Spring Gear.",
- "armorSpecialSummer2016RogueText": "Eel Tail",
- "armorSpecialSummer2016RogueNotes": "This electrifying garment transforms its wearer into a real Eel Rogue! Increases Perception by <%= per %>. Limited Edition 2016 Summer Gear.",
- "armorSpecialSummer2016WarriorText": "Shark Tail",
- "armorSpecialSummer2016WarriorNotes": "This rough garment transforms its wearer into a real Shark Warrior! Increases Constitution by <%= con %>. Limited Edition 2016 Summer Gear.",
- "armorSpecialSummer2016MageText": "Dolphin Tail",
- "armorSpecialSummer2016MageNotes": "This slippery garment transforms its wearer into a real Dolphin Mage! Increases Intelligence by <%= int %>. Limited Edition 2016 Summer Gear.",
- "armorSpecialSummer2016HealerText": "Seahorse Tail",
- "armorSpecialSummer2016HealerNotes": "This spiky garment transforms its wearer into a real Seahorse Healer! Increases Constitution by <%= con %>. Limited Edition 2016 Summer Gear.",
- "armorSpecialFall2016RogueText": "Black Widow Armor",
- "armorSpecialFall2016RogueNotes": "The eyes on this armor are constantly blinking. Increases Perception by <%= per %>. Limited Edition 2016 Autumn Gear.",
- "armorSpecialFall2016WarriorText": "Slime-Streaked Armor",
- "armorSpecialFall2016WarriorNotes": "Mysteriously moist and mossy! Increases Constitution by <%= con %>. Limited Edition 2016 Autumn Gear.",
- "armorSpecialFall2016MageText": "Cloak of Wickedness",
- "armorSpecialFall2016MageNotes": "When your cloak flaps, you hear the sound of cackling laughter. Increases Intelligence by <%= int %>. Limited Edition 2016 Autumn Gear.",
- "armorSpecialFall2016HealerText": "Gorgon Robes",
- "armorSpecialFall2016HealerNotes": "These robes are actually made of stone. How are they so comfortable? Increases Constitution by <%= con %>. Limited Edition 2016 Autumn Gear.",
- "armorSpecialWinter2017RogueText": "Frosty Armor",
- "armorSpecialWinter2017RogueNotes": "This stealthy suit reflects light to dazzle unsuspecting tasks as you take your rewards from them! Increases Perception by <%= per %>. Limited Edition 2016-2017 Winter Gear.",
- "armorSpecialWinter2017WarriorText": "Ice Hockey Armor",
- "armorSpecialWinter2017WarriorNotes": "Show your team spirit and strength in this warm, padded armor. Increases Constitution by <%= con %>. Limited Edition 2016-2017 Winter Gear.",
- "armorSpecialWinter2017MageText": "Wolfish Armor",
- "armorSpecialWinter2017MageNotes": "Made of winter's warmest wool and woven with spells by the mystical Winter Wolf, these robes stave off the chill and keep your mind alert! Increases Intelligence by <%= int %>. Limited Edition 2016-2017 Winter Gear.",
- "armorSpecialWinter2017HealerText": "Shimmer Petal Armor",
- "armorSpecialWinter2017HealerNotes": "Though soft, this armor of petals has fantastic protective power. Increases Constitution by <%= con %>. Limited Edition 2016-2017 Winter Gear.",
- "armorSpecialSpring2017RogueText": "Sneaky Bunny Suit",
- "armorSpecialSpring2017RogueNotes": "Soft but strong, this suit helps you move through gardens with extra stealth. Increases Perception by <%= per %>. Limited Edition 2017 Spring Gear.",
- "armorSpecialSpring2017WarriorText": "Pawsome Armor",
- "armorSpecialSpring2017WarriorNotes": "This fancy armor is as shiny as your finely groomed coat, but with added resistance to attack. Increases Constitution by <%= con %>. Limited Edition 2017 Spring Gear.",
- "armorSpecialSpring2017MageText": "Canine Conjuror Robes",
- "armorSpecialSpring2017MageNotes": "Magical by design, fluffy by choice. Increases Intelligence by <%= int %>. Limited Edition 2017 Spring Gear.",
- "armorSpecialSpring2017HealerText": "Robes of Repose",
- "armorSpecialSpring2017HealerNotes": "The softness of these robes comforts you as well as any who need your healing help! Increases Constitution by <%= con %>. Limited Edition 2017 Spring Gear.",
- "armorSpecialSummer2017RogueText": "Sea Dragon Tail",
- "armorSpecialSummer2017RogueNotes": "This colorful garment transforms its wearer into a real Sea Dragon! Increases Perception by <%= per %>. Limited Edition 2017 Summer Gear.",
- "armorSpecialSummer2017WarriorText": "Sandy Armor",
- "armorSpecialSummer2017WarriorNotes": "Don't be fooled by the crumbly exterior: this armor is harder than steel. Increases Constitution by <%= con %>. Limited Edition 2017 Summer Gear.",
- "armorSpecialSummer2017MageText": "Whirlpool Robes",
- "armorSpecialSummer2017MageNotes": "Careful not to get splashed by these robes woven of enchanted water! Increases Intelligence by <%= int %>. Limited Edition 2017 Summer Gear.",
- "armorSpecialSummer2017HealerText": "Silversea Tail",
- "armorSpecialSummer2017HealerNotes": "This garment of silvery scales transforms its wearer into a real Seahealer! Increases Constitution by <%= con %>. Limited Edition 2017 Summer Gear.",
- "armorSpecialFall2017RogueText": "Pumpkin Patch Robes",
- "armorSpecialFall2017RogueNotes": "Need to hide out? Crouch among the Jack o' Lanterns and these robes will conceal you! Increases Perception by <%= per %>. Limited Edition 2017 Autumn Gear.",
- "armorSpecialFall2017WarriorText": "Strong and Sweet Armor",
- "armorSpecialFall2017WarriorNotes": "This armor will protect you like a delicious candy shell. Increases Constitution by <%= con %>. Limited Edition 2017 Autumn Gear.",
- "armorSpecialFall2017MageText": "Masquerade Robes",
- "armorSpecialFall2017MageNotes": "What masquerade ensemble would be complete without dramatic and sweeping robes? Increases Intelligence by <%= int %>. Limited Edition 2017 Autumn Gear.",
- "armorSpecialFall2017HealerText": "Haunted House Armor",
- "armorSpecialFall2017HealerNotes": "Your heart is an open door. And your shoulders are roofing tiles! Increases Constitution by <%= con %>. Limited Edition 2017 Autumn Gear.",
- "armorSpecialWinter2018RogueText": "Reindeer Costume",
- "armorSpecialWinter2018RogueNotes": "You look so cute and fuzzy, who could suspect you are after holiday loot? Increases Perception by <%= per %>. Limited Edition 2017-2018 Winter Gear.",
- "armorSpecialWinter2018WarriorText": "Wrapping Paper Armor",
- "armorSpecialWinter2018WarriorNotes": "Don't let the papery feel of this armor fool you. It's nearly impossible to rip! Increases Constitution by <%= con %>. Limited Edition 2017-2018 Winter Gear.",
- "armorSpecialWinter2018MageText": "Sparkly Tuxedo",
- "armorSpecialWinter2018MageNotes": "The ultimate in magical formalwear. Increases Intelligence by <%= int %>. Limited Edition 2017-2018 Winter Gear.",
- "armorSpecialWinter2018HealerText": "Mistletoe Robes",
- "armorSpecialWinter2018HealerNotes": "These robes are woven with spells for extra holiday joy. Increases Constitution by <%= con %>. Limited Edition 2017-2018 Winter Gear.",
- "armorSpecialSpring2018RogueText": "Feather Suit",
- "armorSpecialSpring2018RogueNotes": "This fluffy yellow costume will trick your enemies into thinking you're just a harmless ducky! Increases Perception by <%= per %>. Limited Edition 2018 Spring Gear.",
- "armorSpecialSpring2018WarriorText": "Armor of Dawn",
- "armorSpecialSpring2018WarriorNotes": "This colorful plate is forged with the sunrise's fire. Increases Constitution by <%= con %>. Limited Edition 2018 Spring Gear.",
- "armorSpecialSpring2018MageText": "Tulip Robe",
- "armorSpecialSpring2018MageNotes": "Your spell casting can only improve while clad in these soft, silky petals. Increases Intelligence by <%= int %>. Limited Edition 2018 Spring Gear.",
- "armorSpecialSpring2018HealerText": "Garnet Armor",
- "armorSpecialSpring2018HealerNotes": "Let this bright armor infuse your heart with power for healing. Increases Constitution by <%= con %>. Limited Edition 2018 Spring Gear.",
- "armorSpecialSummer2018RogueText": "Pocket Fishing Vest",
- "armorSpecialSummer2018RogueNotes": "Bobbers? Boxes of hooks? Spare line? Lockpicks? Smoke bombs? Whatever you need on hand for your summer fishing getaway, there's a pocket for it! Increases Perception by <%= per %>. Limited Edition 2018 Summer Gear.",
- "armorSpecialSummer2018WarriorText": "Betta Tail Armor",
- "armorSpecialSummer2018WarriorNotes": "Dazzle onlookers with whorls of magnificent color as you spin and dart through the water. How could any opponent dare strike at this beauty? Increases Constitution by <%= con %>. Limited Edition 2018 Summer Gear.",
- "armorSpecialSummer2018MageText": "Lionfish Scale Hauberk",
- "armorSpecialSummer2018MageNotes": "Venom magic has a reputation for subtlety. Not so this colorful armor, whose message is clear to beast and task alike: watch out! Increases Intelligence by <%= int %>. Limited Edition 2018 Summer Gear.",
- "armorSpecialSummer2018HealerText": "Merfolk Monarch Robes",
- "armorSpecialSummer2018HealerNotes": "These cerulean vestments reveal that you have land-walking feet... well. Not even a monarch can be expected to be perfect. Increases Constitution by <%= con %>. Limited Edition 2018 Summer Gear.",
- "armorSpecialFall2018RogueText": "Alter Ego Frock Coat",
- "armorSpecialFall2018RogueNotes": "Style for the day. Comfort and protection for the night. Increases Perception by <%= per %>. Limited Edition 2018 Autumn Gear.",
- "armorSpecialFall2018WarriorText": "Minotaur Platemail",
- "armorSpecialFall2018WarriorNotes": "Complete with hooves to drum a soothing cadence as you walk your meditative labyrinth. Increases Constitution by <%= con %>. Limited Edition 2018 Autumn Gear.",
- "armorSpecialFall2018MageText": "Candymancer's Robes",
- "armorSpecialFall2018MageNotes": "The fabric of these robes has magic candy woven right in! However, we recommend you not attempt to eat them. Increases Intelligence by <%= int %>. Limited Edition 2018 Autumn Gear.",
- "armorSpecialFall2018HealerText": "Robes of Carnivory",
- "armorSpecialFall2018HealerNotes": "It's made from plants, but that doesn't mean it's vegetarian. Bad habits are afraid to come within miles of these robes. Increases Constitution by <%= con %>. Limited Edition 2018 Autumn Gear.",
- "armorSpecialWinter2019RogueText": "Poinsettia Armor",
- "armorSpecialWinter2019RogueNotes": "With holiday greenery all about, no one will notice an extra shrubbery! You can move through seasonal gatherings with ease and stealth. Increases Perception by <%= per %>. Limited Edition 2018-2019 Winter Gear.",
- "armorSpecialWinter2019WarriorText": "Glacial Armor",
- "armorSpecialWinter2019WarriorNotes": "In the heat of battle, this armor will keep you ice cool and ready for action. Increases Constitution by <%= con %>. Limited Edition 2018-2019 Winter Gear.",
- "armorSpecialWinter2019MageText": "Robes of Burning Inspiration",
- "armorSpecialWinter2019MageNotes": "This fireproof garb will help protect you if any of your flashes of brilliance should happen to backfire! Increases Intelligence by <%= int %>. Limited Edition 2018-2019 Winter Gear.",
- "armorSpecialWinter2019HealerText": "Midnight Robe",
- "armorSpecialWinter2019HealerNotes": "Without darkness, there wouldn't be any light. These dark robes help bring peace and rest to promote healing. Increases Constitution by <%= con %>. Limited Edition 2018-2019 Winter Gear.",
- "armorMystery201402Text": "Messenger Robes",
- "armorMystery201402Notes": "Shimmering and strong, these robes have many pockets to carry letters. Confers no benefit. February 2014 Subscriber Item.",
- "armorMystery201403Text": "Forest Walker Armor",
- "armorMystery201403Notes": "This mossy armor of woven wood bends with the movement of the wearer. Confers no benefit. March 2014 Subscriber Item.",
- "armorMystery201405Text": "Flame of Heart",
- "armorMystery201405Notes": "Nothing can hurt you when you are swathed in flames! Confers no benefit. May 2014 Subscriber Item.",
- "armorMystery201406Text": "Octopus Robe",
- "armorMystery201406Notes": "This flexible robe makes it possible for its wearer to slip through even the tiniest cracks. Confers no benefit. June 2014 Subscriber Item.",
- "armorMystery201407Text": "Undersea Explorer Suit",
- "armorMystery201407Notes": "Described alternatively as \"splooshy\", \"overly thick\" and \"frankly, kind of cumbersome\", this suit is the best friend of any intrepid undersea explorer. Confers no benefit. July 2014 Subscriber Item.",
- "armorMystery201408Text": "Sun Robes",
- "armorMystery201408Notes": "These robes are woven with sunlight and gold. Confers no benefit. August 2014 Subscriber Item.",
- "armorMystery201409Text": "Strider Vest",
- "armorMystery201409Notes": "A leaf-covered vest that camouflages the wearer. Confers no benefit. September 2014 Subscriber Item.",
- "armorMystery201410Text": "Goblin Gear",
- "armorMystery201410Notes": "Scaly, slimy, and strong! Confers no benefit. October 2014 Subscriber Item.",
- "armorMystery201412Text": "Penguin Suit",
- "armorMystery201412Notes": "You're a penguin! Confers no benefit. December 2014 Subscriber Item.",
- "armorMystery201501Text": "Starry Armor",
- "armorMystery201501Notes": "Galaxies shimmer in the metal of this armor, strengthening the wearer's resolve. Confers no benefit. January 2015 Subscriber Item.",
- "armorMystery201503Text": "Aquamarine Armor",
- "armorMystery201503Notes": "This blue mineral symbolizes good luck, happiness, and eternal productivity. Confers no benefit. March 2015 Subscriber Item.",
- "armorMystery201504Text": "Busy Bee Robe",
- "armorMystery201504Notes": "You'll be productive as a busy bee in this fetching robe! Confers no benefit. April 2015 Subscriber Item.",
- "armorMystery201506Text": "Snorkel Suit",
- "armorMystery201506Notes": "Snorkel through a coral reef in this brightly-colored swim suit! Confers no benefit. June 2015 Subscriber Item.",
- "armorMystery201508Text": "Cheetah Costume",
- "armorMystery201508Notes": "Run fast as a flash in the fluffy Cheetah Costume! Confers no benefit. August 2015 Subscriber Item.",
- "armorMystery201509Text": "Werewolf Costume",
- "armorMystery201509Notes": "This IS a costume, right? Confers no benefit. September 2015 Subscriber Item.",
- "armorMystery201511Text": "Wooden Armor",
- "armorMystery201511Notes": "Considering this armor was carved directly from a magical log, it's surprisingly comfortable. Confers no benefit. November 2015 Subscriber Item.",
- "armorMystery201512Text": "Cold Fire Armor",
- "armorMystery201512Notes": "Summon the icy flames of winter! Confers no benefit. December 2015 Subscriber Item.",
- "armorMystery201603Text": "Lucky Suit",
- "armorMystery201603Notes": "This suit is sewn from thousands of four-leafed clovers! Confers no benefit. March 2016 Subscriber Item.",
- "armorMystery201604Text": "Armor o' Leaves",
- "armorMystery201604Notes": "You, too, can be a small but fearsome leaf puff. Confers no benefit. April 2016 Subscriber Item.",
- "armorMystery201605Text": "Marching Bard Uniform",
- "armorMystery201605Notes": "Unlike the traditional bards who join adventuring parties, bards who join Habitican marching bands are known for grand parades, not dungeon raids. Confers no benefit. May 2016 Subscriber Item.",
- "armorMystery201606Text": "Selkie Tail",
- "armorMystery201606Notes": "This strong tail shimmers like sea foam crashing upon the shore. Confers no benefit. June 2016 Subscriber Item.",
- "armorMystery201607Text": "Seafloor Rogue Armor",
- "armorMystery201607Notes": "Blend into the sea floor with this stealthy aquatic armor. Confers no benefit. July 2016 Subscriber Item.",
- "armorMystery201609Text": "Cow Armor",
- "armorMystery201609Notes": "Fit in with the rest of the herd in this snuggly armor! Confers no benefit. September 2016 Subscriber Item.",
- "armorMystery201610Text": "Spectral Armor",
- "armorMystery201610Notes": "Mysterious armor that will cause you to float like a ghost! Confers no benefit. October 2016 Subscriber Item.",
- "armorMystery201612Text": "Nutcracker Armor",
- "armorMystery201612Notes": "Crack nuts in style in this spectacular holiday ensemble. Be careful not to pinch your fingers! Confers no benefit. December 2016 Subscriber Item.",
- "armorMystery201703Text": "Shimmer Armor",
- "armorMystery201703Notes": "Though its colors are reminiscent of spring petals, this armor is stronger than steel! Confers no benefit. March 2017 Subscriber Item.",
- "armorMystery201704Text": "Fairytale Armor",
- "armorMystery201704Notes": "Fairy folk crafted this armor from morning dew to capture the colors of the sunrise. Confers no benefit. April 2017 Subscriber Item.",
- "armorMystery201707Text": "Jellymancer Armor",
- "armorMystery201707Notes": "This armor will help you blend in with the creatures of the ocean while you pursue undersea quests and adventures. Confers no benefit. July 2017 Subscriber Item.",
- "armorMystery201710Text": "Imperious Imp Apparel",
- "armorMystery201710Notes": "Scaly, shiny, and strong! Confers no benefit. October 2017 Subscriber Item.",
- "armorMystery201711Text": "Carpet Rider Outfit",
- "armorMystery201711Notes": "This cozy sweater set will help keep you warm as you ride through the sky! Confers no benefit. November 2017 Subscriber Item.",
- "armorMystery201712Text": "Candlemancer Armor",
- "armorMystery201712Notes": "The heat and light generated by this magic armor will warm your heart but never burn your skin! Confers no benefit. December 2017 Subscriber Item.",
- "armorMystery201802Text": "Love Bug Armor",
- "armorMystery201802Notes": "This shiny armor reflects your strength of heart and infuses it into any Habiticans nearby who may need encouragement! Confers no benefit. February 2018 Subscriber Item.",
- "armorMystery201806Text": "Alluring Anglerfish Tail",
- "armorMystery201806Notes": "This sinuous tail features glowing spots to light your way through the deep. Confers no benefit. June 2018 Subscriber Item.",
- "armorMystery201807Text": "Sea Serpent Tail",
- "armorMystery201807Notes": "This powerful tail will propel you through the sea at incredible speeds! Confers no benefit. July 2018 Subscriber Item.",
- "armorMystery201808Text": "Lava Dragon Armor",
- "armorMystery201808Notes": "This armor is made from the shed scales of the elusive (and extremely warm) Lava Dragon. Confers no benefit. August 2018 Subscriber Item.",
- "armorMystery201809Text": "Armor of Autumn Leaves",
- "armorMystery201809Notes": "You are not only a small and fearsome leaf puff, you are sporting the most beautiful colors of the season! Confers no benefit. September 2018 Subscriber Item.",
- "armorMystery201810Text": "Dark Forest Robes",
- "armorMystery201810Notes": "These robes are extra warm to protect you from the ghastly cold of haunted realms. Confers no benefit. October 2018 Subscriber Item.",
- "armorMystery301404Text": "Steampunk Suit",
- "armorMystery301404Notes": "Dapper and dashing, wot! Confers no benefit. February 3015 Subscriber Item.",
- "armorMystery301703Text": "Steampunk Peacock Gown",
- "armorMystery301703Notes": "This elegant gown is well-suited for even the most extravagant gala! Confers no benefit. March 3017 Subscriber Item.",
- "armorMystery301704Text": "Steampunk Pheasant Dress",
- "armorMystery301704Notes": "This fine outfit is perfect for a night out and about or a day in your gadget workshop! Confers no benefit. April 3017 Subscriber Item.",
- "armorArmoireLunarArmorText": "Soothing Lunar Armor",
- "armorArmoireLunarArmorNotes": "The light of the moon will make you strong and savvy. Increases Strength by <%= str %> and Intelligence by <%= int %>. Enchanted Armoire: Soothing Lunar Set (Item 2 of 3).",
- "armorArmoireGladiatorArmorText": "Gladiator Armor",
- "armorArmoireGladiatorArmorNotes": "To be a gladiator you must be not only cunning... but strong. Increases Perception by <%= per %> and Strength by <%= str %>. Enchanted Armoire: Gladiator Set (Item 2 of 3).",
- "armorArmoireRancherRobesText": "Rancher Robes",
- "armorArmoireRancherRobesNotes": "Wrangle your mounts and round up your pets while wearing these magical Rancher Robes! Increases Strength by <%= str %>, Perception by <%= per %>, and Intelligence by <%= int %>. Enchanted Armoire: Rancher Set (Item 2 of 3).",
- "armorArmoireGoldenTogaText": "Golden Toga",
- "armorArmoireGoldenTogaNotes": "This glimmering toga is only worn by true heroes. Increases Strength and Constitution by <%= attrs %> each. Enchanted Armoire: Golden Toga Set (Item 1 of 3).",
- "armorArmoireHornedIronArmorText": "Horned Iron Armor",
- "armorArmoireHornedIronArmorNotes": "Fiercely hammered from iron, this horned armor is nearly impossible to break. Increases Constitution by <%= con %> and Perception by <%= per %>. Enchanted Armoire: Horned Iron Set (Item 2 of 3).",
- "armorArmoirePlagueDoctorOvercoatText": "Plague Doctor Overcoat",
- "armorArmoirePlagueDoctorOvercoatNotes": "An authentic overcoat worn by the doctors who battle the Plague of Procrastination! Increases Intelligence by <%= int %>, Strength by <%= str %>, and Constitution by <%= con %>. Enchanted Armoire: Plague Doctor Set (Item 3 of 3).",
- "armorArmoireShepherdRobesText": "Shepherd Robes",
- "armorArmoireShepherdRobesNotes": "The fabric is cool and breathable, perfect for a hot day herding gryphons in the desert. Increases Strength and Perception by <%= attrs %> each. Enchanted Armoire: Shepherd Set (Item 2 of 3).",
- "armorArmoireRoyalRobesText": "Royal Robes",
- "armorArmoireRoyalRobesNotes": "Wonderful ruler, rule all day long! Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Royal Set (Item 3 of 3).",
- "armorArmoireCrystalCrescentRobesText": "Crystal Crescent Robes",
- "armorArmoireCrystalCrescentRobesNotes": "These magical robes are luminescent at night. Increases Constitution and Perception by <%= attrs %> each. Enchanted Armoire: Crystal Crescent Set (Item 2 of 3).",
- "armorArmoireDragonTamerArmorText": "Dragon Tamer Armor",
- "armorArmoireDragonTamerArmorNotes": "This tough armor is impenetrable to flame. Increases Constitution by <%= con %>. Enchanted Armoire: Dragon Tamer Set (Item 3 of 3).",
- "armorArmoireBarristerRobesText": "Barrister Robes",
- "armorArmoireBarristerRobesNotes": "Very serious and stately. Increases Constitution by <%= con %>. Enchanted Armoire: Barrister Set (Item 2 of 3).",
- "armorArmoireJesterCostumeText": "Jester Costume",
- "armorArmoireJesterCostumeNotes": "Tra-la-la! Despite the look of this costume, you are no fool. Increases Intelligence by <%= int %>. Enchanted Armoire: Jester Set (Item 2 of 3).",
- "armorArmoireMinerOverallsText": "Miner Overalls",
- "armorArmoireMinerOverallsNotes": "They may seem worn, but they are enchanted to repel dirt. Increases Constitution by <%= con %>. Enchanted Armoire: Miner Set (Item 2 of 3).",
- "armorArmoireBasicArcherArmorText": "Basic Archer Armor",
- "armorArmoireBasicArcherArmorNotes": "This camouflaged vest lets you slip unnoticed through the forests. Increases Perception by <%= per %>. Enchanted Armoire: Basic Archer Set (Item 2 of 3).",
- "armorArmoireGraduateRobeText": "Graduate Robe",
- "armorArmoireGraduateRobeNotes": "Congratulations! This weighty robe hangs heavy with all the knowledge you have accrued. Increases Intelligence by <%= int %>. Enchanted Armoire: Graduate Set (Item 2 of 3).",
- "armorArmoireStripedSwimsuitText": "Striped Swimsuit",
- "armorArmoireStripedSwimsuitNotes": "What could be more fun than battling sea monsters on the beach? Increases Constitution by <%= con %>. Enchanted Armoire: Seaside Set (Item 2 of 3).",
- "armorArmoireCannoneerRagsText": "Cannoneer Rags",
- "armorArmoireCannoneerRagsNotes": "These rags be tougher than they look. Increases Constitution by <%= con %>. Enchanted Armoire: Cannoneer Set (Item 2 of 3).",
- "armorArmoireFalconerArmorText": "Falconer Armor",
- "armorArmoireFalconerArmorNotes": "Keep away talon attacks with this sturdy armor! Increases Constitution by <%= con %>. Enchanted Armoire: Falconer Set (Item 1 of 3).",
- "armorArmoireVermilionArcherArmorText": "Vermilion Archer Armor",
- "armorArmoireVermilionArcherArmorNotes": "This armor is made of a specially enchanted red metal for maximum protection, minimal restriction, and maximum flair! Increases Perception by <%= per %>. Enchanted Armoire: Vermilion Archer Set (Item 2 of 3).",
- "armorArmoireOgreArmorText": "Ogre Armor",
- "armorArmoireOgreArmorNotes": "This armor imitates an Ogre's tough skin, but it's lined with fleece for human comfort! Increases Constitution by <%= con %>. Enchanted Armoire: Ogre Outfit (Item 3 of 3).",
- "armorArmoireIronBlueArcherArmorText": "Iron Blue Archer Armor",
- "armorArmoireIronBlueArcherArmorNotes": "This armor will protect you from flying arrows on the battlefield! Increases Strength by <%= str %>. Enchanted Armoire: Iron Archer Set (Item 2 of 3).",
- "armorArmoireRedPartyDressText": "Red Party Dress",
- "armorArmoireRedPartyDressNotes": "You're strong, tough, smart, and so fashionable! Increases Strength, Constitution, and Intelligence by <%= attrs %> each. Enchanted Armoire: Red Hairbow Set (Item 2 of 2).",
- "armorArmoireWoodElfArmorText": "Wood Elf Armor",
- "armorArmoireWoodElfArmorNotes": "This armor of bark and leaves will serve as durable camouflage in the forest. Increases Perception by <%= per %>. Enchanted Armoire: Wood Elf Set (Item 2 of 3).",
- "armorArmoireRamFleeceRobesText": "Ram Fleece Robes",
- "armorArmoireRamFleeceRobesNotes": "These robes keep you warm even through the fiercest blizzard. Increases Constitution by <%= con %> and Strength by <%= str %>. Enchanted Armoire: Ram Barbarian Set (Item 2 of 3).",
- "armorArmoireGownOfHeartsText": "Gown of Hearts",
- "armorArmoireGownOfHeartsNotes": "This gown has all the frills! But that's not all, it will also increase your heart's fortitude. Increases Constitution by <%= con %>. Enchanted Armoire: Queen of Hearts Set (Item 2 of 3).",
- "armorArmoireMushroomDruidArmorText": "Mushroom Druid Armor",
- "armorArmoireMushroomDruidArmorNotes": "This woody brown armor, capped with tiny mushrooms, will help you hear the whispers of forest life. Increases Constitution by <%= con %> and Perception by <%= per %>. Enchanted Armoire: Mushroom Druid Set (Item 2 of 3).",
- "armorArmoireGreenFestivalYukataText": "Green Festival Yukata",
- "armorArmoireGreenFestivalYukataNotes": "This fine lightweight yukata will keep you cool while you enjoy any festive occasion. Increases Constitution and Perception by <%= attrs %> each. Enchanted Armoire: Festival Attire Set (Item 1 of 3).",
- "armorArmoireMerchantTunicText": "Merchant Tunic",
- "armorArmoireMerchantTunicNotes": "The wide sleeves of this tunic are perfect for stashing the coins you've earned! Increases Perception by <%= per %>. Enchanted Armoire: Merchant Set (Item 2 of 3).",
- "armorArmoireVikingTunicText": "Viking Tunic",
- "armorArmoireVikingTunicNotes": "This warm woolen tunic includes a cloak for extra coziness even in ocean gales. Increases Constitution by <%= con %> and Strength by <%= str %>. Enchanted Armoire: Viking Set (Item 1 of 3).",
- "armorArmoireSwanDancerTutuText": "Swan Dancer Tutu",
- "armorArmoireSwanDancerTutuNotes": "You just might fly away into the air as you spin in this gorgeous feathered tutu. Increases Intelligence and Strength by <%= attrs %> each. Enchanted Armoire: Swan Dancer Set (Item 2 of 3).",
- "armorArmoireAntiProcrastinationArmorText": "Anti-Procrastination Armor",
- "armorArmoireAntiProcrastinationArmorNotes": "Infused with ancient productivity spells, this steel armor will give you extra strength to battle your tasks. Increases Strength by <%= str %>. Enchanted Armoire: Anti-Procrastination Set (Item 2 of 3).",
- "armorArmoireYellowPartyDressText": "Yellow Party Dress",
- "armorArmoireYellowPartyDressNotes": "You're perceptive, strong, smart, and so fashionable! Increases Perception, Strength, and Intelligence by <%= attrs %> each. Enchanted Armoire: Yellow Hairbow Set (Item 2 of 2).",
- "armorArmoireFarrierOutfitText": "Farrier Outfit",
- "armorArmoireFarrierOutfitNotes": "These sturdy work clothes can stand up to the messiest Stable. Increases Intelligence, Constitution, and Perception by <%= attrs %> each. Enchanted Armoire: Farrier Set (Item 2 of 3).",
- "armorArmoireCandlestickMakerOutfitText": "Candlestick Maker Outfit",
- "armorArmoireCandlestickMakerOutfitNotes": "This sturdy set of clothes will protect you from hot wax spills as you ply your craft! Increases Constitution by <%= con %>. Enchanted Armoire: Candlestick Maker Set (Item 1 of 3).",
- "armorArmoireWovenRobesText": "Woven Robes",
- "armorArmoireWovenRobesNotes": "Display your weaving work proudly by wearing this colorful robe! Increases Constitution by <%= con %> and Intelligence by <%= int %>. Enchanted Armoire: Weaver Set (Item 1 of 3).",
- "armorArmoireLamplightersGreatcoatText": "Lamplighter's Greatcoat",
- "armorArmoireLamplightersGreatcoatNotes": "This heavy woolen coat can stand up to the harshest wintry night! Increases Perception by <%= per %>. Enchanted Armoire: Lamplighter's Set (Item 2 of 4).",
- "armorArmoireCoachDriverLiveryText": "Coach Driver's Livery",
- "armorArmoireCoachDriverLiveryNotes": "This heavy overcoat will protect you from the weather as you drive. Plus it looks pretty snazzy, too! Increases Strength by <%= str %>. Enchanted Armoire: Coach Driver Set (Item 1 of 3).",
- "armorArmoireRobeOfDiamondsText": "Robe of Diamonds",
- "armorArmoireRobeOfDiamondsNotes": "These royal robes not only make you appear noble, they allow you to see the nobility within others. Increases Perception by <%= per %>. Enchanted Armoire: King of Diamonds Set (Item 1 of 4).",
- "armorArmoireFlutteryFrockText": "Fluttery Frock",
- "armorArmoireFlutteryFrockNotes": "A light and airy gown with a wide skirt the butterflies might mistake for a giant blossom! Increases Constitution, Perception, and Strength by <%= attrs %> each. Enchanted Armoire: Fluttery Frock Set (Item 1 of 4).",
- "armorArmoireCobblersCoverallsText": "Cobbler's Coveralls",
- "armorArmoireCobblersCoverallsNotes": "These sturdy coveralls have lots of pockets for tools, leather scraps, and other useful items! Increases Perception and Strength by <%= attrs %> each. Enchanted Armoire: Cobbler Set (Item 1 of 3).",
- "armorArmoireGlassblowersCoverallsText": "Glassblower's Coveralls",
- "armorArmoireGlassblowersCoverallsNotes": "These coveralls will protect you while you're making masterpieces with hot molten glass. Increases Constitution by <%= con %>. Enchanted Armoire: Glassblower Set (Item 2 of 4).",
- "armorArmoireBluePartyDressText": "Blue Party Dress",
- "armorArmoireBluePartyDressNotes": "You're perceptive, tough, smart, and so fashionable! Increases Perception, Strength, and Constitution by <%= attrs %> each. Enchanted Armoire: Blue Hairbow Set (Item 2 of 2).",
- "armorArmoirePiraticalPrincessGownText": "Piratical Princess Gown",
- "armorArmoirePiraticalPrincessGownNotes": "This luxuriant garment has many pockets for concealing weapons and loot! Increases Perception by <%= per %>. Enchanted Armoire: Piratical Princess Set (Item 2 of 4).",
- "armorArmoireJeweledArcherArmorText": "Jeweled Archer Armor",
- "armorArmoireJeweledArcherArmorNotes": "This finely crafted armor will protect you from projectiles or errant red Dailies! Increases Constitution by <%= con %>. Enchanted Armoire: Jeweled Archer Set (Item 2 of 3).",
- "armorArmoireCoverallsOfBookbindingText": "Coveralls of Bookbinding",
- "armorArmoireCoverallsOfBookbindingNotes": "Everything you need in a set of coveralls, including pockets for everything. A pair of goggles, loose change, a golden ring... Increases Constitution by <%= con %> and Perception by <%= per %>. Enchanted Armoire: Bookbinder Set (Item 2 of 4).",
- "armorArmoireRobeOfSpadesText": "Robe of Spades",
- "armorArmoireRobeOfSpadesNotes": "These luxuriant robes conceal hidden pockets for treasures or weapons--your choice! Increases Strength by <%= str %>. Enchanted Armoire: Ace of Spades Set (Item 2 of 3).",
- "armorArmoireSoftBlueSuitText": "Soft Blue Suit",
- "armorArmoireSoftBlueSuitNotes": "Blue is a calming colour. So calming, some even wear this soft outfit to sleep... zZz. Increases Intelligence by <%= int %> and Perception by <%= per %>. Enchanted Armoire: Blue Loungewear Set (Item 2 of 3).",
- "armorArmoireSoftGreenSuitText": "Soft Green Suit",
- "armorArmoireSoftGreenSuitNotes": "Green is the most refreshing color! Ideal for resting those tired eyes... mmm, or even a nap... Increases Constitution and Intelligence by <%= attrs %> each. Enchanted Armoire: Green Loungewear Set (Item 2 of 3).",
- "armorArmoireSoftRedSuitText": "Soft Red Suit",
- "armorArmoireSoftRedSuitNotes": "Red is such an invigorating color. If you need to wake up bright and early, this suit could make the perfect pajamas... Increases Intelligence by <%= int %> and Strength by <%= str %>. Enchanted Armoire: Red Loungewear Set (Item 2 of 3).",
- "armorArmoireScribesRobeText": "Scribe's Robes",
- "armorArmoireScribesRobeNotes": "These velvety robes are woven with inspirational and motivational magic. Increases Perception and Intelligence by <%= attrs %> each. Enchanted Armoire: Scribe Set (Item 1 of 3).",
- "headgear": "helm",
- "headgearCapitalized": "Headgear",
- "headBase0Text": "No Headgear",
- "headBase0Notes": "No headgear.",
- "headWarrior1Text": "Leather Helm",
- "headWarrior1Notes": "Cap of sturdy boiled hide. Increases Strength by <%= str %>.",
- "headWarrior2Text": "Chain Coif",
- "headWarrior2Notes": "Hood of interlocked metal rings. Increases Strength by <%= str %>.",
- "headWarrior3Text": "Plate Helm",
- "headWarrior3Notes": "Thick steel helmet, proof against any blow. Increases Strength by <%= str %>.",
- "headWarrior4Text": "Red Helm",
- "headWarrior4Notes": "Set with rubies for power, and glows when the wearer is angered. Increases Strength by <%= str %>.",
- "headWarrior5Text": "Golden Helm",
- "headWarrior5Notes": "Regal crown bound to shining armor. Increases Strength by <%= str %>.",
- "headRogue1Text": "Leather Hood",
- "headRogue1Notes": "Basic protective cowl. Increases Perception by <%= per %>.",
- "headRogue2Text": "Black Leather Hood",
- "headRogue2Notes": "Useful for both defense and disguise. Increases Perception by <%= per %>.",
- "headRogue3Text": "Camouflage Hood",
- "headRogue3Notes": "Rugged, but doesn't impede hearing. Increases Perception by <%= per %>.",
- "headRogue4Text": "Penumbral Hood",
- "headRogue4Notes": "Grants perfect vision in darkness. Increases Perception by <%= per %>.",
- "headRogue5Text": "Umbral Hood",
- "headRogue5Notes": "Conceals even thoughts from those who would probe them. Increases Perception by <%= per %>.",
- "headWizard1Text": "Magician Hat",
- "headWizard1Notes": "Simple, comfortable, and fashionable. Increases Perception by <%= per %>.",
- "headWizard2Text": "Cornuthaum",
- "headWizard2Notes": "Traditional headgear of the itinerant wizard. Increases Perception by <%= per %>.",
- "headWizard3Text": "Astrologer Hat",
- "headWizard3Notes": "Adorned with the rings of Saturn. Increases Perception by <%= per %>.",
- "headWizard4Text": "Archmage Hat",
- "headWizard4Notes": "Focuses the mind for intensive spellcasting. Increases Perception by <%= per %>.",
- "headWizard5Text": "Royal Magus Hat",
- "headWizard5Notes": "Shows authority over fortune, weather, and lesser mages. Increases Perception by <%= per %>.",
- "headHealer1Text": "Quartz Circlet",
- "headHealer1Notes": "Jeweled headpiece, for focus on the task at hand. Increases Intelligence by <%= int %>.",
- "headHealer2Text": "Amethyst Circlet",
- "headHealer2Notes": "A taste of luxury for a humble profession. Increases Intelligence by <%= int %>.",
- "headHealer3Text": "Sapphire Circlet",
- "headHealer3Notes": "Shines to let sufferers know their salvation is at hand. Increases Intelligence by <%= int %>.",
- "headHealer4Text": "Emerald Diadem",
- "headHealer4Notes": "Emits an aura of life and growth. Increases Intelligence by <%= int %>.",
- "headHealer5Text": "Royal Diadem",
- "headHealer5Notes": "For king, queen, or miracle-worker. Increases Intelligence by <%= int %>.",
- "headSpecial0Text": "Shade Helm",
- "headSpecial0Notes": "Blood and ash, lava and obsidian give this helm its imagery and power. Increases Intelligence by <%= int %>.",
- "headSpecial1Text": "Crystal Helm",
- "headSpecial1Notes": "The favored crown of those who lead by example. Increases all Stats by <%= attrs %>.",
- "headSpecial2Text": "Nameless Helm",
- "headSpecial2Notes": "A testament to those who gave of themselves while asking nothing in return. Increases Intelligence and Strength by <%= attrs %> each.",
- "headSpecialTakeThisText": "Take This Helm",
- "headSpecialTakeThisNotes": "This helm was earned by participating in a sponsored Challenge made by Take This. Congratulations! Increases all Stats by <%= attrs %>.",
- "headSpecialFireCoralCircletText": "Fire Coral Circlet",
- "headSpecialFireCoralCircletNotes": "This circlet, designed by Habitica's greatest alchemists, allows you to breathe water and dive for treasure! Increases Perception by <%= per %>.",
- "headSpecialPyromancersTurbanText": "Pyromancer's Turban",
- "headSpecialPyromancersTurbanNotes": "This magical turban will help you breathe even in the thickest smoke! Plus it's extremely cozy! Increases Strength by <%= str %>.",
- "headSpecialBardHatText": "Bardic Cap",
- "headSpecialBardHatNotes": "Stick a feather in your cap and call it \"productivity\"! Increases Intelligence by <%= int %>.",
- "headSpecialLunarWarriorHelmText": "Lunar Warrior Helm",
- "headSpecialLunarWarriorHelmNotes": "The power of the moon will strengthen you in battle! Increases Strength and Intelligence by <%= attrs %> each.",
- "headSpecialMammothRiderHelmText": "Mammoth Rider Helm",
- "headSpecialMammothRiderHelmNotes": "Don't let its fluffiness fool you--this hat will grant you piercing powers of perception! Increases Perception by <%= per %>.",
- "headSpecialPageHelmText": "Page Helm",
- "headSpecialPageHelmNotes": "Chainmail: for the stylish AND the practical. Increases Perception by <%= per %>.",
- "headSpecialRoguishRainbowMessengerHoodText": "Roguish Rainbow Messenger Hood",
- "headSpecialRoguishRainbowMessengerHoodNotes": "This bright hood emits a colorful glow that will protect you from unpleasant weather! Increases Constitution by <%= con %>.",
- "headSpecialClandestineCowlText": "Clandestine Cowl",
- "headSpecialClandestineCowlNotes": "Take care to conceal your face as you rob your Tasks of gold and loot! Increases Perception by <%= per %>.",
- "headSpecialSnowSovereignCrownText": "Snow Sovereign Crown",
- "headSpecialSnowSovereignCrownNotes": "The jewels in this crown sparkle like new-fallen snowflakes. Increases Constitution by <%= con %>.",
- "headSpecialSpikedHelmText": "Spiked Helm",
- "headSpecialSpikedHelmNotes": "You'll be well protected from stray Dailies and bad Habits with this functional (and neat-looking!) helm. Increases Strength by <%= str %>.",
- "headSpecialDandyHatText": "Dandy Hat",
- "headSpecialDandyHatNotes": "What a merry chapeau! You'll look quite fine enjoying a stroll in it. Increases Constitution by <%= con %>.",
- "headSpecialKabutoText": "Kabuto",
- "headSpecialKabutoNotes": "This helm is functional and beautiful! Your enemies will become distracted admiring it. Increases Intelligence by <%= int %>.",
- "headSpecialNamingDay2017Text": "Royal Purple Gryphon Helm",
- "headSpecialNamingDay2017Notes": "Happy Naming Day! Wear this fierce and feathery helm as you celebrate Habitica. Confers no benefit.",
- "headSpecialTurkeyHelmBaseText": "Turkey Helm",
- "headSpecialTurkeyHelmBaseNotes": "Your Turkey Day look will be complete when you don this beaked helm! Confers no benefit.",
- "headSpecialTurkeyHelmGildedText": "Gilded Turkey Helm",
- "headSpecialTurkeyHelmGildedNotes": "Gobble gobble! Bling bling! Confers no benefit.",
- "headSpecialNyeText": "Absurd Party Hat",
- "headSpecialNyeNotes": "You've received an Absurd Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
- "headSpecialYetiText": "Yeti-Tamer Helm",
- "headSpecialYetiNotes": "An adorably fearsome hat. Increases Strength by <%= str %>. Limited Edition 2013-2014 Winter Gear.",
- "headSpecialSkiText": "Ski-sassin Helm",
- "headSpecialSkiNotes": "Keeps the wearer's identity secret... and their face toasty. Increases Perception by <%= per %>. Limited Edition 2013-2014 Winter Gear.",
- "headSpecialCandycaneText": "Candy Cane Hat",
- "headSpecialCandycaneNotes": "This is the most delicious hat in the world. It's also known to appear and disappear mysteriously. Increases Perception by <%= per %>. Limited Edition 2013-2014 Winter Gear.",
- "headSpecialSnowflakeText": "Snowflake Crown",
- "headSpecialSnowflakeNotes": "The wearer of this crown is never cold. Increases Intelligence by <%= int %>. Limited Edition 2013-2014 Winter Gear.",
- "headSpecialSpringRogueText": "Stealthy Kitty Mask",
- "headSpecialSpringRogueNotes": "Nobody will EVER guess that you are a cat burglar! Increases Perception by <%= per %>. Limited Edition 2014 Spring Gear.",
- "headSpecialSpringWarriorText": "Clover-steel Helmet",
- "headSpecialSpringWarriorNotes": "Welded from sweet meadow clover, this helmet can resist even the mightiest blow. Increases Strength by <%= str %>. Limited Edition 2014 Spring Gear.",
- "headSpecialSpringMageText": "Swiss Cheese Hat",
- "headSpecialSpringMageNotes": "This hat stores lots of powerful magic! Try not to nibble it. Increases Perception by <%= per %>. Limited Edition 2014 Spring Gear.",
- "headSpecialSpringHealerText": "Crown of Friendship",
- "headSpecialSpringHealerNotes": "This crown symbolizes loyalty and companionship. A dog is an adventurer's best friend, after all! Increases Intelligence by <%= int %>. Limited Edition 2014 Spring Gear.",
- "headSpecialSummerRogueText": "Pirate Hat",
- "headSpecialSummerRogueNotes": "Only the most productive of pirates can wear this fine hat. Increases Perception by <%= per %>. Limited Edition 2014 Summer Gear.",
- "headSpecialSummerWarriorText": "Swashbuckler Bandana",
- "headSpecialSummerWarriorNotes": "This soft, salty cloth fills its wearer with strength. Increases Strength by <%= str %>. Limited Edition 2014 Summer Gear.",
- "headSpecialSummerMageText": "Kelp-Wrapped Hat",
- "headSpecialSummerMageNotes": "What could be more magical than a hat wrapped in seaweed? Increases Perception by <%= per %>. Limited Edition 2014 Summer Gear.",
- "headSpecialSummerHealerText": "Coral Crown",
- "headSpecialSummerHealerNotes": "Enables its wearer to heal damaged reefs. Increases Intelligence by <%= int %>. Limited Edition 2014 Summer Gear.",
- "headSpecialFallRogueText": "Bloodred Hood",
- "headSpecialFallRogueNotes": "A Vampire Smiter's identity must always be hidden. Increases Perception by <%= per %>. Limited Edition 2014 Autumn Gear.",
- "headSpecialFallWarriorText": "Monster Scalp of Science",
- "headSpecialFallWarriorNotes": "Graft on this helm! It's only SLIGHTLY used. Increases Strength by <%= str %>. Limited Edition 2014 Autumn Gear.",
- "headSpecialFallMageText": "Pointy Hat",
- "headSpecialFallMageNotes": "Magic is woven into every thread of this hat. Increases Perception by <%= per %>. Limited Edition 2014 Autumn Gear.",
- "headSpecialFallHealerText": "Head Bandages",
- "headSpecialFallHealerNotes": "Highly sanitary and very fashionable. Increases Intelligence by <%= int %>. Limited Edition 2014 Autumn Gear.",
- "headSpecialNye2014Text": "Silly Party Hat",
- "headSpecialNye2014Notes": "You've received a Silly Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
- "headSpecialWinter2015RogueText": "Icicle Drake Mask",
- "headSpecialWinter2015RogueNotes": "You are truly, definitely, absolutely a genuine Icicle Drake. You are not infiltrating the Icicle Drake hives. You have no interest at all in the hoards of riches rumored to lie in their frigid tunnels. Rawr. Increases Perception by <%= per %>. Limited Edition 2014-2015 Winter Gear.",
- "headSpecialWinter2015WarriorText": "Gingerbread Helm",
- "headSpecialWinter2015WarriorNotes": "Think, think, think as hard as you can. Increases Strength by <%= str %>. Limited Edition 2014-2015 Winter Gear.",
- "headSpecialWinter2015MageText": "Aurora Hat",
- "headSpecialWinter2015MageNotes": "The fabric of this hat shifts and glows when the wearer studies. Increases Perception by <%= per %>. Limited Edition 2014-2015 Winter Gear.",
- "headSpecialWinter2015HealerText": "Snuggly Earmuffs",
- "headSpecialWinter2015HealerNotes": "These warm earmuffs keep out chills and distracting noises. Increases Intelligence by <%= int %>. Limited Edition 2014-2015 Winter Gear.",
- "headSpecialSpring2015RogueText": "Fireproof Helm",
- "headSpecialSpring2015RogueNotes": "Fire? HAH! You squeak fiercely in the face of fire! Increases Perception by <%= per %>. Limited Edition 2015 Spring Gear.",
- "headSpecialSpring2015WarriorText": "Beware Helm",
- "headSpecialSpring2015WarriorNotes": "Beware the Helm! Only a fierce doggy can wear it. Stop laughing. Increases Strength by <%= str %>. Limited Edition 2015 Spring Gear.",
- "headSpecialSpring2015MageText": "Stage Mage Hat",
- "headSpecialSpring2015MageNotes": "Which came first, the bunny or the hat? Increases Perception by <%= per %>. Limited Edition 2015 Spring Gear.",
- "headSpecialSpring2015HealerText": "Comforting Crown",
- "headSpecialSpring2015HealerNotes": "The pearl at the center of this crown calms and comforts those around it. Increases Intelligence by <%= int %>. Limited Edition 2015 Spring Gear.",
- "headSpecialSummer2015RogueText": "Renegade Hat",
- "headSpecialSummer2015RogueNotes": "This pirate hat fell overboard and has been decorated with scraps of fire coral. Increases Perception by <%= per %>. Limited Edition 2015 Summer Gear.",
- "headSpecialSummer2015WarriorText": "Jeweled Oceanic Helm",
- "headSpecialSummer2015WarriorNotes": "Crafted of deep-ocean metal by the artisans of Dilatory, this helm is strong and handsome. Increases Strength by <%= str %>. Limited Edition 2015 Summer Gear.",
- "headSpecialSummer2015MageText": "Soothsayer Scarf",
- "headSpecialSummer2015MageNotes": "Hidden power shines in the threads of this scarf. Increases Perception by <%= per %>. Limited Edition 2015 Summer Gear.",
- "headSpecialSummer2015HealerText": "Sailor's Cap",
- "headSpecialSummer2015HealerNotes": "With your sailor's cap set firmly on your head, you can navigate even the stormiest seas! Increases Intelligence by <%= int %>. Limited Edition 2015 Summer Gear.",
- "headSpecialFall2015RogueText": "Bat-tle Wings",
- "headSpecialFall2015RogueNotes": "Echolocate your enemies with this powerful helm! Increases Perception by <%= per %>. Limited Edition 2015 Autumn Gear.",
- "headSpecialFall2015WarriorText": "Scarecrow Hat",
- "headSpecialFall2015WarriorNotes": "Everyone would want this hat--if they only had a brain. Increases Strength by <%= str %>. Limited Edition 2015 Autumn Gear.",
- "headSpecialFall2015MageText": "Stitched Hat",
- "headSpecialFall2015MageNotes": "Every stitch in this hat augments its power. Increases Perception by <%= per %>. Limited Edition 2015 Autumn Gear.",
- "headSpecialFall2015HealerText": "Hat of Frog",
- "headSpecialFall2015HealerNotes": "This is an extremely serious hat that is worthy of only the most advanced potioners. Increases Intelligence by <%= int %>. Limited Edition 2015 Autumn Gear.",
- "headSpecialNye2015Text": "Ridiculous Party Hat",
- "headSpecialNye2015Notes": "You've received a Ridiculous Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
- "headSpecialWinter2016RogueText": "Cocoa Helm",
- "headSpecialWinter2016RogueNotes": "The protective scarf on this cozy helm is only removed to sip warm winter beverages. Increases Perception by <%= per %>. Limited Edition 2015-2016 Winter Gear.",
- "headSpecialWinter2016WarriorText": "Snowman Cap",
- "headSpecialWinter2016WarriorNotes": "Brr! This mighty helm is truly powerful... until it melts. Increases Strength by <%= str %>. Limited Edition 2015-2016 Winter Gear.",
- "headSpecialWinter2016MageText": "Snowboarder Hood",
- "headSpecialWinter2016MageNotes": "Keeps the snow out of your eyes while you're casting spells. Increases Perception by <%= per %>. Limited Edition 2015-2016 Winter Gear.",
- "headSpecialWinter2016HealerText": "Fairy Wing Helm",
- "headSpecialWinter2016HealerNotes": "Thesewingsfluttersoquicklythattheyblur! Increases Intelligence by <%= int %>. Limited Edition 2015-2016 Winter Gear.",
- "headSpecialSpring2016RogueText": "Good Doggy Mask",
- "headSpecialSpring2016RogueNotes": "Aww, what a cute puppy! Come here and let me pet your head. ...Hey, where did all my Gold go? Increases Perception by <%= per %>. Limited Edition 2016 Spring Gear.",
- "headSpecialSpring2016WarriorText": "Mouse Guard Helm",
- "headSpecialSpring2016WarriorNotes": "Never again shall you be bopped on the head! Let them try! Increases Strength by <%= str %>. Limited Edition 2016 Spring Gear.",
- "headSpecialSpring2016MageText": "Grand Malkin Hat",
- "headSpecialSpring2016MageNotes": "Apparel to set you above the mere alley-mages of the world. Increases Perception by <%= per %>. Limited Edition 2016 Spring Gear.",
- "headSpecialSpring2016HealerText": "Blossom Diadem",
- "headSpecialSpring2016HealerNotes": "It glints with the potential of new life ready to burst forth. Increases Intelligence by <%= int %>. Limited Edition 2016 Spring Gear.",
- "headSpecialSummer2016RogueText": "Eel Helm",
- "headSpecialSummer2016RogueNotes": "Peek out from rocky crevices while wearing this stealthy helm. Increases Perception by <%= per %>. Limited Edition 2016 Summer Gear.",
- "headSpecialSummer2016WarriorText": "Shark Helmet",
- "headSpecialSummer2016WarriorNotes": "Bite those tough tasks with this fearsome helm! Increases Strength by <%= str %>. Limited Edition 2016 Summer Gear.",
- "headSpecialSummer2016MageText": "Blowspout Hat",
- "headSpecialSummer2016MageNotes": "Magical water constantly sprays from this hat. Increases Perception by <%= per %>. Limited Edition 2016 Summer Gear.",
- "headSpecialSummer2016HealerText": "Seahorse Helm",
- "headSpecialSummer2016HealerNotes": "This helm indicates that the wearer was trained by the magical healing seahorses of Dilatory. Increases Intelligence by <%= int %>. Limited Edition 2016 Summer Gear.",
- "headSpecialFall2016RogueText": "Black Widow Helm",
- "headSpecialFall2016RogueNotes": "The legs on this helm are constantly twitching. Increases Perception by <%= per %>. Limited Edition 2016 Autumn Gear.",
- "headSpecialFall2016WarriorText": "Gnarled Bark Helm",
- "headSpecialFall2016WarriorNotes": "This swamp-sogged helm is covered with bits of bog. Increases Strength by <%= str %>. Limited Edition 2016 Autumn Gear.",
- "headSpecialFall2016MageText": "Hood of Wickedness",
- "headSpecialFall2016MageNotes": "Conceal your plotting beneath this shadowy hood. Increases Perception by <%= per %>. Limited Edition 2016 Autumn Gear.",
- "headSpecialFall2016HealerText": "Medusa's Crown",
- "headSpecialFall2016HealerNotes": "Woe to anyone who looks you in the eyes... Increases Intelligence by <%= int %>. Limited Edition 2016 Autumn Gear.",
- "headSpecialNye2016Text": "Whimsical Party Hat",
- "headSpecialNye2016Notes": "You've received a Whimsical Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
- "headSpecialWinter2017RogueText": "Frosty Helm",
- "headSpecialWinter2017RogueNotes": "Fashioned from ice crystals, this helm will help you move unnoticed through wintry landscapes. Increases Perception by <%= per %>. Limited Edition 2016-2017 Winter Gear.",
- "headSpecialWinter2017WarriorText": "Hockey Helm",
- "headSpecialWinter2017WarriorNotes": "This is a hard and durable helmet, made to withstand impacts from ice or even dark red dailies! Increases Strength by <%= str %>. Limited Edition 2016-2017 Winter Gear.",
- "headSpecialWinter2017MageText": "Winter Wolf Helm",
- "headSpecialWinter2017MageNotes": "This helm, fashioned in the image of the legendary Winter Wolf, will keep your head warm and your vision sharp. Increases Perception by <%= per %>. Limited Edition 2016-2017 Winter Gear.",
- "headSpecialWinter2017HealerText": "Sparkling Blossom Helm",
- "headSpecialWinter2017HealerNotes": "These glittering petals focus brainpower! Increases Intelligence by <%= int %>. Limited Edition 2016-2017 Winter Gear.",
- "headSpecialSpring2017RogueText": "Sneaky Bunny Helm",
- "headSpecialSpring2017RogueNotes": "This mask will prevent your cuteness from giving you away as you sneak up on Dailies (or clovers)! Increases Perception by <%= per %>. Limited Edition 2017 Spring Gear.",
- "headSpecialSpring2017WarriorText": "Feline Helm",
- "headSpecialSpring2017WarriorNotes": "Protect your adorable, fuzzy noggin with this finely decorated helm. Increases Strength by <%= str %>. Limited Edition 2017 Spring Gear.",
- "headSpecialSpring2017MageText": "Canine Conjuror Hat",
- "headSpecialSpring2017MageNotes": "This hat can help you cast mighty spells… Or you can just use it to summon tennis balls. Your choice. Increases Perception by <%= per %>. Limited Edition 2017 Spring Gear.",
- "headSpecialSpring2017HealerText": "Petal Circlet",
- "headSpecialSpring2017HealerNotes": "This delicate crown emits the comforting scent of new Spring blooms. Increases Intelligence by <%= int %>. Limited Edition 2017 Spring Gear.",
- "headSpecialSummer2017RogueText": "Sea Dragon Helm",
- "headSpecialSummer2017RogueNotes": "This helm changes colors to help you blend in with your surroundings. Increases Perception by <%= per %>. Limited Edition 2017 Summer Gear.",
- "headSpecialSummer2017WarriorText": "Sandcastle Helm",
- "headSpecialSummer2017WarriorNotes": "The finest helm anyone could hope to wear... at least, until the tide comes in. Increases Strength by <%= str %>. Limited Edition 2017 Summer Gear.",
- "headSpecialSummer2017MageText": "Whirlpool Hat",
- "headSpecialSummer2017MageNotes": "This hat is composed entirely of a swirling, inverted whirlpool. Increases Perception by <%= per %>. Limited Edition 2017 Summer Gear.",
- "headSpecialSummer2017HealerText": "Crown of Sea Creatures",
- "headSpecialSummer2017HealerNotes": "This helm is made up of friendly sea creatures who are temporarily resting on your head, giving you sage advice. Increases Intelligence by <%= int %>. Limited Edition 2017 Summer Gear.",
- "headSpecialFall2017RogueText": "Jack-o-Lantern Helm",
- "headSpecialFall2017RogueNotes": "Ready for treats? Time to don this festive, glowing helm! Increases Perception by <%= per %>. Limited Edition 2017 Autumn Gear.",
- "headSpecialFall2017WarriorText": "Candy Corn Helm",
- "headSpecialFall2017WarriorNotes": "This helm might look like a treat, but wayward tasks won't find it so sweet! Increases Strength by <%= str %>. Limited Edition 2017 Autumn Gear.",
- "headSpecialFall2017MageText": "Masquerade Helm",
- "headSpecialFall2017MageNotes": "When you appear in this feathery hat, everyone will be left guessing the identity of the magical stranger in the room! Increases Perception by <%= per %>. Limited Edition 2017 Autumn Gear.",
- "headSpecialFall2017HealerText": "Haunted House Helm",
- "headSpecialFall2017HealerNotes": "Invite spooky spirits and friendly creatures to seek your healing powers in this helm! Increases Intelligence by <%= int %>. Limited Edition 2017 Autumn Gear.",
- "headSpecialNye2017Text": "Fanciful Party Hat",
- "headSpecialNye2017Notes": "You've received a Fanciful Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
- "headSpecialWinter2018RogueText": "Reindeer Helm",
- "headSpecialWinter2018RogueNotes": "The perfect holiday disguise, with a built-in headlight! Increases Perception by <%= per %>. Limited Edition 2017-2018 Winter Gear.",
- "headSpecialWinter2018WarriorText": "Giftbox Helm",
- "headSpecialWinter2018WarriorNotes": "This jaunty box top and bow are not only festive, but quite sturdy. Increases Strength by <%= str %>. Limited Edition 2017-2018 Winter Gear.",
- "headSpecialWinter2018MageText": "Sparkly Top Hat",
- "headSpecialWinter2018MageNotes": "Ready for some extra special magic? This glittery hat is sure to boost all your spells! Increases Perception by <%= per %>. Limited Edition 2017-2018 Winter Gear.",
- "headSpecialWinter2018HealerText": "Mistletoe Hood",
- "headSpecialWinter2018HealerNotes": "This fancy hood will keep you warm with happy holiday feelings! Increases Intelligence by <%= int %>. Limited Edition 2017-2018 Winter Gear.",
- "headSpecialSpring2018RogueText": "Duck-Billed Helm",
- "headSpecialSpring2018RogueNotes": "Quack quack! Your cuteness belies your clever and sneaky nature. Increases Perception by <%= per %>. Limited Edition 2018 Spring Gear.",
- "headSpecialSpring2018WarriorText": "Helm of Rays",
- "headSpecialSpring2018WarriorNotes": "The brightness of this helm will dazzle any enemies nearby! Increases Strength by <%= str %>. Limited Edition 2018 Spring Gear.",
- "headSpecialSpring2018MageText": "Tulip Helm",
- "headSpecialSpring2018MageNotes": "The fancy petals of this helm will grant you special springtime magic. Increases Perception by <%= per %>. Limited Edition 2018 Spring Gear.",
- "headSpecialSpring2018HealerText": "Garnet Circlet",
- "headSpecialSpring2018HealerNotes": "The polished gems of this circlet will enhance your mental energy. Increases Intelligence by <%= int %>. Limited Edition 2018 Spring Gear.",
- "headSpecialSummer2018RogueText": "Fishing Sun Hat",
- "headSpecialSummer2018RogueNotes": "Provides comfort and protection from the harsh glare of the summer sun over the water. Especially important if you're more accustomed to staying stealthy in the shadows! Increases Perception by <%= per %>. Limited Edition 2018 Summer Gear.",
- "headSpecialSummer2018WarriorText": "Betta Fish Barbute",
- "headSpecialSummer2018WarriorNotes": "Show everyone you're the alpha betta with this flamboyant helm! Increases Strength by <%= str %>. Limited Edition 2018 Summer Gear.",
- "headSpecialSummer2018MageText": "Lionfish Crest",
- "headSpecialSummer2018MageNotes": "Glare dolorously upon anyone who dares say you look like a “tastyfish”. Increases Perception by <%= per %>. Limited Edition 2018 Summer Gear.",
- "headSpecialSummer2018HealerText": "Merfolk Monarch Crown",
- "headSpecialSummer2018HealerNotes": "Adorned with aquamarine, this finned diadem marks leadership of folk, fish, and those who are a bit of both! Increases Intelligence by <%= int %>. Limited Edition 2018 Summer Gear.",
- "headSpecialFall2018RogueText": "Alter Ego Face",
- "headSpecialFall2018RogueNotes": "Most of us hide away our inward struggles. This mask shows that we all experience tension between our good and bad impulses. Plus it comes with a sweet hat! Increases Perception by <%= per %>. Limited Edition 2018 Autumn Gear.",
- "headSpecialFall2018WarriorText": "Minotaur Visage",
- "headSpecialFall2018WarriorNotes": "This fearsome mask shows you can really take your tasks by the horns! Increases Strength by <%= str %>. Limited Edition 2018 Autumn Gear.",
- "headSpecialFall2018MageText": "Candymancer's Hat",
- "headSpecialFall2018MageNotes": "This pointy hat is imbued with powerful spells of sweetness. Careful, if it gets wet it may become sticky! Increases Perception by <%= per %>. Limited Edition 2018 Autumn Gear.",
- "headSpecialFall2018HealerText": "Ravenous Helm",
- "headSpecialFall2018HealerNotes": "This helm is fashioned from a carnivorous plant renowned for its ability to dispatch zombies and other inconveniences. Just watch out that it doesn't chew on your head. Increases Intelligence by <%= int %>. Limited Edition 2018 Autumn Gear.",
- "headSpecialNye2018Text": "Outlandish Party Hat",
- "headSpecialNye2018Notes": "You've received an Outlandish Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
- "headSpecialWinter2019RogueText": "Poinsettia Helm",
- "headSpecialWinter2019RogueNotes": "This leafy helm will attain its brightest red color right around the darkest days of winter, helping you blend in with holiday decor! Increases Perception by <%= per %>. Limited Edition 2018-2019 Winter Gear.",
- "headSpecialWinter2019WarriorText": "Glacial Helm",
- "headSpecialWinter2019WarriorNotes": "It's important to keep a cool head! This icy helm will protect you from any opponent's blows. Increases Strength by <%= str %>. Limited Edition 2018-2019 Winter Gear.",
- "headSpecialWinter2019MageText": "Flaming Fireworks",
- "headSpecialWinter2019MageNotes": "Stand well back and watch the sparks fly! Your tasks cannot stand against this might! Increases Perception by <%= per %>. Limited Edition 2018-2019 Winter Gear.",
- "headSpecialWinter2019HealerText": "Starry Crown",
- "headSpecialWinter2019HealerNotes": "On the darkest, coldest winter night, one particular star shines its brightest. This crown is made from metal from that star, to help you shine! Increases Intelligence by <%= int %>. Limited Edition 2018-2019 Winter Gear.",
- "headSpecialGaymerxText": "Rainbow Warrior Helm",
- "headSpecialGaymerxNotes": "In celebration of the GaymerX Conference, this special helmet is decorated with a radiant, colorful rainbow pattern! GaymerX is a game convention celebrating LGTBQ and gaming and is open to everyone.",
- "headMystery201402Text": "Winged Helm",
- "headMystery201402Notes": "This winged circlet imbues the wearer with the speed of the wind! Confers no benefit. February 2014 Subscriber Item.",
- "headMystery201405Text": "Flame of Mind",
- "headMystery201405Notes": "Burn away the procrastination! Confers no benefit. May 2014 Subscriber Item.",
- "headMystery201406Text": "Crown of Tentacles",
- "headMystery201406Notes": "The tentacles of this helm gather up magical energy from the water. Confers no benefit. June 2014 Subscriber Item.",
- "headMystery201407Text": "Undersea Explorer Helm",
- "headMystery201407Notes": "This helm makes it easy to explore underwater! It sort of makes you look like a googly-eyed fish, too. Very retro! Confers no benefit. July 2014 Subscriber Item.",
- "headMystery201408Text": "Sun Crown",
- "headMystery201408Notes": "This blazing crown gives its wearer great strength of will. Confers no benefit. August 2014 Subscriber Item.",
- "headMystery201411Text": "Steel Helm of Sporting",
- "headMystery201411Notes": "This is the traditional helmet worn in the beloved Habitican sport of Balance Ball, which consists of covering yourself with heavy protective gear and then committing to a healthy work-life balance..... WHILE PURSUED BY HIPPOGRIFFS. Confers no benefit. November 2014 Subscriber Item.",
- "headMystery201412Text": "Penguin Hat",
- "headMystery201412Notes": "Who's a penguin? Confers no benefit. December 2014 Subscriber Item.",
- "headMystery201501Text": "Starry Helm",
- "headMystery201501Notes": "The constellations flicker and swirl in this helm, guiding the wearer's thoughts towards focus. Confers no benefit. January 2015 Subscriber Item.",
- "headMystery201505Text": "Green Knight Helm",
- "headMystery201505Notes": "The green plume on this iron helm waves proudly. Confers no benefit. May 2015 Subscriber Item.",
- "headMystery201508Text": "Cheetah Hat",
- "headMystery201508Notes": "This cozy cheetah hat is very fuzzy! Confers no benefit. August 2015 Subscriber Item.",
- "headMystery201509Text": "Werewolf Mask",
- "headMystery201509Notes": "This IS a mask, right? Confers no benefit. September 2015 Subscriber Item.",
- "headMystery201511Text": "Log Crown",
- "headMystery201511Notes": "Count the number of rings to learn how old this crown is. Confers no benefit. November 2015 Subscriber Item.",
- "headMystery201512Text": "Winter Flame",
- "headMystery201512Notes": "These flames burn cold with pure intellect. Confers no benefit. December 2015 Subscriber Item.",
- "headMystery201601Text": "Helm of True Resolve",
- "headMystery201601Notes": "Stay resolute, brave champion! Confers no benefit. January 2016 Subscriber Item.",
- "headMystery201602Text": "Heartbreaker Hood",
- "headMystery201602Notes": "Shield your identity from all your admirers. Confers no benefit. February 2016 Subscriber Item.",
- "headMystery201603Text": "Lucky Hat",
- "headMystery201603Notes": "This top hat is a magical good-luck charm. Confers no benefit. March 2016 Subscriber Item.",
- "headMystery201604Text": "Crown o' Flowers",
- "headMystery201604Notes": "These woven flowers make a surprisingly strong helm! Confers no benefit. April 2016 Subscriber Item.",
- "headMystery201605Text": "Marching Bard Hat",
- "headMystery201605Notes": "Seventy-six dragons led the big parade, with a hundred and ten gryphons close at hand! Confers no benefit. May 2016 Subscriber Item.",
- "headMystery201606Text": "Selkie Cap",
- "headMystery201606Notes": "Hum the tune of the ocean as you blend in with the frolicking seals! Confers no benefit. June 2016 Subscriber Item.",
- "headMystery201607Text": "Seafloor Rogue Helm",
- "headMystery201607Notes": "The kelp growing from this helm helps camouflage you. Confers no benefit. July 2016 Subscriber Item.",
- "headMystery201608Text": "Helm of Lightning",
- "headMystery201608Notes": "This crackling helm conducts electricity! Confers no benefit. August 2016 Subscriber Item.",
- "headMystery201609Text": "Cow Hat",
- "headMystery201609Notes": "You'll never want to remooooove this cow hat. Confers no benefit. September 2016 Subscriber Item.",
- "headMystery201610Text": "Spectral Flame",
- "headMystery201610Notes": "These flames will awaken your ghostly power. Confers no benefit. October 2016 Subscriber Item.",
- "headMystery201611Text": "Fancy Feasting Hat",
- "headMystery201611Notes": "You're guaranteed to be the fanciest person at the feast in this plumed chapeau. Confers no benefit. November 2016 Subscriber Item.",
- "headMystery201612Text": "Nutcracker Helm",
- "headMystery201612Notes": "This tall and splendid helm adds a magnificent element to your holiday apparel! Confers no benefit. December 2016 Subscriber Item.",
- "headMystery201702Text": "Heartstealer Hood",
- "headMystery201702Notes": "Though this hood conceals your face, it only magnifies your powers of attraction! Confers no benefit. February 2017 Subscriber Item.",
- "headMystery201703Text": "Shimmer Helm",
- "headMystery201703Notes": "The soft light reflected from this horned helm will soothe even the most enraged foe. Confers no benefit. March 2017 Subscriber Item.",
- "headMystery201705Text": "Feathered Fighter Helm",
- "headMystery201705Notes": "Habitica is known for its fierce and productive Gryphon Warriors! Join their prestigious ranks when you don this feathery helm. Confers no benefit. May 2017 Subscriber Item.",
- "headMystery201707Text": "Jellymancer Helm",
- "headMystery201707Notes": "Need some extra hands for your tasks? This translucent jelly helm has quite a few tentacles to lend you help! Confers no benefit. July 2017 Subscriber Item.",
- "headMystery201710Text": "Imperious Imp Helm",
- "headMystery201710Notes": "This helm makes you look intimidating... but it won't do any favors for your depth perception! Confers no benefit. October 2017 Subscriber Item.",
- "headMystery201712Text": "Candlemancer Crown",
- "headMystery201712Notes": "This crown will bring light and warmth to even the darkest winter night. Confers no benefit. December 2017 Subscriber Item.",
- "headMystery201802Text": "Love Bug Helm",
- "headMystery201802Notes": "The antennae on this helm act as cute dowsing rods, detecting feelings of love and support nearby. Confers no benefit. February 2018 Subscriber Item.",
- "headMystery201803Text": "Daring Dragonfly Circlet",
- "headMystery201803Notes": "Although its appearance is quite decorative, you can engage the wings on this circlet for extra lift! Confers no benefit. March 2018 Subscriber Item.",
- "headMystery201805Text": "Phenomenal Peacock Helm",
- "headMystery201805Notes": "This helm will make you the proudest and prettiest (possibly also the loudest) bird in town. Confers no benefit. May 2018 Subscriber Item.",
- "headMystery201806Text": "Alluring Anglerfish Helm",
- "headMystery201806Notes": "The mesmerizing light atop this helm will call all the creatures of the sea to your side. We urge you to use your glowy powers of attraction for good! Confers no benefit. June 2018 Subscriber Item.",
- "headMystery201807Text": "Sea Serpent Helm",
- "headMystery201807Notes": "The strong scales on this helm will protect you from any manner of oceanic foe. Confers no benefit. July 2018 Subscriber Item.",
- "headMystery201808Text": "Lava Dragon Cowl",
- "headMystery201808Notes": "The glowing horns on this cowl will light your way through underground caverns. Confers no benefit. August 2018 Subscriber Item.",
- "headMystery201809Text": "Crown of Autumn Flowers",
- "headMystery201809Notes": "The last flowers of autumn's warm days are a reminder of the beauty of the season. Confers no benefit. September 2018 Subscriber Item.",
- "headMystery201810Text": "Dark Forest Helm",
- "headMystery201810Notes": "If you find yourself traveling through a spooky place, the glowing red eyes of this helm will surely scare away any enemies in your path. Confers no benefit. October 2018 Subscriber Item.",
- "headMystery201811Text": "Splendid Sorcerer's Hat",
- "headMystery201811Notes": "Wear this feathered hat to stand out at even the fanciest wizardly gatherings! Confers no benefit. November 2018 Subscriber Item.",
- "headMystery301404Text": "Fancy Top Hat",
- "headMystery301404Notes": "A fancy top hat for the finest of gentlefolk! January 3015 Subscriber Item. Confers no benefit.",
- "headMystery301405Text": "Basic Top Hat",
- "headMystery301405Notes": "A basic top hat, just begging to be paired with some fancy head accessories. Confers no benefit. May 3015 Subscriber Item.",
- "headMystery301703Text": "Fancy Feather Hat",
- "headMystery301703Notes": "The feathers for this hat were donated by Miss Prue's Finishing School for Fancy Peacocks. Wear them with pride! Confers no benefit. March 3017 Subscriber Item.",
- "headMystery301704Text": "Pheasant Plume Hat",
- "headMystery301704Notes": "What could be more pleasant than a plume from a pheasant? Confers no benefit. April 3017 Subscriber Item.",
- "headArmoireLunarCrownText": "Soothing Lunar Crown",
- "headArmoireLunarCrownNotes": "This crown strengthens health and sharpens senses, especially when the moon is full. Increases Constitution by <%= con %> and Perception by <%= per %>. Enchanted Armoire: Soothing Lunar Set (Item 1 of 3).",
- "headArmoireRedHairbowText": "Red Hairbow",
- "headArmoireRedHairbowNotes": "Become strong, tough, and smart while wearing this beautiful Red Hairbow! Increases Strength by <%= str %>, Constitution by <%= con %>, and Intelligence by <%= int %>. Enchanted Armoire: Red Hairbow Set (Item 1 of 2).",
- "headArmoireVioletFloppyHatText": "Violet Floppy Hat",
- "headArmoireVioletFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a pleasing purple color. Increases Perception by <%= per %>, Intelligence by <%= int %>, and Constitution by <%= con %>. Enchanted Armoire: Independent Item.",
- "headArmoireGladiatorHelmText": "Gladiator Helm",
- "headArmoireGladiatorHelmNotes": "To be a gladiator you must be not only strong.... but cunning. Increases Intelligence by <%= int %> and Perception by <%= per %>. Enchanted Armoire: Gladiator Set (Item 1 of 3).",
- "headArmoireRancherHatText": "Rancher Hat",
- "headArmoireRancherHatNotes": "Round up your pets and wrangle your mounts while wearing this magical Rancher Hat! Increases Strength by <%= str %>, Perception by <%= per %>, and Intelligence by <%= int %>. Enchanted Armoire: Rancher Set (Item 1 of 3).",
- "headArmoireBlueHairbowText": "Blue Hairbow",
- "headArmoireBlueHairbowNotes": "Become perceptive, tough, and smart while wearing this beautiful Blue Hairbow! Increases Perception by <%= per %>, Constitution by <%= con %>, and Intelligence by <%= int %>. Enchanted Armoire: Independent Item.",
- "headArmoireRoyalCrownText": "Royal Crown",
- "headArmoireRoyalCrownNotes": "Hooray for the ruler, mighty and strong! Increases Strength by <%= str %>. Enchanted Armoire: Royal Set (Item 1 of 3).",
- "headArmoireGoldenLaurelsText": "Golden Laurels",
- "headArmoireGoldenLaurelsNotes": "These golden laurels reward those who have conquered bad habits. Increases Perception and Constitution by <%= attrs %> each. Enchanted Armoire: Golden Toga Set (Item 2 of 3).",
- "headArmoireHornedIronHelmText": "Horned Iron Helm",
- "headArmoireHornedIronHelmNotes": "Fiercely hammered from iron, this horned helmet is nearly impossible to break. Increases Constitution by <%= con %> and Strength by <%= str %>. Enchanted Armoire: Horned Iron Set (Item 1 of 3).",
- "headArmoireYellowHairbowText": "Yellow Hairbow",
- "headArmoireYellowHairbowNotes": "Become perceptive, strong, and smart while wearing this beautiful Yellow Hairbow! Increases Perception, Strength, and Intelligence by <%= attrs %> each. Enchanted Armoire: Yellow Hairbow Set (Item 1 of 2).",
- "headArmoireRedFloppyHatText": "Red Floppy Hat",
- "headArmoireRedFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a radiant red color. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Red Loungewear Set (Item 1 of 3).",
- "headArmoirePlagueDoctorHatText": "Plague Doctor Hat",
- "headArmoirePlagueDoctorHatNotes": "An authentic hat worn by the doctors who battle the Plague of Procrastination! Increases Strength by <%= str %>, Intelligence by <%= int %>, and Constitution by <%= con %>. Enchanted Armoire: Plague Doctor Set (Item 1 of 3).",
- "headArmoireBlackCatText": "Black Cat Hat",
- "headArmoireBlackCatNotes": "This black hat is... purring. And twitching its tail. And breathing? Yeah, you just have a sleeping cat on your head. Increases Intelligence and Perception by <%= attrs %> each. Enchanted Armoire: Independent Item.",
- "headArmoireOrangeCatText": "Orange Cat Hat",
- "headArmoireOrangeCatNotes": "This orange hat is... purring. And twitching its tail. And breathing? Yeah, you just have a sleeping cat on your head. Increases Strength and Constitution by <%= attrs %> each. Enchanted Armoire: Independent Item.",
- "headArmoireBlueFloppyHatText": "Blue Floppy Hat",
- "headArmoireBlueFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a brilliant blue color. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Blue Loungewear Set (Item 1 of 3).",
- "headArmoireShepherdHeaddressText": "Shepherd Headdress",
- "headArmoireShepherdHeaddressNotes": "Sometimes the gryphons that you herd like to chew on this headdress, but it makes you seem more intelligent nonetheless. Increases Intelligence by <%= int %>. Enchanted Armoire: Shepherd Set (Item 3 of 3).",
- "headArmoireCrystalCrescentHatText": "Crystal Crescent Hat",
- "headArmoireCrystalCrescentHatNotes": "The design on this hat waxes and wanes with the phases of the moon. Increases Intelligence and Perception by <%= attrs %> each. Enchanted Armoire: Crystal Crescent Set (Item 1 of 3).",
- "headArmoireDragonTamerHelmText": "Dragon Tamer Helm",
- "headArmoireDragonTamerHelmNotes": "You look exactly like a dragon. The perfect camouflage... Increases Intelligence by <%= int %>. Enchanted Armoire: Dragon Tamer Set (Item 1 of 3).",
- "headArmoireBarristerWigText": "Barrister Wig",
- "headArmoireBarristerWigNotes": "This bouncy wig is enough to frighten away even the fiercest foe. Increases Strength by <%= str %>. Enchanted Armoire: Barrister Set (Item 1 of 3).",
- "headArmoireJesterCapText": "Jester Cap",
- "headArmoireJesterCapNotes": "The bells on this hat might distract your opponents, but they just help you focus. Increases Perception by <%= per %>. Enchanted Armoire: Jester Set (Item 1 of 3).",
- "headArmoireMinerHelmetText": "Miner Helmet",
- "headArmoireMinerHelmetNotes": "Protect your head from falling tasks! Increases Intelligence by <%= int %>. Enchanted Armoire: Miner Set (Item 1 of 3).",
- "headArmoireBasicArcherCapText": "Basic Archer Cap",
- "headArmoireBasicArcherCapNotes": "No archer would be complete without a jaunty cap! Increases Perception by <%= per %>. Enchanted Armoire: Basic Archer Set (Item 3 of 3).",
- "headArmoireGraduateCapText": "Graduate Cap",
- "headArmoireGraduateCapNotes": "Congratulations! Your deep thoughts have earned you this thinking cap. Increases Intelligence by <%= int %>. Enchanted Armoire: Graduate Set (Item 3 of 3).",
- "headArmoireGreenFloppyHatText": "Green Floppy Hat",
- "headArmoireGreenFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a gorgeous green color. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Green Loungewear Set (Item 1 of 3).",
- "headArmoireCannoneerBandannaText": "Cannoneer Bandanna",
- "headArmoireCannoneerBandannaNotes": "'Tis a cannoneer's life for me! Increases Intelligence and Perception by <%= attrs %> each. Enchanted Armoire: Cannoneer Set (Item 3 of 3).",
- "headArmoireFalconerCapText": "Falconer Cap",
- "headArmoireFalconerCapNotes": "This jaunty cap helps you better understand birds of prey. Increases Intelligence by <%= int %>. Enchanted Armoire: Falconer Set (Item 2 of 3).",
- "headArmoireVermilionArcherHelmText": "Vermilion Archer Helm",
- "headArmoireVermilionArcherHelmNotes": "The magic ruby in this helm will help you aim with laser focus! Increases Perception by <%= per %>. Enchanted Armoire: Vermilion Archer Set (Item 3 of 3).",
- "headArmoireOgreMaskText": "Ogre Mask",
- "headArmoireOgreMaskNotes": "Your enemies will run for the hills when they see an Ogre coming their way! Increases Constitution and Strength by <%= attrs %> each. Enchanted Armoire: Ogre Outfit (Item 1 of 3).",
- "headArmoireIronBlueArcherHelmText": "Iron Blue Archer Helm",
- "headArmoireIronBlueArcherHelmNotes": "Hard-headed? No, you're just well protected. Increases Constitution by <%= con %>. Enchanted Armoire: Iron Archer Set (Item 1 of 3).",
- "headArmoireWoodElfHelmText": "Wood Elf Helm",
- "headArmoireWoodElfHelmNotes": "This helm of leaves may look delicate, but it can protect you from inclement weather and dangerous foes. Increases Constitution by <%= con %>. Enchanted Armoire: Wood Elf Set (Item 1 of 3).",
- "headArmoireRamHeaddressText": "Ram Headdress",
- "headArmoireRamHeaddressNotes": "This elaborate helm is fashioned to look like a ram's head. Increases Constitution by <%= con %> and Perception by <%= per %>. Enchanted Armoire: Ram Barbarian Set (Item 1 of 3).",
- "headArmoireCrownOfHeartsText": "Crown of Hearts",
- "headArmoireCrownOfHeartsNotes": "This rosy red crown isn't just eye-catching! It will also strengthen your heart against tough tasks. Increases Strength by <%= str %>. Enchanted Armoire: Queen of Hearts Set (Item 1 of 3).",
- "headArmoireMushroomDruidCapText": "Mushroom Druid Cap",
- "headArmoireMushroomDruidCapNotes": "Harvested deep in a misty forest, this cap grants the wearer knowledge of medicinal plants. Increases Intelligence by <%= int %> and Strength by <%= str %>. Enchanted Armoire: Mushroom Druid Set (Item 1 of 3).",
- "headArmoireMerchantChaperonText": "Merchant Chaperon",
- "headArmoireMerchantChaperonNotes": "This versatile wrapped wool hat will surely make you the most stylish seller in the market! Increases Perception and Intelligence by <%= attrs %> each. Enchanted Armoire: Merchant Set (Item 1 of 3).",
- "headArmoireVikingHelmText": "Viking Helm",
- "headArmoireVikingHelmNotes": "No horns or wings are found on this helm: those are too easy for enemies to grab! Increases Strength by <%= str %> and Perception by <%= per %>. Enchanted Armoire: Viking Set (Item 2 of 3).",
- "headArmoireSwanFeatherCrownText": "Swan Feather Crown",
- "headArmoireSwanFeatherCrownNotes": "This tiara is lovely and light as a swan's feather! Increases Intelligence by <%= int %>. Enchanted Armoire: Swan Dancer Set (Item 1 of 3).",
- "headArmoireAntiProcrastinationHelmText": "Anti-Procrastination Helm",
- "headArmoireAntiProcrastinationHelmNotes": "This mighty steel helm will help you win the fight to be healthy, happy, and productive! Increases Perception by <%= per %>. Enchanted Armoire: Anti-Procrastination Set (Item 1 of 3).",
- "headArmoireCandlestickMakerHatText": "Candlestick Maker Hat",
- "headArmoireCandlestickMakerHatNotes": "A jaunty hat makes every job more fun, and candlemaking is no exception! Increases Perception and Intelligence by <%= attrs %> each. Enchanted Armoire: Candlestick Maker Set (Item 2 of 3).",
- "headArmoireLamplightersTopHatText": "Lamplighter's Top Hat",
- "headArmoireLamplightersTopHatNotes": "This jaunty black hat completes your lamp-lighting ensemble! Increases Constitution by <%= con %>. Enchanted Armoire: Lamplighter's Set (Item 3 of 4).",
- "headArmoireCoachDriversHatText": "Coach Driver's Hat",
- "headArmoireCoachDriversHatNotes": "This hat is dressy, but not quite so dressy as a top hat. Make sure you don't lose it as you drive speedily across the land! Increases Intelligence by <%= int %>. Enchanted Armoire: Coach Driver Set (Item 2 of 3).",
- "headArmoireCrownOfDiamondsText": "Crown of Diamonds",
- "headArmoireCrownOfDiamondsNotes": "This shining crown isn't just a great hat; it will also sharpen your mind! Increases Intelligence by <%= int %>. Enchanted Armoire: King of Diamonds Set (Item 2 of 4).",
- "headArmoireFlutteryWigText": "Fluttery Wig",
- "headArmoireFlutteryWigNotes": "This fine powdered wig has plenty of room for your butterflies to rest if they get tired while doing your bidding. Increases Intelligence, Perception, and Strength by <%= attrs %> each. Enchanted Armoire: Fluttery Frock Set (Item 2 of 4).",
- "headArmoireBirdsNestText": "Bird's Nest",
- "headArmoireBirdsNestNotes": "If you start feeling movement and hearing chirps, your new hat might have turned into new friends. Increases Intelligence by <%= int %>. Enchanted Armoire: Independent Item.",
- "headArmoirePaperBagText": "Paper Bag",
- "headArmoirePaperBagNotes": "This bag is a hilarious but surprisingly protective helm (don't worry, we know you look good under there!). Increases Constitution by <%= con %>. Enchanted Armoire: Independent Item.",
- "headArmoireBigWigText": "Big Wig",
- "headArmoireBigWigNotes": "Some powdered wigs are for looking more authoritative, but this one is just for laughs! Increases Strength by <%= str %>. Enchanted Armoire: Independent Item.",
- "headArmoireGlassblowersHatText": "Glassblower's Hat",
- "headArmoireGlassblowersHatNotes": "This hat mainly just looks good with your other protective glassblowing gear! Increases Perception by <%= per %>. Enchanted Armoire: Glassblower Set (Item 3 of 4).",
- "headArmoirePiraticalPrincessHeaddressText": "Piratical Princess Headdress",
- "headArmoirePiraticalPrincessHeaddressNotes": "Fancy buccaneers are known for their fancy headwear! Increases Perception and Intelligence by <%= attrs %> each. Enchanted Armoire: Piratical Princess Set (Item 1 of 4).",
- "headArmoireJeweledArcherHelmText": "Jeweled Archer Helm",
- "headArmoireJeweledArcherHelmNotes": "This helm may look ornate, but it's also exceedingly light and strong. Increases Intelligence by <%= int %>. Enchanted Armoire: Jeweled Archer Set (Item 1 of 3).",
- "headArmoireVeilOfSpadesText": "Veil of Spades",
- "headArmoireVeilOfSpadesNotes": "A shadowy and mysterious veil that will boost your stealth. Increases Perception by <%= per %>. Enchanted Armoire: Ace of Spades Set (Item 1 of 3).",
- "offhand": "off-hand item",
- "offhandCapitalized": "Off-Hand Item",
- "shieldBase0Text": "No Off-Hand Equipment",
- "shieldBase0Notes": "No shield or other off-hand item.",
- "shieldWarrior1Text": "Wooden Shield",
- "shieldWarrior1Notes": "Round shield of thick wood. Increases Constitution by <%= con %>.",
- "shieldWarrior2Text": "Buckler",
- "shieldWarrior2Notes": "Light and sturdy, quick to bring to the defense. Increases Constitution by <%= con %>.",
- "shieldWarrior3Text": "Reinforced Shield",
- "shieldWarrior3Notes": "Made of wood but bolstered with metal bands. Increases Constitution by <%= con %>.",
- "shieldWarrior4Text": "Red Shield",
- "shieldWarrior4Notes": "Rebukes blows with a burst of flame. Increases Constitution by <%= con %>.",
- "shieldWarrior5Text": "Golden Shield",
- "shieldWarrior5Notes": "Shining badge of the vanguard. Increases Constitution by <%= con %>.",
- "shieldHealer1Text": "Medic Buckler",
- "shieldHealer1Notes": "Easy to disengage, freeing a hand for bandaging. Increases Constitution by <%= con %>.",
- "shieldHealer2Text": "Kite Shield",
- "shieldHealer2Notes": "Tapered shield with the symbol of healing. Increases Constitution by <%= con %>.",
- "shieldHealer3Text": "Protector Shield",
- "shieldHealer3Notes": "Traditional shield of defender knights. Increases Constitution by <%= con %>.",
- "shieldHealer4Text": "Savior Shield",
- "shieldHealer4Notes": "Stops blows aimed at nearby innocents as well as those aimed at you. Increases Constitution by <%= con %>.",
- "shieldHealer5Text": "Royal Shield",
- "shieldHealer5Notes": "Bestowed upon those most dedicated to the kingdom's defense. Increases Constitution by <%= con %>.",
- "shieldSpecial0Text": "Tormented Skull",
- "shieldSpecial0Notes": "Sees beyond the veil of death, and displays what it finds there for enemies to fear. Increases Perception by <%= per %>.",
- "shieldSpecial1Text": "Crystal Shield",
- "shieldSpecial1Notes": "Shatters arrows and deflects the words of naysayers. Increases all Stats by <%= attrs %>.",
- "shieldSpecialTakeThisText": "Take This Shield",
- "shieldSpecialTakeThisNotes": "This shield was earned by participating in a sponsored Challenge made by Take This. Congratulations! Increases all Stats by <%= attrs %>.",
- "shieldSpecialGoldenknightText": "Mustaine's Milestone Mashing Morning Star",
- "shieldSpecialGoldenknightNotes": "Meetings, monsters, malaise: managed! Mash! Increases Constitution and Perception by <%= attrs %> each.",
- "shieldSpecialMoonpearlShieldText": "Moonpearl Shield",
- "shieldSpecialMoonpearlShieldNotes": "Designed for fast swimming, and also some defense. Increases Constitution by <%= con %>.",
- "shieldSpecialMammothRiderHornText": "Mammoth Rider's Horn",
- "shieldSpecialMammothRiderHornNotes": "One blow on this mighty rose quartz horn and you'll summon powerful magical forces. Increases Strength by <%= str %>.",
- "shieldSpecialDiamondStaveText": "Diamond Stave",
- "shieldSpecialDiamondStaveNotes": "This valuable stave has mystical powers. Increases Intelligence by <%= int %>.",
- "shieldSpecialRoguishRainbowMessageText": "Roguish Rainbow Message",
- "shieldSpecialRoguishRainbowMessageNotes": "This sparkly envelope contains messages of encouragement from Habiticans, and a touch of magic to help speed your deliveries! Increases Intelligence by <%= int %>.",
- "shieldSpecialLootBagText": "Loot Bag",
- "shieldSpecialLootBagNotes": "This bag is ideal for storing all the goodies you've stealthily removed from unsuspecting Tasks! Increases Strength by <%= str %>.",
- "shieldSpecialWintryMirrorText": "Wintry Mirror",
- "shieldSpecialWintryMirrorNotes": "How else to best admire your wintry look? Increases Intelligence by <%= int %>.",
- "shieldSpecialWakizashiText": "Wakizashi",
- "shieldSpecialWakizashiNotes": "This short sword is perfect for close-quarters battles with your Dailies! Increases Constitution by <%= con %>.",
- "shieldSpecialYetiText": "Yeti-Tamer Shield",
- "shieldSpecialYetiNotes": "This shield reflects light from the snow. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.",
- "shieldSpecialSnowflakeText": "Snowflake Shield",
- "shieldSpecialSnowflakeNotes": "Every shield is unique. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.",
- "shieldSpecialSpringRogueText": "Hook Claws",
- "shieldSpecialSpringRogueNotes": "Great for scaling tall buildings, and also for shredding carpets. Increases Strength <%= str %>. Limited Edition 2014 Spring Gear.",
- "shieldSpecialSpringWarriorText": "Egg Shield",
- "shieldSpecialSpringWarriorNotes": "This shield never cracks, no matter how hard you hit it! Increases Constitution by <%= con %>. Limited Edition 2014 Spring Gear.",
- "shieldSpecialSpringHealerText": "Squeaky Ball of Ultimate Protection",
- "shieldSpecialSpringHealerNotes": "Lets out an obnoxious, continuous squeak when bitten, driving enemies away. Increases Constitution by <%= con %>. Limited Edition 2014 Spring Gear.",
- "shieldSpecialSummerRogueText": "Pirate Cutlass",
- "shieldSpecialSummerRogueNotes": "Avast! You'll make those Dailies walk the plank! Increases Strength by <%= str %>. Limited Edition 2014 Summer Gear.",
- "shieldSpecialSummerWarriorText": "Driftwood Shield",
- "shieldSpecialSummerWarriorNotes": "This shield, made from the wood of wrecked ships, can deter even the stormiest Dailies. Increases Constitution by <%= con %>. Limited Edition 2014 Summer Gear.",
- "shieldSpecialSummerHealerText": "Shield of the Shallows",
- "shieldSpecialSummerHealerNotes": "No one will dare to attack the coral reef when faced with this shiny shield! Increases Constitution by <%= con %>. Limited Edition 2014 Summer Gear.",
- "shieldSpecialFallRogueText": "Silver Stake",
- "shieldSpecialFallRogueNotes": "Dispatches undead. Also grants a bonus against werewolves, because you can never be too careful. Increases Strength by <%= str %>. Limited Edition 2014 Autumn Gear.",
- "shieldSpecialFallWarriorText": "Potent Potion of Science",
- "shieldSpecialFallWarriorNotes": "Spills mysteriously on lab coats. Increases Constitution by <%= con %>. Limited Edition 2014 Autumn Gear.",
- "shieldSpecialFallHealerText": "Jeweled Shield",
- "shieldSpecialFallHealerNotes": "This glittery shield was found in an ancient tomb. Increases Constitution by <%= con %>. Limited Edition 2014 Autumn Gear.",
- "shieldSpecialWinter2015RogueText": "Ice Spike",
- "shieldSpecialWinter2015RogueNotes": "You truly, definitely, absolutely just picked these up off of the ground. Increases Strength by <%= str %>. Limited Edition 2014-2015 Winter Gear.",
- "shieldSpecialWinter2015WarriorText": "Gumdrop Shield",
- "shieldSpecialWinter2015WarriorNotes": "This seemingly-sugary shield is actually made of nutritious, gelatinous vegetables. Increases Constitution by <%= con %>. Limited Edition 2014-2015 Winter Gear.",
- "shieldSpecialWinter2015HealerText": "Soothing Shield",
- "shieldSpecialWinter2015HealerNotes": "This shield deflects the freezing wind. Increases Constitution by <%= con %>. Limited Edition 2014-2015 Winter Gear.",
- "shieldSpecialSpring2015RogueText": "Exploding Squeak",
- "shieldSpecialSpring2015RogueNotes": "Don't let the sound fool you - these explosives pack a punch. Increases Strength by <%= str %>. Limited Edition 2015 Spring Gear.",
- "shieldSpecialSpring2015WarriorText": "Dish Discus",
- "shieldSpecialSpring2015WarriorNotes": "Hurl it at your enemies.... or just hold it, because it will fill up with yummy kibble at dinnertime. Increases Constitution by <%= con %>. Limited Edition 2015 Spring Gear.",
- "shieldSpecialSpring2015HealerText": "Patterned Pillow",
- "shieldSpecialSpring2015HealerNotes": "You can rest your head on this soft pillow, or you can wrestle it with your fearsome claws. Rawr! Increases Constitution by <%= con %>. Limited Edition 2015 Spring Gear.",
- "shieldSpecialSummer2015RogueText": "Firing Coral",
- "shieldSpecialSummer2015RogueNotes": "This relative of fire coral has the ability to propel its venom through the water. Increases Strength by <%= str %>. Limited Edition 2015 Summer Gear.",
- "shieldSpecialSummer2015WarriorText": "Sunfish Shield",
- "shieldSpecialSummer2015WarriorNotes": "Crafted of deep-ocean metal by the artisans of Dilatory, this shield shines like the sand and the sea. Increases Constitution by <%= con %>. Limited Edition 2015 Summer Gear.",
- "shieldSpecialSummer2015HealerText": "Strapping Shield",
- "shieldSpecialSummer2015HealerNotes": "Use this shield to bash away bilge rats. Increases Constitution by <%= con %>. Limited Edition 2015 Summer Gear.",
- "shieldSpecialFall2015RogueText": "Bat-tle Ax",
- "shieldSpecialFall2015RogueNotes": "Fearsome To-Dos cower before the flapping of this ax. Increases Strength by <%= str %>. Limited Edition 2015 Autumn Gear.",
- "shieldSpecialFall2015WarriorText": "Birdseed Bag",
- "shieldSpecialFall2015WarriorNotes": "It's true that you're supposed to be SCARING the crows, but there's nothing wrong with making friends! Increases Constitution by <%= con %>. Limited Edition 2015 Autumn Gear.",
- "shieldSpecialFall2015HealerText": "Stirring Stick",
- "shieldSpecialFall2015HealerNotes": "This stick can stir anything without melting, dissolving, or bursting into flame! It can also be used to fiercely poke enemy tasks. Increases Constitution by <%= con %>. Limited Edition 2015 Autumn Gear.",
- "shieldSpecialWinter2016RogueText": "Cocoa Mug",
- "shieldSpecialWinter2016RogueNotes": "Warming drink, or boiling projectile? You decide... Increases Strength by <%= str %>. Limited Edition 2015-2016 Winter Gear.",
- "shieldSpecialWinter2016WarriorText": "Sled Shield",
- "shieldSpecialWinter2016WarriorNotes": "Use this sled to block attacks, or ride it triumphantly into battle! Increases Constitution by <%= con %>. Limited Edition 2015-2016 Winter Gear.",
- "shieldSpecialWinter2016HealerText": "Pixie Present",
- "shieldSpecialWinter2016HealerNotes": "Open it open it open it open it open it open it!!!!!!!!! Increases Constitution by <%= con %>. Limited Edition 2015-2016 Winter Gear.",
- "shieldSpecialSpring2016RogueText": "Fire Bolas",
- "shieldSpecialSpring2016RogueNotes": "You've mastered the ball, the club, and the knife. Now you advance to juggling fire! Awoo! Increases Strength <%= str %>. Limited Edition 2016 Spring Gear.",
- "shieldSpecialSpring2016WarriorText": "Cheese Wheel",
- "shieldSpecialSpring2016WarriorNotes": "You braved fiendish traps to procure this defense-boosting food. Increases Constitution by <%= con %>. Limited Edition 2016 Spring Gear.",
- "shieldSpecialSpring2016HealerText": "Floral Buckler",
- "shieldSpecialSpring2016HealerNotes": "The April Fool claims this little shield will block Shiny Seeds. Don't believe him. Increases Constitution by <%= con %>. Limited Edition 2016 Spring Gear.",
- "shieldSpecialSummer2016RogueText": "Electric Rod",
- "shieldSpecialSummer2016RogueNotes": "Anyone who battles you is in for a shocking surprise... Increases Strength by <%= str %>. Limited Edition 2016 Summer Gear.",
- "shieldSpecialSummer2016WarriorText": "Shark Tooth",
- "shieldSpecialSummer2016WarriorNotes": "Bite those tough tasks with this toothy shield! Increases Constitution by <%= con %>. Limited Edition 2016 Summer Gear.",
- "shieldSpecialSummer2016HealerText": "Sea Star Shield",
- "shieldSpecialSummer2016HealerNotes": "Sometimes mistakenly called a Starfish Shield. Increases Constitution by <%= con %>. Limited Edition 2016 Summer Gear.",
- "shieldSpecialFall2016RogueText": "Spiderbite Dagger",
- "shieldSpecialFall2016RogueNotes": "Feel the sting of the spider's bite! Increases Strength by <%= str %>. Limited Edition 2016 Autumn Gear.",
- "shieldSpecialFall2016WarriorText": "Defensive Roots",
- "shieldSpecialFall2016WarriorNotes": "Defend against Dailies with these writhing roots! Increases Constitution by <%= con %>. Limited Edition 2016 Autumn Gear.",
- "shieldSpecialFall2016HealerText": "Gorgon Shield",
- "shieldSpecialFall2016HealerNotes": "Don't admire your own reflection in this. Increases Constitution by <%= con %>. Limited Edition 2016 Autumn Gear.",
- "shieldSpecialWinter2017RogueText": "Ice Axe",
- "shieldSpecialWinter2017RogueNotes": "This axe is great for attack, defense, and ice-climbing! Increases Strength by <%= str %>. Limited Edition 2016-2017 Winter Gear.",
- "shieldSpecialWinter2017WarriorText": "Puck Shield",
- "shieldSpecialWinter2017WarriorNotes": "Made from a giant hockey puck, this shield can stand up to quite a beating. Increases Constitution by <%= con %>. Limited Edition 2016-2017 Winter Gear.",
- "shieldSpecialWinter2017HealerText": "Sugarplum Shield",
- "shieldSpecialWinter2017HealerNotes": "This fibrous armament will help protect you from even the sourest of tasks! Increases Constitution by <%= con %>. Limited Edition 2016-2017 Winter Gear.",
- "shieldSpecialSpring2017RogueText": "Karrotana",
- "shieldSpecialSpring2017RogueNotes": "These blades will make quick work of tasks, but also are handy for slicing vegetables! Yum! Increases Strength by <%= str %>. Limited Edition 2017 Spring Gear.",
- "shieldSpecialSpring2017WarriorText": "Yarn Shield",
- "shieldSpecialSpring2017WarriorNotes": "Every fiber of this shield is woven with protective spells! Try not to play with it (too much). Increases Constitution by <%= con %>. Limited Edition 2017 Spring Gear.",
- "shieldSpecialSpring2017HealerText": "Basket Shield",
- "shieldSpecialSpring2017HealerNotes": "Protective and also handy for holding your many healing herbs and accoutrements. Increases Constitution by <%= con %>. Limited Edition 2017 Spring Gear.",
- "shieldSpecialSummer2017RogueText": "Sea Dragon Fins",
- "shieldSpecialSummer2017RogueNotes": "The edges of these fins are razor-sharp. Increases Strength by <%= str %>. Limited Edition 2017 Summer Gear.",
- "shieldSpecialSummer2017WarriorText": "Scallop Shield",
- "shieldSpecialSummer2017WarriorNotes": "This shell that you just found is both decorative AND defensive! Increases Constitution by <%= con %>. Limited Edition 2017 Summer Gear.",
- "shieldSpecialSummer2017HealerText": "Oyster Shield",
- "shieldSpecialSummer2017HealerNotes": "This magical oyster constantly generates pearls as well as protection. Increases Constitution by <%= con %>. Limited Edition 2017 Summer Gear.",
- "shieldSpecialFall2017RogueText": "Candied Apple Mace",
- "shieldSpecialFall2017RogueNotes": "Defeat your foes with sweetness! Increases Strength by <%= str %>. Limited Edition 2017 Autumn Gear.",
- "shieldSpecialFall2017WarriorText": "Candy Corn Shield",
- "shieldSpecialFall2017WarriorNotes": "This candy shield has mighty protective powers, so try not to nibble on it! Increases Constitution by <%= con %>. Limited Edition 2017 Autumn Gear.",
- "shieldSpecialFall2017HealerText": "Haunted Orb",
- "shieldSpecialFall2017HealerNotes": "This orb occasionally screeches. We're sorry, we're not sure why. But it sure looks nifty! Increases Constitution by <%= con %>. Limited Edition 2017 Autumn Gear.",
- "shieldSpecialWinter2018RogueText": "Peppermint Hook",
- "shieldSpecialWinter2018RogueNotes": "Perfect for climbing walls or distracting your foes with sweet, sweet candy. Increases Strength by <%= str %>. Limited Edition 2017-2018 Winter Gear.",
- "shieldSpecialWinter2018WarriorText": "Magic Gift Bag",
- "shieldSpecialWinter2018WarriorNotes": "Just about any useful thing you need can be found in this sack, if you know the right magic words to whisper. Increases Constitution by <%= con %>. Limited Edition 2017-2018 Winter Gear.",
- "shieldSpecialWinter2018HealerText": "Mistletoe Bell",
- "shieldSpecialWinter2018HealerNotes": "What's that sound? The sound of warmth and cheer for all to hear! Increases Constitution by <%= con %>. Limited Edition 2017-2018 Winter Gear.",
- "shieldSpecialSpring2018WarriorText": "Shield of the Morning",
- "shieldSpecialSpring2018WarriorNotes": "This sturdy shield glows with the glory of first light. Increases Constitution by <%= con %>. Limited Edition 2018 Spring Gear.",
- "shieldSpecialSpring2018HealerText": "Garnet Shield",
- "shieldSpecialSpring2018HealerNotes": "Despite its fancy appearance, this garnet shield is quite durable! Increases Constitution by <%= con %>. Limited Edition 2018 Spring Gear.",
- "shieldSpecialSummer2018WarriorText": "Betta Skull Shield",
- "shieldSpecialSummer2018WarriorNotes": "Fashioned from stone, this fearsome skull-styled shield strikes fear into fish foes while rallying your Skeleton pets and mounts. Increases Constitution by <%= con %>. Limited Edition 2018 Summer Gear.",
- "shieldSpecialSummer2018HealerText": "Merfolk Monarch Emblem",
- "shieldSpecialSummer2018HealerNotes": "This shield can produce a dome of air for the benefit of land-dwelling visitors to your watery realm. Increases Constitution by <%= con %>. Limited Edition 2018 Summer Gear.",
- "shieldSpecialFall2018RogueText": "Vial of Temptation",
- "shieldSpecialFall2018RogueNotes": "This bottle represents all the distractions and troubles that keep you from being your best self. Resist! We're cheering for you! Increases Strength by <%= str %>. Limited Edition 2018 Autumn Gear.",
- "shieldSpecialFall2018WarriorText": "Brilliant Shield",
- "shieldSpecialFall2018WarriorNotes": "Super shiny to dissuade any troublesome Gorgons from playing peek-a-boo around the corners! Increases Constitution by <%= con %>. Limited Edition 2018 Autumn Gear.",
- "shieldSpecialFall2018HealerText": "Hungry Shield",
- "shieldSpecialFall2018HealerNotes": "With its wide-open maw, this shield will absorb all your enemies' blows. Increases Constitution by <%= con %>. Limited Edition 2018 Autumn Gear.",
- "shieldSpecialWinter2019WarriorText": "Frozen Shield",
- "shieldSpecialWinter2019WarriorNotes": "This shield was fashioned using the thickest sheets of ice from the oldest glacier in the Stoïkalm Steppes. Increases Constitution by <%= con %>. Limited Edition 2018-2019 Winter Gear.",
- "shieldSpecialWinter2019HealerText": "Enchanted Ice Crystals",
- "shieldSpecialWinter2019HealerNotes": "Thin ice may break, but these perfect crystals will turn back any blow before it lands. Increases Constitution by <%= con %>. Limited Edition 2018-2019 Winter Gear.",
- "shieldMystery201601Text": "Resolution Slayer",
- "shieldMystery201601Notes": "This blade can be used to parry away all distractions. Confers no benefit. January 2016 Subscriber Item.",
- "shieldMystery201701Text": "Time-Freezer Shield",
- "shieldMystery201701Notes": "Freeze time in its tracks and conquer your tasks! Confers no benefit. January 2017 Subscriber Item.",
- "shieldMystery201708Text": "Lava Shield",
- "shieldMystery201708Notes": "This rugged shield of molten rock protects you from bad Habits but won't singe your hands. Confers no benefit. August 2017 Subscriber Item.",
- "shieldMystery201709Text": "Sorcery Handbook",
- "shieldMystery201709Notes": "This book will guide you through your forays into sorcery. Confers no benefit. September 2017 Subscriber Item.",
- "shieldMystery201802Text": "Love Bug Shield",
- "shieldMystery201802Notes": "Although it may look like brittle candy, this shield is resistant to even the strongest Shattering Heartbreak attacks! Confers no benefit. February 2018 Subscriber Item.",
- "shieldMystery301405Text": "Clock Shield",
- "shieldMystery301405Notes": "Time is on your side with this towering clock shield! Confers no benefit. June 3015 Subscriber Item.",
- "shieldMystery301704Text": "Fluttery Fan",
- "shieldMystery301704Notes": "This fine fan will keep you feeling cool and looking fancy! Confers no benefit. April 3017 Subscriber Item.",
- "shieldArmoireGladiatorShieldText": "Gladiator Shield",
- "shieldArmoireGladiatorShieldNotes": "To be a gladiator you must.... eh, whatever, just bash them with your shield. Increases Constitution by <%= con %> and Strength by <%= str %>. Enchanted Armoire: Gladiator Set (Item 3 of 3).",
- "shieldArmoireMidnightShieldText": "Midnight Shield",
- "shieldArmoireMidnightShieldNotes": "This shield is most powerful at the stroke of midnight! Increases Constitution by <%= con %> and Strength by <%= str %>. Enchanted Armoire: Independent Item.",
- "shieldArmoireRoyalCaneText": "Royal Cane",
- "shieldArmoireRoyalCaneNotes": "Hooray for the ruler, worthy of song! Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Royal Set (Item 2 of 3).",
- "shieldArmoireDragonTamerShieldText": "Dragon Tamer Shield",
- "shieldArmoireDragonTamerShieldNotes": "Distract enemies with this dragon-shaped shield. Increases Perception by <%= per %>. Enchanted Armoire: Dragon Tamer Set (Item 2 of 3).",
- "shieldArmoireMysticLampText": "Mystic Lamp",
- "shieldArmoireMysticLampNotes": "Light the darkest caves with this mystic lamp! Increases Perception by <%= per %>. Enchanted Armoire: Independent Item.",
- "shieldArmoireFloralBouquetText": "Bouquet o' Flowers",
- "shieldArmoireFloralBouquetNotes": "Not much help in battle, but aren't they beautiful? Increases Constitution by <%= con %>. Enchanted Armoire: Independent Item.",
- "shieldArmoireSandyBucketText": "Sandy Bucket",
- "shieldArmoireSandyBucketNotes": "Good for storing all that Gold that you'll earn from completing tasks! Increases Perception by <%= per %>. Enchanted Armoire: Seaside Set (Item 3 of 3).",
- "shieldArmoirePerchingFalconText": "Perching Falcon",
- "shieldArmoirePerchingFalconNotes": "A falcon friend perches on your arm, prepared to swoop at your enemies. Increases Strength by <%= str %>. Enchanted Armoire: Falconer Set (Item 3 of 3).",
- "shieldArmoireRamHornShieldText": "Ram Horn Shield",
- "shieldArmoireRamHornShieldNotes": "Ram this shield into opposing Dailies! Increases Constitution and Strength by <%= attrs %> each. Enchanted Armoire: Ram Barbarian Set (Item 3 of 3).",
- "shieldArmoireRedRoseText": "Red Rose",
- "shieldArmoireRedRoseNotes": "This deep red rose smells enchanting. It will also sharpen your understanding. Increases Perception by <%= per %>. Enchanted Armoire: Independent Item.",
- "shieldArmoireMushroomDruidShieldText": "Mushroom Druid Shield",
- "shieldArmoireMushroomDruidShieldNotes": "Though made from a mushroom, there's nothing mushy about this tough shield! Increases Constitution by <%= con %> and Strength by <%= str %>. Enchanted Armoire: Mushroom Druid Set (Item 3 of 3).",
- "shieldArmoireFestivalParasolText": "Festival Parasol",
- "shieldArmoireFestivalParasolNotes": "This lightweight parasol will shield you from the glare--whether it's from the sun or from dark red Dailies! Increases Constitution by <%= con %>. Enchanted Armoire: Festival Attire Set (Item 2 of 3).",
- "shieldArmoireVikingShieldText": "Viking Shield",
- "shieldArmoireVikingShieldNotes": "This sturdy shield of wood and hide can stand up to the most daunting of foes. Increases Perception by <%= per %> and Intelligence by <%= int %>. Enchanted Armoire: Viking Set (Item 3 of 3).",
- "shieldArmoireSwanFeatherFanText": "Swan Feather Fan",
- "shieldArmoireSwanFeatherFanNotes": "Use this fan to accentuate your movement as you dance like a graceful swan. Increases Strength by <%= str %>. Enchanted Armoire: Swan Dancer Set (Item 3 of 3).",
- "shieldArmoireGoldenBatonText": "Golden Baton",
- "shieldArmoireGoldenBatonNotes": "When you dance into battle waving this baton to the beat, you are unstoppable! Increases Intelligence and Strength by <%= attrs %> each. Enchanted Armoire: Independent Item.",
- "shieldArmoireAntiProcrastinationShieldText": "Anti-Procrastination Shield",
- "shieldArmoireAntiProcrastinationShieldNotes": "This strong steel shield will help you block distractions when they approach! Increases Constitution by <%= con %>. Enchanted Armoire: Anti-Procrastination Set (Item 3 of 3).",
- "shieldArmoireHorseshoeText": "Horseshoe",
- "shieldArmoireHorseshoeNotes": "Help protect the feet of your hooved mounts with this iron shoe. Increases Constitution, Perception, and Strength by <%= attrs %> each. Enchanted Armoire: Farrier Set (Item 3 of 3)",
- "shieldArmoireHandmadeCandlestickText": "Handmade Candlestick",
- "shieldArmoireHandmadeCandlestickNotes": "Your fine wax wares provide light and warmth to grateful Habiticans! Increases Strength by <%= str %>. Enchanted Armoire: Candlestick Maker Set (Item 3 of 3).",
- "shieldArmoireWeaversShuttleText": "Weaver's Shuttle",
- "shieldArmoireWeaversShuttleNotes": "This tool passes your weft thread through the warp to make cloth! Increases Intelligence by <%= int %> and Perception by <%= per %>. Enchanted Armoire: Weaver Set (Item 3 of 3).",
- "shieldArmoireShieldOfDiamondsText": "Shield of Diamonds",
- "shieldArmoireShieldOfDiamondsNotes": "This radiant shield not only provides protection, it empowers you with endurance! Increases Constitution by <%= con %>. Enchanted Armoire: King of Diamonds Set (Item 4 of 4).",
- "shieldArmoireFlutteryFanText": "Fluttery Fan",
- "shieldArmoireFlutteryFanNotes": "On a hot day, there's nothing quite like a fancy fan to help you look and feel cool. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Fluttery Frock Set (Item 4 of 4).",
- "shieldArmoireFancyShoeText": "Fancy Shoe",
- "shieldArmoireFancyShoeNotes": "A very special shoe you're working on. It's fit for royalty! Increases Intelligence and Perception by <%= attrs %> each. Enchanted Armoire: Cobbler Set (Item 3 of 3).",
- "shieldArmoireFancyBlownGlassVaseText": "Fancy Blown Glass Vase",
- "shieldArmoireFancyBlownGlassVaseNotes": "What a fancy vase you've made! What will you put inside? Increases Intelligence by <%= int %>. Enchanted Armoire: Glassblower Set (Item 4 of 4).",
- "shieldArmoirePiraticalSkullShieldText": "Piratical Skull Shield",
- "shieldArmoirePiraticalSkullShieldNotes": "This enchanted shield will whisper the secret locations of your enemies' treasures- listen closely! Increases Perception and Intelligence by <%= attrs %> each. Enchanted Armoire: Piratical Princess Set (Item 4 of 4).",
- "shieldArmoireUnfinishedTomeText": "Unfinished Tome",
- "shieldArmoireUnfinishedTomeNotes": "You simply can't procrastinate when you're holding this! The binding needs to be finished so people can read the book! Increases Intelligence by <%= int %>. Enchanted Armoire: Bookbinder Set (Item 4 of 4).",
- "shieldArmoireSoftBluePillowText": "Soft Blue Pillow",
- "shieldArmoireSoftBluePillowNotes": "The sensible warrior packs a pillow for any expedition. Shield yourself from sharp tasks... even while you nap. Increases Constitution by <%= con %>. Enchanted Armoire: Blue Loungewear Set (Item 3 of 3).",
- "shieldArmoireSoftRedPillowText": "Soft Red Pillow",
- "shieldArmoireSoftRedPillowNotes": "The prepared warrior packs a pillow for any expedition. Protect yourself from those tough tasks... even while you nap. Increases Constitution and Strength by <%= attrs %> each. Enchanted Armoire: Red Loungewear Set (Item 3 of 3).",
- "shieldArmoireSoftGreenPillowText": "Soft Green Pillow",
- "shieldArmoireSoftGreenPillowNotes": "The practical warrior packs a pillow for any expedition. Ward off those pesky chores... even while you nap. Increases Constitution by <%= con %> and Intelligence by <%= int %>. Enchanted Armoire: Green Loungewear Set (Item 3 of 3).",
- "shieldArmoireMightyQuillText": "Mighty Quill",
- "shieldArmoireMightyQuillNotes": "Mightier than the sword, they say! Increases Perception by <%= per %>. Enchanted Armoire: Scribe Set (Item 2 of 3).",
- "back": "Back Accessory",
- "backCapitalized": "Back Accessory",
- "backBase0Text": "No Back Accessory",
- "backBase0Notes": "No Back Accessory.",
- "animalTails": "Animal Tails",
- "backMystery201402Text": "Golden Wings",
- "backMystery201402Notes": "These shining wings have feathers that glitter in the sun! Confers no benefit. February 2014 Subscriber Item.",
- "backMystery201404Text": "Twilight Butterfly Wings",
- "backMystery201404Notes": "Be a butterfly and flutter by! Confers no benefit. April 2014 Subscriber Item.",
- "backMystery201410Text": "Goblin Wings",
- "backMystery201410Notes": "Swoop through the night on these strong wings. Confers no benefit. October 2014 Subscriber Item.",
- "backMystery201504Text": "Busy Bee Wings",
- "backMystery201504Notes": "Buzz buzz buzz! Flit from task to task. Confers no benefit. April 2015 Subscriber Item.",
- "backMystery201507Text": "Rad Surfboard",
- "backMystery201507Notes": "Surf off the Diligent Docks and ride the waves in Inkomplete Bay! Confers no benefit. July 2015 Subscriber Item.",
- "backMystery201510Text": "Goblin Tail",
- "backMystery201510Notes": "Prehensile and powerful! Confers no benefit. October 2015 Subscriber Item.",
- "backMystery201602Text": "Heartbreaker Cape",
- "backMystery201602Notes": "With a swish of your cape, your enemies fall before you! Confers no benefit. February 2016 Subscriber Item.",
- "backMystery201608Text": "Cape of Thunder",
- "backMystery201608Notes": "Fly through the stormy skies with this billowing cape! Confers no benefit. August 2016 Subscriber Item.",
- "backMystery201702Text": "Heartstealer Cape",
- "backMystery201702Notes": "A swoosh of this cape, and all near you will be swept off their feet by your charm! Confers no benefit. February 2017 Subscriber Item.",
- "backMystery201704Text": "Fairytale Wings",
- "backMystery201704Notes": "These shimmering wings will carry you anywhere, even the hidden realms ruled by magical creatures. Confers no benefit. April 2017 Subscriber Item.",
- "backMystery201706Text": "Tattered Freebooter's Flag",
- "backMystery201706Notes": "The sight of this Jolly Roger-emblazoned flag fills any To-Do or Daily with dread! Confers no benefit. June 2017 Subscriber Item.",
- "backMystery201709Text": "Stack o' Sorcery Books",
- "backMystery201709Notes": "Learning magic takes a lot of reading, but you're sure to enjoy your studies! Confers no benefit. September 2017 Subscriber Item.",
- "backMystery201801Text": "Frost Sprite Wings",
- "backMystery201801Notes": "They may look as delicate as snowflakes, but these enchanted wings can carry you anywhere you wish! Confers no benefit. January 2018 Subscriber Item.",
- "backMystery201803Text": "Daring Dragonfly Wings",
- "backMystery201803Notes": "These bright and shiny wings will carry you through soft spring breezes and across lily ponds with ease. Confers no benefit. March 2018 Subscriber Item.",
- "backMystery201804Text": "Squirrel Tail",
- "backMystery201804Notes": "Sure, it helps you balance while you jump on branches, but the most important thing is MAXIMUM FLUFF. Confers no benefit. April 2018 Subscriber Item.",
- "backMystery201812Text": "Arctic Fox Tail",
- "backMystery201812Notes": "Your luxurious tail shimmers like an icicle, bobbing happily as you pad softly over the snowdrifts. Confers no benefit. December 2018 Subscriber Item.",
- "backMystery201805Text": "Phenomenal Peacock Tail",
- "backMystery201805Notes": "This gorgeous feathery tail is perfect for a strut down a lovely garden path! Confers no benefit. May 2018 Subscriber Item.",
- "backSpecialWonderconRedText": "Mighty Cape",
- "backSpecialWonderconRedNotes": "Swishes with strength and beauty. Confers no benefit. Special Edition Convention Item.",
- "backSpecialWonderconBlackText": "Sneaky Cape",
- "backSpecialWonderconBlackNotes": "Spun of shadows and whispers. Confers no benefit. Special Edition Convention Item.",
- "backSpecialTakeThisText": "Take This Wings",
- "backSpecialTakeThisNotes": "These wings were earned by participating in a sponsored Challenge made by Take This. Congratulations! Increases all Stats by <%= attrs %>.",
- "backSpecialSnowdriftVeilText": "Snowdrift Veil",
- "backSpecialSnowdriftVeilNotes": "This translucent veil makes it appear you are surrounded by an elegant flurry of snow! Confers no benefit.",
- "backSpecialAetherCloakText": "Aether Cloak",
- "backSpecialAetherCloakNotes": "This cloak once belonged to the Lost Masterclasser herself. Increases Perception by <%= per %>.",
- "backSpecialTurkeyTailBaseText": "Turkey Tail",
- "backSpecialTurkeyTailBaseNotes": "Wear your noble Turkey Tail with pride while you celebrate! Confers no benefit.",
- "backSpecialTurkeyTailGildedText": "Gilded Turkey Tail",
- "backSpecialTurkeyTailGildedNotes": "Plumage fit for a parade! Confers no benefit.",
- "backBearTailText": "Bear Tail",
- "backBearTailNotes": "This tail makes you look like a brave bear! Confers no benefit.",
- "backCactusTailText": "Cactus Tail",
- "backCactusTailNotes": "This tail makes you look like a prickly cactus! Confers no benefit.",
- "backFoxTailText": "Fox Tail",
- "backFoxTailNotes": "This tail makes you look like a wily fox! Confers no benefit.",
- "backLionTailText": "Lion Tail",
- "backLionTailNotes": "This tail makes you look like a regal lion! Confers no benefit.",
- "backPandaTailText": "Panda Tail",
- "backPandaTailNotes": "This tail makes you look like a gentle panda! Confers no benefit.",
- "backPigTailText": "Pig Tail",
- "backPigTailNotes": "This tail makes you look like a whimsical pig! Confers no benefit.",
- "backTigerTailText": "Tiger Tail",
- "backTigerTailNotes": "This tail makes you look like a fierce tiger! Confers no benefit.",
- "backWolfTailText": "Wolf Tail",
- "backWolfTailNotes": "This tail makes you look like a loyal wolf! Confers no benefit.",
- "body": "Body Accessory",
- "bodyCapitalized": "Body Accessory",
- "bodyBase0Text": "No Body Accessory",
- "bodyBase0Notes": "No Body Accessory.",
- "bodySpecialWonderconRedText": "Ruby Collar",
- "bodySpecialWonderconRedNotes": "An attractive ruby collar! Confers no benefit. Special Edition Convention Item.",
- "bodySpecialWonderconGoldText": "Golden Collar",
- "bodySpecialWonderconGoldNotes": "An attractive gold collar! Confers no benefit. Special Edition Convention Item.",
- "bodySpecialWonderconBlackText": "Ebony Collar",
- "bodySpecialWonderconBlackNotes": "An attractive ebony collar! Confers no benefit. Special Edition Convention Item.",
- "bodySpecialTakeThisText": "Take This Pauldrons",
- "bodySpecialTakeThisNotes": "These pauldrons were earned by participating in a sponsored Challenge made by Take This. Congratulations! Increases all Stats by <%= attrs %>.",
- "bodySpecialAetherAmuletText": "Aether Amulet",
- "bodySpecialAetherAmuletNotes": "This amulet has a mysterious history. Increases Constitution and Strength by <%= attrs %> each.",
- "bodySpecialSummerMageText": "Shining Capelet",
- "bodySpecialSummerMageNotes": "Neither salt water nor fresh water can tarnish this metallic capelet. Confers no benefit. Limited Edition 2014 Summer Gear.",
- "bodySpecialSummerHealerText": "Coral Collar",
- "bodySpecialSummerHealerNotes": "A stylish collar of live coral! Confers no benefit. Limited Edition 2014 Summer Gear.",
- "bodySpecialSummer2015RogueText": "Renegade Sash",
- "bodySpecialSummer2015RogueNotes": "You can't be a true Renegade without panache... and a sash. Confers no benefit. Limited Edition 2015 Summer Gear.",
- "bodySpecialSummer2015WarriorText": "Oceanic Spikes",
- "bodySpecialSummer2015WarriorNotes": "Each spike drips jellyfish venom, defending the wearer. Confers no benefit. Limited Edition 2015 Summer Gear.",
- "bodySpecialSummer2015MageText": "Golden Buckle",
- "bodySpecialSummer2015MageNotes": "This buckle adds no power at all, but it's shiny. Confers no benefit. Limited Edition 2015 Summer Gear.",
- "bodySpecialSummer2015HealerText": "Sailor's Neckerchief",
- "bodySpecialSummer2015HealerNotes": "Yo ho ho? No, no, no! Confers no benefit. Limited Edition 2015 Summer Gear.",
- "bodySpecialNamingDay2018Text": "Royal Purple Gryphon Cloak",
- "bodySpecialNamingDay2018Notes": "Happy Naming Day! Wear this fancy and feathery cloak as you celebrate Habitica. Confers no benefit.",
- "bodyMystery201705Text": "Folded Feathered Fighter Wings",
- "bodyMystery201705Notes": "These folded wings don't just look snazzy: they will give you the speed and agility of a gryphon! Confers no benefit. May 2017 Subscriber Item.",
- "bodyMystery201706Text": "Ragged Corsair's Cloak",
- "bodyMystery201706Notes": "This cloak has secret pockets to hide all the Gold you loot from your Tasks. Confers no benefit. June 2017 Subscriber Item.",
- "bodyMystery201711Text": "Carpet Rider Scarf",
- "bodyMystery201711Notes": "This soft knitted scarf looks quite majestic blowing in the wind. Confers no benefit. November 2017 Subscriber Item.",
- "bodyArmoireCozyScarfText": "Cozy Scarf",
- "bodyArmoireCozyScarfNotes": "This fine scarf will keep you warm as you go about your wintry business. Increases Constitution and Perception by <%= attrs %> each. Enchanted Armoire: Lamplighter's Set (Item 4 of 4).",
- "headAccessory": "head accessory",
- "headAccessoryCapitalized": "Head Accessory",
- "accessories": "Accessories",
- "animalEars": "Animal Ears",
- "headAccessoryBase0Text": "No Head Accessory",
- "headAccessoryBase0Notes": "No Head Accessory.",
- "headAccessorySpecialSpringRogueText": "Purple Cat Ears",
- "headAccessorySpecialSpringRogueNotes": "These feline ears twitch to detect incoming threats. Confers no benefit. Limited Edition 2014 Spring Gear.",
- "headAccessorySpecialSpringWarriorText": "Green Bunny Ears",
- "headAccessorySpecialSpringWarriorNotes": "Bunny ears that keenly detect every crunch of a carrot. Confers no benefit. Limited Edition 2014 Spring Gear.",
- "headAccessorySpecialSpringMageText": "Blue Mouse Ears",
- "headAccessorySpecialSpringMageNotes": "These round mouse ears are silky-soft. Confers no benefit. Limited Edition 2014 Spring Gear.",
- "headAccessorySpecialSpringHealerText": "Yellow Dog Ears",
- "headAccessorySpecialSpringHealerNotes": "Floppy but cute. Wanna play? Confers no benefit. Limited Edition 2014 Spring Gear.",
- "headAccessorySpecialSpring2015RogueText": "Yellow Mouse Ears",
- "headAccessorySpecialSpring2015RogueNotes": "These ears steel themselves against the sound of explosions. Confers no benefit. Limited Edition 2015 Spring Gear.",
- "headAccessorySpecialSpring2015WarriorText": "Purple Dog Ears",
- "headAccessorySpecialSpring2015WarriorNotes": "They are purple. They are dog ears. Do not waste your time with further foolishness. Confers no benefit. Limited Edition 2015 Spring Gear.",
- "headAccessorySpecialSpring2015MageText": "Blue Bunny Ears",
- "headAccessorySpecialSpring2015MageNotes": "These ears listen keenly, in case somewhere a magician is revealing secrets. Confers no benefit. Limited Edition 2015 Spring Gear.",
- "headAccessorySpecialSpring2015HealerText": "Green Kitty Ears",
- "headAccessorySpecialSpring2015HealerNotes": "These cute kitty ears will make others green with envy. Confers no benefit. Limited Edition 2015 Spring Gear.",
- "headAccessorySpecialSpring2016RogueText": "Green Dog Ears",
- "headAccessorySpecialSpring2016RogueNotes": "With these, you can keep track of tricky Mages even if they turn invisible! Confers no benefit. Limited Edition 2016 Spring Gear.",
- "headAccessorySpecialSpring2016WarriorText": "Red Mouse Ears",
- "headAccessorySpecialSpring2016WarriorNotes": "To better hear your theme song across clamorous battlefields. Confers no benefit. Limited Edition 2016 Spring Gear.",
- "headAccessorySpecialSpring2016MageText": "Yellow Cat Ears",
- "headAccessorySpecialSpring2016MageNotes": "These sharp ears can detect the minute hum of ambient Mana, or the muted footfalls of a Rogue. Confers no benefit. Limited Edition 2016 Spring Gear.",
- "headAccessorySpecialSpring2016HealerText": "Purple Bunny Ears",
- "headAccessorySpecialSpring2016HealerNotes": "They stand like flags above the fray, letting others know where to run for help. Confers no benefit. Limited Edition 2016 Spring Gear.",
- "headAccessorySpecialSpring2017RogueText": "Red Bunny Ears",
- "headAccessorySpecialSpring2017RogueNotes": "No sounds will escape you thanks to these ears. Confers no benefit. Limited Edition 2017 Spring Gear.",
- "headAccessorySpecialSpring2017WarriorText": "Blue Kitty Ears",
- "headAccessorySpecialSpring2017WarriorNotes": "These ears can hear a bag of kitty treats open even in the din of battle! Confers no benefit. Limited Edition 2017 Spring Gear.",
- "headAccessorySpecialSpring2017MageText": "Teal Dog Ears",
- "headAccessorySpecialSpring2017MageNotes": "You can hear the magic in the air! Confers no benefit. Limited Edition 2017 Spring Gear.",
- "headAccessorySpecialSpring2017HealerText": "Purple Mouse Ears",
- "headAccessorySpecialSpring2017HealerNotes": "These ears will help you hear healing secrets. Confers no benefit. Limited Edition 2017 Spring Gear.",
- "headAccessoryBearEarsText": "Bear Ears",
- "headAccessoryBearEarsNotes": "These ears make you look like a brave bear! Confers no benefit.",
- "headAccessoryCactusEarsText": "Cactus Ears",
- "headAccessoryCactusEarsNotes": "These ears make you look like a prickly cactus! Confers no benefit.",
- "headAccessoryFoxEarsText": "Fox Ears",
- "headAccessoryFoxEarsNotes": "These ears make you look like a wily fox! Confers no benefit.",
- "headAccessoryLionEarsText": "Lion Ears",
- "headAccessoryLionEarsNotes": "These ears make you look like a regal lion! Confers no benefit.",
- "headAccessoryPandaEarsText": "Panda Ears",
- "headAccessoryPandaEarsNotes": "These ears make you look like a gentle panda! Confers no benefit.",
- "headAccessoryPigEarsText": "Pig Ears",
- "headAccessoryPigEarsNotes": "These ears make you look like a whimsical pig! Confers no benefit.",
- "headAccessoryTigerEarsText": "Tiger Ears",
- "headAccessoryTigerEarsNotes": "These ears make you look like a fierce tiger! Confers no benefit.",
- "headAccessoryWolfEarsText": "Wolf Ears",
- "headAccessoryWolfEarsNotes": "These ears make you look like a loyal wolf! Confers no benefit.",
- "headAccessoryBlackHeadbandText": "Black Headband",
- "headAccessoryBlackHeadbandNotes": "A simple black headband. Confers no benefit.",
- "headAccessoryBlueHeadbandText": "Blue Headband",
- "headAccessoryBlueHeadbandNotes": "A simple blue headband. Confers no benefit.",
- "headAccessoryGreenHeadbandText": "Green Headband",
- "headAccessoryGreenHeadbandNotes": "A simple green headband. Confers no benefit.",
- "headAccessoryPinkHeadbandText": "Pink Headband",
- "headAccessoryPinkHeadbandNotes": "A simple pink headband. Confers no benefit.",
- "headAccessoryRedHeadbandText": "Red Headband",
- "headAccessoryRedHeadbandNotes": "A simple red headband. Confers no benefit.",
- "headAccessoryWhiteHeadbandText": "White Headband",
- "headAccessoryWhiteHeadbandNotes": "A simple white headband. Confers no benefit.",
- "headAccessoryYellowHeadbandText": "Yellow Headband",
- "headAccessoryYellowHeadbandNotes": "A simple yellow headband. Confers no benefit.",
- "headAccessoryMystery201403Text": "Forest Walker Antlers",
- "headAccessoryMystery201403Notes": "These antlers shimmer with moss and lichen. Confers no benefit. March 2014 Subscriber Item.",
- "headAccessoryMystery201404Text": "Twilight Butterfly Antennae",
- "headAccessoryMystery201404Notes": "These antennae help the wearer sense dangerous distractions! Confers no benefit. April 2014 Subscriber Item.",
- "headAccessoryMystery201409Text": "Autumn Antlers",
- "headAccessoryMystery201409Notes": "These powerful antlers change colors with the leaves. Confers no benefit. September 2014 Subscriber Item.",
- "headAccessoryMystery201502Text": "Wings of Thought",
- "headAccessoryMystery201502Notes": "Let your imagination take flight! Confers no benefit. February 2015 Subscriber Item.",
- "headAccessoryMystery201510Text": "Goblin Horns",
- "headAccessoryMystery201510Notes": "These fearsome horns are slightly slimy. Confers no benefit. October 2015 Subscriber Item.",
- "headAccessoryMystery201801Text": "Frost Sprite Antlers",
- "headAccessoryMystery201801Notes": "These icy antlers shimmer with the glow of winter auroras. Confers no benefit. January 2018 Subscriber Item.",
- "headAccessoryMystery201804Text": "Squirrel Ears",
- "headAccessoryMystery201804Notes": "These fuzzy sound-catchers will ensure you never miss the rustle of a leaf or the sound of an acorn falling! Confers no benefit. April 2018 Subscriber Item.",
- "headAccessoryMystery201812Text": "Arctic Fox Ears",
- "headAccessoryMystery201812Notes": "You hear the subtle sound of snowflakes falling upon the landscape. Confers no benefit. December 2018 Subscriber Item.",
- "headAccessoryMystery301405Text": "Headwear Goggles",
- "headAccessoryMystery301405Notes": "\"Goggles are for your eyes,\" they said. \"Nobody wants goggles that you can only wear on your head,\" they said. Hah! You sure showed them! Confers no benefit. August 3015 Subscriber Item.",
- "headAccessoryArmoireComicalArrowText": "Comical Arrow",
- "headAccessoryArmoireComicalArrowNotes": "This whimsical item sure is good for a laugh! Increases Strength by <%= str %>. Enchanted Armoire: Independent Item.",
- "headAccessoryArmoireGogglesOfBookbindingText": "Goggles of Bookbinding",
- "headAccessoryArmoireGogglesOfBookbindingNotes": "These goggles will help you zero in on any task, large or small! Increases Perception by <%= per %>. Enchanted Armoire: Bookbinder Set (Item 1 of 4).",
- "eyewear": "Eyewear",
- "eyewearCapitalized": "Eyewear",
- "eyewearBase0Text": "No Eyewear",
- "eyewearBase0Notes": "No Eyewear.",
- "eyewearSpecialBlackTopFrameText": "Black Standard Eyeglasses",
- "eyewearSpecialBlackTopFrameNotes": "Glasses with a black frame above the lenses. Confers no benefit.",
- "eyewearSpecialBlueTopFrameText": "Blue Standard Eyeglasses",
- "eyewearSpecialBlueTopFrameNotes": "Glasses with a blue frame above the lenses. Confers no benefit.",
- "eyewearSpecialGreenTopFrameText": "Green Standard Eyeglasses",
- "eyewearSpecialGreenTopFrameNotes": "Glasses with a green frame above the lenses. Confers no benefit.",
- "eyewearSpecialPinkTopFrameText": "Pink Standard Eyeglasses",
- "eyewearSpecialPinkTopFrameNotes": "Glasses with a pink frame above the lenses. Confers no benefit.",
- "eyewearSpecialRedTopFrameText": "Red Standard Eyeglasses",
- "eyewearSpecialRedTopFrameNotes": "Glasses with a red frame above the lenses. Confers no benefit.",
- "eyewearSpecialWhiteTopFrameText": "White Standard Eyeglasses",
- "eyewearSpecialWhiteTopFrameNotes": "Glasses with a white frame above the lenses. Confers no benefit.",
- "eyewearSpecialYellowTopFrameText": "Yellow Standard Eyeglasses",
- "eyewearSpecialYellowTopFrameNotes": "Glasses with a yellow frame above the lenses. Confers no benefit.",
- "eyewearSpecialAetherMaskText": "Aether Mask",
- "eyewearSpecialAetherMaskNotes": "This mask has a mysterious history. Increases Intelligence by <%= int %>.",
- "eyewearSpecialSummerRogueText": "Roguish Eyepatch",
- "eyewearSpecialSummerRogueNotes": "It doesn't take a scallywag to see how stylish this is! Confers no benefit. Limited Edition 2014 Summer Gear.",
- "eyewearSpecialSummerWarriorText": "Dashing Eyepatch",
- "eyewearSpecialSummerWarriorNotes": "It doesn't take a rapscallion to see how stylish this is! Confers no benefit. Limited Edition 2014 Summer Gear.",
- "eyewearSpecialWonderconRedText": "Mighty Mask",
- "eyewearSpecialWonderconRedNotes": "What a powerful face accessory! Confers no benefit. Special Edition Convention Item.",
- "eyewearSpecialWonderconBlackText": "Sneaky Mask",
- "eyewearSpecialWonderconBlackNotes": "Your motives are definitely legitimate. Confers no benefit. Special Edition Convention Item.",
- "eyewearMystery201503Text": "Aquamarine Eyewear",
- "eyewearMystery201503Notes": "Don't get poked in the eye by these shimmering gems! Confers no benefit. March 2015 Subscriber Item.",
- "eyewearMystery201506Text": "Neon Snorkel",
- "eyewearMystery201506Notes": "This neon snorkel lets its wearer see underwater. Confers no benefit. June 2015 Subscriber Item.",
- "eyewearMystery201507Text": "Rad Sunglasses",
- "eyewearMystery201507Notes": "These sunglasses let you stay cool even when the weather is hot. Confers no benefit. July 2015 Subscriber Item.",
- "eyewearMystery201701Text": "Timeless Shades",
- "eyewearMystery201701Notes": "These sunglasses will protect your eyes from harmful rays and will look stylish no matter where you find yourself in time! Confers no benefit. January 2017 Subscriber Item.",
- "eyewearMystery301404Text": "Eyewear Goggles",
- "eyewearMystery301404Notes": "No eyewear could be fancier than a pair of goggles - except, perhaps, for a monocle. Confers no benefit. April 3015 Subscriber Item.",
- "eyewearMystery301405Text": "Monocle",
- "eyewearMystery301405Notes": "No eyewear could be fancier than a monocle - except, perhaps, for a pair of goggles. Confers no benefit. July 3015 Subscriber Item.",
- "eyewearMystery301703Text": "Peacock Masquerade Mask",
- "eyewearMystery301703Notes": "Perfect for a fancy masquerade or for stealthily moving through a particularly well-dressed crowd. Confers no benefit. March 3017 Subscriber Item.",
- "eyewearArmoirePlagueDoctorMaskText": "Plague Doctor Mask",
- "eyewearArmoirePlagueDoctorMaskNotes": "An authentic mask worn by the doctors who battle the Plague of Procrastination. Increases Constitution and Intelligence by <%= attrs %> each. Enchanted Armoire: Plague Doctor Set (Item 2 of 3).",
- "eyewearArmoireGoofyGlassesText": "Goofy Glasses",
- "eyewearArmoireGoofyGlassesNotes": "Perfect for going incognito or just making your partymates giggle. Increases Perception by <%= per %>. Enchanted Armoire: Independent Item.",
- "twoHandedItem": "Two-handed item."
-}
\ No newline at end of file
+ "set": "",
+ "equipmentType": "Mota",
+ "klass": "",
+ "groupBy": "",
+ "classBonus": "",
+ "classArmor": "",
+ "featuredset": "",
+ "mysterySets": "",
+ "gearNotOwned": "",
+ "noGearItemsOfType": "",
+ "noGearItemsOfClass": "",
+ "classLockedItem": "",
+ "tierLockedItem": "",
+ "sortByType": "",
+ "sortByPrice": "",
+ "sortByCon": "",
+ "sortByPer": "",
+ "sortByStr": "",
+ "sortByInt": "",
+ "weapon": "",
+ "weaponCapitalized": "",
+ "weaponBase0Text": "",
+ "weaponBase0Notes": "",
+ "weaponWarrior0Text": "",
+ "weaponWarrior0Notes": "",
+ "weaponWarrior1Text": "",
+ "weaponWarrior1Notes": "",
+ "weaponWarrior2Text": "",
+ "weaponWarrior2Notes": "",
+ "weaponWarrior3Text": "",
+ "weaponWarrior3Notes": "",
+ "weaponWarrior4Text": "",
+ "weaponWarrior4Notes": "",
+ "weaponWarrior5Text": "",
+ "weaponWarrior5Notes": "",
+ "weaponWarrior6Text": "",
+ "weaponWarrior6Notes": "",
+ "weaponRogue0Text": "",
+ "weaponRogue0Notes": "",
+ "weaponRogue1Text": "",
+ "weaponRogue1Notes": "",
+ "weaponRogue2Text": "",
+ "weaponRogue2Notes": "",
+ "weaponRogue3Text": "",
+ "weaponRogue3Notes": "",
+ "weaponRogue4Text": "",
+ "weaponRogue4Notes": "",
+ "weaponRogue5Text": "",
+ "weaponRogue5Notes": "",
+ "weaponRogue6Text": "",
+ "weaponRogue6Notes": "",
+ "weaponWizard0Text": "",
+ "weaponWizard0Notes": "",
+ "weaponWizard1Text": "",
+ "weaponWizard1Notes": "",
+ "weaponWizard2Text": "",
+ "weaponWizard2Notes": "",
+ "weaponWizard3Text": "",
+ "weaponWizard3Notes": "",
+ "weaponWizard4Text": "",
+ "weaponWizard4Notes": "",
+ "weaponWizard5Text": "",
+ "weaponWizard5Notes": "",
+ "weaponWizard6Text": "",
+ "weaponWizard6Notes": "",
+ "weaponHealer0Text": "",
+ "weaponHealer0Notes": "",
+ "weaponHealer1Text": "",
+ "weaponHealer1Notes": "",
+ "weaponHealer2Text": "",
+ "weaponHealer2Notes": "",
+ "weaponHealer3Text": "",
+ "weaponHealer3Notes": "",
+ "weaponHealer4Text": "",
+ "weaponHealer4Notes": "",
+ "weaponHealer5Text": "",
+ "weaponHealer5Notes": "",
+ "weaponHealer6Text": "",
+ "weaponHealer6Notes": "",
+ "weaponSpecial0Text": "",
+ "weaponSpecial0Notes": "",
+ "weaponSpecial1Text": "",
+ "weaponSpecial1Notes": "",
+ "weaponSpecial2Text": "",
+ "weaponSpecial2Notes": "",
+ "weaponSpecial3Text": "",
+ "weaponSpecial3Notes": "",
+ "weaponSpecialCriticalText": "",
+ "weaponSpecialCriticalNotes": "",
+ "weaponSpecialTakeThisText": "",
+ "weaponSpecialTakeThisNotes": "",
+ "weaponSpecialTridentOfCrashingTidesText": "",
+ "weaponSpecialTridentOfCrashingTidesNotes": "",
+ "weaponSpecialTaskwoodsLanternText": "",
+ "weaponSpecialTaskwoodsLanternNotes": "",
+ "weaponSpecialBardInstrumentText": "",
+ "weaponSpecialBardInstrumentNotes": "",
+ "weaponSpecialLunarScytheText": "",
+ "weaponSpecialLunarScytheNotes": "",
+ "weaponSpecialMammothRiderSpearText": "",
+ "weaponSpecialMammothRiderSpearNotes": "",
+ "weaponSpecialPageBannerText": "",
+ "weaponSpecialPageBannerNotes": "",
+ "weaponSpecialRoguishRainbowMessageText": "",
+ "weaponSpecialRoguishRainbowMessageNotes": "",
+ "weaponSpecialSkeletonKeyText": "",
+ "weaponSpecialSkeletonKeyNotes": "",
+ "weaponSpecialNomadsScimitarText": "",
+ "weaponSpecialNomadsScimitarNotes": "",
+ "weaponSpecialFencingFoilText": "",
+ "weaponSpecialFencingFoilNotes": "",
+ "weaponSpecialTachiText": "",
+ "weaponSpecialTachiNotes": "",
+ "weaponSpecialAetherCrystalsText": "",
+ "weaponSpecialAetherCrystalsNotes": "",
+ "weaponSpecialYetiText": "",
+ "weaponSpecialYetiNotes": "",
+ "weaponSpecialSkiText": "",
+ "weaponSpecialSkiNotes": "",
+ "weaponSpecialCandycaneText": "",
+ "weaponSpecialCandycaneNotes": "",
+ "weaponSpecialSnowflakeText": "",
+ "weaponSpecialSnowflakeNotes": "",
+ "weaponSpecialSpringRogueText": "",
+ "weaponSpecialSpringRogueNotes": "",
+ "weaponSpecialSpringWarriorText": "",
+ "weaponSpecialSpringWarriorNotes": "",
+ "weaponSpecialSpringMageText": "",
+ "weaponSpecialSpringMageNotes": "",
+ "weaponSpecialSpringHealerText": "",
+ "weaponSpecialSpringHealerNotes": "",
+ "weaponSpecialSummerRogueText": "",
+ "weaponSpecialSummerRogueNotes": "",
+ "weaponSpecialSummerWarriorText": "",
+ "weaponSpecialSummerWarriorNotes": "",
+ "weaponSpecialSummerMageText": "",
+ "weaponSpecialSummerMageNotes": "",
+ "weaponSpecialSummerHealerText": "",
+ "weaponSpecialSummerHealerNotes": "",
+ "weaponSpecialFallRogueText": "",
+ "weaponSpecialFallRogueNotes": "",
+ "weaponSpecialFallWarriorText": "",
+ "weaponSpecialFallWarriorNotes": "",
+ "weaponSpecialFallMageText": "",
+ "weaponSpecialFallMageNotes": "",
+ "weaponSpecialFallHealerText": "",
+ "weaponSpecialFallHealerNotes": "",
+ "weaponSpecialWinter2015RogueText": "",
+ "weaponSpecialWinter2015RogueNotes": "",
+ "weaponSpecialWinter2015WarriorText": "",
+ "weaponSpecialWinter2015WarriorNotes": "",
+ "weaponSpecialWinter2015MageText": "",
+ "weaponSpecialWinter2015MageNotes": "",
+ "weaponSpecialWinter2015HealerText": "",
+ "weaponSpecialWinter2015HealerNotes": "",
+ "weaponSpecialSpring2015RogueText": "",
+ "weaponSpecialSpring2015RogueNotes": "",
+ "weaponSpecialSpring2015WarriorText": "",
+ "weaponSpecialSpring2015WarriorNotes": "",
+ "weaponSpecialSpring2015MageText": "",
+ "weaponSpecialSpring2015MageNotes": "",
+ "weaponSpecialSpring2015HealerText": "",
+ "weaponSpecialSpring2015HealerNotes": "",
+ "weaponSpecialSummer2015RogueText": "",
+ "weaponSpecialSummer2015RogueNotes": "",
+ "weaponSpecialSummer2015WarriorText": "",
+ "weaponSpecialSummer2015WarriorNotes": "",
+ "weaponSpecialSummer2015MageText": "",
+ "weaponSpecialSummer2015MageNotes": "",
+ "weaponSpecialSummer2015HealerText": "",
+ "weaponSpecialSummer2015HealerNotes": "",
+ "weaponSpecialFall2015RogueText": "",
+ "weaponSpecialFall2015RogueNotes": "",
+ "weaponSpecialFall2015WarriorText": "",
+ "weaponSpecialFall2015WarriorNotes": "",
+ "weaponSpecialFall2015MageText": "",
+ "weaponSpecialFall2015MageNotes": "",
+ "weaponSpecialFall2015HealerText": "",
+ "weaponSpecialFall2015HealerNotes": "",
+ "weaponSpecialWinter2016RogueText": "",
+ "weaponSpecialWinter2016RogueNotes": "",
+ "weaponSpecialWinter2016WarriorText": "",
+ "weaponSpecialWinter2016WarriorNotes": "",
+ "weaponSpecialWinter2016MageText": "",
+ "weaponSpecialWinter2016MageNotes": "",
+ "weaponSpecialWinter2016HealerText": "",
+ "weaponSpecialWinter2016HealerNotes": "",
+ "weaponSpecialSpring2016RogueText": "",
+ "weaponSpecialSpring2016RogueNotes": "",
+ "weaponSpecialSpring2016WarriorText": "",
+ "weaponSpecialSpring2016WarriorNotes": "",
+ "weaponSpecialSpring2016MageText": "",
+ "weaponSpecialSpring2016MageNotes": "",
+ "weaponSpecialSpring2016HealerText": "",
+ "weaponSpecialSpring2016HealerNotes": "",
+ "weaponSpecialSummer2016RogueText": "",
+ "weaponSpecialSummer2016RogueNotes": "",
+ "weaponSpecialSummer2016WarriorText": "",
+ "weaponSpecialSummer2016WarriorNotes": "",
+ "weaponSpecialSummer2016MageText": "",
+ "weaponSpecialSummer2016MageNotes": "",
+ "weaponSpecialSummer2016HealerText": "",
+ "weaponSpecialSummer2016HealerNotes": "",
+ "weaponSpecialFall2016RogueText": "",
+ "weaponSpecialFall2016RogueNotes": "",
+ "weaponSpecialFall2016WarriorText": "",
+ "weaponSpecialFall2016WarriorNotes": "",
+ "weaponSpecialFall2016MageText": "",
+ "weaponSpecialFall2016MageNotes": "",
+ "weaponSpecialFall2016HealerText": "",
+ "weaponSpecialFall2016HealerNotes": "",
+ "weaponSpecialWinter2017RogueText": "",
+ "weaponSpecialWinter2017RogueNotes": "",
+ "weaponSpecialWinter2017WarriorText": "",
+ "weaponSpecialWinter2017WarriorNotes": "",
+ "weaponSpecialWinter2017MageText": "",
+ "weaponSpecialWinter2017MageNotes": "",
+ "weaponSpecialWinter2017HealerText": "",
+ "weaponSpecialWinter2017HealerNotes": "",
+ "weaponSpecialSpring2017RogueText": "",
+ "weaponSpecialSpring2017RogueNotes": "",
+ "weaponSpecialSpring2017WarriorText": "",
+ "weaponSpecialSpring2017WarriorNotes": "",
+ "weaponSpecialSpring2017MageText": "",
+ "weaponSpecialSpring2017MageNotes": "",
+ "weaponSpecialSpring2017HealerText": "",
+ "weaponSpecialSpring2017HealerNotes": "",
+ "weaponSpecialSummer2017RogueText": "",
+ "weaponSpecialSummer2017RogueNotes": "",
+ "weaponSpecialSummer2017WarriorText": "",
+ "weaponSpecialSummer2017WarriorNotes": "",
+ "weaponSpecialSummer2017MageText": "",
+ "weaponSpecialSummer2017MageNotes": "",
+ "weaponSpecialSummer2017HealerText": "",
+ "weaponSpecialSummer2017HealerNotes": "",
+ "weaponSpecialFall2017RogueText": "",
+ "weaponSpecialFall2017RogueNotes": "",
+ "weaponSpecialFall2017WarriorText": "",
+ "weaponSpecialFall2017WarriorNotes": "",
+ "weaponSpecialFall2017MageText": "",
+ "weaponSpecialFall2017MageNotes": "",
+ "weaponSpecialFall2017HealerText": "",
+ "weaponSpecialFall2017HealerNotes": "",
+ "weaponSpecialWinter2018RogueText": "",
+ "weaponSpecialWinter2018RogueNotes": "",
+ "weaponSpecialWinter2018WarriorText": "",
+ "weaponSpecialWinter2018WarriorNotes": "",
+ "weaponSpecialWinter2018MageText": "",
+ "weaponSpecialWinter2018MageNotes": "",
+ "weaponSpecialWinter2018HealerText": "",
+ "weaponSpecialWinter2018HealerNotes": "",
+ "weaponSpecialSpring2018RogueText": "",
+ "weaponSpecialSpring2018RogueNotes": "",
+ "weaponSpecialSpring2018WarriorText": "",
+ "weaponSpecialSpring2018WarriorNotes": "",
+ "weaponSpecialSpring2018MageText": "",
+ "weaponSpecialSpring2018MageNotes": "",
+ "weaponSpecialSpring2018HealerText": "",
+ "weaponSpecialSpring2018HealerNotes": "",
+ "weaponSpecialSummer2018RogueText": "",
+ "weaponSpecialSummer2018RogueNotes": "",
+ "weaponSpecialSummer2018WarriorText": "",
+ "weaponSpecialSummer2018WarriorNotes": "",
+ "weaponSpecialSummer2018MageText": "",
+ "weaponSpecialSummer2018MageNotes": "",
+ "weaponSpecialSummer2018HealerText": "",
+ "weaponSpecialSummer2018HealerNotes": "",
+ "weaponSpecialFall2018RogueText": "",
+ "weaponSpecialFall2018RogueNotes": "",
+ "weaponSpecialFall2018WarriorText": "",
+ "weaponSpecialFall2018WarriorNotes": "",
+ "weaponSpecialFall2018MageText": "",
+ "weaponSpecialFall2018MageNotes": "",
+ "weaponSpecialFall2018HealerText": "",
+ "weaponSpecialFall2018HealerNotes": "",
+ "weaponSpecialWinter2019RogueText": "",
+ "weaponSpecialWinter2019RogueNotes": "",
+ "weaponSpecialWinter2019WarriorText": "",
+ "weaponSpecialWinter2019WarriorNotes": "",
+ "weaponSpecialWinter2019MageText": "",
+ "weaponSpecialWinter2019MageNotes": "",
+ "weaponSpecialWinter2019HealerText": "",
+ "weaponSpecialWinter2019HealerNotes": "",
+ "weaponMystery201411Text": "",
+ "weaponMystery201411Notes": "",
+ "weaponMystery201502Text": "",
+ "weaponMystery201502Notes": "",
+ "weaponMystery201505Text": "",
+ "weaponMystery201505Notes": "",
+ "weaponMystery201611Text": "",
+ "weaponMystery201611Notes": "",
+ "weaponMystery201708Text": "",
+ "weaponMystery201708Notes": "",
+ "weaponMystery201811Text": "",
+ "weaponMystery201811Notes": "",
+ "weaponMystery301404Text": "",
+ "weaponMystery301404Notes": "",
+ "weaponArmoireBasicCrossbowText": "",
+ "weaponArmoireBasicCrossbowNotes": "",
+ "weaponArmoireLunarSceptreText": "",
+ "weaponArmoireLunarSceptreNotes": "",
+ "weaponArmoireRancherLassoText": "",
+ "weaponArmoireRancherLassoNotes": "",
+ "weaponArmoireMythmakerSwordText": "",
+ "weaponArmoireMythmakerSwordNotes": "",
+ "weaponArmoireIronCrookText": "",
+ "weaponArmoireIronCrookNotes": "",
+ "weaponArmoireGoldWingStaffText": "",
+ "weaponArmoireGoldWingStaffNotes": "",
+ "weaponArmoireBatWandText": "",
+ "weaponArmoireBatWandNotes": "",
+ "weaponArmoireShepherdsCrookText": "",
+ "weaponArmoireShepherdsCrookNotes": "",
+ "weaponArmoireCrystalCrescentStaffText": "",
+ "weaponArmoireCrystalCrescentStaffNotes": "",
+ "weaponArmoireBlueLongbowText": "",
+ "weaponArmoireBlueLongbowNotes": "",
+ "weaponArmoireGlowingSpearText": "",
+ "weaponArmoireGlowingSpearNotes": "",
+ "weaponArmoireBarristerGavelText": "",
+ "weaponArmoireBarristerGavelNotes": "",
+ "weaponArmoireJesterBatonText": "",
+ "weaponArmoireJesterBatonNotes": "",
+ "weaponArmoireMiningPickaxText": "",
+ "weaponArmoireMiningPickaxNotes": "",
+ "weaponArmoireBasicLongbowText": "",
+ "weaponArmoireBasicLongbowNotes": "",
+ "weaponArmoireHabiticanDiplomaText": "",
+ "weaponArmoireHabiticanDiplomaNotes": "",
+ "weaponArmoireSandySpadeText": "",
+ "weaponArmoireSandySpadeNotes": "",
+ "weaponArmoireCannonText": "",
+ "weaponArmoireCannonNotes": "",
+ "weaponArmoireVermilionArcherBowText": "",
+ "weaponArmoireVermilionArcherBowNotes": "",
+ "weaponArmoireOgreClubText": "",
+ "weaponArmoireOgreClubNotes": "",
+ "weaponArmoireWoodElfStaffText": "",
+ "weaponArmoireWoodElfStaffNotes": "",
+ "weaponArmoireWandOfHeartsText": "",
+ "weaponArmoireWandOfHeartsNotes": "",
+ "weaponArmoireForestFungusStaffText": "",
+ "weaponArmoireForestFungusStaffNotes": "",
+ "weaponArmoireFestivalFirecrackerText": "",
+ "weaponArmoireFestivalFirecrackerNotes": "",
+ "weaponArmoireMerchantsDisplayTrayText": "",
+ "weaponArmoireMerchantsDisplayTrayNotes": "",
+ "weaponArmoireBattleAxeText": "",
+ "weaponArmoireBattleAxeNotes": "",
+ "weaponArmoireHoofClippersText": "",
+ "weaponArmoireHoofClippersNotes": "",
+ "weaponArmoireWeaversCombText": "",
+ "weaponArmoireWeaversCombNotes": "",
+ "weaponArmoireLamplighterText": "",
+ "weaponArmoireLamplighterNotes": "",
+ "weaponArmoireCoachDriversWhipText": "",
+ "weaponArmoireCoachDriversWhipNotes": "",
+ "weaponArmoireScepterOfDiamondsText": "",
+ "weaponArmoireScepterOfDiamondsNotes": "",
+ "weaponArmoireFlutteryArmyText": "",
+ "weaponArmoireFlutteryArmyNotes": "",
+ "weaponArmoireCobblersHammerText": "",
+ "weaponArmoireCobblersHammerNotes": "",
+ "weaponArmoireGlassblowersBlowpipeText": "",
+ "weaponArmoireGlassblowersBlowpipeNotes": "",
+ "weaponArmoirePoisonedGobletText": "",
+ "weaponArmoirePoisonedGobletNotes": "",
+ "weaponArmoireJeweledArcherBowText": "",
+ "weaponArmoireJeweledArcherBowNotes": "",
+ "weaponArmoireNeedleOfBookbindingText": "",
+ "weaponArmoireNeedleOfBookbindingNotes": "",
+ "weaponArmoireSpearOfSpadesText": "",
+ "weaponArmoireSpearOfSpadesNotes": "",
+ "weaponArmoireArcaneScrollText": "",
+ "weaponArmoireArcaneScrollNotes": "",
+ "armor": "",
+ "armorCapitalized": "",
+ "armorBase0Text": "",
+ "armorBase0Notes": "",
+ "armorWarrior1Text": "",
+ "armorWarrior1Notes": "",
+ "armorWarrior2Text": "",
+ "armorWarrior2Notes": "",
+ "armorWarrior3Text": "",
+ "armorWarrior3Notes": "",
+ "armorWarrior4Text": "",
+ "armorWarrior4Notes": "",
+ "armorWarrior5Text": "",
+ "armorWarrior5Notes": "",
+ "armorRogue1Text": "",
+ "armorRogue1Notes": "",
+ "armorRogue2Text": "",
+ "armorRogue2Notes": "",
+ "armorRogue3Text": "",
+ "armorRogue3Notes": "",
+ "armorRogue4Text": "",
+ "armorRogue4Notes": "",
+ "armorRogue5Text": "",
+ "armorRogue5Notes": "",
+ "armorWizard1Text": "",
+ "armorWizard1Notes": "",
+ "armorWizard2Text": "",
+ "armorWizard2Notes": "",
+ "armorWizard3Text": "",
+ "armorWizard3Notes": "",
+ "armorWizard4Text": "",
+ "armorWizard4Notes": "",
+ "armorWizard5Text": "",
+ "armorWizard5Notes": "",
+ "armorHealer1Text": "",
+ "armorHealer1Notes": "",
+ "armorHealer2Text": "",
+ "armorHealer2Notes": "",
+ "armorHealer3Text": "",
+ "armorHealer3Notes": "",
+ "armorHealer4Text": "",
+ "armorHealer4Notes": "",
+ "armorHealer5Text": "",
+ "armorHealer5Notes": "",
+ "armorSpecial0Text": "",
+ "armorSpecial0Notes": "",
+ "armorSpecial1Text": "",
+ "armorSpecial1Notes": "",
+ "armorSpecial2Text": "",
+ "armorSpecial2Notes": "",
+ "armorSpecialTakeThisText": "",
+ "armorSpecialTakeThisNotes": "",
+ "armorSpecialFinnedOceanicArmorText": "",
+ "armorSpecialFinnedOceanicArmorNotes": "",
+ "armorSpecialPyromancersRobesText": "",
+ "armorSpecialPyromancersRobesNotes": "",
+ "armorSpecialBardRobesText": "",
+ "armorSpecialBardRobesNotes": "",
+ "armorSpecialLunarWarriorArmorText": "",
+ "armorSpecialLunarWarriorArmorNotes": "",
+ "armorSpecialMammothRiderArmorText": "",
+ "armorSpecialMammothRiderArmorNotes": "",
+ "armorSpecialPageArmorText": "",
+ "armorSpecialPageArmorNotes": "",
+ "armorSpecialRoguishRainbowMessengerRobesText": "",
+ "armorSpecialRoguishRainbowMessengerRobesNotes": "",
+ "armorSpecialSneakthiefRobesText": "",
+ "armorSpecialSneakthiefRobesNotes": "",
+ "armorSpecialSnowSovereignRobesText": "",
+ "armorSpecialSnowSovereignRobesNotes": "",
+ "armorSpecialNomadsCuirassText": "",
+ "armorSpecialNomadsCuirassNotes": "",
+ "armorSpecialDandySuitText": "",
+ "armorSpecialDandySuitNotes": "",
+ "armorSpecialSamuraiArmorText": "",
+ "armorSpecialSamuraiArmorNotes": "",
+ "armorSpecialTurkeyArmorBaseText": "",
+ "armorSpecialTurkeyArmorBaseNotes": "",
+ "armorSpecialTurkeyArmorGildedText": "",
+ "armorSpecialTurkeyArmorGildedNotes": "",
+ "armorSpecialYetiText": "",
+ "armorSpecialYetiNotes": "",
+ "armorSpecialSkiText": "",
+ "armorSpecialSkiNotes": "",
+ "armorSpecialCandycaneText": "",
+ "armorSpecialCandycaneNotes": "",
+ "armorSpecialSnowflakeText": "",
+ "armorSpecialSnowflakeNotes": "",
+ "armorSpecialBirthdayText": "",
+ "armorSpecialBirthdayNotes": "",
+ "armorSpecialBirthday2015Text": "",
+ "armorSpecialBirthday2015Notes": "",
+ "armorSpecialBirthday2016Text": "",
+ "armorSpecialBirthday2016Notes": "",
+ "armorSpecialBirthday2017Text": "",
+ "armorSpecialBirthday2017Notes": "",
+ "armorSpecialBirthday2018Text": "",
+ "armorSpecialBirthday2018Notes": "",
+ "armorSpecialGaymerxText": "",
+ "armorSpecialGaymerxNotes": "",
+ "armorSpecialSpringRogueText": "",
+ "armorSpecialSpringRogueNotes": "",
+ "armorSpecialSpringWarriorText": "",
+ "armorSpecialSpringWarriorNotes": "",
+ "armorSpecialSpringMageText": "",
+ "armorSpecialSpringMageNotes": "",
+ "armorSpecialSpringHealerText": "",
+ "armorSpecialSpringHealerNotes": "",
+ "armorSpecialSummerRogueText": "",
+ "armorSpecialSummerRogueNotes": "",
+ "armorSpecialSummerWarriorText": "",
+ "armorSpecialSummerWarriorNotes": "",
+ "armorSpecialSummerMageText": "",
+ "armorSpecialSummerMageNotes": "",
+ "armorSpecialSummerHealerText": "",
+ "armorSpecialSummerHealerNotes": "",
+ "armorSpecialFallRogueText": "",
+ "armorSpecialFallRogueNotes": "",
+ "armorSpecialFallWarriorText": "",
+ "armorSpecialFallWarriorNotes": "",
+ "armorSpecialFallMageText": "",
+ "armorSpecialFallMageNotes": "",
+ "armorSpecialFallHealerText": "",
+ "armorSpecialFallHealerNotes": "",
+ "armorSpecialWinter2015RogueText": "",
+ "armorSpecialWinter2015RogueNotes": "",
+ "armorSpecialWinter2015WarriorText": "",
+ "armorSpecialWinter2015WarriorNotes": "",
+ "armorSpecialWinter2015MageText": "",
+ "armorSpecialWinter2015MageNotes": "",
+ "armorSpecialWinter2015HealerText": "",
+ "armorSpecialWinter2015HealerNotes": "",
+ "armorSpecialSpring2015RogueText": "",
+ "armorSpecialSpring2015RogueNotes": "",
+ "armorSpecialSpring2015WarriorText": "",
+ "armorSpecialSpring2015WarriorNotes": "",
+ "armorSpecialSpring2015MageText": "",
+ "armorSpecialSpring2015MageNotes": "",
+ "armorSpecialSpring2015HealerText": "",
+ "armorSpecialSpring2015HealerNotes": "",
+ "armorSpecialSummer2015RogueText": "",
+ "armorSpecialSummer2015RogueNotes": "",
+ "armorSpecialSummer2015WarriorText": "",
+ "armorSpecialSummer2015WarriorNotes": "",
+ "armorSpecialSummer2015MageText": "",
+ "armorSpecialSummer2015MageNotes": "",
+ "armorSpecialSummer2015HealerText": "",
+ "armorSpecialSummer2015HealerNotes": "",
+ "armorSpecialFall2015RogueText": "",
+ "armorSpecialFall2015RogueNotes": "",
+ "armorSpecialFall2015WarriorText": "",
+ "armorSpecialFall2015WarriorNotes": "",
+ "armorSpecialFall2015MageText": "",
+ "armorSpecialFall2015MageNotes": "",
+ "armorSpecialFall2015HealerText": "",
+ "armorSpecialFall2015HealerNotes": "",
+ "armorSpecialWinter2016RogueText": "",
+ "armorSpecialWinter2016RogueNotes": "",
+ "armorSpecialWinter2016WarriorText": "",
+ "armorSpecialWinter2016WarriorNotes": "",
+ "armorSpecialWinter2016MageText": "",
+ "armorSpecialWinter2016MageNotes": "",
+ "armorSpecialWinter2016HealerText": "",
+ "armorSpecialWinter2016HealerNotes": "",
+ "armorSpecialSpring2016RogueText": "",
+ "armorSpecialSpring2016RogueNotes": "",
+ "armorSpecialSpring2016WarriorText": "",
+ "armorSpecialSpring2016WarriorNotes": "",
+ "armorSpecialSpring2016MageText": "",
+ "armorSpecialSpring2016MageNotes": "",
+ "armorSpecialSpring2016HealerText": "",
+ "armorSpecialSpring2016HealerNotes": "",
+ "armorSpecialSummer2016RogueText": "",
+ "armorSpecialSummer2016RogueNotes": "",
+ "armorSpecialSummer2016WarriorText": "",
+ "armorSpecialSummer2016WarriorNotes": "",
+ "armorSpecialSummer2016MageText": "",
+ "armorSpecialSummer2016MageNotes": "",
+ "armorSpecialSummer2016HealerText": "",
+ "armorSpecialSummer2016HealerNotes": "",
+ "armorSpecialFall2016RogueText": "",
+ "armorSpecialFall2016RogueNotes": "",
+ "armorSpecialFall2016WarriorText": "",
+ "armorSpecialFall2016WarriorNotes": "",
+ "armorSpecialFall2016MageText": "",
+ "armorSpecialFall2016MageNotes": "",
+ "armorSpecialFall2016HealerText": "",
+ "armorSpecialFall2016HealerNotes": "",
+ "armorSpecialWinter2017RogueText": "",
+ "armorSpecialWinter2017RogueNotes": "",
+ "armorSpecialWinter2017WarriorText": "",
+ "armorSpecialWinter2017WarriorNotes": "",
+ "armorSpecialWinter2017MageText": "",
+ "armorSpecialWinter2017MageNotes": "",
+ "armorSpecialWinter2017HealerText": "",
+ "armorSpecialWinter2017HealerNotes": "",
+ "armorSpecialSpring2017RogueText": "",
+ "armorSpecialSpring2017RogueNotes": "",
+ "armorSpecialSpring2017WarriorText": "",
+ "armorSpecialSpring2017WarriorNotes": "",
+ "armorSpecialSpring2017MageText": "",
+ "armorSpecialSpring2017MageNotes": "",
+ "armorSpecialSpring2017HealerText": "",
+ "armorSpecialSpring2017HealerNotes": "",
+ "armorSpecialSummer2017RogueText": "",
+ "armorSpecialSummer2017RogueNotes": "",
+ "armorSpecialSummer2017WarriorText": "",
+ "armorSpecialSummer2017WarriorNotes": "",
+ "armorSpecialSummer2017MageText": "",
+ "armorSpecialSummer2017MageNotes": "",
+ "armorSpecialSummer2017HealerText": "",
+ "armorSpecialSummer2017HealerNotes": "",
+ "armorSpecialFall2017RogueText": "",
+ "armorSpecialFall2017RogueNotes": "",
+ "armorSpecialFall2017WarriorText": "",
+ "armorSpecialFall2017WarriorNotes": "",
+ "armorSpecialFall2017MageText": "",
+ "armorSpecialFall2017MageNotes": "",
+ "armorSpecialFall2017HealerText": "",
+ "armorSpecialFall2017HealerNotes": "",
+ "armorSpecialWinter2018RogueText": "",
+ "armorSpecialWinter2018RogueNotes": "",
+ "armorSpecialWinter2018WarriorText": "",
+ "armorSpecialWinter2018WarriorNotes": "",
+ "armorSpecialWinter2018MageText": "",
+ "armorSpecialWinter2018MageNotes": "",
+ "armorSpecialWinter2018HealerText": "",
+ "armorSpecialWinter2018HealerNotes": "",
+ "armorSpecialSpring2018RogueText": "",
+ "armorSpecialSpring2018RogueNotes": "",
+ "armorSpecialSpring2018WarriorText": "",
+ "armorSpecialSpring2018WarriorNotes": "",
+ "armorSpecialSpring2018MageText": "",
+ "armorSpecialSpring2018MageNotes": "",
+ "armorSpecialSpring2018HealerText": "",
+ "armorSpecialSpring2018HealerNotes": "",
+ "armorSpecialSummer2018RogueText": "",
+ "armorSpecialSummer2018RogueNotes": "",
+ "armorSpecialSummer2018WarriorText": "",
+ "armorSpecialSummer2018WarriorNotes": "",
+ "armorSpecialSummer2018MageText": "",
+ "armorSpecialSummer2018MageNotes": "",
+ "armorSpecialSummer2018HealerText": "",
+ "armorSpecialSummer2018HealerNotes": "",
+ "armorSpecialFall2018RogueText": "",
+ "armorSpecialFall2018RogueNotes": "",
+ "armorSpecialFall2018WarriorText": "",
+ "armorSpecialFall2018WarriorNotes": "",
+ "armorSpecialFall2018MageText": "",
+ "armorSpecialFall2018MageNotes": "",
+ "armorSpecialFall2018HealerText": "",
+ "armorSpecialFall2018HealerNotes": "",
+ "armorSpecialWinter2019RogueText": "",
+ "armorSpecialWinter2019RogueNotes": "",
+ "armorSpecialWinter2019WarriorText": "",
+ "armorSpecialWinter2019WarriorNotes": "",
+ "armorSpecialWinter2019MageText": "",
+ "armorSpecialWinter2019MageNotes": "",
+ "armorSpecialWinter2019HealerText": "",
+ "armorSpecialWinter2019HealerNotes": "",
+ "armorMystery201402Text": "",
+ "armorMystery201402Notes": "",
+ "armorMystery201403Text": "",
+ "armorMystery201403Notes": "",
+ "armorMystery201405Text": "",
+ "armorMystery201405Notes": "",
+ "armorMystery201406Text": "",
+ "armorMystery201406Notes": "",
+ "armorMystery201407Text": "",
+ "armorMystery201407Notes": "",
+ "armorMystery201408Text": "",
+ "armorMystery201408Notes": "",
+ "armorMystery201409Text": "",
+ "armorMystery201409Notes": "",
+ "armorMystery201410Text": "",
+ "armorMystery201410Notes": "",
+ "armorMystery201412Text": "",
+ "armorMystery201412Notes": "",
+ "armorMystery201501Text": "",
+ "armorMystery201501Notes": "",
+ "armorMystery201503Text": "",
+ "armorMystery201503Notes": "",
+ "armorMystery201504Text": "",
+ "armorMystery201504Notes": "",
+ "armorMystery201506Text": "",
+ "armorMystery201506Notes": "",
+ "armorMystery201508Text": "",
+ "armorMystery201508Notes": "",
+ "armorMystery201509Text": "",
+ "armorMystery201509Notes": "",
+ "armorMystery201511Text": "",
+ "armorMystery201511Notes": "",
+ "armorMystery201512Text": "",
+ "armorMystery201512Notes": "",
+ "armorMystery201603Text": "",
+ "armorMystery201603Notes": "",
+ "armorMystery201604Text": "",
+ "armorMystery201604Notes": "",
+ "armorMystery201605Text": "",
+ "armorMystery201605Notes": "",
+ "armorMystery201606Text": "",
+ "armorMystery201606Notes": "",
+ "armorMystery201607Text": "",
+ "armorMystery201607Notes": "",
+ "armorMystery201609Text": "",
+ "armorMystery201609Notes": "",
+ "armorMystery201610Text": "",
+ "armorMystery201610Notes": "",
+ "armorMystery201612Text": "",
+ "armorMystery201612Notes": "",
+ "armorMystery201703Text": "",
+ "armorMystery201703Notes": "",
+ "armorMystery201704Text": "",
+ "armorMystery201704Notes": "",
+ "armorMystery201707Text": "",
+ "armorMystery201707Notes": "",
+ "armorMystery201710Text": "",
+ "armorMystery201710Notes": "",
+ "armorMystery201711Text": "",
+ "armorMystery201711Notes": "",
+ "armorMystery201712Text": "",
+ "armorMystery201712Notes": "",
+ "armorMystery201802Text": "",
+ "armorMystery201802Notes": "",
+ "armorMystery201806Text": "",
+ "armorMystery201806Notes": "",
+ "armorMystery201807Text": "",
+ "armorMystery201807Notes": "",
+ "armorMystery201808Text": "",
+ "armorMystery201808Notes": "",
+ "armorMystery201809Text": "",
+ "armorMystery201809Notes": "",
+ "armorMystery201810Text": "",
+ "armorMystery201810Notes": "",
+ "armorMystery301404Text": "",
+ "armorMystery301404Notes": "",
+ "armorMystery301703Text": "",
+ "armorMystery301703Notes": "",
+ "armorMystery301704Text": "",
+ "armorMystery301704Notes": "",
+ "armorArmoireLunarArmorText": "",
+ "armorArmoireLunarArmorNotes": "",
+ "armorArmoireGladiatorArmorText": "",
+ "armorArmoireGladiatorArmorNotes": "",
+ "armorArmoireRancherRobesText": "",
+ "armorArmoireRancherRobesNotes": "",
+ "armorArmoireGoldenTogaText": "",
+ "armorArmoireGoldenTogaNotes": "",
+ "armorArmoireHornedIronArmorText": "",
+ "armorArmoireHornedIronArmorNotes": "",
+ "armorArmoirePlagueDoctorOvercoatText": "",
+ "armorArmoirePlagueDoctorOvercoatNotes": "",
+ "armorArmoireShepherdRobesText": "",
+ "armorArmoireShepherdRobesNotes": "",
+ "armorArmoireRoyalRobesText": "",
+ "armorArmoireRoyalRobesNotes": "",
+ "armorArmoireCrystalCrescentRobesText": "",
+ "armorArmoireCrystalCrescentRobesNotes": "",
+ "armorArmoireDragonTamerArmorText": "",
+ "armorArmoireDragonTamerArmorNotes": "",
+ "armorArmoireBarristerRobesText": "",
+ "armorArmoireBarristerRobesNotes": "",
+ "armorArmoireJesterCostumeText": "",
+ "armorArmoireJesterCostumeNotes": "",
+ "armorArmoireMinerOverallsText": "",
+ "armorArmoireMinerOverallsNotes": "",
+ "armorArmoireBasicArcherArmorText": "",
+ "armorArmoireBasicArcherArmorNotes": "",
+ "armorArmoireGraduateRobeText": "",
+ "armorArmoireGraduateRobeNotes": "",
+ "armorArmoireStripedSwimsuitText": "",
+ "armorArmoireStripedSwimsuitNotes": "",
+ "armorArmoireCannoneerRagsText": "",
+ "armorArmoireCannoneerRagsNotes": "",
+ "armorArmoireFalconerArmorText": "",
+ "armorArmoireFalconerArmorNotes": "",
+ "armorArmoireVermilionArcherArmorText": "",
+ "armorArmoireVermilionArcherArmorNotes": "",
+ "armorArmoireOgreArmorText": "",
+ "armorArmoireOgreArmorNotes": "",
+ "armorArmoireIronBlueArcherArmorText": "",
+ "armorArmoireIronBlueArcherArmorNotes": "",
+ "armorArmoireRedPartyDressText": "",
+ "armorArmoireRedPartyDressNotes": "",
+ "armorArmoireWoodElfArmorText": "",
+ "armorArmoireWoodElfArmorNotes": "",
+ "armorArmoireRamFleeceRobesText": "",
+ "armorArmoireRamFleeceRobesNotes": "",
+ "armorArmoireGownOfHeartsText": "",
+ "armorArmoireGownOfHeartsNotes": "",
+ "armorArmoireMushroomDruidArmorText": "",
+ "armorArmoireMushroomDruidArmorNotes": "",
+ "armorArmoireGreenFestivalYukataText": "",
+ "armorArmoireGreenFestivalYukataNotes": "",
+ "armorArmoireMerchantTunicText": "",
+ "armorArmoireMerchantTunicNotes": "",
+ "armorArmoireVikingTunicText": "",
+ "armorArmoireVikingTunicNotes": "",
+ "armorArmoireSwanDancerTutuText": "",
+ "armorArmoireSwanDancerTutuNotes": "",
+ "armorArmoireAntiProcrastinationArmorText": "",
+ "armorArmoireAntiProcrastinationArmorNotes": "",
+ "armorArmoireYellowPartyDressText": "",
+ "armorArmoireYellowPartyDressNotes": "",
+ "armorArmoireFarrierOutfitText": "",
+ "armorArmoireFarrierOutfitNotes": "",
+ "armorArmoireCandlestickMakerOutfitText": "",
+ "armorArmoireCandlestickMakerOutfitNotes": "",
+ "armorArmoireWovenRobesText": "",
+ "armorArmoireWovenRobesNotes": "",
+ "armorArmoireLamplightersGreatcoatText": "",
+ "armorArmoireLamplightersGreatcoatNotes": "",
+ "armorArmoireCoachDriverLiveryText": "",
+ "armorArmoireCoachDriverLiveryNotes": "",
+ "armorArmoireRobeOfDiamondsText": "",
+ "armorArmoireRobeOfDiamondsNotes": "",
+ "armorArmoireFlutteryFrockText": "",
+ "armorArmoireFlutteryFrockNotes": "",
+ "armorArmoireCobblersCoverallsText": "",
+ "armorArmoireCobblersCoverallsNotes": "",
+ "armorArmoireGlassblowersCoverallsText": "",
+ "armorArmoireGlassblowersCoverallsNotes": "",
+ "armorArmoireBluePartyDressText": "",
+ "armorArmoireBluePartyDressNotes": "",
+ "armorArmoirePiraticalPrincessGownText": "",
+ "armorArmoirePiraticalPrincessGownNotes": "",
+ "armorArmoireJeweledArcherArmorText": "",
+ "armorArmoireJeweledArcherArmorNotes": "",
+ "armorArmoireCoverallsOfBookbindingText": "",
+ "armorArmoireCoverallsOfBookbindingNotes": "",
+ "armorArmoireRobeOfSpadesText": "",
+ "armorArmoireRobeOfSpadesNotes": "",
+ "armorArmoireSoftBlueSuitText": "",
+ "armorArmoireSoftBlueSuitNotes": "",
+ "armorArmoireSoftGreenSuitText": "",
+ "armorArmoireSoftGreenSuitNotes": "",
+ "armorArmoireSoftRedSuitText": "",
+ "armorArmoireSoftRedSuitNotes": "",
+ "armorArmoireScribesRobeText": "",
+ "armorArmoireScribesRobeNotes": "",
+ "headgear": "",
+ "headgearCapitalized": "",
+ "headBase0Text": "",
+ "headBase0Notes": "",
+ "headWarrior1Text": "",
+ "headWarrior1Notes": "",
+ "headWarrior2Text": "",
+ "headWarrior2Notes": "",
+ "headWarrior3Text": "",
+ "headWarrior3Notes": "",
+ "headWarrior4Text": "",
+ "headWarrior4Notes": "",
+ "headWarrior5Text": "",
+ "headWarrior5Notes": "",
+ "headRogue1Text": "",
+ "headRogue1Notes": "",
+ "headRogue2Text": "",
+ "headRogue2Notes": "",
+ "headRogue3Text": "",
+ "headRogue3Notes": "",
+ "headRogue4Text": "",
+ "headRogue4Notes": "",
+ "headRogue5Text": "",
+ "headRogue5Notes": "",
+ "headWizard1Text": "",
+ "headWizard1Notes": "",
+ "headWizard2Text": "",
+ "headWizard2Notes": "",
+ "headWizard3Text": "",
+ "headWizard3Notes": "",
+ "headWizard4Text": "",
+ "headWizard4Notes": "",
+ "headWizard5Text": "",
+ "headWizard5Notes": "",
+ "headHealer1Text": "",
+ "headHealer1Notes": "",
+ "headHealer2Text": "",
+ "headHealer2Notes": "",
+ "headHealer3Text": "",
+ "headHealer3Notes": "",
+ "headHealer4Text": "",
+ "headHealer4Notes": "",
+ "headHealer5Text": "",
+ "headHealer5Notes": "",
+ "headSpecial0Text": "",
+ "headSpecial0Notes": "",
+ "headSpecial1Text": "",
+ "headSpecial1Notes": "",
+ "headSpecial2Text": "",
+ "headSpecial2Notes": "",
+ "headSpecialTakeThisText": "",
+ "headSpecialTakeThisNotes": "",
+ "headSpecialFireCoralCircletText": "",
+ "headSpecialFireCoralCircletNotes": "",
+ "headSpecialPyromancersTurbanText": "",
+ "headSpecialPyromancersTurbanNotes": "",
+ "headSpecialBardHatText": "",
+ "headSpecialBardHatNotes": "",
+ "headSpecialLunarWarriorHelmText": "",
+ "headSpecialLunarWarriorHelmNotes": "",
+ "headSpecialMammothRiderHelmText": "",
+ "headSpecialMammothRiderHelmNotes": "",
+ "headSpecialPageHelmText": "",
+ "headSpecialPageHelmNotes": "",
+ "headSpecialRoguishRainbowMessengerHoodText": "",
+ "headSpecialRoguishRainbowMessengerHoodNotes": "",
+ "headSpecialClandestineCowlText": "",
+ "headSpecialClandestineCowlNotes": "",
+ "headSpecialSnowSovereignCrownText": "",
+ "headSpecialSnowSovereignCrownNotes": "",
+ "headSpecialSpikedHelmText": "",
+ "headSpecialSpikedHelmNotes": "",
+ "headSpecialDandyHatText": "",
+ "headSpecialDandyHatNotes": "",
+ "headSpecialKabutoText": "",
+ "headSpecialKabutoNotes": "",
+ "headSpecialNamingDay2017Text": "",
+ "headSpecialNamingDay2017Notes": "",
+ "headSpecialTurkeyHelmBaseText": "",
+ "headSpecialTurkeyHelmBaseNotes": "",
+ "headSpecialTurkeyHelmGildedText": "",
+ "headSpecialTurkeyHelmGildedNotes": "",
+ "headSpecialNyeText": "",
+ "headSpecialNyeNotes": "",
+ "headSpecialYetiText": "",
+ "headSpecialYetiNotes": "",
+ "headSpecialSkiText": "",
+ "headSpecialSkiNotes": "",
+ "headSpecialCandycaneText": "",
+ "headSpecialCandycaneNotes": "",
+ "headSpecialSnowflakeText": "",
+ "headSpecialSnowflakeNotes": "",
+ "headSpecialSpringRogueText": "",
+ "headSpecialSpringRogueNotes": "",
+ "headSpecialSpringWarriorText": "",
+ "headSpecialSpringWarriorNotes": "",
+ "headSpecialSpringMageText": "",
+ "headSpecialSpringMageNotes": "",
+ "headSpecialSpringHealerText": "",
+ "headSpecialSpringHealerNotes": "",
+ "headSpecialSummerRogueText": "",
+ "headSpecialSummerRogueNotes": "",
+ "headSpecialSummerWarriorText": "",
+ "headSpecialSummerWarriorNotes": "",
+ "headSpecialSummerMageText": "",
+ "headSpecialSummerMageNotes": "",
+ "headSpecialSummerHealerText": "",
+ "headSpecialSummerHealerNotes": "",
+ "headSpecialFallRogueText": "",
+ "headSpecialFallRogueNotes": "",
+ "headSpecialFallWarriorText": "",
+ "headSpecialFallWarriorNotes": "",
+ "headSpecialFallMageText": "",
+ "headSpecialFallMageNotes": "",
+ "headSpecialFallHealerText": "",
+ "headSpecialFallHealerNotes": "",
+ "headSpecialNye2014Text": "",
+ "headSpecialNye2014Notes": "",
+ "headSpecialWinter2015RogueText": "",
+ "headSpecialWinter2015RogueNotes": "",
+ "headSpecialWinter2015WarriorText": "",
+ "headSpecialWinter2015WarriorNotes": "",
+ "headSpecialWinter2015MageText": "",
+ "headSpecialWinter2015MageNotes": "",
+ "headSpecialWinter2015HealerText": "",
+ "headSpecialWinter2015HealerNotes": "",
+ "headSpecialSpring2015RogueText": "",
+ "headSpecialSpring2015RogueNotes": "",
+ "headSpecialSpring2015WarriorText": "",
+ "headSpecialSpring2015WarriorNotes": "",
+ "headSpecialSpring2015MageText": "",
+ "headSpecialSpring2015MageNotes": "",
+ "headSpecialSpring2015HealerText": "",
+ "headSpecialSpring2015HealerNotes": "",
+ "headSpecialSummer2015RogueText": "",
+ "headSpecialSummer2015RogueNotes": "",
+ "headSpecialSummer2015WarriorText": "",
+ "headSpecialSummer2015WarriorNotes": "",
+ "headSpecialSummer2015MageText": "",
+ "headSpecialSummer2015MageNotes": "",
+ "headSpecialSummer2015HealerText": "",
+ "headSpecialSummer2015HealerNotes": "",
+ "headSpecialFall2015RogueText": "",
+ "headSpecialFall2015RogueNotes": "",
+ "headSpecialFall2015WarriorText": "",
+ "headSpecialFall2015WarriorNotes": "",
+ "headSpecialFall2015MageText": "",
+ "headSpecialFall2015MageNotes": "",
+ "headSpecialFall2015HealerText": "",
+ "headSpecialFall2015HealerNotes": "",
+ "headSpecialNye2015Text": "",
+ "headSpecialNye2015Notes": "",
+ "headSpecialWinter2016RogueText": "",
+ "headSpecialWinter2016RogueNotes": "",
+ "headSpecialWinter2016WarriorText": "",
+ "headSpecialWinter2016WarriorNotes": "",
+ "headSpecialWinter2016MageText": "",
+ "headSpecialWinter2016MageNotes": "",
+ "headSpecialWinter2016HealerText": "",
+ "headSpecialWinter2016HealerNotes": "",
+ "headSpecialSpring2016RogueText": "",
+ "headSpecialSpring2016RogueNotes": "",
+ "headSpecialSpring2016WarriorText": "",
+ "headSpecialSpring2016WarriorNotes": "",
+ "headSpecialSpring2016MageText": "",
+ "headSpecialSpring2016MageNotes": "",
+ "headSpecialSpring2016HealerText": "",
+ "headSpecialSpring2016HealerNotes": "",
+ "headSpecialSummer2016RogueText": "",
+ "headSpecialSummer2016RogueNotes": "",
+ "headSpecialSummer2016WarriorText": "",
+ "headSpecialSummer2016WarriorNotes": "",
+ "headSpecialSummer2016MageText": "",
+ "headSpecialSummer2016MageNotes": "",
+ "headSpecialSummer2016HealerText": "",
+ "headSpecialSummer2016HealerNotes": "",
+ "headSpecialFall2016RogueText": "",
+ "headSpecialFall2016RogueNotes": "",
+ "headSpecialFall2016WarriorText": "",
+ "headSpecialFall2016WarriorNotes": "",
+ "headSpecialFall2016MageText": "",
+ "headSpecialFall2016MageNotes": "",
+ "headSpecialFall2016HealerText": "",
+ "headSpecialFall2016HealerNotes": "",
+ "headSpecialNye2016Text": "",
+ "headSpecialNye2016Notes": "",
+ "headSpecialWinter2017RogueText": "",
+ "headSpecialWinter2017RogueNotes": "",
+ "headSpecialWinter2017WarriorText": "",
+ "headSpecialWinter2017WarriorNotes": "",
+ "headSpecialWinter2017MageText": "",
+ "headSpecialWinter2017MageNotes": "",
+ "headSpecialWinter2017HealerText": "",
+ "headSpecialWinter2017HealerNotes": "",
+ "headSpecialSpring2017RogueText": "",
+ "headSpecialSpring2017RogueNotes": "",
+ "headSpecialSpring2017WarriorText": "",
+ "headSpecialSpring2017WarriorNotes": "",
+ "headSpecialSpring2017MageText": "",
+ "headSpecialSpring2017MageNotes": "",
+ "headSpecialSpring2017HealerText": "",
+ "headSpecialSpring2017HealerNotes": "",
+ "headSpecialSummer2017RogueText": "",
+ "headSpecialSummer2017RogueNotes": "",
+ "headSpecialSummer2017WarriorText": "",
+ "headSpecialSummer2017WarriorNotes": "",
+ "headSpecialSummer2017MageText": "",
+ "headSpecialSummer2017MageNotes": "",
+ "headSpecialSummer2017HealerText": "",
+ "headSpecialSummer2017HealerNotes": "",
+ "headSpecialFall2017RogueText": "",
+ "headSpecialFall2017RogueNotes": "",
+ "headSpecialFall2017WarriorText": "",
+ "headSpecialFall2017WarriorNotes": "",
+ "headSpecialFall2017MageText": "",
+ "headSpecialFall2017MageNotes": "",
+ "headSpecialFall2017HealerText": "",
+ "headSpecialFall2017HealerNotes": "",
+ "headSpecialNye2017Text": "",
+ "headSpecialNye2017Notes": "",
+ "headSpecialWinter2018RogueText": "",
+ "headSpecialWinter2018RogueNotes": "",
+ "headSpecialWinter2018WarriorText": "",
+ "headSpecialWinter2018WarriorNotes": "",
+ "headSpecialWinter2018MageText": "",
+ "headSpecialWinter2018MageNotes": "",
+ "headSpecialWinter2018HealerText": "",
+ "headSpecialWinter2018HealerNotes": "",
+ "headSpecialSpring2018RogueText": "",
+ "headSpecialSpring2018RogueNotes": "",
+ "headSpecialSpring2018WarriorText": "",
+ "headSpecialSpring2018WarriorNotes": "",
+ "headSpecialSpring2018MageText": "",
+ "headSpecialSpring2018MageNotes": "",
+ "headSpecialSpring2018HealerText": "",
+ "headSpecialSpring2018HealerNotes": "",
+ "headSpecialSummer2018RogueText": "",
+ "headSpecialSummer2018RogueNotes": "",
+ "headSpecialSummer2018WarriorText": "",
+ "headSpecialSummer2018WarriorNotes": "",
+ "headSpecialSummer2018MageText": "",
+ "headSpecialSummer2018MageNotes": "",
+ "headSpecialSummer2018HealerText": "",
+ "headSpecialSummer2018HealerNotes": "",
+ "headSpecialFall2018RogueText": "",
+ "headSpecialFall2018RogueNotes": "",
+ "headSpecialFall2018WarriorText": "",
+ "headSpecialFall2018WarriorNotes": "",
+ "headSpecialFall2018MageText": "",
+ "headSpecialFall2018MageNotes": "",
+ "headSpecialFall2018HealerText": "",
+ "headSpecialFall2018HealerNotes": "",
+ "headSpecialNye2018Text": "",
+ "headSpecialNye2018Notes": "",
+ "headSpecialWinter2019RogueText": "",
+ "headSpecialWinter2019RogueNotes": "",
+ "headSpecialWinter2019WarriorText": "",
+ "headSpecialWinter2019WarriorNotes": "",
+ "headSpecialWinter2019MageText": "",
+ "headSpecialWinter2019MageNotes": "",
+ "headSpecialWinter2019HealerText": "",
+ "headSpecialWinter2019HealerNotes": "",
+ "headSpecialGaymerxText": "",
+ "headSpecialGaymerxNotes": "",
+ "headMystery201402Text": "",
+ "headMystery201402Notes": "",
+ "headMystery201405Text": "",
+ "headMystery201405Notes": "",
+ "headMystery201406Text": "",
+ "headMystery201406Notes": "",
+ "headMystery201407Text": "",
+ "headMystery201407Notes": "",
+ "headMystery201408Text": "",
+ "headMystery201408Notes": "",
+ "headMystery201411Text": "",
+ "headMystery201411Notes": "",
+ "headMystery201412Text": "",
+ "headMystery201412Notes": "",
+ "headMystery201501Text": "",
+ "headMystery201501Notes": "",
+ "headMystery201505Text": "",
+ "headMystery201505Notes": "",
+ "headMystery201508Text": "",
+ "headMystery201508Notes": "",
+ "headMystery201509Text": "",
+ "headMystery201509Notes": "",
+ "headMystery201511Text": "",
+ "headMystery201511Notes": "",
+ "headMystery201512Text": "",
+ "headMystery201512Notes": "",
+ "headMystery201601Text": "",
+ "headMystery201601Notes": "",
+ "headMystery201602Text": "",
+ "headMystery201602Notes": "",
+ "headMystery201603Text": "",
+ "headMystery201603Notes": "",
+ "headMystery201604Text": "",
+ "headMystery201604Notes": "",
+ "headMystery201605Text": "",
+ "headMystery201605Notes": "",
+ "headMystery201606Text": "",
+ "headMystery201606Notes": "",
+ "headMystery201607Text": "",
+ "headMystery201607Notes": "",
+ "headMystery201608Text": "",
+ "headMystery201608Notes": "",
+ "headMystery201609Text": "",
+ "headMystery201609Notes": "",
+ "headMystery201610Text": "",
+ "headMystery201610Notes": "",
+ "headMystery201611Text": "",
+ "headMystery201611Notes": "",
+ "headMystery201612Text": "",
+ "headMystery201612Notes": "",
+ "headMystery201702Text": "",
+ "headMystery201702Notes": "",
+ "headMystery201703Text": "",
+ "headMystery201703Notes": "",
+ "headMystery201705Text": "",
+ "headMystery201705Notes": "",
+ "headMystery201707Text": "",
+ "headMystery201707Notes": "",
+ "headMystery201710Text": "",
+ "headMystery201710Notes": "",
+ "headMystery201712Text": "",
+ "headMystery201712Notes": "",
+ "headMystery201802Text": "",
+ "headMystery201802Notes": "",
+ "headMystery201803Text": "",
+ "headMystery201803Notes": "",
+ "headMystery201805Text": "",
+ "headMystery201805Notes": "",
+ "headMystery201806Text": "",
+ "headMystery201806Notes": "",
+ "headMystery201807Text": "",
+ "headMystery201807Notes": "",
+ "headMystery201808Text": "",
+ "headMystery201808Notes": "",
+ "headMystery201809Text": "",
+ "headMystery201809Notes": "",
+ "headMystery201810Text": "",
+ "headMystery201810Notes": "",
+ "headMystery201811Text": "",
+ "headMystery201811Notes": "",
+ "headMystery301404Text": "",
+ "headMystery301404Notes": "",
+ "headMystery301405Text": "",
+ "headMystery301405Notes": "",
+ "headMystery301703Text": "",
+ "headMystery301703Notes": "",
+ "headMystery301704Text": "",
+ "headMystery301704Notes": "",
+ "headArmoireLunarCrownText": "",
+ "headArmoireLunarCrownNotes": "",
+ "headArmoireRedHairbowText": "",
+ "headArmoireRedHairbowNotes": "",
+ "headArmoireVioletFloppyHatText": "",
+ "headArmoireVioletFloppyHatNotes": "",
+ "headArmoireGladiatorHelmText": "",
+ "headArmoireGladiatorHelmNotes": "",
+ "headArmoireRancherHatText": "",
+ "headArmoireRancherHatNotes": "",
+ "headArmoireBlueHairbowText": "",
+ "headArmoireBlueHairbowNotes": "",
+ "headArmoireRoyalCrownText": "",
+ "headArmoireRoyalCrownNotes": "",
+ "headArmoireGoldenLaurelsText": "",
+ "headArmoireGoldenLaurelsNotes": "",
+ "headArmoireHornedIronHelmText": "",
+ "headArmoireHornedIronHelmNotes": "",
+ "headArmoireYellowHairbowText": "",
+ "headArmoireYellowHairbowNotes": "",
+ "headArmoireRedFloppyHatText": "",
+ "headArmoireRedFloppyHatNotes": "",
+ "headArmoirePlagueDoctorHatText": "",
+ "headArmoirePlagueDoctorHatNotes": "",
+ "headArmoireBlackCatText": "",
+ "headArmoireBlackCatNotes": "",
+ "headArmoireOrangeCatText": "",
+ "headArmoireOrangeCatNotes": "",
+ "headArmoireBlueFloppyHatText": "",
+ "headArmoireBlueFloppyHatNotes": "",
+ "headArmoireShepherdHeaddressText": "",
+ "headArmoireShepherdHeaddressNotes": "",
+ "headArmoireCrystalCrescentHatText": "",
+ "headArmoireCrystalCrescentHatNotes": "",
+ "headArmoireDragonTamerHelmText": "",
+ "headArmoireDragonTamerHelmNotes": "",
+ "headArmoireBarristerWigText": "",
+ "headArmoireBarristerWigNotes": "",
+ "headArmoireJesterCapText": "",
+ "headArmoireJesterCapNotes": "",
+ "headArmoireMinerHelmetText": "",
+ "headArmoireMinerHelmetNotes": "",
+ "headArmoireBasicArcherCapText": "",
+ "headArmoireBasicArcherCapNotes": "",
+ "headArmoireGraduateCapText": "",
+ "headArmoireGraduateCapNotes": "",
+ "headArmoireGreenFloppyHatText": "",
+ "headArmoireGreenFloppyHatNotes": "",
+ "headArmoireCannoneerBandannaText": "",
+ "headArmoireCannoneerBandannaNotes": "",
+ "headArmoireFalconerCapText": "",
+ "headArmoireFalconerCapNotes": "",
+ "headArmoireVermilionArcherHelmText": "",
+ "headArmoireVermilionArcherHelmNotes": "",
+ "headArmoireOgreMaskText": "",
+ "headArmoireOgreMaskNotes": "",
+ "headArmoireIronBlueArcherHelmText": "",
+ "headArmoireIronBlueArcherHelmNotes": "",
+ "headArmoireWoodElfHelmText": "",
+ "headArmoireWoodElfHelmNotes": "",
+ "headArmoireRamHeaddressText": "",
+ "headArmoireRamHeaddressNotes": "",
+ "headArmoireCrownOfHeartsText": "",
+ "headArmoireCrownOfHeartsNotes": "",
+ "headArmoireMushroomDruidCapText": "",
+ "headArmoireMushroomDruidCapNotes": "",
+ "headArmoireMerchantChaperonText": "",
+ "headArmoireMerchantChaperonNotes": "",
+ "headArmoireVikingHelmText": "",
+ "headArmoireVikingHelmNotes": "",
+ "headArmoireSwanFeatherCrownText": "",
+ "headArmoireSwanFeatherCrownNotes": "",
+ "headArmoireAntiProcrastinationHelmText": "",
+ "headArmoireAntiProcrastinationHelmNotes": "",
+ "headArmoireCandlestickMakerHatText": "",
+ "headArmoireCandlestickMakerHatNotes": "",
+ "headArmoireLamplightersTopHatText": "",
+ "headArmoireLamplightersTopHatNotes": "",
+ "headArmoireCoachDriversHatText": "",
+ "headArmoireCoachDriversHatNotes": "",
+ "headArmoireCrownOfDiamondsText": "",
+ "headArmoireCrownOfDiamondsNotes": "",
+ "headArmoireFlutteryWigText": "",
+ "headArmoireFlutteryWigNotes": "",
+ "headArmoireBirdsNestText": "",
+ "headArmoireBirdsNestNotes": "",
+ "headArmoirePaperBagText": "",
+ "headArmoirePaperBagNotes": "",
+ "headArmoireBigWigText": "",
+ "headArmoireBigWigNotes": "",
+ "headArmoireGlassblowersHatText": "",
+ "headArmoireGlassblowersHatNotes": "",
+ "headArmoirePiraticalPrincessHeaddressText": "",
+ "headArmoirePiraticalPrincessHeaddressNotes": "",
+ "headArmoireJeweledArcherHelmText": "",
+ "headArmoireJeweledArcherHelmNotes": "",
+ "headArmoireVeilOfSpadesText": "",
+ "headArmoireVeilOfSpadesNotes": "",
+ "offhand": "",
+ "offhandCapitalized": "",
+ "shieldBase0Text": "",
+ "shieldBase0Notes": "",
+ "shieldWarrior1Text": "",
+ "shieldWarrior1Notes": "",
+ "shieldWarrior2Text": "",
+ "shieldWarrior2Notes": "",
+ "shieldWarrior3Text": "",
+ "shieldWarrior3Notes": "",
+ "shieldWarrior4Text": "",
+ "shieldWarrior4Notes": "",
+ "shieldWarrior5Text": "",
+ "shieldWarrior5Notes": "",
+ "shieldHealer1Text": "",
+ "shieldHealer1Notes": "",
+ "shieldHealer2Text": "",
+ "shieldHealer2Notes": "",
+ "shieldHealer3Text": "",
+ "shieldHealer3Notes": "",
+ "shieldHealer4Text": "",
+ "shieldHealer4Notes": "",
+ "shieldHealer5Text": "",
+ "shieldHealer5Notes": "",
+ "shieldSpecial0Text": "",
+ "shieldSpecial0Notes": "",
+ "shieldSpecial1Text": "",
+ "shieldSpecial1Notes": "",
+ "shieldSpecialTakeThisText": "",
+ "shieldSpecialTakeThisNotes": "",
+ "shieldSpecialGoldenknightText": "",
+ "shieldSpecialGoldenknightNotes": "",
+ "shieldSpecialMoonpearlShieldText": "",
+ "shieldSpecialMoonpearlShieldNotes": "",
+ "shieldSpecialMammothRiderHornText": "",
+ "shieldSpecialMammothRiderHornNotes": "",
+ "shieldSpecialDiamondStaveText": "",
+ "shieldSpecialDiamondStaveNotes": "",
+ "shieldSpecialRoguishRainbowMessageText": "",
+ "shieldSpecialRoguishRainbowMessageNotes": "",
+ "shieldSpecialLootBagText": "",
+ "shieldSpecialLootBagNotes": "",
+ "shieldSpecialWintryMirrorText": "",
+ "shieldSpecialWintryMirrorNotes": "",
+ "shieldSpecialWakizashiText": "",
+ "shieldSpecialWakizashiNotes": "",
+ "shieldSpecialYetiText": "",
+ "shieldSpecialYetiNotes": "",
+ "shieldSpecialSnowflakeText": "",
+ "shieldSpecialSnowflakeNotes": "",
+ "shieldSpecialSpringRogueText": "",
+ "shieldSpecialSpringRogueNotes": "",
+ "shieldSpecialSpringWarriorText": "",
+ "shieldSpecialSpringWarriorNotes": "",
+ "shieldSpecialSpringHealerText": "",
+ "shieldSpecialSpringHealerNotes": "",
+ "shieldSpecialSummerRogueText": "",
+ "shieldSpecialSummerRogueNotes": "",
+ "shieldSpecialSummerWarriorText": "",
+ "shieldSpecialSummerWarriorNotes": "",
+ "shieldSpecialSummerHealerText": "",
+ "shieldSpecialSummerHealerNotes": "",
+ "shieldSpecialFallRogueText": "",
+ "shieldSpecialFallRogueNotes": "",
+ "shieldSpecialFallWarriorText": "",
+ "shieldSpecialFallWarriorNotes": "",
+ "shieldSpecialFallHealerText": "",
+ "shieldSpecialFallHealerNotes": "",
+ "shieldSpecialWinter2015RogueText": "",
+ "shieldSpecialWinter2015RogueNotes": "",
+ "shieldSpecialWinter2015WarriorText": "",
+ "shieldSpecialWinter2015WarriorNotes": "",
+ "shieldSpecialWinter2015HealerText": "",
+ "shieldSpecialWinter2015HealerNotes": "",
+ "shieldSpecialSpring2015RogueText": "",
+ "shieldSpecialSpring2015RogueNotes": "",
+ "shieldSpecialSpring2015WarriorText": "",
+ "shieldSpecialSpring2015WarriorNotes": "",
+ "shieldSpecialSpring2015HealerText": "",
+ "shieldSpecialSpring2015HealerNotes": "",
+ "shieldSpecialSummer2015RogueText": "",
+ "shieldSpecialSummer2015RogueNotes": "",
+ "shieldSpecialSummer2015WarriorText": "",
+ "shieldSpecialSummer2015WarriorNotes": "",
+ "shieldSpecialSummer2015HealerText": "",
+ "shieldSpecialSummer2015HealerNotes": "",
+ "shieldSpecialFall2015RogueText": "",
+ "shieldSpecialFall2015RogueNotes": "",
+ "shieldSpecialFall2015WarriorText": "",
+ "shieldSpecialFall2015WarriorNotes": "",
+ "shieldSpecialFall2015HealerText": "",
+ "shieldSpecialFall2015HealerNotes": "",
+ "shieldSpecialWinter2016RogueText": "",
+ "shieldSpecialWinter2016RogueNotes": "",
+ "shieldSpecialWinter2016WarriorText": "",
+ "shieldSpecialWinter2016WarriorNotes": "",
+ "shieldSpecialWinter2016HealerText": "",
+ "shieldSpecialWinter2016HealerNotes": "",
+ "shieldSpecialSpring2016RogueText": "",
+ "shieldSpecialSpring2016RogueNotes": "",
+ "shieldSpecialSpring2016WarriorText": "",
+ "shieldSpecialSpring2016WarriorNotes": "",
+ "shieldSpecialSpring2016HealerText": "",
+ "shieldSpecialSpring2016HealerNotes": "",
+ "shieldSpecialSummer2016RogueText": "",
+ "shieldSpecialSummer2016RogueNotes": "",
+ "shieldSpecialSummer2016WarriorText": "",
+ "shieldSpecialSummer2016WarriorNotes": "",
+ "shieldSpecialSummer2016HealerText": "",
+ "shieldSpecialSummer2016HealerNotes": "",
+ "shieldSpecialFall2016RogueText": "",
+ "shieldSpecialFall2016RogueNotes": "",
+ "shieldSpecialFall2016WarriorText": "",
+ "shieldSpecialFall2016WarriorNotes": "",
+ "shieldSpecialFall2016HealerText": "",
+ "shieldSpecialFall2016HealerNotes": "",
+ "shieldSpecialWinter2017RogueText": "",
+ "shieldSpecialWinter2017RogueNotes": "",
+ "shieldSpecialWinter2017WarriorText": "",
+ "shieldSpecialWinter2017WarriorNotes": "",
+ "shieldSpecialWinter2017HealerText": "",
+ "shieldSpecialWinter2017HealerNotes": "",
+ "shieldSpecialSpring2017RogueText": "",
+ "shieldSpecialSpring2017RogueNotes": "",
+ "shieldSpecialSpring2017WarriorText": "",
+ "shieldSpecialSpring2017WarriorNotes": "",
+ "shieldSpecialSpring2017HealerText": "",
+ "shieldSpecialSpring2017HealerNotes": "",
+ "shieldSpecialSummer2017RogueText": "",
+ "shieldSpecialSummer2017RogueNotes": "",
+ "shieldSpecialSummer2017WarriorText": "",
+ "shieldSpecialSummer2017WarriorNotes": "",
+ "shieldSpecialSummer2017HealerText": "",
+ "shieldSpecialSummer2017HealerNotes": "",
+ "shieldSpecialFall2017RogueText": "",
+ "shieldSpecialFall2017RogueNotes": "",
+ "shieldSpecialFall2017WarriorText": "",
+ "shieldSpecialFall2017WarriorNotes": "",
+ "shieldSpecialFall2017HealerText": "",
+ "shieldSpecialFall2017HealerNotes": "",
+ "shieldSpecialWinter2018RogueText": "",
+ "shieldSpecialWinter2018RogueNotes": "",
+ "shieldSpecialWinter2018WarriorText": "",
+ "shieldSpecialWinter2018WarriorNotes": "",
+ "shieldSpecialWinter2018HealerText": "",
+ "shieldSpecialWinter2018HealerNotes": "",
+ "shieldSpecialSpring2018WarriorText": "",
+ "shieldSpecialSpring2018WarriorNotes": "",
+ "shieldSpecialSpring2018HealerText": "",
+ "shieldSpecialSpring2018HealerNotes": "",
+ "shieldSpecialSummer2018WarriorText": "",
+ "shieldSpecialSummer2018WarriorNotes": "",
+ "shieldSpecialSummer2018HealerText": "",
+ "shieldSpecialSummer2018HealerNotes": "",
+ "shieldSpecialFall2018RogueText": "",
+ "shieldSpecialFall2018RogueNotes": "",
+ "shieldSpecialFall2018WarriorText": "",
+ "shieldSpecialFall2018WarriorNotes": "",
+ "shieldSpecialFall2018HealerText": "",
+ "shieldSpecialFall2018HealerNotes": "",
+ "shieldSpecialWinter2019WarriorText": "",
+ "shieldSpecialWinter2019WarriorNotes": "",
+ "shieldSpecialWinter2019HealerText": "",
+ "shieldSpecialWinter2019HealerNotes": "",
+ "shieldMystery201601Text": "",
+ "shieldMystery201601Notes": "",
+ "shieldMystery201701Text": "",
+ "shieldMystery201701Notes": "",
+ "shieldMystery201708Text": "",
+ "shieldMystery201708Notes": "",
+ "shieldMystery201709Text": "",
+ "shieldMystery201709Notes": "",
+ "shieldMystery201802Text": "",
+ "shieldMystery201802Notes": "",
+ "shieldMystery301405Text": "",
+ "shieldMystery301405Notes": "",
+ "shieldMystery301704Text": "",
+ "shieldMystery301704Notes": "",
+ "shieldArmoireGladiatorShieldText": "",
+ "shieldArmoireGladiatorShieldNotes": "",
+ "shieldArmoireMidnightShieldText": "",
+ "shieldArmoireMidnightShieldNotes": "",
+ "shieldArmoireRoyalCaneText": "",
+ "shieldArmoireRoyalCaneNotes": "",
+ "shieldArmoireDragonTamerShieldText": "",
+ "shieldArmoireDragonTamerShieldNotes": "",
+ "shieldArmoireMysticLampText": "",
+ "shieldArmoireMysticLampNotes": "",
+ "shieldArmoireFloralBouquetText": "",
+ "shieldArmoireFloralBouquetNotes": "",
+ "shieldArmoireSandyBucketText": "",
+ "shieldArmoireSandyBucketNotes": "",
+ "shieldArmoirePerchingFalconText": "",
+ "shieldArmoirePerchingFalconNotes": "",
+ "shieldArmoireRamHornShieldText": "",
+ "shieldArmoireRamHornShieldNotes": "",
+ "shieldArmoireRedRoseText": "",
+ "shieldArmoireRedRoseNotes": "",
+ "shieldArmoireMushroomDruidShieldText": "",
+ "shieldArmoireMushroomDruidShieldNotes": "",
+ "shieldArmoireFestivalParasolText": "",
+ "shieldArmoireFestivalParasolNotes": "",
+ "shieldArmoireVikingShieldText": "",
+ "shieldArmoireVikingShieldNotes": "",
+ "shieldArmoireSwanFeatherFanText": "",
+ "shieldArmoireSwanFeatherFanNotes": "",
+ "shieldArmoireGoldenBatonText": "",
+ "shieldArmoireGoldenBatonNotes": "",
+ "shieldArmoireAntiProcrastinationShieldText": "",
+ "shieldArmoireAntiProcrastinationShieldNotes": "",
+ "shieldArmoireHorseshoeText": "",
+ "shieldArmoireHorseshoeNotes": "",
+ "shieldArmoireHandmadeCandlestickText": "",
+ "shieldArmoireHandmadeCandlestickNotes": "",
+ "shieldArmoireWeaversShuttleText": "",
+ "shieldArmoireWeaversShuttleNotes": "",
+ "shieldArmoireShieldOfDiamondsText": "",
+ "shieldArmoireShieldOfDiamondsNotes": "",
+ "shieldArmoireFlutteryFanText": "",
+ "shieldArmoireFlutteryFanNotes": "",
+ "shieldArmoireFancyShoeText": "",
+ "shieldArmoireFancyShoeNotes": "",
+ "shieldArmoireFancyBlownGlassVaseText": "",
+ "shieldArmoireFancyBlownGlassVaseNotes": "",
+ "shieldArmoirePiraticalSkullShieldText": "",
+ "shieldArmoirePiraticalSkullShieldNotes": "",
+ "shieldArmoireUnfinishedTomeText": "",
+ "shieldArmoireUnfinishedTomeNotes": "",
+ "shieldArmoireSoftBluePillowText": "",
+ "shieldArmoireSoftBluePillowNotes": "",
+ "shieldArmoireSoftRedPillowText": "",
+ "shieldArmoireSoftRedPillowNotes": "",
+ "shieldArmoireSoftGreenPillowText": "",
+ "shieldArmoireSoftGreenPillowNotes": "",
+ "shieldArmoireMightyQuillText": "",
+ "shieldArmoireMightyQuillNotes": "",
+ "back": "",
+ "backCapitalized": "",
+ "backBase0Text": "",
+ "backBase0Notes": "",
+ "animalTails": "",
+ "backMystery201402Text": "",
+ "backMystery201402Notes": "",
+ "backMystery201404Text": "",
+ "backMystery201404Notes": "",
+ "backMystery201410Text": "",
+ "backMystery201410Notes": "",
+ "backMystery201504Text": "",
+ "backMystery201504Notes": "",
+ "backMystery201507Text": "",
+ "backMystery201507Notes": "",
+ "backMystery201510Text": "",
+ "backMystery201510Notes": "",
+ "backMystery201602Text": "",
+ "backMystery201602Notes": "",
+ "backMystery201608Text": "",
+ "backMystery201608Notes": "",
+ "backMystery201702Text": "",
+ "backMystery201702Notes": "",
+ "backMystery201704Text": "",
+ "backMystery201704Notes": "",
+ "backMystery201706Text": "",
+ "backMystery201706Notes": "",
+ "backMystery201709Text": "",
+ "backMystery201709Notes": "",
+ "backMystery201801Text": "",
+ "backMystery201801Notes": "",
+ "backMystery201803Text": "",
+ "backMystery201803Notes": "",
+ "backMystery201804Text": "",
+ "backMystery201804Notes": "",
+ "backMystery201812Text": "",
+ "backMystery201812Notes": "",
+ "backMystery201805Text": "",
+ "backMystery201805Notes": "",
+ "backSpecialWonderconRedText": "",
+ "backSpecialWonderconRedNotes": "",
+ "backSpecialWonderconBlackText": "",
+ "backSpecialWonderconBlackNotes": "",
+ "backSpecialTakeThisText": "",
+ "backSpecialTakeThisNotes": "",
+ "backSpecialSnowdriftVeilText": "",
+ "backSpecialSnowdriftVeilNotes": "",
+ "backSpecialAetherCloakText": "",
+ "backSpecialAetherCloakNotes": "",
+ "backSpecialTurkeyTailBaseText": "",
+ "backSpecialTurkeyTailBaseNotes": "",
+ "backSpecialTurkeyTailGildedText": "",
+ "backSpecialTurkeyTailGildedNotes": "",
+ "backBearTailText": "",
+ "backBearTailNotes": "",
+ "backCactusTailText": "",
+ "backCactusTailNotes": "",
+ "backFoxTailText": "",
+ "backFoxTailNotes": "",
+ "backLionTailText": "",
+ "backLionTailNotes": "",
+ "backPandaTailText": "",
+ "backPandaTailNotes": "",
+ "backPigTailText": "",
+ "backPigTailNotes": "",
+ "backTigerTailText": "",
+ "backTigerTailNotes": "",
+ "backWolfTailText": "",
+ "backWolfTailNotes": "",
+ "body": "",
+ "bodyCapitalized": "",
+ "bodyBase0Text": "",
+ "bodyBase0Notes": "",
+ "bodySpecialWonderconRedText": "",
+ "bodySpecialWonderconRedNotes": "",
+ "bodySpecialWonderconGoldText": "",
+ "bodySpecialWonderconGoldNotes": "",
+ "bodySpecialWonderconBlackText": "",
+ "bodySpecialWonderconBlackNotes": "",
+ "bodySpecialTakeThisText": "",
+ "bodySpecialTakeThisNotes": "",
+ "bodySpecialAetherAmuletText": "",
+ "bodySpecialAetherAmuletNotes": "",
+ "bodySpecialSummerMageText": "",
+ "bodySpecialSummerMageNotes": "",
+ "bodySpecialSummerHealerText": "",
+ "bodySpecialSummerHealerNotes": "",
+ "bodySpecialSummer2015RogueText": "",
+ "bodySpecialSummer2015RogueNotes": "",
+ "bodySpecialSummer2015WarriorText": "",
+ "bodySpecialSummer2015WarriorNotes": "",
+ "bodySpecialSummer2015MageText": "",
+ "bodySpecialSummer2015MageNotes": "",
+ "bodySpecialSummer2015HealerText": "",
+ "bodySpecialSummer2015HealerNotes": "",
+ "bodySpecialNamingDay2018Text": "",
+ "bodySpecialNamingDay2018Notes": "",
+ "bodyMystery201705Text": "",
+ "bodyMystery201705Notes": "",
+ "bodyMystery201706Text": "",
+ "bodyMystery201706Notes": "",
+ "bodyMystery201711Text": "",
+ "bodyMystery201711Notes": "",
+ "bodyArmoireCozyScarfText": "",
+ "bodyArmoireCozyScarfNotes": "",
+ "headAccessory": "",
+ "headAccessoryCapitalized": "",
+ "accessories": "",
+ "animalEars": "",
+ "headAccessoryBase0Text": "",
+ "headAccessoryBase0Notes": "",
+ "headAccessorySpecialSpringRogueText": "",
+ "headAccessorySpecialSpringRogueNotes": "",
+ "headAccessorySpecialSpringWarriorText": "",
+ "headAccessorySpecialSpringWarriorNotes": "",
+ "headAccessorySpecialSpringMageText": "",
+ "headAccessorySpecialSpringMageNotes": "",
+ "headAccessorySpecialSpringHealerText": "",
+ "headAccessorySpecialSpringHealerNotes": "",
+ "headAccessorySpecialSpring2015RogueText": "",
+ "headAccessorySpecialSpring2015RogueNotes": "",
+ "headAccessorySpecialSpring2015WarriorText": "",
+ "headAccessorySpecialSpring2015WarriorNotes": "",
+ "headAccessorySpecialSpring2015MageText": "",
+ "headAccessorySpecialSpring2015MageNotes": "",
+ "headAccessorySpecialSpring2015HealerText": "",
+ "headAccessorySpecialSpring2015HealerNotes": "",
+ "headAccessorySpecialSpring2016RogueText": "",
+ "headAccessorySpecialSpring2016RogueNotes": "",
+ "headAccessorySpecialSpring2016WarriorText": "",
+ "headAccessorySpecialSpring2016WarriorNotes": "",
+ "headAccessorySpecialSpring2016MageText": "",
+ "headAccessorySpecialSpring2016MageNotes": "",
+ "headAccessorySpecialSpring2016HealerText": "",
+ "headAccessorySpecialSpring2016HealerNotes": "",
+ "headAccessorySpecialSpring2017RogueText": "",
+ "headAccessorySpecialSpring2017RogueNotes": "",
+ "headAccessorySpecialSpring2017WarriorText": "",
+ "headAccessorySpecialSpring2017WarriorNotes": "",
+ "headAccessorySpecialSpring2017MageText": "",
+ "headAccessorySpecialSpring2017MageNotes": "",
+ "headAccessorySpecialSpring2017HealerText": "",
+ "headAccessorySpecialSpring2017HealerNotes": "",
+ "headAccessoryBearEarsText": "",
+ "headAccessoryBearEarsNotes": "",
+ "headAccessoryCactusEarsText": "",
+ "headAccessoryCactusEarsNotes": "",
+ "headAccessoryFoxEarsText": "",
+ "headAccessoryFoxEarsNotes": "",
+ "headAccessoryLionEarsText": "",
+ "headAccessoryLionEarsNotes": "",
+ "headAccessoryPandaEarsText": "",
+ "headAccessoryPandaEarsNotes": "",
+ "headAccessoryPigEarsText": "",
+ "headAccessoryPigEarsNotes": "",
+ "headAccessoryTigerEarsText": "",
+ "headAccessoryTigerEarsNotes": "",
+ "headAccessoryWolfEarsText": "",
+ "headAccessoryWolfEarsNotes": "",
+ "headAccessoryBlackHeadbandText": "",
+ "headAccessoryBlackHeadbandNotes": "",
+ "headAccessoryBlueHeadbandText": "",
+ "headAccessoryBlueHeadbandNotes": "",
+ "headAccessoryGreenHeadbandText": "",
+ "headAccessoryGreenHeadbandNotes": "",
+ "headAccessoryPinkHeadbandText": "",
+ "headAccessoryPinkHeadbandNotes": "",
+ "headAccessoryRedHeadbandText": "",
+ "headAccessoryRedHeadbandNotes": "",
+ "headAccessoryWhiteHeadbandText": "",
+ "headAccessoryWhiteHeadbandNotes": "",
+ "headAccessoryYellowHeadbandText": "",
+ "headAccessoryYellowHeadbandNotes": "",
+ "headAccessoryMystery201403Text": "",
+ "headAccessoryMystery201403Notes": "",
+ "headAccessoryMystery201404Text": "",
+ "headAccessoryMystery201404Notes": "",
+ "headAccessoryMystery201409Text": "",
+ "headAccessoryMystery201409Notes": "",
+ "headAccessoryMystery201502Text": "",
+ "headAccessoryMystery201502Notes": "",
+ "headAccessoryMystery201510Text": "",
+ "headAccessoryMystery201510Notes": "",
+ "headAccessoryMystery201801Text": "",
+ "headAccessoryMystery201801Notes": "",
+ "headAccessoryMystery201804Text": "",
+ "headAccessoryMystery201804Notes": "",
+ "headAccessoryMystery201812Text": "",
+ "headAccessoryMystery201812Notes": "",
+ "headAccessoryMystery301405Text": "",
+ "headAccessoryMystery301405Notes": "",
+ "headAccessoryArmoireComicalArrowText": "",
+ "headAccessoryArmoireComicalArrowNotes": "",
+ "headAccessoryArmoireGogglesOfBookbindingText": "",
+ "headAccessoryArmoireGogglesOfBookbindingNotes": "",
+ "eyewear": "",
+ "eyewearCapitalized": "",
+ "eyewearBase0Text": "",
+ "eyewearBase0Notes": "",
+ "eyewearSpecialBlackTopFrameText": "",
+ "eyewearSpecialBlackTopFrameNotes": "",
+ "eyewearSpecialBlueTopFrameText": "",
+ "eyewearSpecialBlueTopFrameNotes": "",
+ "eyewearSpecialGreenTopFrameText": "",
+ "eyewearSpecialGreenTopFrameNotes": "",
+ "eyewearSpecialPinkTopFrameText": "",
+ "eyewearSpecialPinkTopFrameNotes": "",
+ "eyewearSpecialRedTopFrameText": "",
+ "eyewearSpecialRedTopFrameNotes": "",
+ "eyewearSpecialWhiteTopFrameText": "",
+ "eyewearSpecialWhiteTopFrameNotes": "",
+ "eyewearSpecialYellowTopFrameText": "",
+ "eyewearSpecialYellowTopFrameNotes": "",
+ "eyewearSpecialAetherMaskText": "",
+ "eyewearSpecialAetherMaskNotes": "",
+ "eyewearSpecialSummerRogueText": "",
+ "eyewearSpecialSummerRogueNotes": "",
+ "eyewearSpecialSummerWarriorText": "",
+ "eyewearSpecialSummerWarriorNotes": "",
+ "eyewearSpecialWonderconRedText": "",
+ "eyewearSpecialWonderconRedNotes": "",
+ "eyewearSpecialWonderconBlackText": "",
+ "eyewearSpecialWonderconBlackNotes": "",
+ "eyewearMystery201503Text": "",
+ "eyewearMystery201503Notes": "",
+ "eyewearMystery201506Text": "",
+ "eyewearMystery201506Notes": "",
+ "eyewearMystery201507Text": "",
+ "eyewearMystery201507Notes": "",
+ "eyewearMystery201701Text": "",
+ "eyewearMystery201701Notes": "",
+ "eyewearMystery301404Text": "",
+ "eyewearMystery301404Notes": "",
+ "eyewearMystery301405Text": "",
+ "eyewearMystery301405Notes": "",
+ "eyewearMystery301703Text": "",
+ "eyewearMystery301703Notes": "",
+ "eyewearArmoirePlagueDoctorMaskText": "",
+ "eyewearArmoirePlagueDoctorMaskNotes": "",
+ "eyewearArmoireGoofyGlassesText": "",
+ "eyewearArmoireGoofyGlassesNotes": "",
+ "twoHandedItem": ""
+}
diff --git a/website/common/locales/eu/generic.json b/website/common/locales/eu/generic.json
index b620494f90..5abddd00b0 100755
--- a/website/common/locales/eu/generic.json
+++ b/website/common/locales/eu/generic.json
@@ -1,294 +1,296 @@
{
- "languageName": "English",
- "stringNotFound": "String '<%= string %>' not found.",
- "titleIndex": "Habitica | Your Life The Role Playing Game",
+ "languageName": "Euskara",
+ "stringNotFound": "Ez da aurkitu '<%= string %>' katea.",
+ "titleIndex": "Habitica | Zure bizitzaren rol-jokoa",
"habitica": "Habitica",
- "habiticaLink": "Habitica",
- "onward": "Onward!",
- "done": "Done",
- "gotIt": "Got it!",
- "titleTasks": "Tasks",
- "titleAvatar": "Avatar",
- "titleBackgrounds": "Backgrounds",
- "titleStats": "Stats",
- "titleAchievs": "Achievements",
- "titleProfile": "Profile",
- "titleInbox": "Inbox",
- "titleTavern": "Tavern",
- "titleParty": "Party",
- "titleHeroes": "Hall of Heroes",
- "titlePatrons": "Hall of Patrons",
- "titleGuilds": "Guilds",
- "titleChallenges": "Challenges",
- "titleDrops": "Market",
- "titleQuests": "Quests",
- "titlePets": "Pets",
- "titleMounts": "Mounts",
- "titleEquipment": "Equipment",
- "titleTimeTravelers": "Time Travelers",
- "titleSeasonalShop": "Seasonal Shop",
- "titleSettings": "Settings",
- "saveEdits": "Save Edits",
- "showMore": "Show More",
- "showLess": "Show Less",
- "expandToolbar": "Expand Toolbar",
- "collapseToolbar": "Collapse Toolbar",
- "markdownHelpLink": "Markdown formatting help",
- "showFormattingHelp": "Show formatting help",
- "hideFormattingHelp": "Hide formatting help",
- "youType": "You type:",
- "youSee": "You see:",
- "italics": "*Italics*",
- "bold": "**Bold**",
- "strikethrough": "~~Strikethrough~~",
+ "habiticaLink": "Habitica",
+ "onward": "Aurrera!",
+ "done": "Eginda",
+ "gotIt": "Ados!",
+ "titleTasks": "Zereginak",
+ "titleAvatar": "Avatarra",
+ "titleBackgrounds": "Atzeko planoak",
+ "titleStats": "Atributuak",
+ "titleAchievs": "Lorpenak",
+ "titleProfile": "Profila",
+ "titleInbox": "Sarrerako ontzia",
+ "titleTavern": "Taberna",
+ "titleParty": "Taldea",
+ "titleHeroes": "Heroien aretoa",
+ "titlePatrons": "Babesleen aretoa",
+ "titleGuilds": "Gremioak",
+ "titleChallenges": "Erronkak",
+ "titleDrops": "Merkatua",
+ "titleQuests": "Misioak",
+ "titlePets": "Maskotak",
+ "titleMounts": "Animalia helduak",
+ "titleEquipment": "Ekipamendua",
+ "titleTimeTravelers": "Denbora-bidaiariak",
+ "titleSeasonalShop": "Sasoiko denda",
+ "titleSettings": "Ezarpenak",
+ "saveEdits": "Gorde aldaketak",
+ "showMore": "Gehiago erakutsi",
+ "showLess": "Gutxiago erakutsi",
+ "expandToolbar": "Zabaldu tresna-barra",
+ "collapseToolbar": "Tolestu tresna-barra",
+ "markdownHelpLink": "Markdown formatuari buruzko laguntza",
+ "showFormattingHelp": "Erakutsi formatuari buruzko laguntza",
+ "hideFormattingHelp": "Ezkutatu formatuari buruzko laguntza",
+ "youType": "Hau idazten baduzu:",
+ "youSee": "Hau ikusiko duzu:",
+ "italics": "*Letra etzana*",
+ "bold": "**Letra lodia**",
+ "strikethrough": "~~Testu marratua~~",
"emojiExample": ":smile:",
- "markdownLinkEx": "[Habitica is great!](https://habitica.com)",
- "markdownImageEx": "",
- "unorderedListHTML": "+ First item + Second item + Third item",
- "unorderedListMarkdown": "+ First item\n+ Second item\n+ Third item",
- "code": "`code`",
- "achievements": "Achievements",
- "basicAchievs": "Basic Achievements",
- "seasonalAchievs": "Seasonal Achievements",
- "specialAchievs": "Special Achievements",
- "modalAchievement": "Achievement!",
- "special": "Special",
- "site": "Site",
- "help": "Help",
- "user": "User",
- "market": "Market",
- "groupPlansTitle": "Group Plans",
- "newGroupTitle": "New Group",
- "subscriberItem": "Mystery Item",
- "newSubscriberItem": "You have new Mystery Items",
- "subscriberItemText": "Each month, subscribers will receive a mystery item. This is usually released about one week before the end of the month. See the wiki's 'Mystery Item' page for more information.",
- "all": "All",
- "none": "None",
- "more": "<%= count %> more",
- "and": "and",
- "loginSuccess": "Login successful!",
- "youSure": "Are you sure?",
- "submit": "Submit",
- "close": "Close",
- "saveAndClose": "Save & Close",
- "saveAndConfirm": "Save & Confirm",
- "cancel": "Cancel",
- "ok": "OK",
- "add": "Add",
- "undo": "Undo",
- "continue": "Continue",
- "accept": "Accept",
- "reject": "Reject",
- "neverMind": "Never mind",
- "buyMoreGems": "Buy More Gems",
- "notEnoughGems": "Not enough Gems",
- "alreadyHave": "Whoops! You already have this item. No need to buy it again!",
- "delete": "Delete",
- "gemsPopoverTitle": "Gems",
- "gems": "Gems",
- "gemButton": "You have <%= number %> Gems.",
- "needMoreGems": "Need More Gems?",
- "needMoreGemsInfo": "Purchase Gems now, or become a subscriber to buy Gems with Gold, get monthly mystery items, enjoy increased drop caps and more!",
- "moreInfo": "More Info",
- "moreInfoChallengesURL": "http://habitica.wikia.com/wiki/Challenges",
- "moreInfoTagsURL": "http://habitica.wikia.com/wiki/Tags",
- "showMoreMore": "(show more)",
- "showMoreLess": "(show less)",
- "gemsWhatFor": "Click to buy Gems! Gems let you purchase special items like Quests, avatar customizations, and seasonal equipment.",
- "veteran": "Veteran",
- "veteranText": "Has weathered Habit The Grey (our pre Angular website), and has gained many battle-scars from its bugs.",
- "originalUser": "Original User!",
- "originalUserText": "One of the very original early adopters. Talk about alpha tester!",
- "habitBirthday": "Habitica Birthday Bash",
- "habitBirthdayText": "Celebrated the Habitica Birthday Bash!",
- "habitBirthdayPluralText": "Celebrated <%= count %> Habitica Birthday Bashes!",
- "habiticaDay": "Habitica Naming Day",
- "habiticaDaySingularText": "Celebrated Habitica's Naming Day! Thanks for being a fantastic user.",
- "habiticaDayPluralText": "Celebrated <%= count %> Naming Days! Thanks for being a fantastic user.",
- "achievementDilatory": "Savior of Dilatory",
- "achievementDilatoryText": "Helped defeat the Dread Drag'on of Dilatory during the 2014 Summer Splash Event!",
- "costumeContest": "Costume Contestant",
- "costumeContestText": "Participated in the Habitoween Costume Contest. See some of the awesome entries at blog.habitrpg.com!",
- "costumeContestTextPlural": "Participated in <%= count %> Habitoween Costume Contests. See some of the awesome entries at blog.habitrpg.com!",
- "memberSince": "- Member since",
- "lastLoggedIn": "- Last logged in",
- "notPorted": "This feature is not yet ported from the original site.",
- "buyThis": "Buy this <%= text %> with <%= price %> of your <%= gems %> Gems?",
- "noReachServer": "Server not currently reachable, try again later",
- "errorUpCase": "ERROR:",
- "newPassSent": "If we have your email on file, instructions for setting a new password have been sent to your email.",
- "serverUnreach": "Server currently unreachable.",
- "requestError": "Yikes, an error occurred! Please reload the page, your last action may not have been saved correctly.",
- "seeConsole": "If the error persists, please report it at Help > Report a Bug. If you're familiar with your browser's console, please include any error messages.",
- "error": "Error",
- "menu": "Menu",
- "notifications": "Notifications",
- "noNotifications": "You're all caught up!",
- "noNotificationsText": "The notification fairies give you a raucous round of applause! Well done!",
- "clear": "Clear",
- "endTour": "End Tour",
- "audioTheme": "Audio Theme",
- "audioTheme_off": "Off",
- "audioTheme_danielTheBard": "Daniel The Bard",
- "audioTheme_wattsTheme": "Watts' Theme",
- "audioTheme_gokulTheme": "Gokul Theme",
- "audioTheme_luneFoxTheme": "LuneFox's Theme",
- "audioTheme_rosstavoTheme": "Rosstavo's Theme",
- "audioTheme_dewinTheme": "Dewin's Theme",
- "audioTheme_airuTheme": "Airu's Theme",
- "audioTheme_beatscribeNesTheme": "Beatscribe's NES Theme",
- "audioTheme_arashiTheme": "Arashi's Theme",
- "audioTheme_triumphTheme": "Triumph Theme",
- "audioTheme_lunasolTheme": "Lunasol Theme",
- "audioTheme_spacePenguinTheme": "SpacePenguin's Theme",
- "audioTheme_maflTheme": "MAFL Theme",
- "audioTheme_pizildenTheme": "Pizilden's Theme",
- "audioTheme_farvoidTheme": "Farvoid Theme",
- "askQuestion": "Ask a Question",
- "reportBug": "Report a Bug",
- "HabiticaWiki": "The Habitica Wiki",
- "HabiticaWikiFrontPage": "http://habitica.wikia.com/wiki/Habitica_Wiki",
- "contributeToHRPG": "Contribute to Habitica",
- "overview": "Overview for New Users",
- "January": "January",
- "February": "February",
- "March": "March",
- "April": "April",
- "May": "May",
- "June": "June",
- "July": "July",
- "August": "August",
- "September": "September",
- "October": "October",
- "November": "November",
- "December": "December",
- "dateFormat": "Date Format",
- "achievementStressbeast": "Savior of Stoïkalm",
- "achievementStressbeastText": "Helped defeat the Abominable Stressbeast during the 2014 Winter Wonderland Event!",
- "achievementBurnout": "Savior of the Flourishing Fields",
- "achievementBurnoutText": "Helped defeat Burnout and restore the Exhaust Spirits during the 2015 Fall Festival Event!",
- "achievementBewilder": "Savior of Mistiflying",
- "achievementBewilderText": "Helped defeat the Be-Wilder during the 2016 Spring Fling Event!",
- "achievementDysheartener": "Savior of the Shattered",
- "achievementDysheartenerText": "Helped defeat the Dysheartener during the 2018 Valentine's Event!",
- "checkOutProgress": "Check out my progress in Habitica!",
- "cards": "Cards",
- "sentCardToUser": "You sent a card to <%= profileName %>",
- "cardReceivedFrom": "<%= cardType %> from <%= userName %>",
- "cardReceived": "You received a <%= card %>",
- "greetingCard": "Greeting Card",
- "greetingCardExplanation": "You both receive the Cheery Chum achievement!",
- "greetingCardNotes": "Send a greeting card to a party member.",
- "greeting0": "Hi there!",
- "greeting1": "Just saying hello :)",
- "greeting2": "`waves frantically`",
- "greeting3": "Hey you!",
- "greetingCardAchievementTitle": "Cheery Chum",
- "greetingCardAchievementText": "Hey! Hi! Hello! Sent or received <%= count %> greeting cards.",
- "thankyouCard": "Thank-You Card",
- "thankyouCardExplanation": "You both receive the Greatly Grateful achievement!",
- "thankyouCardNotes": "Send a Thank-You card to a party member.",
- "thankyou0": "Thank you very much!",
- "thankyou1": "Thank you, thank you, thank you!",
- "thankyou2": "Sending you a thousand thanks.",
- "thankyou3": "I'm very grateful - thank you!",
- "thankyouCardAchievementTitle": "Greatly Grateful",
- "thankyouCardAchievementText": "Thanks for being thankful! Sent or received <%= count %> Thank-You cards.",
- "birthdayCard": "Birthday Card",
- "birthdayCardExplanation": "You both receive the Birthday Bonanza achievement!",
- "birthdayCardNotes": "Send a birthday card to a party member.",
- "birthday0": "Happy birthday to you!",
- "birthdayCardAchievementTitle": "Birthday Bonanza",
- "birthdayCardAchievementText": "Many happy returns! Sent or received <%= count %> birthday cards.",
- "congratsCard": "Congratulations Card",
- "congratsCardExplanation": "You both receive the Congratulatory Companion achievement!",
- "congratsCardNotes": "Send a Congratulations card to a party member.",
- "congrats0": "Congratulations on your success!",
- "congrats1": "I'm so proud of you!",
- "congrats2": "Well done!",
- "congrats3": "A round of applause for you!",
- "congrats4": "Bask in your well-deserved success!",
- "congratsCardAchievementTitle": "Congratulatory Companion",
- "congratsCardAchievementText": "It's great to celebrate your friends' achievements! Sent or received <%= count %> congratulations cards.",
- "getwellCard": "Get Well Card",
- "getwellCardExplanation": "You both receive the Caring Confidant achievement!",
- "getwellCardNotes": "Send a Get Well card to a party member.",
- "getwell0": "Hope you feel better soon!",
- "getwell1": "Take care! <3",
- "getwell2": "You're in my thoughts!",
- "getwell3": "Sorry you're not feeling your best!",
- "getwellCardAchievementTitle": "Caring Confidant",
- "getwellCardAchievementText": "Well-wishes are always appreciated. Sent or received <%= count %> get well cards.",
- "goodluckCard": "Good Luck Card",
- "goodluckCardExplanation": "You both receive the Lucky Letter achievement!",
- "goodluckCardNotes": "Send a good luck card to a party member.",
- "goodluck0": "May luck always follow you!",
- "goodluck1": "Wishing you lots of luck!",
- "goodluck2": "I hope luck is on your side today and always!!",
- "goodluckCardAchievementTitle": "Lucky Letter",
- "goodluckCardAchievementText": "Wishes for good luck are great encouragement! Sent or received <%= count %> good luck cards.",
- "streakAchievement": "You earned a streak achievement!",
- "firstStreakAchievement": "21-Day Streak",
- "streakAchievementCount": "<%= streaks %> 21-Day Streaks",
- "twentyOneDays": "You've completed your Daily for 21 days in a row!",
- "dontBreakStreak": "Amazing job. Don't break the streak!",
- "dontStop": "Don't Stop Now!",
- "levelUpShare": "I leveled up in Habitica by improving my real-life habits!",
- "questUnlockShare": "I unlocked a new quest in Habitica!",
- "hatchPetShare": "I hatched a new pet by completing my real-life tasks!",
- "raisePetShare": "I raised a pet into a mount by completing my real-life tasks!",
- "wonChallengeShare": "I won a challenge in Habitica!",
- "achievementShare": "I earned a new achievement in Habitica!",
- "orderBy": "Order By <%= item %>",
- "you": "(you)",
- "enableDesktopNotifications": "Enable Desktop Notifications",
- "online": "online",
- "onlineCount": "<%= count %> online",
- "loading": "Loading...",
- "userIdRequired": "User ID is required",
- "resetFilters": "Clear all filters",
- "applyFilters": "Apply Filters",
- "wantToWorkOn": "I want to work on:",
- "categories": "Categories",
- "habiticaOfficial": "Habitica Official",
- "animals": "Animals",
- "artDesign": "Art & Design",
- "booksWriting": "Books & Writing",
- "comicsHobbies": "Comics & Hobbies",
- "diyCrafts": "DIY & Crafts",
- "education": "Education",
- "foodCooking": "Food & Cooking",
- "healthFitness": "Health & Fitness",
- "music": "Music",
- "relationship": "Relationships",
- "scienceTech": "Science & Technology",
- "exercise": "Exercise",
- "creativity": "Creativity",
- "budgeting": "Budgeting",
- "health_wellness": "Health & Wellness",
- "self_care": "Self-Care",
- "habitica_official": "Habitica Official",
- "academics": "Academics",
- "advocacy_causes": "Advocacy + Causes",
- "entertainment": "Entertainment",
- "finance": "Finance",
- "health_fitness": "Health + Fitness",
- "hobbies_occupations": "Hobbies + Occupations",
- "location_based": "Location-based",
- "mental_health": "Mental Health + Self-Care",
- "getting_organized": "Getting Organized",
- "self_improvement": "Self-Improvement",
- "spirituality": "Spirituality",
- "time_management": "Time-Management + Accountability",
- "recovery_support_groups": "Recovery + Support Groups",
- "dismissAll": "Dismiss All",
- "messages": "Messages",
- "emptyMessagesLine1": "You don't have any messages",
- "emptyMessagesLine2": "Send a message to start a conversation!",
- "userSentMessage": "<%= user %> sent you a message",
- "letsgo": "Let's Go!",
- "selected": "Selected",
- "howManyToBuy": "How many would you like to buy?",
- "habiticaHasUpdated": "There is a new Habitica update. Refresh to get the latest version!",
- "contactForm": "Contact the Moderation Team"
-}
\ No newline at end of file
+ "markdownLinkEx": "[Habitica zoragarria da!](https://habitica.com)",
+ "markdownImageEx": "",
+ "unorderedListHTML": "+ Lehenengo elementua + Bigarren elementua + Hirugarren elementua",
+ "unorderedListMarkdown": "+ Lehenengo elementua\n+ Bigarren elementua\n+ Hirugarren elementua",
+ "code": "`kodea`",
+ "achievements": "Lorpenak",
+ "basicAchievs": "Oinarrizko lorpenak",
+ "seasonalAchievs": "Sasoiko lorpenak",
+ "specialAchievs": "Lorpen bereziak",
+ "modalAchievement": "Lorpena!",
+ "special": "",
+ "site": "",
+ "help": "",
+ "user": "",
+ "market": "",
+ "groupPlansTitle": "",
+ "newGroupTitle": "",
+ "subscriberItem": "",
+ "newSubscriberItem": "",
+ "subscriberItemText": "",
+ "all": "",
+ "none": "",
+ "more": "",
+ "and": "",
+ "loginSuccess": "",
+ "youSure": "",
+ "submit": "",
+ "close": "",
+ "saveAndClose": "",
+ "saveAndConfirm": "",
+ "cancel": "",
+ "ok": "",
+ "add": "",
+ "undo": "",
+ "continue": "",
+ "accept": "",
+ "reject": "",
+ "neverMind": "",
+ "buyMoreGems": "",
+ "notEnoughGems": "",
+ "alreadyHave": "",
+ "delete": "",
+ "gemsPopoverTitle": "",
+ "gems": "",
+ "gemButton": "",
+ "needMoreGems": "",
+ "needMoreGemsInfo": "",
+ "moreInfo": "",
+ "moreInfoChallengesURL": "",
+ "moreInfoTagsURL": "",
+ "showMoreMore": "",
+ "showMoreLess": "",
+ "gemsWhatFor": "",
+ "veteran": "",
+ "veteranText": "",
+ "originalUser": "",
+ "originalUserText": "",
+ "habitBirthday": "",
+ "habitBirthdayText": "",
+ "habitBirthdayPluralText": "",
+ "habiticaDay": "",
+ "habiticaDaySingularText": "",
+ "habiticaDayPluralText": "",
+ "achievementDilatory": "",
+ "achievementDilatoryText": "",
+ "costumeContest": "",
+ "costumeContestText": "",
+ "costumeContestTextPlural": "",
+ "memberSince": "",
+ "lastLoggedIn": "",
+ "notPorted": "",
+ "buyThis": "",
+ "noReachServer": "",
+ "errorUpCase": "",
+ "newPassSent": "",
+ "serverUnreach": "",
+ "requestError": "",
+ "seeConsole": "",
+ "error": "",
+ "menu": "",
+ "notifications": "",
+ "noNotifications": "",
+ "noNotificationsText": "",
+ "clear": "",
+ "endTour": "",
+ "audioTheme": "",
+ "audioTheme_off": "",
+ "audioTheme_danielTheBard": "",
+ "audioTheme_wattsTheme": "",
+ "audioTheme_gokulTheme": "",
+ "audioTheme_luneFoxTheme": "",
+ "audioTheme_rosstavoTheme": "",
+ "audioTheme_dewinTheme": "",
+ "audioTheme_airuTheme": "",
+ "audioTheme_beatscribeNesTheme": "",
+ "audioTheme_arashiTheme": "",
+ "audioTheme_triumphTheme": "",
+ "audioTheme_lunasolTheme": "",
+ "audioTheme_spacePenguinTheme": "",
+ "audioTheme_maflTheme": "",
+ "audioTheme_pizildenTheme": "",
+ "audioTheme_farvoidTheme": "",
+ "askQuestion": "",
+ "reportBug": "",
+ "HabiticaWiki": "",
+ "HabiticaWikiFrontPage": "",
+ "contributeToHRPG": "",
+ "overview": "",
+ "January": "",
+ "February": "",
+ "March": "",
+ "April": "",
+ "May": "",
+ "June": "",
+ "July": "",
+ "August": "",
+ "September": "",
+ "October": "",
+ "November": "",
+ "December": "",
+ "dateFormat": "",
+ "achievementStressbeast": "",
+ "achievementStressbeastText": "",
+ "achievementBurnout": "",
+ "achievementBurnoutText": "",
+ "achievementBewilder": "",
+ "achievementBewilderText": "",
+ "achievementDysheartener": "",
+ "achievementDysheartenerText": "",
+ "checkOutProgress": "",
+ "cards": "",
+ "sentCardToUser": "",
+ "cardReceivedFrom": "",
+ "cardReceived": "",
+ "greetingCard": "",
+ "greetingCardExplanation": "",
+ "greetingCardNotes": "",
+ "greeting0": "",
+ "greeting1": "",
+ "greeting2": "",
+ "greeting3": "",
+ "greetingCardAchievementTitle": "",
+ "greetingCardAchievementText": "",
+ "thankyouCard": "",
+ "thankyouCardExplanation": "",
+ "thankyouCardNotes": "",
+ "thankyou0": "",
+ "thankyou1": "",
+ "thankyou2": "",
+ "thankyou3": "",
+ "thankyouCardAchievementTitle": "",
+ "thankyouCardAchievementText": "",
+ "birthdayCard": "",
+ "birthdayCardExplanation": "",
+ "birthdayCardNotes": "",
+ "birthday0": "",
+ "birthdayCardAchievementTitle": "",
+ "birthdayCardAchievementText": "",
+ "congratsCard": "",
+ "congratsCardExplanation": "",
+ "congratsCardNotes": "",
+ "congrats0": "",
+ "congrats1": "",
+ "congrats2": "",
+ "congrats3": "",
+ "congrats4": "",
+ "congratsCardAchievementTitle": "",
+ "congratsCardAchievementText": "",
+ "getwellCard": "",
+ "getwellCardExplanation": "",
+ "getwellCardNotes": "",
+ "getwell0": "",
+ "getwell1": "",
+ "getwell2": "",
+ "getwell3": "",
+ "getwellCardAchievementTitle": "",
+ "getwellCardAchievementText": "",
+ "goodluckCard": "",
+ "goodluckCardExplanation": "",
+ "goodluckCardNotes": "",
+ "goodluck0": "",
+ "goodluck1": "",
+ "goodluck2": "",
+ "goodluckCardAchievementTitle": "",
+ "goodluckCardAchievementText": "",
+ "streakAchievement": "",
+ "firstStreakAchievement": "",
+ "streakAchievementCount": "",
+ "twentyOneDays": "",
+ "dontBreakStreak": "",
+ "dontStop": "",
+ "levelUpShare": "",
+ "questUnlockShare": "",
+ "hatchPetShare": "",
+ "raisePetShare": "",
+ "wonChallengeShare": "",
+ "achievementShare": "",
+ "orderBy": "",
+ "you": "",
+ "enableDesktopNotifications": "",
+ "online": "",
+ "onlineCount": "",
+ "loading": "",
+ "userIdRequired": "",
+ "resetFilters": "",
+ "applyFilters": "",
+ "wantToWorkOn": "",
+ "categories": "",
+ "habiticaOfficial": "",
+ "animals": "",
+ "artDesign": "",
+ "booksWriting": "",
+ "comicsHobbies": "",
+ "diyCrafts": "",
+ "education": "",
+ "foodCooking": "",
+ "healthFitness": "",
+ "music": "",
+ "relationship": "",
+ "scienceTech": "",
+ "exercise": "",
+ "creativity": "",
+ "budgeting": "",
+ "health_wellness": "",
+ "self_care": "",
+ "habitica_official": "",
+ "academics": "",
+ "advocacy_causes": "",
+ "entertainment": "",
+ "finance": "",
+ "health_fitness": "",
+ "hobbies_occupations": "",
+ "location_based": "",
+ "mental_health": "",
+ "getting_organized": "",
+ "self_improvement": "",
+ "spirituality": "",
+ "time_management": "",
+ "recovery_support_groups": "",
+ "dismissAll": "",
+ "messages": "",
+ "emptyMessagesLine1": "",
+ "emptyMessagesLine2": "",
+ "userSentMessage": "",
+ "letsgo": "",
+ "selected": "",
+ "howManyToBuy": "",
+ "habiticaHasUpdated": "",
+ "contactForm": "",
+ "options": "Aukerak",
+ "finish": "Amaitu"
+}
diff --git a/website/common/locales/eu/groups.json b/website/common/locales/eu/groups.json
index 6e6e551019..4ebba7285d 100755
--- a/website/common/locales/eu/groups.json
+++ b/website/common/locales/eu/groups.json
@@ -1,483 +1,483 @@
{
- "tavern": "Tavern Chat",
- "tavernChat": "Tavern Chat",
- "innCheckOut": "Check Out of Inn",
- "innCheckIn": "Rest in the Inn",
- "innText": "You're resting in the Inn! While checked-in, your Dailies won't hurt you at the day's end, but they will still refresh every day. Be warned: If you are participating in a Boss Quest, the Boss will still damage you for your Party mates' missed Dailies unless they are also in the Inn! Also, your own damage to the Boss (or items collected) will not be applied until you check out of the Inn.",
- "innTextBroken": "You're resting in the Inn, I guess... While checked-in, your Dailies won't hurt you at the day's end, but they will still refresh every day... If you are participating in a Boss Quest, the Boss will still damage you for your Party mates' missed Dailies... unless they are also in the Inn... Also, your own damage to the Boss (or items collected) will not be applied until you check out of the Inn... so tired...",
- "innCheckOutBanner": "You are currently checked into the Inn. Your Dailies won't damage you and you won't make progress towards Quests.",
- "innCheckOutBannerShort": "You are checked into the Inn.",
- "resumeDamage": "Resume Damage",
- "helpfulLinks": "Helpful Links",
- "communityGuidelinesLink": "Community Guidelines",
- "lookingForGroup": "Looking for Group (Party Wanted) Posts",
- "dataDisplayTool": "Data Display Tool",
- "reportProblem": "Report a Bug",
- "requestFeature": "Request a Feature",
- "askAQuestion": "Ask a Question",
- "askQuestionGuild": "Ask a Question (Habitica Help guild)",
- "contributing": "Contributing",
- "faq": "FAQ",
- "lfgPosts": "Looking for Group (Party Wanted) Posts",
- "tutorial": "Tutorial",
- "glossary": "Glossary",
- "wiki": "Wiki",
- "wikiLink": "Wiki",
- "reportAP": "Report a Problem",
- "requestAF": "Request a Feature",
- "community": "Community Forum",
- "dataTool": "Data Display Tool",
- "resources": "Resources",
- "askQuestionNewbiesGuild": "Ask a Question (Habitica Help guild)",
- "tavernAlert1": "To report a bug, visit",
- "tavernAlert2": "the Report a Bug Guild",
- "moderatorIntro1": "Tavern and guild moderators are:",
- "communityGuidelines": "Community Guidelines",
- "communityGuidelinesRead1": "Please read our",
- "communityGuidelinesRead2": "before chatting.",
- "bannedWordUsed": "Oops! Looks like this post contains a swearword, religious oath, or reference to an addictive substance or adult topic (<%= swearWordsUsed %>). Habitica has users from all backgrounds, so we keep our chat very clean. Feel free to edit your message so you can post it!",
- "bannedSlurUsed": "Your post contained inappropriate language, and your chat privileges have been revoked.",
- "party": "Party",
- "createAParty": "Create A Party",
- "updatedParty": "Party settings updated.",
- "errorNotInParty": "You are not in a Party",
- "noPartyText": "You are either not in a Party or your Party is taking a while to load. You can either create one and invite friends, or if you want to join an existing Party, have them enter your Unique User ID below and then come back here to look for the invitation:",
- "LFG": "To advertise your new Party or find one to join, go to the <%= linkStart %>Party Wanted (Looking for Group)<%= linkEnd %> Guild.",
- "wantExistingParty": "Want to join an existing Party? Go to the <%= linkStart %>Party Wanted Guild<%= linkEnd %> and post this User ID:",
- "joinExistingParty": "Join Someone Else's Party",
- "usernameCopied": "Username copied to clipboard.",
- "needPartyToStartQuest": "Whoops! You need to create or join a Party before you can start a quest!",
- "createGroupPlan": "Create",
- "create": "Create",
- "userId": "User ID",
- "invite": "Invite",
- "leave": "Leave",
- "invitedToParty": "You were invited to join the Party <%= party %>",
- "invitedToPrivateGuild": "You were invited to join the private Guild <%= guild %>",
- "invitedToPublicGuild": "You were invited to join the Guild <%= guild %>",
- "partyInvitationsText": "You have <%= numberInvites %> Party invitations! Choose wisely, because you can only be in one Party at a time.",
- "joinPartyConfirmationText": "Are you sure you want to join the Party \"<%= partyName %>\"? You can only be in one Party at a time. If you join, all other Party invitations will be rejected.",
- "invitationAcceptedHeader": "Your Invitation has been Accepted",
- "invitationAcceptedBody": "<%= username %> accepted your invitation to <%= groupName %>!",
- "joinNewParty": "Join New Party",
- "declineInvitation": "Decline Invitation",
- "partyLoading1": "Your Party is being summoned. Please wait...",
- "partyLoading2": "Your Party is coming in from battle. Please wait...",
- "partyLoading3": "Your Party is gathering. Please wait...",
- "partyLoading4": "Your Party is materializing. Please wait...",
- "systemMessage": "System Message",
- "newMsgGuild": "<%= name %> has new posts",
- "newMsgParty": "Your Party, <%= name %>, has new posts",
- "chat": "Chat",
- "sendChat": "Send Chat",
- "toolTipMsg": "Fetch Recent Messages",
- "sendChatToolTip": "You can send a chat from the keyboard by tabbing to the 'Send Chat' button and pressing Enter or by pressing Control (Command on a Mac) + Enter.",
- "syncPartyAndChat": "Sync Party and Chat",
- "guildBankPop1": "Guild Bank",
- "guildBankPop2": "Gems which your guild leader can use for challenge prizes.",
- "guildGems": "Guild Gems",
- "group": "Group",
- "editGroup": "Edit Group",
- "newGroupName": "<%= groupType %> Name",
- "groupName": "Group Name",
- "groupLeader": "Group Leader",
- "groupID": "Group ID",
- "groupDescr": "Description shown in public Guilds list (Markdown OK)",
- "logoUrl": "Logo URL",
- "assignLeader": "Assign Group Leader",
- "members": "Members",
- "memberList": "Member List",
- "partyList": "Order for Party members in header",
- "banTip": "Boot Member",
- "moreMembers": "more members",
- "invited": "Invited",
- "leaderMsg": "Message from group leader (Markdown OK)",
- "name": "Name",
- "description": "Description",
- "public": "Public",
- "inviteOnly": "Invite Only",
- "gemCost": "The Gem cost promotes high quality Guilds, and is transferred into your Guild's bank for use as prizes in Guild Challenges!",
- "search": "Search",
- "publicGuilds": "Public Guilds",
- "createGuild": "Create Guild",
- "createGuild2": "Create",
- "guild": "Guild",
- "guilds": "Guilds",
- "guildsLink": "Guilds",
- "sureKick": "Do you really want to remove this member from the Party/Guild?",
- "optionalMessage": "Optional message",
- "yesRemove": "Yes, remove them",
- "foreverAlone": "Can't like your own message. Don't be that person.",
- "sortBackground": "Sort by Background",
- "sortClass": "Sort by Class",
- "sortDateJoined": "Sort by Join Date",
- "sortLogin": "Sort by Login Date",
- "sortLevel": "Sort by Level",
- "sortName": "Sort by Name",
- "sortTier": "Sort by Tier",
- "ascendingAbbrev": "Asc",
- "descendingAbbrev": "Desc",
- "applySortToHeader": "Apply Sort Options to Party Header",
- "confirmGuild": "Create Guild for 4 Gems?",
- "leaveGroupCha": "Leave Guild challenges and...",
- "confirm": "Confirm",
- "leaveGroup": "Leave Guild",
- "leavePartyCha": "Leave Party challenges and...",
- "leaveParty": "Leave Party",
- "sendPM": "Send private message",
- "send": "Send",
- "messageSentAlert": "Message sent",
- "pmHeading": "Private message to <%= name %>",
- "pmsMarkedRead": "Your Private Messages have been marked as read",
- "possessiveParty": "<%= name %>'s Party",
- "clearAll": "Delete All Messages",
- "confirmDeleteAllMessages": "Are you sure you want to delete all messages in your inbox? Other users will still see messages you have sent to them.",
- "PMPlaceholderTitle": "Nothing Here Yet",
- "PMPlaceholderDescription": "Select a conversation on the left",
- "PMPlaceholderTitleRevoked": "Your chat privileges have been revoked",
+ "tavern": "",
+ "tavernChat": "",
+ "innCheckOut": "",
+ "innCheckIn": "",
+ "innText": "",
+ "innTextBroken": "",
+ "innCheckOutBanner": "",
+ "innCheckOutBannerShort": "",
+ "resumeDamage": "",
+ "helpfulLinks": "",
+ "communityGuidelinesLink": "",
+ "lookingForGroup": "",
+ "dataDisplayTool": "",
+ "reportProblem": "",
+ "requestFeature": "",
+ "askAQuestion": "",
+ "askQuestionGuild": "",
+ "contributing": "",
+ "faq": "",
+ "lfgPosts": "",
+ "tutorial": "",
+ "glossary": "",
+ "wiki": "",
+ "wikiLink": "",
+ "reportAP": "",
+ "requestAF": "",
+ "community": "",
+ "dataTool": "",
+ "resources": "",
+ "askQuestionNewbiesGuild": "",
+ "tavernAlert1": "",
+ "tavernAlert2": "",
+ "moderatorIntro1": "",
+ "communityGuidelines": "",
+ "communityGuidelinesRead1": "",
+ "communityGuidelinesRead2": "",
+ "bannedWordUsed": "",
+ "bannedSlurUsed": "",
+ "party": "",
+ "createAParty": "",
+ "updatedParty": "",
+ "errorNotInParty": "",
+ "noPartyText": "",
+ "LFG": "",
+ "wantExistingParty": "",
+ "joinExistingParty": "",
+ "usernameCopied": "",
+ "needPartyToStartQuest": "",
+ "createGroupPlan": "",
+ "create": "",
+ "userId": "",
+ "invite": "",
+ "leave": "",
+ "invitedToParty": "",
+ "invitedToPrivateGuild": "",
+ "invitedToPublicGuild": "",
+ "partyInvitationsText": "",
+ "joinPartyConfirmationText": "",
+ "invitationAcceptedHeader": "",
+ "invitationAcceptedBody": "",
+ "joinNewParty": "",
+ "declineInvitation": "",
+ "partyLoading1": "",
+ "partyLoading2": "",
+ "partyLoading3": "",
+ "partyLoading4": "",
+ "systemMessage": "",
+ "newMsgGuild": "",
+ "newMsgParty": "",
+ "chat": "",
+ "sendChat": "",
+ "toolTipMsg": "",
+ "sendChatToolTip": "",
+ "syncPartyAndChat": "",
+ "guildBankPop1": "",
+ "guildBankPop2": "",
+ "guildGems": "",
+ "group": "",
+ "editGroup": "",
+ "newGroupName": "",
+ "groupName": "",
+ "groupLeader": "",
+ "groupID": "",
+ "groupDescr": "",
+ "logoUrl": "",
+ "assignLeader": "",
+ "members": "",
+ "memberList": "",
+ "partyList": "",
+ "banTip": "",
+ "moreMembers": "",
+ "invited": "",
+ "leaderMsg": "",
+ "name": "",
+ "description": "",
+ "public": "",
+ "inviteOnly": "",
+ "gemCost": "",
+ "search": "",
+ "publicGuilds": "",
+ "createGuild": "",
+ "createGuild2": "",
+ "guild": "",
+ "guilds": "",
+ "guildsLink": "",
+ "sureKick": "",
+ "optionalMessage": "",
+ "yesRemove": "",
+ "foreverAlone": "",
+ "sortBackground": "",
+ "sortClass": "",
+ "sortDateJoined": "",
+ "sortLogin": "",
+ "sortLevel": "",
+ "sortName": "",
+ "sortTier": "",
+ "ascendingAbbrev": "",
+ "descendingAbbrev": "",
+ "applySortToHeader": "",
+ "confirmGuild": "",
+ "leaveGroupCha": "",
+ "confirm": "",
+ "leaveGroup": "",
+ "leavePartyCha": "",
+ "leaveParty": "",
+ "sendPM": "",
+ "send": "",
+ "messageSentAlert": "",
+ "pmHeading": "",
+ "pmsMarkedRead": "",
+ "possessiveParty": "",
+ "clearAll": "",
+ "confirmDeleteAllMessages": "",
+ "PMPlaceholderTitle": "",
+ "PMPlaceholderDescription": "",
+ "PMPlaceholderTitleRevoked": "",
"PMPlaceholderDescriptionRevoked": "You are not able to send private messages because your chat privileges have been revoked. If you have questions or concerns about this, please email admin@habitica.com to discuss it with the staff.",
- "PMReceive": "Receive Private Messages",
- "PMEnabledOptPopoverText": "Private Messages are enabled. Users can contact you via your profile.",
- "PMDisabledOptPopoverText": "Private Messages are disabled. Enable this option to allow users to contact you via your profile.",
- "PMDisabledCaptionTitle": "Private Messages are disabled",
- "PMDisabledCaptionText": "You can still send messages, but no one can send them to you.",
- "block": "Block",
- "unblock": "Un-block",
- "blockWarning": "Block - This will have no effect if the player is a moderator now or becomes a moderator in future.",
- "pm-reply": "Send a reply",
- "inbox": "Inbox",
- "messageRequired": "A message is required.",
- "toUserIDRequired": "A User ID is required",
- "gemAmountRequired": "A number of gems is required",
- "notAuthorizedToSendMessageToThisUser": "You can't send a message to this player because they have chosen to block messages.",
- "privateMessageGiftGemsMessage": "Hello <%= receiverName %>, <%= senderName %> has sent you <%= gemAmount %> gems!",
- "privateMessageGiftSubscriptionMessage": "<%= numberOfMonths %> months of subscription!",
- "cannotSendGemsToYourself": "Cannot send gems to yourself. Try a subscription instead.",
- "badAmountOfGemsToSend": "Amount must be within 1 and your current number of gems.",
- "report": "Report",
- "abuseFlag": "Report violation of Community Guidelines",
- "abuseFlagModalHeading": "Report a Violation",
- "abuseFlagModalBody": "Are you sure you want to report this post? You should only report a post that violates the <%= firstLinkStart %>Community Guidelines<%= linkEnd %> and/or <%= secondLinkStart %>Terms of Service<%= linkEnd %>. Inappropriately reporting a post is a violation of the Community Guidelines and may give you an infraction.",
- "abuseFlagModalButton": "Report Violation",
- "abuseReported": "Thank you for reporting this violation. The moderators have been notified.",
- "abuseAlreadyReported": "You have already reported this message.",
- "whyReportingPost": "Why are you reporting this post?",
- "whyReportingPostPlaceholder": "Please help our moderators by letting us know why you are reporting this post for a violation, e.g., spam, swearing, religious oaths, bigotry, slurs, adult topics, violence.",
- "optional": "Optional",
- "needsText": "Please type a message.",
- "needsTextPlaceholder": "Type your message here.",
- "copyMessageAsToDo": "Copy message as To-Do",
- "copyAsTodo": "Copy as To-Do",
- "messageAddedAsToDo": "Message copied as To-Do.",
- "messageWroteIn": "<%= user %> wrote in <%= group %>",
- "msgPreviewHeading": "Message Preview",
- "leaderOnlyChallenges": "Only group leader can create challenges",
- "sendGift": "Send Gift",
- "inviteFriends": "Invite Friends",
- "partyMembersInfo": "Your Party currently has <%= memberCount %> members and <%= invitationCount %> pending invitations. The limit of members in a Party is <%= limitMembers %>. Invitations above this limit cannot be sent.",
- "inviteByEmail": "Invite by Email",
- "inviteByEmailExplanation": "If a friend joins Habitica via your email, they'll automatically be invited to your Party!",
- "inviteMembersHowTo": "Invite people via a valid email or 36-digit User ID. If an email isn't registered yet, we'll invite them to join Habitica.",
- "inviteFriendsNow": "Invite Friends Now",
- "inviteFriendsLater": "Invite Friends Later",
- "inviteAlertInfo": "If you have friends already using Habitica, invite them by User ID here.",
- "inviteExistUser": "Invite Existing Users",
- "byColon": "By:",
- "inviteNewUsers": "Invite New Users",
- "sendInvitations": "Send Invites",
- "invitationsSent": "Invitations sent!",
- "invitationSent": "Invitation sent!",
- "invitedFriend": "Invited a Friend",
- "invitedFriendText": "This user invited a friend (or friends) who joined them on their adventure!",
- "inviteAlertInfo2": "Or share this link (copy/paste):",
- "inviteLimitReached": "You have already sent the maximum number of email invitations. We have a limit to prevent spamming, however if you would like more, please contact us at <%= techAssistanceEmail %> and we'll be happy to discuss it!",
- "sendGiftHeading": "Send Gift to <%= name %>",
- "sendGiftGemsBalance": "From <%= number %> Gems",
- "sendGiftCost": "Total: $<%= cost %> USD",
- "sendGiftFromBalance": "From Balance",
- "sendGiftPurchase": "Purchase",
- "sendGiftMessagePlaceholder": "Personal message (optional)",
- "sendGiftSubscription": "<%= months %> Month(s): $<%= price %> USD",
- "gemGiftsAreOptional": "Please note that Habitica will never require you to gift gems to other players. Begging people for gems is a violation of the Community Guidelines, and all such instances should be reported to <%= hrefTechAssistanceEmail %>.",
- "battleWithFriends": "Battle Monsters With Friends",
- "startPartyWithFriends": "Start a Party with your friends!",
- "startAParty": "Start a Party",
- "addToParty": "Add someone to your Party",
- "likePost": "Click if you like this post!",
- "partyExplanation1": "Play Habitica with friends to stay accountable!",
- "partyExplanation2": "Battle monsters and create Challenges!",
- "partyExplanation3": "Invite friends now to earn a Quest Scroll!",
- "wantToStartParty": "Do you want to start a Party?",
- "exclusiveQuestScroll": "Inviting a friend to your Party will grant you an exclusive Quest Scroll to battle the Basi-List together!",
- "nameYourParty": "Name your new Party!",
- "partyEmpty": "You're the only one in your Party. Invite your friends!",
- "partyChatEmpty": "Your Party chat is empty! Type a message in the box above to start chatting.",
- "guildChatEmpty": "This guild's chat is empty! Type a message in the box above to start chatting.",
- "requestAcceptGuidelines": "If you would like to post messages in the Tavern or any Party or Guild chat, please first read our <%= linkStart %>Community Guidelines<%= linkEnd %> and then click the button below to indicate that you accept them.",
- "partyUpName": "Party Up",
- "partyOnName": "Party On",
- "partyUpText": "Joined a Party with another person! Have fun battling monsters and supporting each other.",
- "partyOnText": "Joined a Party with at least four people! Enjoy your increased accountability as you unite with your friends to vanquish your foes!",
- "groupNotFound": "Group not found or you don't have access.",
- "groupTypesRequired": "You must supply a valid \"type\" query string.",
- "questLeaderCannotLeaveGroup": "You cannot leave your Party when you have started a quest. Abort the quest first.",
- "cannotLeaveWhileActiveQuest": "You cannot leave Party during an active quest. Please leave the quest first.",
- "onlyLeaderCanRemoveMember": "Only group leader can remove a member!",
- "cannotRemoveCurrentLeader": "You cannot remove the group leader. Assign a new a leader first.",
- "memberCannotRemoveYourself": "You cannot remove yourself!",
- "groupMemberNotFound": "User not found among group's members",
- "mustBeGroupMember": "Must be member of the group.",
- "canOnlyInviteEmailUuid": "Can only invite using user IDs, emails, or usernames.",
- "inviteMissingEmail": "Missing email address in invite.",
- "inviteMissingUuid": "Missing user id in invite",
- "inviteMustNotBeEmpty": "Invite must not be empty.",
- "partyMustbePrivate": "Parties must be private",
- "userAlreadyInGroup": "UserID: <%= userId %>, User \"<%= username %>\" already in that group.",
- "youAreAlreadyInGroup": "You are already a member of this group.",
- "cannotInviteSelfToGroup": "You cannot invite yourself to a group.",
- "userAlreadyInvitedToGroup": "UserID: <%= userId %>, User \"<%= username %>\" already invited to that group.",
- "userAlreadyPendingInvitation": "UserID: <%= userId %>, User \"<%= username %>\" already pending invitation.",
- "userAlreadyInAParty": "UserID: <%= userId %>, User \"<%= username %>\" already in a party.",
- "userWithIDNotFound": "User with id \"<%= userId %>\" not found.",
- "userWithUsernameNotFound": "User with username \"<%= username %>\" not found.",
- "userHasNoLocalRegistration": "User does not have a local registration (username, email, password).",
- "uuidsMustBeAnArray": "User ID invites must be an array.",
- "emailsMustBeAnArray": "Email address invites must be an array.",
- "usernamesMustBeAnArray": "Username invites must be an array.",
- "canOnlyInviteMaxInvites": "You can only invite \"<%= maxInvites %>\" at a time",
- "partyExceedsMembersLimit": "Party size is limited to <%= maxMembersParty %> members",
- "onlyCreatorOrAdminCanDeleteChat": "Not authorized to delete this message!",
- "onlyGroupLeaderCanEditTasks": "Not authorized to manage tasks!",
- "onlyGroupTasksCanBeAssigned": "Only group tasks can be assigned",
- "assignedTo": "Assigned To",
- "assignedToUser": "Assigned to <%= userName %>",
- "assignedToMembers": "Assigned to <%= userCount %> members",
- "assignedToYouAndMembers": "Assigned to you and <%= userCount %> members",
- "youAreAssigned": "You are assigned to this task",
- "taskIsUnassigned": "This task is unassigned",
- "confirmClaim": "Are you sure you want to claim this task?",
- "confirmUnClaim": "Are you sure you want to unclaim this task?",
- "confirmApproval": "Are you sure you want to approve this task?",
- "confirmNeedsWork": "Are you sure you want to mark this task as needing work?",
- "userRequestsApproval": "<%= userName %> requests approval",
- "userCountRequestsApproval": "<%= userCount %> members request approval",
- "youAreRequestingApproval": "You are requesting approval",
- "chatPrivilegesRevoked": "You cannot do that because your chat privileges have been revoked.",
+ "PMReceive": "",
+ "PMEnabledOptPopoverText": "",
+ "PMDisabledOptPopoverText": "",
+ "PMDisabledCaptionTitle": "",
+ "PMDisabledCaptionText": "",
+ "block": "",
+ "unblock": "",
+ "blockWarning": "",
+ "pm-reply": "",
+ "inbox": "",
+ "messageRequired": "",
+ "toUserIDRequired": "",
+ "gemAmountRequired": "",
+ "notAuthorizedToSendMessageToThisUser": "",
+ "privateMessageGiftGemsMessage": "",
+ "privateMessageGiftSubscriptionMessage": "",
+ "cannotSendGemsToYourself": "",
+ "badAmountOfGemsToSend": "",
+ "report": "",
+ "abuseFlag": "",
+ "abuseFlagModalHeading": "",
+ "abuseFlagModalBody": "",
+ "abuseFlagModalButton": "",
+ "abuseReported": "",
+ "abuseAlreadyReported": "",
+ "whyReportingPost": "",
+ "whyReportingPostPlaceholder": "",
+ "optional": "",
+ "needsText": "",
+ "needsTextPlaceholder": "",
+ "copyMessageAsToDo": "",
+ "copyAsTodo": "",
+ "messageAddedAsToDo": "",
+ "messageWroteIn": "",
+ "msgPreviewHeading": "",
+ "leaderOnlyChallenges": "",
+ "sendGift": "",
+ "inviteFriends": "",
+ "partyMembersInfo": "",
+ "inviteByEmail": "",
+ "inviteByEmailExplanation": "",
+ "inviteMembersHowTo": "",
+ "inviteFriendsNow": "",
+ "inviteFriendsLater": "",
+ "inviteAlertInfo": "",
+ "inviteExistUser": "",
+ "byColon": "",
+ "inviteNewUsers": "",
+ "sendInvitations": "",
+ "invitationsSent": "",
+ "invitationSent": "",
+ "invitedFriend": "",
+ "invitedFriendText": "",
+ "inviteAlertInfo2": "",
+ "inviteLimitReached": "",
+ "sendGiftHeading": "",
+ "sendGiftGemsBalance": "",
+ "sendGiftCost": "",
+ "sendGiftFromBalance": "",
+ "sendGiftPurchase": "",
+ "sendGiftMessagePlaceholder": "",
+ "sendGiftSubscription": "",
+ "gemGiftsAreOptional": "",
+ "battleWithFriends": "",
+ "startPartyWithFriends": "",
+ "startAParty": "",
+ "addToParty": "",
+ "likePost": "",
+ "partyExplanation1": "",
+ "partyExplanation2": "",
+ "partyExplanation3": "",
+ "wantToStartParty": "",
+ "exclusiveQuestScroll": "",
+ "nameYourParty": "",
+ "partyEmpty": "",
+ "partyChatEmpty": "",
+ "guildChatEmpty": "",
+ "requestAcceptGuidelines": "",
+ "partyUpName": "",
+ "partyOnName": "",
+ "partyUpText": "",
+ "partyOnText": "",
+ "groupNotFound": "",
+ "groupTypesRequired": "",
+ "questLeaderCannotLeaveGroup": "",
+ "cannotLeaveWhileActiveQuest": "",
+ "onlyLeaderCanRemoveMember": "",
+ "cannotRemoveCurrentLeader": "",
+ "memberCannotRemoveYourself": "",
+ "groupMemberNotFound": "",
+ "mustBeGroupMember": "",
+ "canOnlyInviteEmailUuid": "",
+ "inviteMissingEmail": "",
+ "inviteMissingUuid": "",
+ "inviteMustNotBeEmpty": "",
+ "partyMustbePrivate": "",
+ "userAlreadyInGroup": "",
+ "youAreAlreadyInGroup": "",
+ "cannotInviteSelfToGroup": "",
+ "userAlreadyInvitedToGroup": "",
+ "userAlreadyPendingInvitation": "",
+ "userAlreadyInAParty": "",
+ "userWithIDNotFound": "",
+ "userWithUsernameNotFound": "",
+ "userHasNoLocalRegistration": "",
+ "uuidsMustBeAnArray": "",
+ "emailsMustBeAnArray": "",
+ "usernamesMustBeAnArray": "",
+ "canOnlyInviteMaxInvites": "",
+ "partyExceedsMembersLimit": "",
+ "onlyCreatorOrAdminCanDeleteChat": "",
+ "onlyGroupLeaderCanEditTasks": "",
+ "onlyGroupTasksCanBeAssigned": "",
+ "assignedTo": "",
+ "assignedToUser": "",
+ "assignedToMembers": "",
+ "assignedToYouAndMembers": "",
+ "youAreAssigned": "",
+ "taskIsUnassigned": "",
+ "confirmClaim": "",
+ "confirmUnClaim": "",
+ "confirmApproval": "",
+ "confirmNeedsWork": "",
+ "userRequestsApproval": "",
+ "userCountRequestsApproval": "",
+ "youAreRequestingApproval": "",
+ "chatPrivilegesRevoked": "",
"cannotCreatePublicGuildWhenMuted": "You cannot create a public guild because your chat privileges have been revoked.",
"cannotInviteWhenMuted": "You cannot invite anyone to a guild or party because your chat privileges have been revoked.",
- "newChatMessagePlainNotification": "New message in <%= groupName %> by <%= authorName %>. Click here to open the chat page!",
- "newChatMessageTitle": "New message in <%= groupName %>",
- "exportInbox": "Export Messages",
- "exportInboxPopoverTitle": "Export your messages as HTML",
- "exportInboxPopoverBody": "HTML allows easy reading of messages in a browser. For a machine-readable format, use Data > Export Data",
- "to": "To:",
- "from": "From:",
- "desktopNotificationsText": "We need your permission to enable desktop notifications for new messages in party chat! Follow your browser's instructions to turn them on.
You'll receive these notifications only while you have Habitica open. If you decide you don't like them, they can be disabled in your browser's settings.
This box will close automatically when a decision is made.",
- "confirmAddTag": "Do you want to assign this task to \"<%= tag %>\"?",
- "confirmRemoveTag": "Do you really want to remove \"<%= tag %>\"?",
- "groupHomeTitle": "Home",
- "assignTask": "Assign Task",
- "claim": "Claim",
- "removeClaim": "Remove Claim",
- "onlyGroupLeaderCanManageSubscription": "Only the group leader can manage the group's subscription",
- "yourTaskHasBeenApproved": "Your task <%= taskText %> has been approved.",
- "taskNeedsWork": "<%= managerName %> marked <%= taskText %> as needing additional work.",
- "userHasRequestedTaskApproval": "<%= user %> requests approval for <%= taskName %>",
- "approve": "Approve",
- "approveTask": "Approve Task",
- "needsWork": "Needs Work",
- "viewRequests": "View Requests",
- "approvalTitle": "<%= userName %> has completed <%= type %>: \"<%= text %>\"",
- "confirmTaskApproval": "Do you want to reward <%= username %> for completing this task?",
- "groupSubscriptionPrice": "$9 every month + $3 a month for every additional group member",
- "groupAdditionalUserCost": "+$3.00/month/user",
- "groupBenefitsTitle": "How a group plan can help you",
- "groupBenefitsDescription": "We've just launched the beta version of our group plans! Upgrading to a group plan unlocks some unique features to optimize the social side of Habitica.",
- "groupBenefitOneTitle": "Create a shared task list",
- "groupBenefitOneDescription": "Set up a shared task list for the group that everyone can easily view and edit.",
- "groupBenefitTwoTitle": "Assign tasks to group members",
- "groupBenefitTwoDescription": "Want a coworker to answer a critical email? Need your roommate to pick up the groceries? Just assign them the tasks you create, and they'll automatically appear in that person's task dashboard.",
- "groupBenefitThreeTitle": "Claim a task that you are working on",
- "groupBenefitThreeDescription": "Stake your claim on any group task with a simple click. Make it clear what everybody is working on!",
- "groupBenefitFourTitle": "Mark tasks that require special approval",
- "groupBenefitFourDescription": "Need to verify that a task really did get done before that user gets their rewards? Just adjust the approval settings for added control.",
- "groupBenefitFiveTitle": "Chat privately with your group",
- "groupBenefitFiveDescription": "Stay in the loop about important decisions in our easy-to-use chatroom!",
- "groupBenefitSixTitle": "Get a free subscription",
- "groupBenefitSixDescription": "Get full subscription benefits, including exclusive monthly items and the ability to buy gems with gold! (If you're already a subscriber, your old subscription will be cancelled but your consecutive subscription benefits such as monthly hourglasses will remain.)",
- "groupBenefitSevenTitle": "Get a brand-new exclusive Jackalope Mount",
- "groupBenefitEightTitle": "Add Group Managers to help manage tasks",
- "groupBenefitEightDescription": "Want to share your group's responsibilities? Promote people to Group Managers to help the Leader add, assign, and approve tasks!",
- "groupBenefitMessageLimitTitle": "Increase message limit",
- "groupBenefitMessageLimitDescription": "Your message limit is doubled to house up to 400 messages at a time!",
- "teamBasedTasks": "Team-based Tasks",
- "specializedCommunication": "Specialized Communication",
- "funExtras": "Fun Extras",
- "enterprisePlansButton": "Ask about Enterprise Plans",
- "enterprisePlansDescription": "Looking for a larger install with custom needs? See if our enterprise plans are right for you.",
- "familyPlansButton": "Sign Up for Family Plan Mailing List",
- "familyPlansDescription": "Want a cozier solution to manage your household? Family Plans are coming soon!",
- "createAGroup": "Create a Group",
- "getAGroupPlanToday": "Get a Group Plan Today",
- "assignFieldPlaceholder": "Type a group member's profile name",
- "cannotDeleteActiveGroup": "You cannot remove a group with an active subscription",
- "groupTasksTitle": "Group Tasks List",
- "approvalsTitle": "Tasks Awaiting Approval",
- "upgradeTitle": "Upgrade",
- "blankApprovalsDescription": "When your group completes tasks that need your approval, they'll appear here! Adjust approval requirement settings under task editing.",
- "userIsClamingTask": "`<%= username %> has claimed:` <%= task %>",
- "approvalRequested": "Approval Requested",
- "refreshApprovals": "Refresh Approvals",
- "refreshGroupTasks": "Refresh Group Tasks",
- "claimedBy": "Claimed by: <%= claimingUsers %>",
- "cantDeleteAssignedGroupTasks": "Can't delete group tasks that are assigned to you.",
- "confirmGuildPlanCreation": "Create this group?",
- "groupPlanUpgraded": "<%= groupName %> was upgraded to a Group Plan!",
- "groupPlanCreated": "<%= groupName %> was created!",
- "onlyGroupLeaderCanInviteToGroupPlan": "Only the group leader can invite users to a group with a subscription.",
- "paymentDetails": "Payment Details",
- "aboutToJoinCancelledGroupPlan": "You are about to join a group with a canceled plan. You will NOT receive a free subscription.",
- "cannotChangeLeaderWithActiveGroupPlan": "You can not change the leader while the group has an active plan.",
- "leaderCannotLeaveGroupWithActiveGroup": "A leader can not leave a group while the group has an active plan",
- "youHaveGroupPlan": "You have a free subscription because you are a member of a group that has a Group Plan. This will end when you are no longer in the group that has a Group Plan. Any months of extra subscription credit you have will be applied at the end of the Group Plan.",
- "cancelGroupSub": "Cancel Group Plan",
- "confirmCancelGroupPlan": "Are you sure you want to cancel the group plan and remove its benefits from all members, including their free subscriptions?",
- "canceledGroupPlan": "Canceled Group Plan",
- "groupPlanCanceled": "Group Plan will become inactive on",
- "purchasedGroupPlanPlanExtraMonths": "You have <%= months %> months of extra group plan credit.",
- "addManager": "Assign Manager",
- "removeManager2": "Unassign Manager",
- "userMustBeMember": "User must be a member",
- "userIsNotManager": "User is not manager",
- "canOnlyApproveTaskOnce": "This task has already been approved.",
- "addTaskToGroupPlan": "Create",
- "joinedGuild": "Joined a Guild",
- "joinedGuildText": "Ventured into the social side of Habitica by joining a Guild!",
- "badAmountOfGemsToPurchase": "Amount must be at least 1.",
- "groupPolicyCannotGetGems": "The policy of one group you're part of prevents its members from obtaining gems.",
- "viewParty": "View Party",
- "newGuildPlaceholder": "Enter your guild's name.",
- "guildMembers": "Guild Members",
- "guildBank": "Guild Bank",
- "chatPlaceholder": "Type your message to Guild members here",
- "partyChatPlaceholder": "Type your message to Party members here",
- "fetchRecentMessages": "Fetch Recent Messages",
- "like": "Like",
- "liked": "Liked",
- "joinGuild": "Join Guild",
- "inviteToGuild": "Invite to Guild",
- "inviteToParty": "Invite to Party",
- "inviteEmailUsername": "Invite via Email or Username",
- "inviteEmailUsernameInfo": "Invite users via a valid email or username. If an email isn't registered yet, we'll invite them to join.",
- "emailOrUsernameInvite": "Email address or username",
- "messageGuildLeader": "Message Guild Leader",
- "donateGems": "Donate Gems",
- "updateGuild": "Update Guild",
- "viewMembers": "View Members",
- "memberCount": "Member Count",
- "recentActivity": "Recent Activity",
- "myGuilds": "My Guilds",
- "guildsDiscovery": "Discover Guilds",
- "role": "Role",
- "guildOrPartyLeader": "Leader",
- "guildLeader": "Guild Leader",
- "member": "Member",
- "guildSize": "Guild Size",
- "goldTier": "Gold Tier",
- "silverTier": "Silver Tier",
- "bronzeTier": "Bronze Tier",
- "privacySettings": "Privacy Settings",
- "onlyLeaderCreatesChallenges": "Only the Leader can create Challenges",
- "onlyLeaderCreatesChallengesDetail": "With this option selected, ordinary group members cannot create Challenges for the group.",
- "privateGuild": "Private Guild",
- "charactersRemaining": "<%= characters %> characters remaining",
- "guildSummary": "Summary",
- "guildSummaryPlaceholder": "Write a short description advertising your Guild to other Habiticans. What is the main purpose of your Guild and why should people join it? Try to include useful keywords in the summary so that Habiticans can easily find it when they search!",
- "groupDescription": "Description",
- "guildDescriptionPlaceholder": "Use this section to go into more detail about everything that Guild members should know about your Guild. Useful tips, helpful links, and encouraging statements all go here!",
- "markdownFormattingHelp": "[Markdown formatting help](http://habitica.wikia.com/wiki/Markdown_Cheat_Sheet)",
- "partyDescriptionPlaceholder": "This is our Party's description. It describes what we do in this Party. If you want to learn more about what we do in this Party, read the description. Party on.",
- "guildGemCostInfo": "A Gem cost promotes high quality Guilds and is transferred into your Guild's bank.",
- "noGuildsTitle": "You aren't a member of any Guilds.",
- "noGuildsParagraph1": "Guilds are social groups created by other players that can offer you support, accountability, and encouraging chat.",
- "noGuildsParagraph2": "Click the Discover tab to see recommended Guilds based on your interests, browse Habitica's public Guilds, or create your own Guild.",
- "noGuildsMatchFilters": "We couldn't find any matching Guilds.",
- "privateDescription": "A private Guild will not be displayed in Habitica's Guild directory. New members can be added by invitation only.",
- "removeInvite": "Remove Invitation",
- "removeMember": "Remove Member",
- "sendMessage": "Send Message",
- "promoteToLeader": "Transfer Ownership",
- "inviteFriendsParty": "Inviting friends to your Party will grant you an exclusive Quest Scroll to battle the Basi-List together!",
- "upgradeParty": "Upgrade Party",
- "createParty": "Create a Party",
- "inviteMembersNow": "Would you like to invite members now?",
- "playInPartyTitle": "Play Habitica in a Party!",
- "playInPartyDescription": "Take on amazing quests with friends or on your own. Battle monsters, create Challenges, and help yourself stay accountable through Parties.",
- "startYourOwnPartyTitle": "Start your own Party",
- "startYourOwnPartyDescription": "Battle monsters solo or invite as many of your friends as you'd like!",
- "wantToJoinPartyTitle": "Want to join a Party?",
- "wantToJoinPartyDescription": "Give your username to a friend who already has a Party, or head to the Party Wanted Guild to meet potential comrades!",
- "copy": "Copy",
- "inviteToPartyOrQuest": "Invite Party to Quest",
- "inviteInformation": "Clicking \"Invite\" will send an invitation to your Party members. When all members have accepted or denied, the Quest begins.",
- "questOwnerRewards": "Quest Owner Rewards",
- "updateParty": "Update Party",
- "upgrade": "Upgrade",
- "selectPartyMember": "Select a Party Member",
- "areYouSureDeleteMessage": "Are you sure you want to delete this message?",
- "reverseChat": "Reverse Chat",
- "invites": "Invites",
- "details": "Details",
- "participantDesc": "Once all members have either accepted or declined, the Quest begins. Only those who clicked 'accept' will be able to participate in the Quest and receive the rewards.",
- "groupGems": "Group Gems",
- "groupGemsDesc": "Guild Gems can be spent to make Challenges! In the future, you will be able to add more Guild Gems.",
- "groupTaskBoard": "Task Board",
- "groupInformation": "Group Information",
- "groupBilling": "Group Billing",
- "wouldYouParticipate": "Would you like to participate?",
- "managerAdded": "Manager added successfully",
- "managerRemoved": "Manager removed successfully",
- "leaderChanged": "Leader has been changed",
- "groupNoNotifications": "This Guild does not have notifications due to member size. Be sure to check back often for replies to your messages!",
- "whatIsWorldBoss": "What is a World Boss?",
- "worldBossDesc": "A World Boss is a special event that brings the Habitica community together to take down a powerful monster with their tasks! All Habitica users are rewarded upon its defeat, even those who have been resting in the Inn or have not used Habitica for the entirety of the quest.",
- "worldBossLink": "Read more about the previous World Bosses of Habitica on the Wiki.",
- "worldBossBullet1": "Complete tasks to damage the World Boss",
- "worldBossBullet2": "The World Boss won’t damage you for missed tasks, but its Rage meter will go up. If the bar fills up, the Boss will attack one of Habitica’s shopkeepers!",
- "worldBossBullet3": "You can continue with normal Quest Bosses, damage will apply to both",
- "worldBossBullet4": "Check the Tavern regularly to see World Boss progress and Rage attacks",
- "worldBoss": "World Boss",
- "groupPlanTitle": "Need more for your crew?",
- "groupPlanDesc": "Managing a small team or organizing household chores? Our group plans grant you exclusive access to a private task board and chat area dedicated to you and your group members!",
- "billedMonthly": "*billed as a monthly subscription",
- "teamBasedTasksList": "Team-Based Task List",
- "teamBasedTasksListDesc": "Set up an easily-viewed shared task list for the group. Assign tasks to your fellow group members, or let them claim their own tasks to make it clear what everyone is working on!",
- "groupManagementControls": "Group Management Controls",
- "groupManagementControlsDesc": "Use task approvals to verify that a task that was really completed, add Group Managers to share responsibilities, and enjoy a private group chat for all team members.",
- "inGameBenefits": "In-Game Benefits",
- "inGameBenefitsDesc": "Group members get an exclusive Jackalope Mount, as well as full subscription benefits, including special monthly equipment sets and the ability to buy gems with gold.",
- "inspireYourParty": "Inspire your party, gamify life together.",
- "letsMakeAccount": "First, let’s make you an account",
- "nameYourGroup": "Next, Name Your Group",
- "exampleGroupName": "Example: Avengers Academy",
- "exampleGroupDesc": "For those selected to join the training academy for The Avengers Superhero Initiative",
- "thisGroupInviteOnly": "This group is invitation only.",
- "gettingStarted": "Getting Started",
- "congratsOnGroupPlan": "Congratulations on creating your new Group! Here are a few answers to some of the more commonly asked questions.",
- "whatsIncludedGroup": "What's included in the subscription",
- "whatsIncludedGroupDesc": "All members of the Group receive full subscription benefits, including the monthly subscriber items, the ability to buy Gems with Gold, and the Royal Purple Jackalope mount, which is exclusive to users with a Group Plan membership.",
- "howDoesBillingWork": "How does billing work?",
- "howDoesBillingWorkDesc": "Group Leaders are billed based on group member count on a monthly basis. This charge includes the $9 (USD) price for the Group Leader subscription, plus $3 USD for each additional group member. For example: A group of four users will cost $18 USD/month, as the group consists of 1 Group Leader + 3 group members.",
- "howToAssignTask": "How do you assign a Task?",
- "howToAssignTaskDesc": "Assign any Task to one or more Group members (including the Group Leader or Managers themselves) by entering their usernames in the \"Assign To\" field within the Create Task modal. You can also decide to assign a Task after creating it, by editing the Task and adding the user in the \"Assign To\" field!",
- "howToRequireApproval": "How do you mark a Task as requiring approval?",
- "howToRequireApprovalDesc": "Toggle the \"Requires Approval\" setting to mark a specific task as requiring Group Leader or Manager confirmation. The user who checked off the task won't get their rewards for completing it until it has been approved.",
- "howToRequireApprovalDesc2": "Group Leaders and Managers can approve completed Tasks directly from the Task Board or from the Notifications panel.",
- "whatIsGroupManager": "What is a Group Manager?",
- "whatIsGroupManagerDesc": "A Group Manager is a user role that do not have access to the group's billing details, but can create, assign, and approve shared Tasks for the Group's members. Promote Group Managers from the Group’s member list.",
- "goToTaskBoard": "Go to Task Board",
- "sharedCompletion": "Shared Completion",
- "recurringCompletion": "None - Group task does not complete",
- "singleCompletion": "Single - Completes when any assigned user finishes",
- "allAssignedCompletion": "All - Completes when all assigned users finish"
-}
\ No newline at end of file
+ "newChatMessagePlainNotification": "",
+ "newChatMessageTitle": "",
+ "exportInbox": "",
+ "exportInboxPopoverTitle": "",
+ "exportInboxPopoverBody": "",
+ "to": "",
+ "from": "",
+ "desktopNotificationsText": "",
+ "confirmAddTag": "",
+ "confirmRemoveTag": "",
+ "groupHomeTitle": "",
+ "assignTask": "",
+ "claim": "",
+ "removeClaim": "",
+ "onlyGroupLeaderCanManageSubscription": "",
+ "yourTaskHasBeenApproved": "",
+ "taskNeedsWork": "",
+ "userHasRequestedTaskApproval": "",
+ "approve": "",
+ "approveTask": "",
+ "needsWork": "",
+ "viewRequests": "",
+ "approvalTitle": "",
+ "confirmTaskApproval": "",
+ "groupSubscriptionPrice": "",
+ "groupAdditionalUserCost": "",
+ "groupBenefitsTitle": "",
+ "groupBenefitsDescription": "",
+ "groupBenefitOneTitle": "",
+ "groupBenefitOneDescription": "",
+ "groupBenefitTwoTitle": "",
+ "groupBenefitTwoDescription": "",
+ "groupBenefitThreeTitle": "",
+ "groupBenefitThreeDescription": "",
+ "groupBenefitFourTitle": "",
+ "groupBenefitFourDescription": "",
+ "groupBenefitFiveTitle": "",
+ "groupBenefitFiveDescription": "",
+ "groupBenefitSixTitle": "",
+ "groupBenefitSixDescription": "",
+ "groupBenefitSevenTitle": "",
+ "groupBenefitEightTitle": "",
+ "groupBenefitEightDescription": "",
+ "groupBenefitMessageLimitTitle": "",
+ "groupBenefitMessageLimitDescription": "",
+ "teamBasedTasks": "",
+ "specializedCommunication": "",
+ "funExtras": "",
+ "enterprisePlansButton": "",
+ "enterprisePlansDescription": "",
+ "familyPlansButton": "",
+ "familyPlansDescription": "",
+ "createAGroup": "",
+ "getAGroupPlanToday": "",
+ "assignFieldPlaceholder": "",
+ "cannotDeleteActiveGroup": "",
+ "groupTasksTitle": "",
+ "approvalsTitle": "",
+ "upgradeTitle": "",
+ "blankApprovalsDescription": "",
+ "userIsClamingTask": "",
+ "approvalRequested": "",
+ "refreshApprovals": "",
+ "refreshGroupTasks": "",
+ "claimedBy": "",
+ "cantDeleteAssignedGroupTasks": "",
+ "confirmGuildPlanCreation": "",
+ "groupPlanUpgraded": "",
+ "groupPlanCreated": "",
+ "onlyGroupLeaderCanInviteToGroupPlan": "",
+ "paymentDetails": "",
+ "aboutToJoinCancelledGroupPlan": "",
+ "cannotChangeLeaderWithActiveGroupPlan": "",
+ "leaderCannotLeaveGroupWithActiveGroup": "",
+ "youHaveGroupPlan": "",
+ "cancelGroupSub": "",
+ "confirmCancelGroupPlan": "",
+ "canceledGroupPlan": "",
+ "groupPlanCanceled": "",
+ "purchasedGroupPlanPlanExtraMonths": "",
+ "addManager": "",
+ "removeManager2": "",
+ "userMustBeMember": "",
+ "userIsNotManager": "",
+ "canOnlyApproveTaskOnce": "",
+ "addTaskToGroupPlan": "",
+ "joinedGuild": "",
+ "joinedGuildText": "",
+ "badAmountOfGemsToPurchase": "",
+ "groupPolicyCannotGetGems": "",
+ "viewParty": "",
+ "newGuildPlaceholder": "",
+ "guildMembers": "",
+ "guildBank": "",
+ "chatPlaceholder": "",
+ "partyChatPlaceholder": "",
+ "fetchRecentMessages": "",
+ "like": "",
+ "liked": "",
+ "joinGuild": "",
+ "inviteToGuild": "",
+ "inviteToParty": "",
+ "inviteEmailUsername": "",
+ "inviteEmailUsernameInfo": "",
+ "emailOrUsernameInvite": "",
+ "messageGuildLeader": "",
+ "donateGems": "",
+ "updateGuild": "",
+ "viewMembers": "",
+ "memberCount": "",
+ "recentActivity": "",
+ "myGuilds": "",
+ "guildsDiscovery": "",
+ "role": "",
+ "guildOrPartyLeader": "",
+ "guildLeader": "",
+ "member": "",
+ "guildSize": "",
+ "goldTier": "",
+ "silverTier": "",
+ "bronzeTier": "",
+ "privacySettings": "",
+ "onlyLeaderCreatesChallenges": "",
+ "onlyLeaderCreatesChallengesDetail": "",
+ "privateGuild": "",
+ "charactersRemaining": "",
+ "guildSummary": "",
+ "guildSummaryPlaceholder": "",
+ "groupDescription": "",
+ "guildDescriptionPlaceholder": "",
+ "markdownFormattingHelp": "",
+ "partyDescriptionPlaceholder": "",
+ "guildGemCostInfo": "",
+ "noGuildsTitle": "",
+ "noGuildsParagraph1": "",
+ "noGuildsParagraph2": "",
+ "noGuildsMatchFilters": "",
+ "privateDescription": "",
+ "removeInvite": "",
+ "removeMember": "",
+ "sendMessage": "",
+ "promoteToLeader": "",
+ "inviteFriendsParty": "",
+ "upgradeParty": "",
+ "createParty": "",
+ "inviteMembersNow": "",
+ "playInPartyTitle": "",
+ "playInPartyDescription": "",
+ "startYourOwnPartyTitle": "",
+ "startYourOwnPartyDescription": "",
+ "wantToJoinPartyTitle": "",
+ "wantToJoinPartyDescription": "",
+ "copy": "",
+ "inviteToPartyOrQuest": "",
+ "inviteInformation": "",
+ "questOwnerRewards": "",
+ "updateParty": "",
+ "upgrade": "",
+ "selectPartyMember": "",
+ "areYouSureDeleteMessage": "",
+ "reverseChat": "",
+ "invites": "",
+ "details": "",
+ "participantDesc": "",
+ "groupGems": "",
+ "groupGemsDesc": "",
+ "groupTaskBoard": "",
+ "groupInformation": "",
+ "groupBilling": "",
+ "wouldYouParticipate": "",
+ "managerAdded": "",
+ "managerRemoved": "",
+ "leaderChanged": "",
+ "groupNoNotifications": "",
+ "whatIsWorldBoss": "",
+ "worldBossDesc": "",
+ "worldBossLink": "",
+ "worldBossBullet1": "",
+ "worldBossBullet2": "",
+ "worldBossBullet3": "",
+ "worldBossBullet4": "",
+ "worldBoss": "",
+ "groupPlanTitle": "",
+ "groupPlanDesc": "",
+ "billedMonthly": "",
+ "teamBasedTasksList": "",
+ "teamBasedTasksListDesc": "",
+ "groupManagementControls": "",
+ "groupManagementControlsDesc": "",
+ "inGameBenefits": "",
+ "inGameBenefitsDesc": "",
+ "inspireYourParty": "",
+ "letsMakeAccount": "",
+ "nameYourGroup": "",
+ "exampleGroupName": "",
+ "exampleGroupDesc": "",
+ "thisGroupInviteOnly": "",
+ "gettingStarted": "",
+ "congratsOnGroupPlan": "",
+ "whatsIncludedGroup": "",
+ "whatsIncludedGroupDesc": "",
+ "howDoesBillingWork": "",
+ "howDoesBillingWorkDesc": "",
+ "howToAssignTask": "",
+ "howToAssignTaskDesc": "",
+ "howToRequireApproval": "",
+ "howToRequireApprovalDesc": "",
+ "howToRequireApprovalDesc2": "",
+ "whatIsGroupManager": "",
+ "whatIsGroupManagerDesc": "",
+ "goToTaskBoard": "",
+ "sharedCompletion": "",
+ "recurringCompletion": "",
+ "singleCompletion": "",
+ "allAssignedCompletion": ""
+}
diff --git a/website/common/locales/eu/inventory.json b/website/common/locales/eu/inventory.json
index f9730a68bd..4900bc0065 100755
--- a/website/common/locales/eu/inventory.json
+++ b/website/common/locales/eu/inventory.json
@@ -1,8 +1,8 @@
{
- "noItemsAvailableForType": "You have no <%= type %>.",
- "foodItemType": "Food",
- "eggsItemType": "Eggs",
- "hatchingPotionsItemType": "Hatching Potions",
- "specialItemType": "Special items",
- "lockedItem": "Locked Item"
+ "noItemsAvailableForType": "",
+ "foodItemType": "",
+ "eggsItemType": "",
+ "hatchingPotionsItemType": "",
+ "specialItemType": "",
+ "lockedItem": ""
}
diff --git a/website/common/locales/eu/limited.json b/website/common/locales/eu/limited.json
index 4cd23632e6..3079b3fa6b 100755
--- a/website/common/locales/eu/limited.json
+++ b/website/common/locales/eu/limited.json
@@ -1,155 +1,155 @@
{
- "limitedEdition": "Limited Edition",
- "seasonalEdition": "Seasonal Edition",
- "winterColors": "Winter Colors",
- "annoyingFriends": "Annoying Friends",
- "annoyingFriendsText": "Got snowballed <%= count %> times by party members.",
- "alarmingFriends": "Alarming Friends",
- "alarmingFriendsText": "Got spooked <%= count %> times by party members.",
- "agriculturalFriends": "Agricultural Friends",
- "agriculturalFriendsText": "Got transformed into a flower <%= count %> times by party members.",
- "aquaticFriends": "Aquatic Friends",
- "aquaticFriendsText": "Got splashed <%= count %> times by party members.",
- "valentineCard": "Valentine's Day Card",
- "valentineCardExplanation": "For enduring such a saccharine poem, you both receive the \"Adoring Friends\" badge!",
- "valentineCardNotes": "Send a Valentine's Day card to a party member.",
- "valentine0": "\"Roses are red\n\nMy Dailies are blue\n\nI'm happy that I'm\n\nIn a Party with you!\"",
- "valentine1": "\"Roses are red\n\nViolets are nice\n\nLet's get together\n\nAnd fight against Vice!\"",
- "valentine2": "\"Roses are red\n\nThis poem style is old\n\nI hope that you like this\n\n'Cause it cost ten Gold.\"",
- "valentine3": "\"Roses are red\n\nIce Drakes are blue\n\nNo treasure is better\n\nThan time spent with you!\"",
- "valentineCardAchievementTitle": "Adoring Friends",
- "valentineCardAchievementText": "Aww, you and your friend must really care about each other! Sent or received <%= count %> Valentine's Day cards.",
- "polarBear": "Polar Bear",
- "turkey": "Turkey",
- "gildedTurkey": "Gilded Turkey",
- "polarBearPup": "Polar Bear Cub",
- "jackolantern": "Jack-O-Lantern",
- "ghostJackolantern": "Ghost Jack-O-Lantern",
- "glowJackolantern": "Glow-in-the-Dark Jack-O-Lantern",
- "seasonalShop": "Seasonal Shop",
- "seasonalShopClosedTitle": "<%= linkStart %>Leslie<%= linkEnd %>",
- "seasonalShopTitle": "<%= linkStart %>Seasonal Sorceress<%= linkEnd %>",
- "seasonalShopClosedText": "The Seasonal Shop is currently closed!! It’s only open during Habitica’s four Grand Galas.",
- "seasonalShopSummerText": "Happy Summer Splash!! Would you like to buy some rare items? They’ll only be available until July 31st!",
- "seasonalShopFallText": "Happy Fall Festival!! Would you like to buy some rare items? They’ll only be available until October 31st!",
- "seasonalShopWinterText": "Happy Winter Wonderland!! Would you like to buy some rare items? They’ll only be available until January 31st!",
- "seasonalShopSpringText": "Happy Spring Fling!! Would you like to buy some rare items? They’ll only be available until April 30th!",
- "seasonalShopFallTextBroken": "Oh.... Welcome to the Seasonal Shop... We're stocking autumn Seasonal Edition goodies, or something... Everything here will be available to purchase during the Fall Festival event each year, but we're only open until October 31... I guess you should to stock up now, or you'll have to wait... and wait... and wait... *sigh*",
- "seasonalShopBrokenText": "My pavilion!!!!!!! My decorations!!!! Oh, the Dysheartener's destroyed everything :( Please help defeat it in the Tavern so I can rebuild!",
- "seasonalShopRebirth": "If you bought any of this equipment in the past but don't currently own it, you can repurchase it in the Rewards Column. Initially, you'll only be able to purchase the items for your current class (Warrior by default), but fear not, the other class-specific items will become available if you switch to that class.",
- "candycaneSet": "Candy Cane (Mage)",
- "skiSet": "Ski-sassin (Rogue)",
- "snowflakeSet": "Snowflake (Healer)",
- "yetiSet": "Yeti Tamer (Warrior)",
- "northMageSet": "Mage of the North (Mage)",
- "icicleDrakeSet": "Icicle Drake (Rogue)",
- "soothingSkaterSet": "Soothing Skater (Healer)",
- "gingerbreadSet": "Gingerbread Warrior (Warrior)",
- "snowDaySet": "Snow Day Warrior (Warrior)",
- "snowboardingSet": "Snowboarding Sorcerer (Mage)",
- "festiveFairySet": "Festive Fairy (Healer)",
- "cocoaSet": "Cocoa Rogue (Rogue)",
- "toAndFromCard": "To: <%= toName %>, From: <%= fromName %>",
- "nyeCard": "New Year's Card",
- "nyeCardExplanation": "For celebrating the new year together, you both receive the \"Auld Acquaintance\" badge!",
- "nyeCardNotes": "Send a New Year's card to a party member.",
- "seasonalItems": "Seasonal Items",
- "nyeCardAchievementTitle": "Auld Acquaintance",
- "nyeCardAchievementText": "Happy New Year! Sent or received <%= count %> New Year's cards.",
- "nye0": "Happy New Year! May you slay many a bad Habit.",
- "nye1": "Happy New Year! May you reap many Rewards.",
- "nye2": "Happy New Year! May you earn many a Perfect Day.",
- "nye3": "Happy New Year! May your To-Do list stay short and sweet.",
- "nye4": "Happy New Year! May you not get attacked by a raging Hippogriff.",
- "holidayCard": "Received a holiday card!",
- "mightyBunnySet": "Mighty Bunny (Warrior)",
- "magicMouseSet": "Magic Mouse (Mage)",
- "lovingPupSet": "Loving Pup (Healer)",
- "stealthyKittySet": "Stealthy Kitty (Rogue)",
- "daringSwashbucklerSet": "Daring Swashbuckler (Warrior)",
- "emeraldMermageSet": "Emerald Mermage (Mage)",
- "reefSeahealerSet": "Reef Seahealer (Healer)",
- "roguishPirateSet": "Roguish Pirate (Rogue)",
- "monsterOfScienceSet": "Monster of Science (Warrior)",
- "witchyWizardSet": "Witchy Wizard (Mage)",
- "mummyMedicSet": "Mummy Medic (Healer)",
- "vampireSmiterSet": "Vampire Smiter (Rogue)",
- "bewareDogSet": "Beware Dog (Warrior)",
- "magicianBunnySet": "Magician's Bunny (Mage)",
- "comfortingKittySet": "Comforting Kitty (Healer)",
- "sneakySqueakerSet": "Sneaky Squeaker (Rogue)",
- "sunfishWarriorSet": "Sunfish Warrior (Warrior)",
- "shipSoothsayerSet": "Ship Soothsayer (Mage)",
- "strappingSailorSet": "Strapping Sailor (Healer)",
- "reefRenegadeSet": "Reef Renegade (Rogue)",
- "scarecrowWarriorSet": "Scarecrow Warrior (Warrior)",
- "stitchWitchSet": "Stitch Witch (Mage)",
- "potionerSet": "Potioner (Healer)",
- "battleRogueSet": "Bat-tle Rogue (Rogue)",
- "springingBunnySet": "Springing Bunny (Healer)",
- "grandMalkinSet": "Grand Malkin (Mage)",
- "cleverDogSet": "Clever Dog (Rogue)",
- "braveMouseSet": "Brave Mouse (Warrior)",
- "summer2016SharkWarriorSet": "Shark Warrior (Warrior)",
- "summer2016DolphinMageSet": "Dolphin Mage (Mage)",
- "summer2016SeahorseHealerSet": "Seahorse Healer (Healer)",
- "summer2016EelSet": "Eel Rogue (Rogue)",
- "fall2016SwampThingSet": "Swamp Thing (Warrior)",
- "fall2016WickedSorcererSet": "Wicked Sorcerer (Mage)",
- "fall2016GorgonHealerSet": "Gorgon Healer (Healer)",
- "fall2016BlackWidowSet": "Black Widow Rogue (Rogue)",
- "winter2017IceHockeySet": "Ice Hockey (Warrior)",
- "winter2017WinterWolfSet": "Winter Wolf (Mage)",
- "winter2017SugarPlumSet": "Sugar Plum Healer (Healer)",
- "winter2017FrostyRogueSet": "Frosty Rogue (Rogue)",
- "spring2017FelineWarriorSet": "Feline Warrior (Warrior)",
- "spring2017CanineConjurorSet": "Canine Conjuror (Mage)",
- "spring2017FloralMouseSet": "Floral Mouse (Healer)",
- "spring2017SneakyBunnySet": "Sneaky Bunny (Rogue)",
- "summer2017SandcastleWarriorSet": "Sandcastle Warrior (Warrior)",
- "summer2017WhirlpoolMageSet": "Whirlpool Mage (Mage)",
- "summer2017SeashellSeahealerSet": "Seashell Seahealer (Healer)",
- "summer2017SeaDragonSet": "Sea Dragon (Rogue)",
- "fall2017HabitoweenSet": "Habitoween Warrior (Warrior)",
- "fall2017MasqueradeSet": "Masquerade Mage (Mage)",
- "fall2017HauntedHouseSet": "Haunted House Healer (Healer)",
- "fall2017TrickOrTreatSet": "Trick or Treat Rogue (Rogue)",
- "winter2018ConfettiSet": "Confetti Mage (Mage)",
- "winter2018GiftWrappedSet": "Gift-Wrapped Warrior (Warrior)",
- "winter2018MistletoeSet": "Mistletoe Healer (Healer)",
- "winter2018ReindeerSet": "Reindeer Rogue (Rogue)",
- "spring2018SunriseWarriorSet": "Sunrise Warrior (Warrior)",
- "spring2018TulipMageSet": "Tulip Mage (Mage)",
- "spring2018GarnetHealerSet": "Garnet Healer (Healer)",
- "spring2018DucklingRogueSet": "Duckling Rogue (Rogue)",
- "summer2018BettaFishWarriorSet": "Betta Fish Warrior (Warrior)",
- "summer2018LionfishMageSet": "Lionfish Mage (Mage)",
- "summer2018MerfolkMonarchSet": "Merfolk Monarch (Healer)",
- "summer2018FisherRogueSet": "Fisher-Rogue (Rogue)",
- "fall2018MinotaurWarriorSet": "Minotaur (Warrior)",
- "fall2018CandymancerMageSet": "Candymancer (Mage)",
- "fall2018CarnivorousPlantSet": "Carnivorous Plant (Healer)",
- "fall2018AlterEgoSet": "Alter Ego (Rogue)",
- "winter2019BlizzardSet": "Blizzard (Warrior)",
- "winter2019PyrotechnicSet": "Pyrotechnic (Mage)",
- "winter2019WinterStarSet": "Winter Star (Healer)",
- "winter2019PoinsettiaSet": "Poinsettia (Rogue)",
- "eventAvailability": "Available for purchase until <%= date(locale) %>.",
- "dateEndMarch": "April 30",
- "dateEndApril": "April 19",
- "dateEndMay": "May 31",
- "dateEndJune": "June 14",
- "dateEndJuly": "July 31",
- "dateEndAugust": "August 31",
- "dateEndSeptember": "September 21",
- "dateEndOctober": "October 31",
- "dateEndNovember": "December 3",
- "dateEndJanuary": "January 31",
- "dateEndFebruary": "February 28",
- "winterPromoGiftHeader": "GIFT A SUBSCRIPTION AND GET ONE FREE!",
- "winterPromoGiftDetails1": "Until January 15th only, when you gift somebody a subscription, you get the same subscription for yourself for free!",
- "winterPromoGiftDetails2": "Please note that if you or your gift recipient already have a recurring subscription, the gifted subscription will only start after that subscription is cancelled or has expired. Thanks so much for your support! <3",
- "discountBundle": "bundle",
- "g1g1Announcement": "Gift a Subscription, Get a Subscription Free event going on now!",
- "g1g1Details": "Gift a sub to a friend from their profile and you’ll receive the same sub for free!"
-}
\ No newline at end of file
+ "limitedEdition": "",
+ "seasonalEdition": "",
+ "winterColors": "",
+ "annoyingFriends": "",
+ "annoyingFriendsText": "",
+ "alarmingFriends": "",
+ "alarmingFriendsText": "",
+ "agriculturalFriends": "",
+ "agriculturalFriendsText": "",
+ "aquaticFriends": "",
+ "aquaticFriendsText": "",
+ "valentineCard": "",
+ "valentineCardExplanation": "",
+ "valentineCardNotes": "",
+ "valentine0": "",
+ "valentine1": "",
+ "valentine2": "",
+ "valentine3": "",
+ "valentineCardAchievementTitle": "",
+ "valentineCardAchievementText": "",
+ "polarBear": "",
+ "turkey": "",
+ "gildedTurkey": "",
+ "polarBearPup": "",
+ "jackolantern": "",
+ "ghostJackolantern": "",
+ "glowJackolantern": "",
+ "seasonalShop": "",
+ "seasonalShopClosedTitle": "",
+ "seasonalShopTitle": "",
+ "seasonalShopClosedText": "",
+ "seasonalShopSummerText": "",
+ "seasonalShopFallText": "",
+ "seasonalShopWinterText": "",
+ "seasonalShopSpringText": "",
+ "seasonalShopFallTextBroken": "",
+ "seasonalShopBrokenText": "",
+ "seasonalShopRebirth": "",
+ "candycaneSet": "",
+ "skiSet": "",
+ "snowflakeSet": "",
+ "yetiSet": "",
+ "northMageSet": "",
+ "icicleDrakeSet": "",
+ "soothingSkaterSet": "",
+ "gingerbreadSet": "",
+ "snowDaySet": "",
+ "snowboardingSet": "",
+ "festiveFairySet": "",
+ "cocoaSet": "",
+ "toAndFromCard": "",
+ "nyeCard": "",
+ "nyeCardExplanation": "",
+ "nyeCardNotes": "",
+ "seasonalItems": "",
+ "nyeCardAchievementTitle": "",
+ "nyeCardAchievementText": "",
+ "nye0": "",
+ "nye1": "",
+ "nye2": "",
+ "nye3": "",
+ "nye4": "",
+ "holidayCard": "",
+ "mightyBunnySet": "",
+ "magicMouseSet": "",
+ "lovingPupSet": "",
+ "stealthyKittySet": "",
+ "daringSwashbucklerSet": "",
+ "emeraldMermageSet": "",
+ "reefSeahealerSet": "",
+ "roguishPirateSet": "",
+ "monsterOfScienceSet": "",
+ "witchyWizardSet": "",
+ "mummyMedicSet": "",
+ "vampireSmiterSet": "",
+ "bewareDogSet": "",
+ "magicianBunnySet": "",
+ "comfortingKittySet": "",
+ "sneakySqueakerSet": "",
+ "sunfishWarriorSet": "",
+ "shipSoothsayerSet": "",
+ "strappingSailorSet": "",
+ "reefRenegadeSet": "",
+ "scarecrowWarriorSet": "",
+ "stitchWitchSet": "",
+ "potionerSet": "",
+ "battleRogueSet": "",
+ "springingBunnySet": "",
+ "grandMalkinSet": "",
+ "cleverDogSet": "",
+ "braveMouseSet": "",
+ "summer2016SharkWarriorSet": "",
+ "summer2016DolphinMageSet": "",
+ "summer2016SeahorseHealerSet": "",
+ "summer2016EelSet": "",
+ "fall2016SwampThingSet": "",
+ "fall2016WickedSorcererSet": "",
+ "fall2016GorgonHealerSet": "",
+ "fall2016BlackWidowSet": "",
+ "winter2017IceHockeySet": "",
+ "winter2017WinterWolfSet": "",
+ "winter2017SugarPlumSet": "",
+ "winter2017FrostyRogueSet": "",
+ "spring2017FelineWarriorSet": "",
+ "spring2017CanineConjurorSet": "",
+ "spring2017FloralMouseSet": "",
+ "spring2017SneakyBunnySet": "",
+ "summer2017SandcastleWarriorSet": "",
+ "summer2017WhirlpoolMageSet": "",
+ "summer2017SeashellSeahealerSet": "",
+ "summer2017SeaDragonSet": "",
+ "fall2017HabitoweenSet": "",
+ "fall2017MasqueradeSet": "",
+ "fall2017HauntedHouseSet": "",
+ "fall2017TrickOrTreatSet": "",
+ "winter2018ConfettiSet": "",
+ "winter2018GiftWrappedSet": "",
+ "winter2018MistletoeSet": "",
+ "winter2018ReindeerSet": "",
+ "spring2018SunriseWarriorSet": "",
+ "spring2018TulipMageSet": "",
+ "spring2018GarnetHealerSet": "",
+ "spring2018DucklingRogueSet": "",
+ "summer2018BettaFishWarriorSet": "",
+ "summer2018LionfishMageSet": "",
+ "summer2018MerfolkMonarchSet": "",
+ "summer2018FisherRogueSet": "",
+ "fall2018MinotaurWarriorSet": "",
+ "fall2018CandymancerMageSet": "",
+ "fall2018CarnivorousPlantSet": "",
+ "fall2018AlterEgoSet": "",
+ "winter2019BlizzardSet": "",
+ "winter2019PyrotechnicSet": "",
+ "winter2019WinterStarSet": "",
+ "winter2019PoinsettiaSet": "",
+ "eventAvailability": "",
+ "dateEndMarch": "",
+ "dateEndApril": "",
+ "dateEndMay": "",
+ "dateEndJune": "",
+ "dateEndJuly": "",
+ "dateEndAugust": "",
+ "dateEndSeptember": "",
+ "dateEndOctober": "",
+ "dateEndNovember": "",
+ "dateEndJanuary": "",
+ "dateEndFebruary": "",
+ "winterPromoGiftHeader": "",
+ "winterPromoGiftDetails1": "",
+ "winterPromoGiftDetails2": "",
+ "discountBundle": "",
+ "g1g1Announcement": "",
+ "g1g1Details": ""
+}
diff --git a/website/common/locales/eu/loadingscreentips.json b/website/common/locales/eu/loadingscreentips.json
index 765ec2ca30..b5b1fd66e4 100755
--- a/website/common/locales/eu/loadingscreentips.json
+++ b/website/common/locales/eu/loadingscreentips.json
@@ -1,38 +1,38 @@
{
- "tipTitle": "Tip #<%= tipNumber %>",
- "tip1": "Check tasks on the go with the Habitica mobile apps.",
- "tip2": "Click any equipment to see a preview, or equip it instantly by clicking the star in its upper-left corner!",
- "tip3": "Use emoji to quickly differentiate between your tasks.",
- "tip4": "Use the # sign before a task name to make it really big!",
- "tip5": "It’s best to use skills that cause buffs in the morning so they last longer.",
- "tip6": "Hover over a task and click the dots to access advanced task controls, such as the ability to push tasks to the top/bottom of your list.",
- "tip7": "Some backgrounds connect perfectly if Party members use the same background. Ex: Mountain Lake, Pagodas, and Rolling Hills.",
- "tip8": "Send a Message to someone by clicking their name in chat and then clicking the envelope icon at the top of their profile!",
- "tip9": "Use the filters + search bar in the Inventories, Shops, Guilds, and Challenges to quickly find what you want.",
- "tip10": "You can win gems by competing in Challenges. New ones are added every day!",
- "tip11": "Having more than four Party members increases accountability!",
- "tip12": "Add checklists to your To-Dos to multiply your rewards!",
- "tip13": "Click “Tags” on your task page to make an unwieldy task list very manageable!",
- "tip14": "You can add headers or inspirational quotes to your list as Habits with no (+/-).",
- "tip15": "Complete all the Masterclasser Quest-lines to learn about Habitica’s secret lore.",
- "tip16": "Click the link to the Data Display Tool in the footer for valuable insights on your progress.",
- "tip17": "Use the mobile apps to set reminders for your tasks.",
- "tip18": "Habits that are just positive or just negative gradually “fade” and return to yellow.",
- "tip19": "Boost your Intelligence Stat to gain more experience when you complete a task.",
- "tip20": "Boost your Perception Stat to get more drops and gold.",
- "tip21": "Boost your Strength Stat to do more boss damage or get critical hits.",
- "tip22": "Boost your Constitution Stat to lessen the damage from incomplete Dailies.",
- "tip23": "Reach level 100 to unlock the Orb of Rebirth for free and start a new adventure!",
- "tip24": "Have a question? Ask in the Habitica Help Guild!",
- "tip25": "The four seasonal Grand Galas start near the solstices and equinoxes.",
- "tip26": "You can look for a Party or find Party members in the Party Wanted Guild!",
- "tip27": "Did a Daily yesterday, but forgot to check it off? Don't worry! With Record Yesterday's Activity, you'll have a chance to record what you did before starting your new day.",
- "tip28": "Set a Custom Day Start under User Icon > Settings to control when your day restarts.",
- "tip29": "Complete all your Dailies to get a Perfect Day Buff that increases your Stats!",
- "tip30": "You can invite people to Guilds, not just Parties.",
- "tip31": "Check out the pre-made lists in the Library of Tasks and Challenges Guild for example tasks.",
- "tip32": "Lots of Habitica’s code, art, and writing is made by volunteer contributors! Head to the Aspiring Legends Guild to help.",
- "tip33": "Check out The Bulletin Board Guild for news about Guilds, Challenges, and other player-created events - and announce your own there!",
- "tip34": "Occasionally re-evaluate your tasks to make sure they’re up-to-date!",
- "tip35": "Users who are part of a Group Plan gain the ability to assign tasks to other users in that Group for extra task management and accountability."
+ "tipTitle": "<%= tipNumber %>. aholkua",
+ "tip1": "",
+ "tip2": "",
+ "tip3": "",
+ "tip4": "",
+ "tip5": "",
+ "tip6": "",
+ "tip7": "",
+ "tip8": "",
+ "tip9": "",
+ "tip10": "",
+ "tip11": "",
+ "tip12": "",
+ "tip13": "",
+ "tip14": "",
+ "tip15": "",
+ "tip16": "",
+ "tip17": "",
+ "tip18": "",
+ "tip19": "",
+ "tip20": "",
+ "tip21": "",
+ "tip22": "",
+ "tip23": "",
+ "tip24": "",
+ "tip25": "",
+ "tip26": "",
+ "tip27": "",
+ "tip28": "",
+ "tip29": "",
+ "tip30": "",
+ "tip31": "",
+ "tip32": "",
+ "tip33": "",
+ "tip34": "",
+ "tip35": ""
}
diff --git a/website/common/locales/eu/loginincentives.json b/website/common/locales/eu/loginincentives.json
index c8f5248ba9..d8638166f7 100755
--- a/website/common/locales/eu/loginincentives.json
+++ b/website/common/locales/eu/loginincentives.json
@@ -1,29 +1,29 @@
{
- "unlockedReward": "You have received <%= reward %>",
- "earnedRewardForDevotion": "You have earned <%= reward %> for being committed to improving your life.",
- "nextRewardUnlocksIn": "Check-ins until your next prize: <%= numberOfCheckinsLeft %>",
- "awesome": "Awesome!",
- "totalCount": "<%= count %> total count",
- "countLeft": "Check-ins until next reward: <%= count %>",
- "incentivesDescription": "When it comes to building habits, consistency is key. Each day you check-in you get closer to a prize.",
- "totalCheckins": "<%= count %> Check-Ins",
- "checkinEarned": "Your Check-In Counter went up!",
- "unlockedCheckInReward": "You unlocked a Check-In Prize!",
- "totalCheckinsTitle": "Total Check-Ins",
- "checkinProgressTitle": "Progress until next",
- "incentiveBackgroundsUnlockedWithCheckins": "Locked Plain Backgrounds will unlock with Daily Check-Ins.",
- "checkinReceivedAllRewardsMessage": "You have received all the Check-In prizes available! Congratulations!",
- "oneOfAllPetEggs": "one of each standard Pet Egg",
- "twoOfAllPetEggs": "two of each standard Pet Egg",
- "threeOfAllPetEggs": "three of each standard Pet Egg",
- "oneOfAllHatchingPotions": "one of each standard Hatching Potion",
- "threeOfEachFood": "three of each standard Pet Food",
- "fourOfEachFood": "four of each standard Pet Food",
- "twoSaddles": "two Saddles",
- "threeSaddles": "three Saddles",
- "incentiveAchievement": "the Royally Loyal achievement",
- "royallyLoyal": "Royally Loyal",
- "royallyLoyalText": "This user has checked in over 500 times, and has earned every Check-In Prize!",
- "checkInRewards": "Check-In Rewards",
- "backloggedCheckInRewards": "You received Check-In Prizes! Visit your Inventory and Equipment to see what's new."
+ "unlockedReward": "",
+ "earnedRewardForDevotion": "",
+ "nextRewardUnlocksIn": "",
+ "awesome": "",
+ "totalCount": "",
+ "countLeft": "",
+ "incentivesDescription": "",
+ "totalCheckins": "",
+ "checkinEarned": "",
+ "unlockedCheckInReward": "",
+ "totalCheckinsTitle": "",
+ "checkinProgressTitle": "",
+ "incentiveBackgroundsUnlockedWithCheckins": "",
+ "checkinReceivedAllRewardsMessage": "",
+ "oneOfAllPetEggs": "",
+ "twoOfAllPetEggs": "",
+ "threeOfAllPetEggs": "",
+ "oneOfAllHatchingPotions": "",
+ "threeOfEachFood": "",
+ "fourOfEachFood": "",
+ "twoSaddles": "",
+ "threeSaddles": "",
+ "incentiveAchievement": "",
+ "royallyLoyal": "",
+ "royallyLoyalText": "",
+ "checkInRewards": "",
+ "backloggedCheckInRewards": ""
}
diff --git a/website/common/locales/eu/maintenance.json b/website/common/locales/eu/maintenance.json
index 8678d61654..d6fa68e62e 100755
--- a/website/common/locales/eu/maintenance.json
+++ b/website/common/locales/eu/maintenance.json
@@ -1,34 +1,33 @@
{
- "habiticaBackSoon": "Don't worry, Habitica will be back soon!",
- "importantMaintenance": "We are doing important maintenance that we estimate will last until 10pm Pacific Time (5am UTC).",
- "maintenance": "Maintenance",
- "maintenanceMoreInfo": "Want more information about the maintenance? <%= linkStart %>Check out our info page<%= linkEnd %>.",
- "noDamageKeepStreaks": "You will NOT take damage or lose streaks!",
- "thanksForPatience": "Thanks for your patience!",
- "twitterMaintenanceUpdates": "For the most recent updates, watch our Twitter, where we will be posting status information.",
- "veteranPetAward": "At the end, you will receive a Veteran pet!",
-
- "maintenanceInfoTitle": "Information about Upcoming Maintenance to Habitica",
- "maintenanceInfoWhat": "What is happening?",
- "maintenanceInfoWhatText": "On May 21, Habitica will be down for maintenance for most of the day. You will not take any damage or have your account harmed during that weekend, even if you can’t log in to check off your Dailies in time! We will be working very hard to make the downtime as short as possible, and will be posting regular updates on our Twitter account. At the end of the downtime, to thank everyone for their patience, you will all receive a rare pet!",
- "maintenanceInfoWhy": "Why is this happening?",
- "maintenanceInfoWhyText": "For the past several months, we have been thoroughly revamping Habitica behind-the-scenes. Specifically, we have rewritten the API. While it may not look much different on the surface, it’s a whole new world underneath. This will allow us WAY more flexibility when we want to build features in the future, and lead to improved performance!",
- "maintenanceInfoTechDetails": "Want more details on the technical side of the process? Visit The Forge, our dev blog.",
- "maintenanceInfoMore": "More Information",
- "maintenanceInfoAccountChanges": "What changes will I see to my account after the rewrite is complete?",
- "maintenanceInfoAccountChangesText": "At first, there won’t be any notable changes aside from performance improvements for features such as Challenges. If you notice any changes that shouldn’t be there, email us at <%= hrefTechAssistanceEmail %> and we will investigate them for you!",
- "maintenanceInfoAddFeatures": "What kind of features will this allow Habitica to add?",
- "maintenanceInfoAddFeaturesText": "Completing this rewrite will allow us to start building out improved chat and Guilds, plans for organizations and families, and additional productivity features like Monthlies and the ability to record yesterday’s activity! Those are all involved features on their own, so it will take time to build them, but until we were finished with this rewrite, there was no way we could start them.",
- "maintenanceInfoHowLong": "How long will the maintenance take?",
- "maintenanceInfoHowLongText": "We have to migrate tasks and data for all 1.3 million Habitica users -- not an easy task! We anticipate that it will take place between approximately 1pm Pacific Time (8pm UTC) and 10pm Pacific Time (5am UTC). Rest assured that we’re doing everything we can to make it go as quickly as possible! You can follow updates on our Twitter.",
- "maintenanceInfoStatsAffected": "How will my Dailies, Streaks, Buffs, and Quests be affected?",
- "maintenanceInfoStatsAffectedText1": "You will NOT take any damage or lose any streaks that weekend, but otherwise, your day will reset normally! Dailies that you checked will become unchecked, buffs will reset, etc. If you are in a Collection Quest, you will still find items. If you are in a Boss Battle, you will still deal damage to the Boss, but the Boss will not deal damage to you. (Even monsters need a break!)",
- "maintenanceInfoStatsAffectedText2": "After a lot of thought, our team concluded that this was the most fair way to handle the fact that many users will not be able to check off their Dailies normally during the maintenance. We’re sorry for any inconvenience this causes!",
- "maintenanceInfoSeeTasks": "What if I need to see my task list?",
- "maintenanceInfoSeeTasksText": "If you know that you will need to see your task list on Saturday to remind yourself what you have to do, we recommend that before the maintenance begins, you take a screenshot of your tasks so that you can use it as a reference.",
- "maintenanceInfoRarePet": "What kind of rare pet will I receive?",
- "maintenanceInfoRarePetText": "To thank you for your patience during the downtime, everyone will get a rare Veteran Pet. If you’ve never received a Veteran Pet before, you will receive a Veteran Wolf. If you already have a Veteran Wolf, you will receive a Veteran Tiger. And if you already have a Veteran Wolf and a Veteran Tiger, you will receive a never-before-seen Veteran pet! After the migration is completed, it may take several hours for your pet to show up, but never fear, everyone will get one.",
- "maintenanceInfoWho": "Who worked on this massive project?",
- "maintenanceInfoWhoText": "We’re glad you asked! It was spearheaded by our amazing contributor paglias, with lots of help from Blade, TheHollidayInn, SabreCat, Victor Pudeyev, TheUnknown, and Alys.",
- "maintenanceInfoTesting": "The new version was also tirelessly tested by a bunch of our amazing open-source volunteers. Thank you -- we couldn't have done this without you."
+ "habiticaBackSoon": "",
+ "importantMaintenance": "",
+ "maintenance": "",
+ "maintenanceMoreInfo": "",
+ "noDamageKeepStreaks": "",
+ "thanksForPatience": "",
+ "twitterMaintenanceUpdates": "",
+ "veteranPetAward": "",
+ "maintenanceInfoTitle": "",
+ "maintenanceInfoWhat": "",
+ "maintenanceInfoWhatText": "",
+ "maintenanceInfoWhy": "",
+ "maintenanceInfoWhyText": "",
+ "maintenanceInfoTechDetails": "",
+ "maintenanceInfoMore": "",
+ "maintenanceInfoAccountChanges": "",
+ "maintenanceInfoAccountChangesText": "",
+ "maintenanceInfoAddFeatures": "",
+ "maintenanceInfoAddFeaturesText": "",
+ "maintenanceInfoHowLong": "",
+ "maintenanceInfoHowLongText": "",
+ "maintenanceInfoStatsAffected": "",
+ "maintenanceInfoStatsAffectedText1": "",
+ "maintenanceInfoStatsAffectedText2": "",
+ "maintenanceInfoSeeTasks": "",
+ "maintenanceInfoSeeTasksText": "",
+ "maintenanceInfoRarePet": "",
+ "maintenanceInfoRarePetText": "",
+ "maintenanceInfoWho": "",
+ "maintenanceInfoWhoText": "",
+ "maintenanceInfoTesting": ""
}
diff --git a/website/common/locales/eu/merch.json b/website/common/locales/eu/merch.json
index cca4a94a81..794f0cb76e 100755
--- a/website/common/locales/eu/merch.json
+++ b/website/common/locales/eu/merch.json
@@ -1,20 +1,14 @@
{
- "merch" : "Merchandise",
- "merchandiseDescription": "Looking for t-shirts, mugs, or stickers to show off your Habitica pride? Click here!",
-
- "merch-teespring-summary" : "Teespring is a platform that makes it easy for anyone to create and sell high-quality products people love, with no cost or risk.",
- "merch-teespring-goto" : "Get a Habitica T-shirt",
-
- "merch-teespring-mug-summary" : "Teespring is a platform that makes it easy for anyone to create and sell high-quality products people love, with no cost or risk.",
- "merch-teespring-mug-goto" : "Get a Habitica Mug",
-
- "merch-teespring-eu-summary" : "EUROPEAN VERSION : Teespring is a platform that makes it easy for anyone to create and sell high-quality products people love, with no cost or risk.",
- "merch-teespring-eu-goto" : "Get a Habitica T-shirt (EU)",
-
- "merch-teespring-mug-eu-summary" : "EUROPEAN VERSION : Teespring is a platform that makes it easy for anyone to create and sell high-quality products people love, with no cost or risk.",
- "merch-teespring-mug-eu-goto" : "Get a Habitica Mug (EU)",
-
- "merch-stickermule-summary" : "Stick proud Melior wherever you (or someone else) need a reminder of both present and future accomplishments!",
- "merch-stickermule-goto" : "Get Habitica stickers"
-
+ "merch": "",
+ "merchandiseDescription": "",
+ "merch-teespring-summary": "",
+ "merch-teespring-goto": "",
+ "merch-teespring-mug-summary": "",
+ "merch-teespring-mug-goto": "",
+ "merch-teespring-eu-summary": "",
+ "merch-teespring-eu-goto": "",
+ "merch-teespring-mug-eu-summary": "",
+ "merch-teespring-mug-eu-goto": "",
+ "merch-stickermule-summary": "",
+ "merch-stickermule-goto": ""
}
diff --git a/website/common/locales/eu/messages.json b/website/common/locales/eu/messages.json
index bd44447ecb..c9aa434922 100755
--- a/website/common/locales/eu/messages.json
+++ b/website/common/locales/eu/messages.json
@@ -1,66 +1,66 @@
{
- "messageLostItem": "Your <%= itemText %> broke.",
- "messageTaskNotFound": "Task not found.",
- "messageDuplicateTaskID": "A task with that ID already exists.",
- "messageTagNotFound": "Tag not found.",
- "messagePetNotFound": ":pet not found in user.items.pets",
- "messageFoodNotFound": ":food not found in user.items.food",
- "messageNotAvailable": "This item is not currently available for purchase.",
- "messageCannotFeedPet": "Can't feed this pet.",
- "messageAlreadyMount": "You already have that mount. Try feeding another pet.",
- "messageEvolve": "You have tamed <%= egg %>, let's go for a ride!",
- "messageLikesFood": "<%= egg %> really likes <%= foodText %>!",
- "messageDontEnjoyFood": "<%= egg %> eats <%= foodText %> but doesn't seem to enjoy it.",
- "messageBought": "Bought <%= itemText %>",
- "messageEquipped": "<%= itemText %> equipped.",
- "messageUnEquipped": "<%= itemText %> unequipped.",
- "messageMissingEggPotion": "You're missing either that egg or that potion",
- "messageInvalidEggPotionCombo": "You can't hatch Quest Pet Eggs with Magic Hatching Potions! Try a different egg.",
- "messageAlreadyPet": "You already have that pet. Try hatching a different combination!",
- "messageHatched": "Your egg hatched! Visit your stable to equip your pet.",
- "messageNotEnoughGold": "Not Enough Gold",
- "messageTwoHandedEquip": "Wielding <%= twoHandedText %> takes two hands, so <%= offHandedText %> has been unequipped.",
- "messageTwoHandedUnequip": "Wielding <%= twoHandedText %> takes two hands, so it was unequipped when you armed yourself with <%= offHandedText %>.",
- "messageDropFood": "You've found <%= dropText %>!",
- "messageDropEgg": "You've found a <%= dropText %> Egg!",
- "messageDropPotion": "You've found a <%= dropText %> Hatching Potion!",
- "messageDropQuest": "You've found a quest!",
- "messageDropMysteryItem": "You open the box and find <%= dropText %>!",
- "messageFoundQuest": "You've found the quest \"<%= questText %>\"!",
- "messageAlreadyPurchasedGear": "You purchased this gear in the past, but do not currently own it. You can buy it again in the rewards column on the tasks page.",
- "messageAlreadyOwnGear": "You already own this item. Equip it by going to the equipment page.",
- "previousGearNotOwned": "You need to purchase a lower level gear before this one.",
- "messageHealthAlreadyMax": "You already have maximum health.",
- "messageHealthAlreadyMin": "Oh no! You have already run out of health so it's too late to buy a health potion, but don't worry - you can revive!",
- "armoireEquipment": "<%= image %> You found a piece of rare Equipment in the Armoire: <%= dropText %>! Awesome!",
- "armoireFood": "<%= image %> You rummage in the Armoire and find <%= dropText %>. What's that doing in here?",
- "armoireExp": "You wrestle with the Armoire and gain Experience. Take that!",
- "messageInsufficientGems": "Not enough gems!",
- "messageAuthPasswordMustMatch": ":password and :confirmPassword don't match",
- "messageAuthCredentialsRequired": ":username, :email, :password, :confirmPassword required",
- "messageAuthEmailTaken": "Email already taken",
- "messageAuthNoUserFound": "No user found.",
- "messageAuthMustBeLoggedIn": "You must be logged in.",
- "messageAuthMustIncludeTokens": "You must include a token and uid (user id) in your request",
- "messageGroupAlreadyInParty": "Already in a party, try refreshing.",
- "messageGroupOnlyLeaderCanUpdate": "Only the group leader can update the group!",
- "messageGroupRequiresInvite": "Can't join a group you're not invited to.",
- "messageGroupCannotRemoveSelf": "You cannot remove yourself!",
- "messageGroupChatBlankMessage": "You cannot send a blank message",
- "messageGroupChatLikeOwnMessage": "Can't like your own message. Don't be that person.",
- "messageGroupChatFlagAlreadyReported": "You have already reported this message",
- "messageGroupChatNotFound": "Message not found!",
- "messageGroupChatAdminClearFlagCount": "Only an admin can clear the flag count!",
- "messageCannotFlagSystemMessages": "You cannot flag a system message. If you need to report a violation of the Community Guidelines related to this message, please email a screenshot and explanation to Lemoness at <%= communityManagerEmail %>.",
- "messageGroupChatSpam": "Whoops, looks like you're posting too many messages! Please wait a minute and try again. The Tavern chat only holds 200 messages at a time, so Habitica encourages posting longer, more thoughtful messages and consolidating replies. Can't wait to hear what you have to say. :)",
- "messageCannotLeaveWhileQuesting": "You cannot accept this party invitation while you are in a quest. If you'd like to join this party, you must first abort your quest, which you can do from your party screen. You will be given back the quest scroll.",
- "messageUserOperationProtected": "path `<%= operation %>` was not saved, as it's a protected path.",
- "messageUserOperationNotFound": "<%= operation %> operation not found",
- "messageNotificationNotFound": "Notification not found.",
- "messageNotAbleToBuyInBulk": "This item cannot be purchased in quantities above 1.",
- "notificationsRequired": "Notification ids are required.",
- "unallocatedStatsPoints": "You have <%= points %> unallocated Stat Points",
- "beginningOfConversation": "This is the beginning of your conversation with <%= userName %>. Remember to be kind, respectful, and follow the Community Guidelines!",
- "messageDeletedUser": "Sorry, this user has deleted their account.",
- "messageMissingDisplayName": "Missing display name."
-}
\ No newline at end of file
+ "messageLostItem": "",
+ "messageTaskNotFound": "",
+ "messageDuplicateTaskID": "",
+ "messageTagNotFound": "",
+ "messagePetNotFound": "",
+ "messageFoodNotFound": "",
+ "messageNotAvailable": "",
+ "messageCannotFeedPet": "",
+ "messageAlreadyMount": "",
+ "messageEvolve": "",
+ "messageLikesFood": "",
+ "messageDontEnjoyFood": "",
+ "messageBought": "",
+ "messageEquipped": "",
+ "messageUnEquipped": "",
+ "messageMissingEggPotion": "",
+ "messageInvalidEggPotionCombo": "",
+ "messageAlreadyPet": "",
+ "messageHatched": "",
+ "messageNotEnoughGold": "",
+ "messageTwoHandedEquip": "",
+ "messageTwoHandedUnequip": "",
+ "messageDropFood": "",
+ "messageDropEgg": "",
+ "messageDropPotion": "",
+ "messageDropQuest": "",
+ "messageDropMysteryItem": "",
+ "messageFoundQuest": "",
+ "messageAlreadyPurchasedGear": "",
+ "messageAlreadyOwnGear": "",
+ "previousGearNotOwned": "",
+ "messageHealthAlreadyMax": "",
+ "messageHealthAlreadyMin": "",
+ "armoireEquipment": "",
+ "armoireFood": "",
+ "armoireExp": "",
+ "messageInsufficientGems": "",
+ "messageAuthPasswordMustMatch": "",
+ "messageAuthCredentialsRequired": "",
+ "messageAuthEmailTaken": "",
+ "messageAuthNoUserFound": "",
+ "messageAuthMustBeLoggedIn": "",
+ "messageAuthMustIncludeTokens": "",
+ "messageGroupAlreadyInParty": "",
+ "messageGroupOnlyLeaderCanUpdate": "",
+ "messageGroupRequiresInvite": "",
+ "messageGroupCannotRemoveSelf": "",
+ "messageGroupChatBlankMessage": "",
+ "messageGroupChatLikeOwnMessage": "",
+ "messageGroupChatFlagAlreadyReported": "",
+ "messageGroupChatNotFound": "",
+ "messageGroupChatAdminClearFlagCount": "",
+ "messageCannotFlagSystemMessages": "",
+ "messageGroupChatSpam": "",
+ "messageCannotLeaveWhileQuesting": "",
+ "messageUserOperationProtected": "",
+ "messageUserOperationNotFound": "",
+ "messageNotificationNotFound": "",
+ "messageNotAbleToBuyInBulk": "",
+ "notificationsRequired": "",
+ "unallocatedStatsPoints": "",
+ "beginningOfConversation": "",
+ "messageDeletedUser": "",
+ "messageMissingDisplayName": ""
+}
diff --git a/website/common/locales/eu/noscript.json b/website/common/locales/eu/noscript.json
index 6057268ef2..bc9dd1536f 100755
--- a/website/common/locales/eu/noscript.json
+++ b/website/common/locales/eu/noscript.json
@@ -1,6 +1,6 @@
{
- "jsDisabledHeading": "Alas! Your browser doesn't have JavaScript enabled",
- "jsDisabledHeadingFull": "Alas! Your browser doesn't have JavaScript enabled and without it, Habitica can't work properly",
- "jsDisabledText": "Habitica can't properly display the site without it!",
- "jsDisabledLink": "Please enable JavaScript to continue!"
-}
\ No newline at end of file
+ "jsDisabledHeading": "Hara! JavaScript ez dago gaituta arakatzailean",
+ "jsDisabledHeadingFull": "Hara! JavaScript ez dago gaituta arakatzailean. Hura gabe, Habitica-k ezin du ongi funtzionatu.",
+ "jsDisabledText": "",
+ "jsDisabledLink": ""
+}
diff --git a/website/common/locales/eu/npc.json b/website/common/locales/eu/npc.json
index 8e01d21b1f..47cbf84a33 100755
--- a/website/common/locales/eu/npc.json
+++ b/website/common/locales/eu/npc.json
@@ -1,171 +1,171 @@
{
- "npc": "NPC",
- "npcAchievementName": "<%= key %> NPC",
- "npcAchievementText": "Backed the Kickstarter project at the maximum level!",
- "welcomeTo": "Welcome to",
- "welcomeBack": "Welcome back!",
- "justin": "Justin",
- "justinIntroMessage1": "Hello there! You must be new here. My name is Justin, and I'll be your guide in Habitica.",
- "justinIntroMessage2": "To start, you'll need to create an avatar.",
- "justinIntroMessage3": "Great! Now, what are you interested in working on throughout this journey?",
- "justinIntroMessageUsername": "Before we begin, let’s figure out what to call you. Below you’ll find a display name and username I’ve generated for you. After you’ve picked a display name and username, we’ll get started by creating an avatar!",
- "justinIntroMessageAppearance": "So how would you like to look? Don’t worry, you can change this later.",
- "introTour": "Here we are! I've filled out some Tasks for you based on your interests, so you can get started right away. Click a Task to edit or add new Tasks to fit your routine!",
- "prev": "Prev",
- "next": "Next",
- "randomize": "Randomize",
- "mattBoch": "Matt Boch",
- "mattShall": "Shall I bring you your steed, <%= name %>? Once you've fed a pet enough food to turn it into a mount, it will appear here. Click a mount to saddle up!",
- "mattBochText1": "Welcome to the Stable! I'm Matt, the beast master. Starting at level 3, you will find eggs and potions to hatch pets with. When you hatch a pet in the Market, it will appear here! Click a pet's image to add it to your avatar. Feed them with the food you find after level 3, and they'll grow into hardy mounts.",
- "welcomeToTavern": "Welcome to The Tavern!",
- "sleepDescription": "Need a break? Check into Daniel's Inn to pause some of Habitica's more difficult game mechanics:",
- "sleepBullet1": "Missed Dailies won't damage you",
- "sleepBullet2": "Tasks won't lose streaks or decay in color",
- "sleepBullet3": "Bosses won't do damage for your missed Dailies",
- "sleepBullet4": "Your boss damage or collection Quest items will stay pending until check-out",
- "pauseDailies": "Pause Damage",
- "unpauseDailies": "Unpause Damage",
- "staffAndModerators": "Staff and Moderators",
- "communityGuidelinesIntro": "Habitica tries to create a welcoming environment for users of all ages and backgrounds, especially in public spaces like the Tavern. If you have any questions, please consult our Community Guidelines.",
- "acceptCommunityGuidelines": "I agree to follow the Community Guidelines",
- "daniel": "Daniel",
- "danielText": "Welcome to the Tavern! Stay a while and meet the locals. If you need to rest (vacation? illness?), I'll set you up at the Inn. While checked-in, your Dailies won't hurt you at the day's end, but you can still check them off.",
- "danielText2": "Be warned: If you are participating in a boss quest, the boss will still damage you for your party mates' missed Dailies! Also, your own damage to the Boss (or items collected) will not be applied until you check out of the Inn.",
- "danielTextBroken": "Welcome to the Tavern... I guess... If you need to rest, I'll set you up at the Inn... While checked-in, your Dailies won't hurt you at the day's end, but you can still check them off... if you have the energy...",
- "danielText2Broken": "Oh... If you are participating in a boss quest, the boss will still damage you for your party mates' missed Dailies... Also, your own damage to the Boss (or items collected) will not be applied until you check out of the Inn...",
- "worldBossEvent": "World Boss Event",
- "worldBossDescription": "World Boss Description",
- "alexander": "Alexander the Merchant",
- "welcomeMarket": "Welcome to the Market! Buy hard-to-find eggs and potions! Sell your extras! Commission useful services! Come see what we have to offer.",
- "welcomeMarketMobile": "Welcome to the Market! Buy hard-to-find eggs and potions! Come see what we have to offer.",
- "displayItemForGold": "Do you want to sell a <%= itemType %>?",
- "displayEggForGold": "Do you want to sell a <%= itemType %> Egg?",
- "displayPotionForGold": "Do you want to sell a <%= itemType %> Potion?",
- "sellForGold": "Sell it for <%= gold %> Gold",
- "howManyToSell": "How many would you like to sell?",
- "yourBalance": "Your balance",
- "sell": "Sell",
- "buyNow": "Buy Now",
- "sortByNumber": "Number",
- "featuredItems": "Featured Items!",
- "hideLocked": "Hide locked",
- "hidePinned": "Hide pinned",
- "hideMissing": "Hide Missing",
- "amountExperience": "<%= amount %> Experience",
- "amountGold": "<%= amount %> Gold",
- "namedHatchingPotion": "<%= type %> Hatching Potion",
- "buyGems": "Buy Gems",
- "purchaseGems": "Purchase Gems",
- "items": "Items",
- "AZ": "A-Z",
- "sort": "Sort",
- "sortBy": "Sort By",
- "groupBy2": "Group By",
- "sortByName": "Name",
- "quantity": "Quantity",
- "cost": "Cost",
- "shops": "Shops",
- "custom": "Custom",
- "wishlist": "Wishlist",
- "wrongItemType": "The item type \"<%= type %>\" is not valid.",
- "wrongItemPath": "The item path \"<%= path %>\" is not valid.",
- "unpinnedItem": "You unpinned <%= item %>! It will no longer display in your Rewards column.",
- "cannotUnpinArmoirPotion": "The Health Potion and Enchanted Armoire cannot be unpinned.",
- "purchasedItem": "You bought <%= itemName %>",
- "ian": "Ian",
- "ianText": "Welcome to the Quest Shop! Here you can use Quest Scrolls to battle monsters with your friends. Be sure to check out our fine array of Quest Scrolls for purchase on the right!",
- "ianTextMobile": "Can I interest you in some quest scrolls? Activate them to battle monsters with your Party!",
- "ianBrokenText": "Welcome to the Quest Shop... Here you can use Quest Scrolls to battle monsters with your friends... Be sure to check out our fine array of Quest Scrolls for purchase on the right...",
- "featuredQuests": "Featured Quests!",
- "cannotBuyItem": "You can't buy this item.",
- "mustPurchaseToSet": "Must purchase <%= val %> to set it on <%= key %>.",
- "typeRequired": "Type is required",
- "positiveAmountRequired": "Positive amount is required",
- "notAccteptedType": "Type must be in [eggs, hatchingPotions, premiumHatchingPotions, food, quests, gear]",
- "contentKeyNotFound": "Key not found for Content <%= type %>",
- "plusGem": "+<%= count %> Gem",
- "typeNotSellable": "Type is not sellable. Must be one of the following <%= acceptedTypes %>",
- "userItemsKeyNotFound": "Key not found for user.items <%= type %>",
- "userItemsNotEnough": "You do not have enough <%= type %>",
- "pathRequired": "Path string is required",
- "unlocked": "Items have been unlocked",
- "alreadyUnlocked": "Full set already unlocked.",
- "alreadyUnlockedPart": "Full set already partially unlocked.",
- "invalidQuantity": "Quantity to purchase must be a number.",
- "USD": "(USD)",
- "newStuff": "New Stuff by Bailey",
- "newBaileyUpdate": "New Bailey Update!",
- "tellMeLater": "Tell Me Later",
- "dismissAlert": "Dismiss This Alert",
- "donateText1": "Adds 20 Gems to your account. Gems are used to buy special in-game items, such as shirts and hairstyles.",
- "donateText2": "Help support Habitica",
- "donateText3": "Habitica is an open source project that depends on our users for support. The money you spend on gems helps us keep the servers running, maintain a small staff, develop new features, and provide incentives for our volunteer programmers. Thank you for your generosity!",
- "donationDesc": "20 Gems, Donation to Habitica",
- "payWithCard": "Pay with Card",
- "payNote": "Note: PayPal sometimes takes a long time to clear. We recommend paying with card.",
- "card": "Credit Card (using Stripe)",
- "amazonInstructions": "Click the button to pay using Amazon Payments",
- "paymentMethods": "Purchase using",
- "paymentSuccessful": "Your payment was successful!",
- "paymentYouReceived": "You received:",
- "paymentYouSentGems": "You sent <%= name %>:",
- "paymentYouSentSubscription": "You sent <%= name %> a <%= months %>-months Habitica subscription.",
- "paymentSubBilling": "Your subscription will be billed $<%= amount %> every <%= months %> months.",
- "success": "Success!",
- "classGear": "Class Gear",
- "classGearText": "Congratulations on choosing a class! I've added your new basic weapon to your inventory. Take a look below to equip it!",
- "classStats": "These are your class's Stats; they affect the game-play. Each time you level up, you get one Point to allocate to a particular Stat. Hover over each Stat for more information.",
- "autoAllocate": "Auto Allocate",
- "autoAllocateText": "If 'Automatic Allocation' is selected, your avatar gains Stats automatically based on your tasks' Stats, which you can find in TASK > Edit > Advanced Settings > Stat Allocation. Eg, if you hit the gym often, and your 'Gym' Daily is set to 'Strength', you'll gain Strength automatically.",
- "spells": "Skills",
- "spellsText": "You can now unlock class-specific skills. You'll see your first at level 11. Your mana replenishes 10 points per day, plus 1 point per completed To-Do.",
- "skillsTitle": "Skills",
- "toDo": "To-Do",
- "moreClass": "For more information on the class-system, see Wikia.",
- "tourWelcome": "Welcome to Habitica! This is your To-Do list. Check off a task to proceed!",
- "tourExp": "Great job! Checking off a task gives you Experience and Gold!",
- "tourDailies": "This column is for Daily tasks. To proceed, enter a task you should do every day! Sample Dailies: Make Bed, Floss, Check Work Email",
- "tourCron": "Splendid! Your Dailies will reset every day.",
- "tourHP": "Watch out! If you don't complete a Daily by midnight, it will hurt you!",
- "tourHabits": "This column is for good and bad Habits that you do many times a day! To proceed, click the pencil to edit the names, then click the checkmark to save.",
- "tourStats": "Good Habits add Experience and Gold! Bad Habits remove health.",
- "tourGP": "To proceed, buy the Training Sword with the gold you just earned!",
- "tourAvatar": "Customize Your Avatar
Your avatar represents you.
Customize now, or return later.
Your avatar starts plain until you've earned Equipment!
",
- "tourScrollDown": "Be sure to scroll all the way down to see all the options! Click on your avatar again to return to the tasks page.",
- "tourMuchMore": "When you're done with tasks, you can form a Party with friends, chat in the shared-interest Guilds, join Challenges, and more!",
- "tourStatsPage": "This is your Stats page! Earn achievements by completing the listed tasks.",
- "tourTavernPage": "Welcome to the Tavern, an all-ages chat room! You can keep your Dailies from hurting you in case of illness or travel by clicking \"Pause Damage\". Come say hi!",
- "tourPartyPage": "Your Party will help you stay accountable. Invite friends to unlock a Quest Scroll!",
- "tourGuildsPage": "Guilds are common-interest chat groups created by the players, for the players. Browse through the list and join the Guilds that interest you. Be sure to check out the popular Habitica Help: Ask a Question guild, where anyone can ask questions about Habitica!",
- "tourChallengesPage": "Challenges are themed task lists created by users! Joining a Challenge will add its tasks to your account. Compete against other users to win Gem prizes!",
- "tourMarketPage": "Starting at Level 4, eggs and hatching potions drop randomly when you complete tasks. They appear here - use them to hatch pets! You can also buy items from the Market.",
- "tourHallPage": "Welcome to the Hall of Heroes, where open-source contributors to Habitica are honored. Whether through code, art, music, writing, or even just helpfulness, they have earned Gems, exclusive equipment, and prestigious titles. You can contribute to Habitica, too!",
- "tourPetsPage": "This is the Stable! After reaching level 3, you will gather pet eggs and hatching potions as you complete tasks. When you hatch a pet in the Market, it will appear here! Click a pet's image to add it to your avatar. Feed them with the food you find after level 3, and they'll grow into powerful mounts.",
- "tourMountsPage": "Once you've fed a pet enough food to turn it into a mount, it will appear here. Click a mount to saddle up!",
- "tourEquipmentPage": "This is where your Equipment is stored! Your Battle Gear affects your Stats. If you want to show different Equipment on your avatar without changing your Stats, click \"Enable Costume.\"",
- "equipmentAlreadyOwned": "You already own that piece of equipment",
- "tourOkay": "Okay!",
- "tourAwesome": "Awesome!",
- "tourSplendid": "Splendid!",
- "tourNifty": "Nifty!",
- "tourAvatarProceed": "Show me my tasks!",
- "tourToDosBrief": "To-Do List
Check off To-Dos to earn Gold & Experience!
To-Dos never make your avatar lose Health.
",
- "tourDailiesBrief": "Daily Tasks
Dailies repeat every day.
You lose Health if you skip Dailies.
",
- "tourDailiesProceed": "I'll be careful!",
- "tourHabitsBrief": "Good & Bad Habits
Good Habits award Gold & Experience.
Bad Habits make you lose Health.
",
- "tourHabitsProceed": "Makes sense!",
- "tourRewardsBrief": "Reward List
Spend your hard-earned Gold here!
Purchase Equipment for your avatar, or set custom Rewards.
",
- "tourRewardsArmoire": "Reward List
Spend your hard-earned Gold here!
Purchase Equipment for your avatar, get a random prize from the Enchanted Armoire, or set custom Rewards.
",
- "tourRewardsProceed": "That's all!",
- "welcomeToHabit": "Welcome to Habitica!",
- "welcome1": "Create a basic avatar.",
- "welcome1notes": "This avatar will represent you as you progress.",
- "welcome2": "Set up your tasks.",
- "welcome2notes": "How well you do on your real-life tasks will control how well you do in the game!",
- "welcome3": "Progress in life and the game!",
- "welcome3notes": "As you improve your life, your avatar will level up and unlock pets, quests, equipment, and more!",
- "welcome4": "Avoid bad habits that drain Health (HP), or your avatar will die!",
- "welcome5": "Now you'll customize your avatar and set up your tasks...",
- "imReady": "Enter Habitica",
- "limitedOffer": "Available until <%= date %>"
-}
\ No newline at end of file
+ "npc": "",
+ "npcAchievementName": "",
+ "npcAchievementText": "",
+ "welcomeTo": "",
+ "welcomeBack": "",
+ "justin": "",
+ "justinIntroMessage1": "",
+ "justinIntroMessage2": "",
+ "justinIntroMessage3": "",
+ "justinIntroMessageUsername": "",
+ "justinIntroMessageAppearance": "",
+ "introTour": "",
+ "prev": "",
+ "next": "",
+ "randomize": "",
+ "mattBoch": "",
+ "mattShall": "",
+ "mattBochText1": "",
+ "welcomeToTavern": "",
+ "sleepDescription": "",
+ "sleepBullet1": "",
+ "sleepBullet2": "",
+ "sleepBullet3": "",
+ "sleepBullet4": "",
+ "pauseDailies": "",
+ "unpauseDailies": "",
+ "staffAndModerators": "",
+ "communityGuidelinesIntro": "",
+ "acceptCommunityGuidelines": "",
+ "daniel": "",
+ "danielText": "",
+ "danielText2": "",
+ "danielTextBroken": "",
+ "danielText2Broken": "",
+ "worldBossEvent": "",
+ "worldBossDescription": "",
+ "alexander": "",
+ "welcomeMarket": "",
+ "welcomeMarketMobile": "",
+ "displayItemForGold": "",
+ "displayEggForGold": "",
+ "displayPotionForGold": "",
+ "sellForGold": "",
+ "howManyToSell": "",
+ "yourBalance": "",
+ "sell": "",
+ "buyNow": "",
+ "sortByNumber": "",
+ "featuredItems": "",
+ "hideLocked": "",
+ "hidePinned": "",
+ "hideMissing": "",
+ "amountExperience": "",
+ "amountGold": "",
+ "namedHatchingPotion": "",
+ "buyGems": "",
+ "purchaseGems": "",
+ "items": "",
+ "AZ": "",
+ "sort": "",
+ "sortBy": "",
+ "groupBy2": "",
+ "sortByName": "",
+ "quantity": "",
+ "cost": "",
+ "shops": "",
+ "custom": "",
+ "wishlist": "",
+ "wrongItemType": "",
+ "wrongItemPath": "",
+ "unpinnedItem": "",
+ "cannotUnpinArmoirPotion": "",
+ "purchasedItem": "",
+ "ian": "",
+ "ianText": "",
+ "ianTextMobile": "",
+ "ianBrokenText": "",
+ "featuredQuests": "",
+ "cannotBuyItem": "",
+ "mustPurchaseToSet": "",
+ "typeRequired": "",
+ "positiveAmountRequired": "",
+ "notAccteptedType": "",
+ "contentKeyNotFound": "",
+ "plusGem": "",
+ "typeNotSellable": "",
+ "userItemsKeyNotFound": "",
+ "userItemsNotEnough": "",
+ "pathRequired": "",
+ "unlocked": "",
+ "alreadyUnlocked": "",
+ "alreadyUnlockedPart": "",
+ "invalidQuantity": "",
+ "USD": "",
+ "newStuff": "",
+ "newBaileyUpdate": "",
+ "tellMeLater": "",
+ "dismissAlert": "",
+ "donateText1": "",
+ "donateText2": "",
+ "donateText3": "",
+ "donationDesc": "",
+ "payWithCard": "",
+ "payNote": "",
+ "card": "",
+ "amazonInstructions": "",
+ "paymentMethods": "",
+ "paymentSuccessful": "",
+ "paymentYouReceived": "",
+ "paymentYouSentGems": "",
+ "paymentYouSentSubscription": "",
+ "paymentSubBilling": "",
+ "success": "",
+ "classGear": "",
+ "classGearText": "",
+ "classStats": "",
+ "autoAllocate": "",
+ "autoAllocateText": "",
+ "spells": "",
+ "spellsText": "",
+ "skillsTitle": "",
+ "toDo": "",
+ "moreClass": "",
+ "tourWelcome": "",
+ "tourExp": "",
+ "tourDailies": "",
+ "tourCron": "",
+ "tourHP": "",
+ "tourHabits": "",
+ "tourStats": "",
+ "tourGP": "",
+ "tourAvatar": "",
+ "tourScrollDown": "",
+ "tourMuchMore": "",
+ "tourStatsPage": "",
+ "tourTavernPage": "",
+ "tourPartyPage": "",
+ "tourGuildsPage": "",
+ "tourChallengesPage": "",
+ "tourMarketPage": "",
+ "tourHallPage": "",
+ "tourPetsPage": "",
+ "tourMountsPage": "",
+ "tourEquipmentPage": "",
+ "equipmentAlreadyOwned": "",
+ "tourOkay": "",
+ "tourAwesome": "",
+ "tourSplendid": "",
+ "tourNifty": "",
+ "tourAvatarProceed": "",
+ "tourToDosBrief": "",
+ "tourDailiesBrief": "",
+ "tourDailiesProceed": "",
+ "tourHabitsBrief": "",
+ "tourHabitsProceed": "",
+ "tourRewardsBrief": "",
+ "tourRewardsArmoire": "",
+ "tourRewardsProceed": "",
+ "welcomeToHabit": "",
+ "welcome1": "",
+ "welcome1notes": "",
+ "welcome2": "",
+ "welcome2notes": "",
+ "welcome3": "",
+ "welcome3notes": "",
+ "welcome4": "",
+ "welcome5": "",
+ "imReady": "",
+ "limitedOffer": ""
+}
diff --git a/website/common/locales/eu/overview.json b/website/common/locales/eu/overview.json
index c559cd3c76..e54e4047a4 100755
--- a/website/common/locales/eu/overview.json
+++ b/website/common/locales/eu/overview.json
@@ -1,14 +1,10 @@
{
- "needTips": "Need some tips on how to begin? Here's a straightforward guide!",
-
- "step1": "Step 1: Enter Tasks",
- "webStep1Text": "Habitica is nothing without real-world goals, so enter a few tasks. You can add more later as you think of them! All tasks can be added by clicking the green \"Create\" button.\n* **Set up [To-Dos](http://habitica.wikia.com/wiki/To-Dos):** Enter tasks you do once or rarely in the To-Dos column, one at a time. You can click on the tasks to edit them and add checklists, due dates, and more!\n* **Set up [Dailies](http://habitica.wikia.com/wiki/Dailies):** Enter activities you need to do daily or on a particular day of the week, month, or year in the Dailies column. Click task to edit when it will be due and/or set a start date. You can also make it due on a repeating basis, for example, every 3 days.\n* **Set up [Habits](http://habitica.wikia.com/wiki/Habits):** Enter habits you want to establish in the Habits column. You can edit the Habit to change it to just a good habit :heavy_plus_sign: or a bad habit :heavy_minus_sign:\n* **Set up [Rewards](http://habitica.wikia.com/wiki/Rewards):** In addition to the in-game Rewards offered, add activities or treats which you want to use as a motivation to the Rewards column. It's important to give yourself a break or allow some indulgence in moderation!\n* If you need inspiration for which tasks to add, you can look at the wiki's pages on [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits), [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies), [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos), and [Sample Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards).",
-
- "step2": "Step 2: Gain Points by Doing Things in Real Life",
- "webStep2Text": "Now, start tackling your goals from the list! As you complete tasks and check them off in Habitica, you will gain [Experience](http://habitica.wikia.com/wiki/Experience_Points), which helps you level up, and [Gold](http://habitica.wikia.com/wiki/Gold_Points), which allows you to purchase Rewards. If you fall into bad habits or miss your Dailies, you will lose [Health](http://habitica.wikia.com/wiki/Health_Points). In that way, the Habitica Experience and Health bars serve as a fun indicator of your progress toward your goals. You'll start seeing your real life improve as your character advances in the game.",
-
- "step3": "Step 3: Customize and Explore Habitica",
- "webStep3Text": "Once you're familiar with the basics, you can get even more out of Habitica with these nifty features:\n * Organize your tasks with [tags](http://habitica.wikia.com/wiki/Tags) (edit a task to add them).\n * Customize your [avatar](http://habitica.wikia.com/wiki/Avatar) by clicking the user icon in the upper-right corner.\n * Buy your [Equipment](http://habitica.wikia.com/wiki/Equipment) under Rewards or from the [Shops](<%= shopUrl %>), and change it under [Inventory > Equipment](<%= equipUrl %>).\n * Connect with other users via the [Tavern](http://habitica.wikia.com/wiki/Tavern).\n * Starting at Level 3, hatch [Pets](http://habitica.wikia.com/wiki/Pets) by collecting [eggs](http://habitica.wikia.com/wiki/Eggs) and [hatching potions](http://habitica.wikia.com/wiki/Hatching_Potions). [Feed](http://habitica.wikia.com/wiki/Food) them to create [Mounts](http://habitica.wikia.com/wiki/Mounts).\n * At level 10: Choose a particular [class](http://habitica.wikia.com/wiki/Class_System) and then use class-specific [skills](http://habitica.wikia.com/wiki/Skills) (levels 11 to 14).\n * Form a party with your friends (by clicking [Party](<%= partyUrl %>) in the navigation bar) to stay accountable and earn a Quest scroll.\n * Defeat monsters and collect objects on [quests](http://habitica.wikia.com/wiki/Quests) (you will be given a quest at level 15).",
-
- "overviewQuestions": "Have questions? Check out the [FAQ](<%= faqUrl %>)! If your question isn't mentioned there, you can ask for further help in the [Habitica Help guild](<%= helpGuildUrl %>).\n\nGood luck with your tasks!"
+ "needTips": "Hasteko aholkuren bat behar duzu? Hona hemen azalpen argi bat!",
+ "step1": "1. urratsa: sortu zeregin batzuk",
+ "webStep1Text": "Habiticak ez du ezertarako balio ez baduzu bizitza errealeko helbururik gehitzen; beraz, sor itzazu zeregin batzuk. Bururatzen zaizkizun heinean, zeregin gehiago sor ditzakezu! Zereginak gehitzeko, \"Gehitu zeregina\" dioen botoi berdea saka dezakezu.\n* **Ezarri [egitekoak](http://habitica.fandom.com/wiki/To-Dos):** behin edo gutxitan egiten dituzun zereginak Egitekoak zutabean gehi ditzakezu, banan-banan. Zeregin bat sakatuz gero, hura aldatu, zerrenda bat sortu, epemuga gehitu eta beste gauza asko egin ahal izango dituzu!\n* **Ezarri [eguneroko zereginak](http://habitica.fandom.com/wiki/Dailies):** asteko, hilabeteko edo urteko egun jakinetan edo egunero egin behar dituzun gauzak gehi ditzakezu Eguneroko zereginak zutabean. Sakatu zeregin bat haren epemuga edo/eta hasiera-data ezartzeko. Errepikakor gisa ezar dezakezu zeregina; adibidez, 3 egunean behin errepika dadin.\n* **Ezarri [ohiturak](http://habitica.fandom.com/wiki/Habits):** finkatu nahi duzun ohituraren bat baduzu, gehi ezazu Ohiturak zutabean. Zutabe horretako ohitura bakoitza ona :heavy_plus_sign: edo txarra :heavy_minus_sign: den adieraz dezakezu.\n* **Ezarri [sariak](http://habitica.fandom.com/wiki/Rewards):** jokoan eskaintzen diren sariez gain, zeure burua motibatzeko erabili nahi dituzun jarduerak edo gustuko dituzun gauzak gehi ditzakezu Sariak zutabean. Garrantzitsua da zeure buruarekin horren gogorra ez izatea eta batzuetan apetak asetzea (baina ez gehiegi)!\n* Inspirazioa behar baduzu, gehi daitezkeen zereginen adibideak ikus ditzakezu wikiko orri hauetan (ingelesez): [Ohituren adibideak](http://habitica.fandom.com/wiki/Sample_Habits), [Eguneroko zereginen adibideak](http://habitica.fandom.com/wiki/Sample_Dailies), [Egitekoen adibideak](http://habitica.fandom.com/wiki/Sample_To-Dos) eta [Sarien adibideak](http://habitica.fandom.com/wiki/Sample_Custom_Rewards).",
+ "step2": "2. urratsa: irabazi puntuak bizitza errealean gauzak eginez",
+ "webStep2Text": "Orain, has zaitez zerrendako helburuak lortzen! Zeregin bat egiten eta Habitican burutu gisa markatzen duzun bakoitzean, [esperientzia](http://habitica.fandom.com/wiki/Experience_Points) lortuko duzu. Mailaz igotzeko balio du esperientziak. Horretaz gain, [urrea](http://habitica.fandom.com/wiki/Gold_Points) irabaziko duzu ere, sariak erosteko erabil dezakezuna. Ohitura txarretan aritzen bazara edo eguneroko zereginen bat ez baduzu egiten, [osasuna](http://habitica.fandom.com/wiki/Health_Points) galduko duzu. Horrela, Habiticako esperientzia eta osasunaren barrek zure helburuak lortzeko egiten dituzun aurrerapenak adierazten dituzte, modu dibertigarri batean. Zure pertsonaiak jokoan aurrera egiten duen heinean zure bizitza hobetzen doala ikusiko duzu.",
+ "step3": "3. urratsa: pertsonalizatu eta arakatu Habitica",
+ "webStep3Text": "Oinarrizko funtzionamendua ongi ezagutzen duzunean, eginbide bikain hauek proba ditzakezu Habiticaz are gehiago gozatzeko:\n * Antolatu zereginak [etiketak](http://habitica.fandom.com/wiki/Tags) erabiliz (zereginak editatuz ezar ditzakezu etiketak).\n * Pertsonalizatu [avatarra](http://habitica.fandom.com/wiki/Avatar) goiko eskuineko izkinan dagoen erabiltzaile-ikonoa sakatuz.\n * Erosi [ekipamendua](http://habitica.fandom.com/wiki/Equipment) Sariak atalean edo [dendetan](<%= shopUrl %>), eta alda ezazu [Inbentarioa > Ekipamendua](<%= equipUrl %>) atalean.\n * Ezagutu beste erabiltzaileak [tabernan](http://habitica.fandom.com/wiki/Tavern).\n * 3. mailatik aurrera, lortu [maskotak](http://habitica.fandom.com/wiki/Pets). Horretarako, [arrautzak](http://habitica.fandom.com/wiki/Eggs) eta [eklosionatzeko edabeak](http://habitica.fandom.com/wiki/Hatching_Potions) aurkitu behar dituzu. Eman [janaria](http://habitica.fandom.com/wiki/Food) maskotei zu bizkarrean eraman zaitzaketen [animalia heldu](http://habitica.fandom.com/wiki/Mounts) bihur daitezen.\n * 10. mailan: aukeratu [klase](http://habitica.fandom.com/wiki/Class_System) jakin bat eta erabili klase horren [trebetasun](http://habitica.fandom.com/wiki/Skills) bereziak (11. eta 14. mailen artean).\n * Sortu talde bat zure lagunekin batera (nabigazio-barran [Taldea](<%= partyUrl %>) sakatuz) bakoitza besteen aurrean bere ekintzen erantzule izan dadin eta elkarrekin misio-pergamino bat eskuratzeko.\n * Menderatu munstroak eta aurkitu objektuak [misioetan](http://habitica.fandom.com/wiki/Quests) (15. mailan misio bat jasoko duzu).",
+ "overviewQuestions": "Galderarik al duzu? Begiratu [FAQ](<%= faqUrl %>) atala! Zure galdera ez badago hor, eskatu laguntza [Habitica Help guild](<%= helpGuildUrl %>) gremioan.\n\nZorte on zereginekin!"
}
diff --git a/website/common/locales/eu/quests.json b/website/common/locales/eu/quests.json
index c069fdd2dc..271a21c534 100755
--- a/website/common/locales/eu/quests.json
+++ b/website/common/locales/eu/quests.json
@@ -1,130 +1,130 @@
{
- "quests": "Quests",
- "quest": "quest",
- "whereAreMyQuests": "Quests are now available on their own page! Click on Inventory -> Quests to find them.",
- "yourQuests": "Your Quests",
- "questsForSale": "Quests for Sale",
- "petQuests": "Pet and Mount Quests",
- "unlockableQuests": "Unlockable Quests",
- "goldQuests": "Masterclasser Quest Lines",
- "questDetails": "Quest Details",
- "questDetailsTitle": "Quest Details",
- "questDescription": "Quests allow players to focus on long-term, in-game goals with the members of their party.",
- "invitations": "Invitations",
- "completed": "Completed!",
- "rewardsAllParticipants": "Rewards for all Quest Participants",
- "rewardsQuestOwner": "Additional Rewards for Quest Owner",
- "questOwnerReceived": "The Quest Owner Has Also Received",
- "youWillReceive": "You Will Receive",
- "questOwnerWillReceive": "The Quest Owner Will Also Receive",
- "youReceived": "You've Received",
- "dropQuestCongrats": "Congratulations on earning this quest scroll! You can invite your party to begin the quest now, or come back to it any time in your Inventory > Quests.",
- "questSend": "Clicking \"Invite\" will send an invitation to your party members. When all members have accepted or denied, the quest begins. See status under Social > Party.",
- "questSendBroken": "Clicking \"Invite\" will send an invitation to your party members... When all members have accepted or denied, the quest begins... See status under Social > Party...",
- "inviteParty": "Invite Party to Quest",
- "questInvitation": "Quest Invitation:",
- "questInvitationTitle": "Quest Invitation",
+ "quests": "",
+ "quest": "",
+ "whereAreMyQuests": "",
+ "yourQuests": "",
+ "questsForSale": "",
+ "petQuests": "",
+ "unlockableQuests": "",
+ "goldQuests": "",
+ "questDetails": "",
+ "questDetailsTitle": "",
+ "questDescription": "",
+ "invitations": "",
+ "completed": "",
+ "rewardsAllParticipants": "",
+ "rewardsQuestOwner": "",
+ "questOwnerReceived": "",
+ "youWillReceive": "",
+ "questOwnerWillReceive": "",
+ "youReceived": "",
+ "dropQuestCongrats": "",
+ "questSend": "",
+ "questSendBroken": "",
+ "inviteParty": "",
+ "questInvitation": "",
+ "questInvitationTitle": "",
"questInvitationInfo": "Invitation for the Quest <%= quest %>",
- "invitedToQuest": "You were invited to the Quest <%= quest %>",
- "askLater": "Ask Later",
- "questLater": "Quest Later",
- "buyQuest": "Buy Quest",
- "accepted": "Accepted",
- "declined": "Declined",
- "rejected": "Rejected",
- "pending": "Pending",
- "questStart": "Once all members have either accepted or rejected, the quest begins. Only those that clicked \"accept\" will be able to participate in the quest and receive the drops. If members are pending too long (inactive?), the quest owner can start the quest without them by clicking \"Begin\". The quest owner can also cancel the quest and regain the quest scroll by clicking \"Cancel\".",
- "questStartBroken": "Once all members have either accepted or rejected, the quest begins... Only those that clicked \"accept\" will be able to participate in the quest and receive the drops... If members are pending too long (inactive?), the quest owner can start the quest without them by clicking \"Begin\"... The quest owner can also cancel the quest and regain the quest scroll by clicking \"Cancel\"...",
- "questCollection": "+ <%= val %> quest item(s) found",
- "questDamage": "+ <%= val %> damage to boss",
- "begin": "Begin",
- "bossHP": "Boss HP",
- "bossStrength": "Boss Strength",
- "rage": "Rage",
- "collect": "Collect",
- "collected": "Collected",
- "collectionItems": "<%= number %> <%= items %>",
- "itemsToCollect": "Items to Collect",
- "bossDmg1": "Each completed Daily and To-Do and each positive Habit hurts the boss. Hurt it more with redder tasks or Brutal Smash and Burst of Flames. The boss will deal damage to every quest participant for every Daily you've missed (multiplied by the boss's Strength) in addition to your regular damage, so keep your party healthy by completing your Dailies! All damage to and from a boss is tallied on cron (your day roll-over).",
- "bossDmg2": "Only participants will fight the boss and share in the quest loot.",
- "bossDmg1Broken": "Each completed Daily and To-Do and each positive Habit hurts the boss... Hurt it more with redder tasks or Brutal Smash and Burst of Flames... The boss will deal damage to every quest participant for every Daily you've missed (multiplied by the boss's Strength) in addition to your regular damage, so keep your party healthy by completing your Dailies... All damage to and from a boss is tallied on cron (your day roll-over)...",
- "bossDmg2Broken": "Only participants will fight the boss and share in the quest loot...",
- "tavernBossInfo": "Complete Dailies and To-Dos and score positive Habits to damage the World Boss! Incomplete Dailies fill the Rage Bar. When the Rage bar is full, the World Boss will attack an NPC. A World Boss will never damage individual players or accounts in any way. Only active accounts not resting in the Inn will have their tasks tallied.",
- "tavernBossInfoBroken": "Complete Dailies and To-Dos and score positive Habits to damage the World Boss... Incomplete Dailies fill the Exhaust Strike Bar... When the Exhaust Strike bar is full, the World Boss will attack an NPC... A World Boss will never damage individual players or accounts in any way... Only active accounts not resting in the Inn will have their tasks tallied...",
- "bossColl1": "To collect items, do your positive tasks. Quest items drop just like normal items; you can monitor your quest item drops by hovering over the quest progress icon.",
- "bossColl2": "Only participants can collect items and share in the quest loot.",
- "bossColl1Broken": "To collect items, do your positive tasks... Quest items drop just like normal items; you can monitor your quest item drops by hovering over the quest progress icon...",
- "bossColl2Broken": "Only participants can collect items and share in the quest loot...",
- "abort": "Abort",
- "leaveQuest": "Leave Quest",
- "sureLeave": "Are you sure you want to leave the active quest? All your quest progress will be lost.",
- "questOwner": "Quest Owner",
- "questTaskDamage": "+ <%= damage %> pending damage to boss",
- "questTaskCollection": "<%= items %> items collected today",
- "questOwnerNotInPendingQuest": "The quest owner has left the quest and can no longer begin it. It is recommended that you cancel it now. The quest owner will retain possession of the quest scroll.",
- "questOwnerNotInRunningQuest": "The quest owner has left the quest. You can abort the quest if you need to. You can also allow it to keep running and all remaining participants will receive the quest rewards when the quest finishes.",
- "questOwnerNotInPendingQuestParty": "The quest owner has left the party and can no longer begin the quest. It is recommended that you cancel it now. The quest scroll will be returned to the quest owner.",
- "questOwnerNotInRunningQuestParty": "The quest owner has left the party. You can abort the quest if you need to but you can also leave it running and all remaining participants will receive the quest rewards when the quest finishes.",
- "questParticipants": "Participants",
- "scrolls": "Quest Scrolls",
- "noScrolls": "You don't have any quest scrolls.",
- "scrollsText1": "Quests require parties. If you want to quest solo,",
- "scrollsText2": "create an empty party",
- "scrollsPre": "You haven't unlocked this quest yet!",
- "alreadyEarnedQuestLevel": "You already earned this quest by attaining Level <%= level %>.",
- "alreadyEarnedQuestReward": "You already earned this quest by completing <%= priorQuest %>.",
- "completedQuests": "Completed the following quests",
- "mustComplete": "You must first complete <%= quest %>.",
- "mustLevel": "You must be level <%= level %> to begin this quest.",
- "mustLvlQuest": "You must be level <%= level %> to buy this quest!",
- "mustInviteFriend": "To earn this quest, invite a friend to your Party. Invite someone now?",
- "unlockByQuesting": "To unlock this quest, complete <%= title %>.",
- "questConfirm": "Are you sure? Only <%= questmembers %> of your <%= totalmembers %> party members have joined this quest! Quests start automatically when all players have joined or rejected the invitation.",
- "sureCancel": "Are you sure you want to cancel this quest? All invitation acceptances will be lost. The quest owner will retain possession of the quest scroll.",
- "sureAbort": "Are you sure you want to abort this mission? It will abort it for everyone in your party and all progress will be lost. The quest scroll will be returned to the quest owner.",
- "doubleSureAbort": "Are you double sure? Make sure they won't hate you forever!",
- "questWarning": "If new players join the party before the quest starts, they will also receive an invitation. However once the quest has started, no new party members can join the quest.",
- "questWarningBroken": "If new players join the party before the quest starts, they will also receive an invitation... However once the quest has started, no new party members can join the quest...",
- "bossRageTitle": "Rage",
- "bossRageDescription": "When this bar fills, the boss will unleash a special attack!",
- "startAQuest": "START A QUEST",
- "startQuest": "Start Quest",
- "whichQuestStart": "Which quest do you want to start?",
- "getMoreQuests": "Get more quests",
- "unlockedAQuest": "You unlocked a quest!",
- "leveledUpReceivedQuest": "You leveled up to Level <%= level %> and received a quest scroll!",
- "questInvitationDoesNotExist": "No quest invitation has been sent out yet.",
- "questInviteNotFound": "No quest invitation found.",
- "guildQuestsNotSupported": "Guilds cannot be invited on quests.",
- "questNotOwned": "You don't own that quest scroll.",
- "questNotGoldPurchasable": "Quest \"<%= key %>\" is not a Gold-purchasable quest.",
- "questNotGemPurchasable": "Quest \"<%= key %>\" is not a Gem-purchasable quest.",
- "questLevelTooHigh": "You must be level <%= level %> to begin this quest.",
- "questAlreadyUnderway": "Your party is already on a quest. Try again when the current quest has ended.",
- "questAlreadyAccepted": "You already accepted the quest invitation.",
- "noActiveQuestToLeave": "No active quest to leave",
- "questLeaderCannotLeaveQuest": "Quest leader cannot leave quest",
- "notPartOfQuest": "You are not part of the quest",
- "youAreNotOnQuest": "You're not on a quest",
- "noActiveQuestToAbort": "There is no active quest to abort.",
- "onlyLeaderAbortQuest": "Only the group or quest leader can abort a quest.",
- "questAlreadyRejected": "You already rejected the quest invitation.",
- "cantCancelActiveQuest": "You can not cancel an active quest, use the abort functionality.",
- "onlyLeaderCancelQuest": "Only the group or quest leader can cancel the quest.",
- "questNotPending": "There is no quest to start.",
- "questOrGroupLeaderOnlyStartQuest": "Only the quest leader or group leader can force start the quest",
- "createAccountReward": "Create Account",
- "loginIncentiveQuest": "To unlock this quest, check in to Habitica on <%= count %> different days!",
- "loginIncentiveQuestObtained": "You earned this quest by checking in to Habitica on <%= count %> different days!",
- "loginReward": "<%= count %> Check-ins",
- "createAccountQuest": "You received this quest when you joined Habitica! If a friend joins, they'll get one too.",
- "questBundles": "Discounted Quest Bundles",
- "buyQuestBundle": "Buy Quest Bundle",
- "noQuestToStart": "Can’t find a quest to start? Try checking out the Quest Shop in the Market for new releases!",
- "pendingDamage": "<%= damage %> pending damage",
- "pendingDamageLabel": "pending damage",
- "bossHealth": "<%= currentHealth %> / <%= maxHealth %> Health",
- "rageAttack": "Rage Attack:",
- "bossRage": "<%= currentRage %> / <%= maxRage %> Rage",
- "rageStrikes": "Rage Strikes"
-}
\ No newline at end of file
+ "invitedToQuest": "",
+ "askLater": "",
+ "questLater": "",
+ "buyQuest": "",
+ "accepted": "",
+ "declined": "",
+ "rejected": "",
+ "pending": "",
+ "questStart": "",
+ "questStartBroken": "",
+ "questCollection": "",
+ "questDamage": "",
+ "begin": "",
+ "bossHP": "",
+ "bossStrength": "",
+ "rage": "",
+ "collect": "",
+ "collected": "",
+ "collectionItems": "",
+ "itemsToCollect": "",
+ "bossDmg1": "",
+ "bossDmg2": "",
+ "bossDmg1Broken": "",
+ "bossDmg2Broken": "",
+ "tavernBossInfo": "",
+ "tavernBossInfoBroken": "",
+ "bossColl1": "",
+ "bossColl2": "",
+ "bossColl1Broken": "",
+ "bossColl2Broken": "",
+ "abort": "",
+ "leaveQuest": "",
+ "sureLeave": "",
+ "questOwner": "",
+ "questTaskDamage": "",
+ "questTaskCollection": "",
+ "questOwnerNotInPendingQuest": "",
+ "questOwnerNotInRunningQuest": "",
+ "questOwnerNotInPendingQuestParty": "",
+ "questOwnerNotInRunningQuestParty": "",
+ "questParticipants": "",
+ "scrolls": "",
+ "noScrolls": "",
+ "scrollsText1": "",
+ "scrollsText2": "",
+ "scrollsPre": "",
+ "alreadyEarnedQuestLevel": "",
+ "alreadyEarnedQuestReward": "",
+ "completedQuests": "",
+ "mustComplete": "",
+ "mustLevel": "",
+ "mustLvlQuest": "",
+ "mustInviteFriend": "",
+ "unlockByQuesting": "",
+ "questConfirm": "",
+ "sureCancel": "",
+ "sureAbort": "",
+ "doubleSureAbort": "",
+ "questWarning": "",
+ "questWarningBroken": "",
+ "bossRageTitle": "",
+ "bossRageDescription": "",
+ "startAQuest": "",
+ "startQuest": "",
+ "whichQuestStart": "",
+ "getMoreQuests": "",
+ "unlockedAQuest": "",
+ "leveledUpReceivedQuest": "",
+ "questInvitationDoesNotExist": "",
+ "questInviteNotFound": "",
+ "guildQuestsNotSupported": "",
+ "questNotOwned": "",
+ "questNotGoldPurchasable": "",
+ "questNotGemPurchasable": "",
+ "questLevelTooHigh": "",
+ "questAlreadyUnderway": "",
+ "questAlreadyAccepted": "",
+ "noActiveQuestToLeave": "",
+ "questLeaderCannotLeaveQuest": "",
+ "notPartOfQuest": "",
+ "youAreNotOnQuest": "",
+ "noActiveQuestToAbort": "",
+ "onlyLeaderAbortQuest": "",
+ "questAlreadyRejected": "",
+ "cantCancelActiveQuest": "",
+ "onlyLeaderCancelQuest": "",
+ "questNotPending": "",
+ "questOrGroupLeaderOnlyStartQuest": "",
+ "createAccountReward": "",
+ "loginIncentiveQuest": "",
+ "loginIncentiveQuestObtained": "",
+ "loginReward": "",
+ "createAccountQuest": "",
+ "questBundles": "",
+ "buyQuestBundle": "",
+ "noQuestToStart": "",
+ "pendingDamage": "",
+ "pendingDamageLabel": "",
+ "bossHealth": "",
+ "rageAttack": "",
+ "bossRage": "",
+ "rageStrikes": ""
+}
diff --git a/website/common/locales/eu/questscontent.json b/website/common/locales/eu/questscontent.json
index 8a6d9be006..de24a8b341 100755
--- a/website/common/locales/eu/questscontent.json
+++ b/website/common/locales/eu/questscontent.json
@@ -1,638 +1,638 @@
{
- "questEvilSantaText": "Trapper Santa",
- "questEvilSantaNotes": "You hear agonized roars deep in the icefields. You follow the growls - punctuated by the sound of cackling - to a clearing in the woods, where you see a fully-grown polar bear. She's caged and shackled, fighting for her life. Dancing atop the cage is a malicious little imp wearing a castaway costume. Vanquish Trapper Santa, and save the beast!",
- "questEvilSantaCompletion": "Trapper Santa squeals in anger, and bounces off into the night. The grateful she-bear, through roars and growls, tries to tell you something. You take her back to the stables, where Matt Boch the Beast Master listens to her tale with a gasp of horror. She has a cub! He ran off into the icefields when mama bear was captured.",
- "questEvilSantaBoss": "Trapper Santa",
- "questEvilSantaDropBearCubPolarMount": "Polar Bear (Mount)",
- "questEvilSanta2Text": "Find The Cub",
- "questEvilSanta2Notes": "When Trapper Santa captured the polar bear mount, her cub ran off into the icefields. You hear twig-snaps and snow crunch through the crystalline sound of the forest. Paw prints! You start racing to follow the trail. Find all the prints and broken twigs, and retrieve the cub!",
- "questEvilSanta2Completion": "You've found the cub! It will keep you company forever.",
- "questEvilSanta2CollectTracks": "Tracks",
- "questEvilSanta2CollectBranches": "Broken Twigs",
- "questEvilSanta2DropBearCubPolarPet": "Polar Bear (Pet)",
- "questGryphonText": "The Fiery Gryphon",
- "questGryphonNotes": "The grand beast master, baconsaur, has come to your party seeking help. \"Please, adventurers, you must help me! My prized gryphon has broken free and is terrorizing Habit City! If you can stop her, I could reward you with some of her eggs!\"",
- "questGryphonCompletion": "Defeated, the mighty beast ashamedly slinks back to its master. \"My word! Well done, adventurers!\" baconsaur exclaims, \"Please, have some of the gryphon's eggs. I am sure you will raise these young ones well!\"",
- "questGryphonBoss": "Fiery Gryphon",
- "questGryphonDropGryphonEgg": "Gryphon (Egg)",
- "questGryphonUnlockText": "Unlocks purchasable Gryphon eggs in the Market",
- "questHedgehogText": "The Hedgebeast",
- "questHedgehogNotes": "Hedgehogs are a funny group of animals. They are some of the most affectionate pets a Habiteer could own. But rumor has it, if you feed them milk after midnight, they grow quite irritable. And fifty times their size. And InspectorCaracal did just that. Oops.",
- "questHedgehogCompletion": "Your party successfully calmed down the hedgehog! After shrinking down to a normal size, she hobbles away to her eggs. She returns squeaking and nudging some of her eggs along towards your party. Hopefully, these hedgehogs like milk better!",
- "questHedgehogBoss": "Hedgebeast",
- "questHedgehogDropHedgehogEgg": "Hedgehog (Egg)",
- "questHedgehogUnlockText": "Unlocks purchasable Hedgehog eggs in the Market",
- "questGhostStagText": "The Spirit of Spring",
- "questGhostStagNotes": "Ahh, Spring. The time of year when color once again begins to fill the landscape. Gone are the cold, snowy mounds of winter. Where frost once stood, vibrant plant life takes its place. Luscious green leaves fill in the trees, grass returns to its former vivid hue, a rainbow of flowers rise along the plains, and a white mystical fog covers the land! ... Wait. Mystical fog? \"Oh no,\" InspectorCaracal says apprehensively, \"It would appear that some kind of spirit is the cause of this fog. Oh, and it is charging right at you.\"",
- "questGhostStagCompletion": "The spirit, seemingly unwounded, lowers its nose to the ground. A calming voice envelops your party. \"I apologize for my behavior. I have only just awoken from my slumber, and it would appear my wits have not completely returned to me. Please take these as a token of my apology.\" A cluster of eggs materialize on the grass before the spirit. Without another word, the spirit runs off into the forest with flowers falling in his wake.",
- "questGhostStagBoss": "Ghost Stag",
- "questGhostStagDropDeerEgg": "Deer (Egg)",
- "questGhostStagUnlockText": "Unlocks purchasable Deer eggs in the Market",
- "questRatText": "The Rat King",
- "questRatNotes": "Garbage! Massive piles of unchecked Dailies are lying all across Habitica. The problem has become so serious that hordes of rats are now seen everywhere. You notice @Pandah petting one of the beasts lovingly. She explains that rats are gentle creatures that feed on unchecked Dailies. The real problem is that the Dailies have fallen into the sewer, creating a dangerous pit that must be cleared. As you descend into the sewers, a massive rat, with blood red eyes and mangled yellow teeth, attacks you, defending its horde. Will you cower in fear or face the fabled Rat King?",
- "questRatCompletion": "Your final strike saps the gargantuan rat's strength, his eyes fading to a dull grey. The beast splits into many tiny rats, which scurry off in fright. You notice @Pandah standing behind you, looking at the once mighty creature. She explains that the citizens of Habitica have been inspired by your courage and are quickly completing all their unchecked Dailies. She warns you that we must be vigilant, for should we let down our guard, the Rat King will return. As payment, @Pandah offers you several rat eggs. Noticing your uneasy expression, she smiles, \"They make wonderful pets.\"",
- "questRatBoss": "Rat King",
- "questRatDropRatEgg": "Rat (Egg)",
- "questRatUnlockText": "Unlocks purchasable Rat eggs in the Market",
- "questOctopusText": "The Call of Octothulu",
- "questOctopusNotes": "@Urse, a wild-eyed young scribe, has asked for your help exploring a mysterious cave by the sea shore. Among the twilight tidepools stands a massive gate of stalactites and stalagmites. As you near the gate, a dark whirlpool begins to spin at its base. You stare in awe as a squid-like dragon rises through the maw. \"The sticky spawn of the stars has awakened,\" roars @Urse madly. \"After vigintillions of years, the great Octothulu is loose again, and ravening for delight!\"",
- "questOctopusCompletion": "With a final blow, the creature slips away into the whirlpool from which it came. You cannot tell if @Urse is happy with your victory or saddened to see the beast go. Wordlessly, your companion points to three slimy, gargantuan eggs in a nearby tidepool, set in a nest of gold coins. \"Probably just octopus eggs,\" you say nervously. As you return home, @Urse frantically scribbles in a journal and you suspect this is not the last time you will hear of the great Octothulu.",
- "questOctopusBoss": "Octothulu",
- "questOctopusDropOctopusEgg": "Octopus (Egg)",
- "questOctopusUnlockText": "Unlocks purchasable Octopus eggs in the Market",
- "questHarpyText": "Help! Harpy!",
- "questHarpyNotes": "The brave adventurer @UncommonCriminal has disappeared into the forest, following the trail of a winged monster that was sighted several days ago. You are about to begin a search when a wounded parrot lands on your arm, an ugly scar marring its beautiful plumage. Attached to its leg is a scrawled note explaining that while defending the parrots, @UncommonCriminal was captured by a vicious Harpy, and desperately needs your help to escape. Will you follow the bird, defeat the Harpy, and save @UncommonCriminal?",
- "questHarpyCompletion": "A final blow to the Harpy brings it down, feathers flying in all directions. After a quick climb to its nest you find @UncommonCriminal, surrounded by parrot eggs. As a team, you quickly place the eggs back in the nearby nests. The scarred parrot who found you caws loudly, dropping several eggs in your arms. \"The Harpy attack has left some eggs in need of protection,\" explains @UncommonCriminal. \"It seems you have been made an honorary parrot.\"",
- "questHarpyBoss": "Harpy",
- "questHarpyDropParrotEgg": "Parrot (Egg)",
- "questHarpyUnlockText": "Unlocks purchasable Parrot eggs in the Market",
- "questRoosterText": "Rooster Rampage",
- "questRoosterNotes": "For years the farmer @extrajordanary has used Roosters as an alarm clock. But now a giant Rooster has appeared, crowing louder than any before – and waking up everyone in Habitica! The sleep-deprived Habiticans struggle through their daily tasks. @Pandoro decides the time has come to put a stop to this. \"Please, is there anyone who can teach that Rooster to crow quietly?\" You volunteer, approaching the Rooster early one morning – but it turns, flapping its giant wings and showing its sharp claws, and crows a battle cry.",
- "questRoosterCompletion": "With finesse and strength, you have tamed the wild beast. Its ears, once filled with feathers and half-remembered tasks, are now clear as day. It crows at you quietly, snuggling its beak into your shoulder. The next day you’re set to take your leave, but @EmeraldOx runs up to you with a covered basket. “Wait! When I went into the farmhouse this morning, the Rooster had pushed these against the door where you slept. I think he wants you to have them.” You uncover the basket to see three delicate eggs.",
- "questRoosterBoss": "Rooster",
- "questRoosterDropRoosterEgg": "Rooster (Egg)",
- "questRoosterUnlockText": "Unlocks purchasable Rooster eggs in the Market",
- "questSpiderText": "The Icy Arachnid",
- "questSpiderNotes": "As the weather starts cooling down, delicate frost begins appearing on Habiticans' windowpanes in lacy webs... except for @Arcosine, whose windows are frozen completely shut by the Frost Spider currently taking up residence in his home. Oh dear.",
- "questSpiderCompletion": "The Frost Spider collapses, leaving behind a small pile of frost and a few of her enchanted egg sacs. @Arcosine rather hurriedly offers them to you as a reward--perhaps you could raise some non-threatening spiders as pets of your own?",
- "questSpiderBoss": "Spider",
- "questSpiderDropSpiderEgg": "Spider (Egg)",
- "questSpiderUnlockText": "Unlocks purchasable Spider eggs in the Market",
- "questGroupVice": "Vice the Shadow Wyrm",
- "questVice1Text": "Vice, Part 1: Free Yourself of the Dragon's Influence",
- "questVice1Notes": "
They say there lies a terrible evil in the caverns of Mt. Habitica. A monster whose presence twists the wills of the strong heroes of the land, turning them towards bad habits and laziness! The beast is a grand dragon of immense power and comprised of the shadows themselves: Vice, the treacherous Shadow Wyrm. Brave Habiteers, stand up and defeat this foul beast once and for all, but only if you believe you can stand against its immense power.
Vice Part 1:
How can you expect to fight the beast if it already has control over you? Don't fall victim to laziness and vice! Work hard to fight against the dragon's dark influence and dispel his hold on you!
",
- "questVice1Boss": "Vice's Shade",
- "questVice1Completion": "With Vice's influence over you dispelled, you feel a surge of strength you didn't know you had return to you. Congratulations! But a more frightening foe awaits...",
- "questVice1DropVice2Quest": "Vice Part 2 (Scroll)",
- "questVice2Text": "Vice, Part 2: Find the Lair of the Wyrm",
- "questVice2Notes": "Confident in yourselves and your ability to withstand the influence of Vice the Shadow Wyrm, your Party makes its way to Mt. Habitica. You approach the entrance to the mountain's caverns and pause. Swells of shadows, almost like fog, wisp out from the opening. It is near impossible to see anything in front of you. The light from your lanterns seem to end abruptly where the shadows begin. It is said that only magical light can pierce the dragon's infernal haze. If you can find enough light crystals, you could make your way to the dragon.",
- "questVice2CollectLightCrystal": "Light Crystals",
- "questVice2Completion": "As you lift the final crystal aloft, the shadows are dispelled, and your path forward is clear. With a quickening heart, you step forward into the cavern.",
- "questVice2DropVice3Quest": "Vice Part 3 (Scroll)",
- "questVice3Text": "Vice, Part 3: Vice Awakens",
- "questVice3Notes": "After much effort, your party has discovered Vice's lair. The hulking monster eyes your party with distaste. As shadows swirl around you, a voice whispers through your head, \"More foolish citizens of Habitica come to stop me? Cute. You'd have been wise not to come.\" The scaly titan rears back its head and prepares to attack. This is your chance! Give it everything you've got and defeat Vice once and for all!",
- "questVice3Completion": "The shadows dissipate from the cavern and a steely silence falls. My word, you've done it! You have defeated Vice! You and your party may finally breathe a sigh of relief. Enjoy your victory, brave Habiteers, but take the lessons you've learned from battling Vice and move forward. There are still Habits to be done and potentially worse evils to conquer!",
- "questVice3Boss": "Vice, the Shadow Wyrm",
- "questVice3DropWeaponSpecial2": "Stephen Weber's Shaft of the Dragon",
- "questVice3DropDragonEgg": "Dragon (Egg)",
- "questVice3DropShadeHatchingPotion": "Shade Hatching Potion",
- "questGroupMoonstone": "Recidivate Rising",
- "questMoonstone1Text": "Recidivate, Part 1: The Moonstone Chain",
- "questMoonstone1Notes": "A terrible affliction has struck Habiticans. Bad Habits thought long-dead are rising back up with a vengeance. Dishes lie unwashed, textbooks linger unread, and procrastination runs rampant!
You track some of your own returning Bad Habits to the Swamps of Stagnation and discover the culprit: the ghostly Necromancer, Recidivate. You rush in, weapons swinging, but they slide through her specter uselessly.
\"Don’t bother,\" she hisses with a dry rasp. \"Without a chain of moonstones, nothing can harm me – and master jeweler @aurakami scattered all the moonstones across Habitica long ago!\" Panting, you retreat... but you know what you must do.",
- "questMoonstone1CollectMoonstone": "Moonstones",
- "questMoonstone1Completion": "At last, you manage to pull the final moonstone from the swampy sludge. It’s time to go fashion your collection into a weapon that can finally defeat Recidivate!",
- "questMoonstone1DropMoonstone2Quest": "Recidivate, Part 2: Recidivate the Necromancer (Scroll)",
- "questMoonstone2Text": "Recidivate, Part 2: Recidivate the Necromancer",
- "questMoonstone2Notes": "The brave weaponsmith @InspectorCaracal helps you fashion the enchanted moonstones into a chain. You’re ready to confront Recidivate at last, but as you enter the Swamps of Stagnation, a terrible chill sweeps over you.
Rotting breath whispers in your ear. \"Back again? How delightful...\" You spin and lunge, and under the light of the moonstone chain, your weapon strikes solid flesh. \"You may have bound me to the world once more,\" Recidivate snarls, \"but now it is time for you to leave it!\"",
- "questMoonstone2Boss": "The Necromancer",
- "questMoonstone2Completion": "Recidivate staggers backwards under your final blow, and for a moment, your heart brightens – but then she throws back her head and lets out a horrible laugh. What’s happening?",
- "questMoonstone2DropMoonstone3Quest": "Recidivate, Part 3: Recidivate Transformed (Scroll)",
- "questMoonstone3Text": "Recidivate, Part 3: Recidivate Transformed",
- "questMoonstone3Notes": "Laughing wickedly, Recidivate crumples to the ground, and you strike at her again with the moonstone chain. To your horror, Recidivate seizes the gems, eyes burning with triumph.
\"Foolish creature of flesh!\" she shouts. \"These moonstones will restore me to a physical form, true, but not as you imagined. As the full moon waxes from the dark, so too does my power flourish, and from the shadows I summon the specter of your most feared foe!\"
A sickly green fog rises from the swamp, and Recidivate’s body writhes and contorts into a shape that fills you with dread – the undead body of Vice, horribly reborn.",
- "questMoonstone3Completion": "Your breath comes hard and sweat stings your eyes as the undead Wyrm collapses. The remains of Recidivate dissipate into a thin grey mist that clears quickly under the onslaught of a refreshing breeze, and you hear the distant, rallying cries of Habiticans defeating their Bad Habits for once and for all.
@Baconsaur the beast master swoops down on a gryphon. \"I saw the end of your battle from the sky, and I was greatly moved. Please, take this enchanted tunic – your bravery speaks of a noble heart, and I believe you were meant to have it.\"",
- "questMoonstone3Boss": "Necro-Vice",
- "questMoonstone3DropRottenMeat": "Rotten Meat (Food)",
- "questMoonstone3DropZombiePotion": "Zombie Hatching Potion",
- "questGroupGoldenknight": "The Golden Knight",
- "questGoldenknight1Text": "The Golden Knight, Part 1: A Stern Talking-To",
- "questGoldenknight1Notes": "The Golden Knight has been getting on poor Habiticans' cases. Didn't do all of your Dailies? Checked off a negative Habit? She will use this as a reason to harass you about how you should follow her example. She is the shining example of a perfect Habitican, and you are naught but a failure. Well, that is not nice at all! Everyone makes mistakes. They should not have to be met with such negativity for it. Perhaps it is time you gather some testimonies from hurt Habiticans and give the Golden Knight a stern talking-to!",
- "questGoldenknight1CollectTestimony": "Testimonies",
- "questGoldenknight1Completion": "Look at all these testimonies! Surely this will be enough to convince the Golden Knight. Now all you need to do is find her.",
- "questGoldenknight1DropGoldenknight2Quest": "The Golden Knight Part 2: Gold Knight (Scroll)",
- "questGoldenknight2Text": "The Golden Knight, Part 2: Gold Knight",
- "questGoldenknight2Notes": "Armed with dozens of Habiticans' testimonies, you finally confront the Golden Knight. You begin to recite the Habitcans' complaints to her, one by one. \"And @Pfeffernusse says that your constant bragging-\" The knight raises her hand to silence you and scoffs, \"Please, these people are merely jealous of my success. Instead of complaining, they should simply work as hard as I! Perhaps I shall show you the power you can attain through diligence such as mine!\" She raises her morningstar and prepares to attack you!",
- "questGoldenknight2Boss": "Gold Knight",
- "questGoldenknight2Completion": "The Golden Knight lowers her Morningstar in consternation. “I apologize for my rash outburst,” she says. “The truth is, it’s painful to think that I’ve been inadvertently hurting others, and it made me lash out in defense… but perhaps I can still apologize?”",
- "questGoldenknight2DropGoldenknight3Quest": "The Golden Knight Part 3: The Iron Knight (Scroll)",
- "questGoldenknight3Text": "The Golden Knight, Part 3: The Iron Knight",
- "questGoldenknight3Notes": "@Jon Arinbjorn cries out to you to get your attention. In the aftermath of your battle, a new figure has appeared. A knight coated in stained-black iron slowly approaches you with sword in hand. The Golden Knight shouts to the figure, \"Father, no!\" but the knight shows no signs of stopping. She turns to you and says, \"I am sorry. I have been a fool, with a head too big to see how cruel I have been. But my father is crueler than I could ever be. If he isn't stopped he'll destroy us all. Here, use my morningstar and halt the Iron Knight!\"",
- "questGoldenknight3Completion": "With a satisfying clang, the Iron Knight falls to his knees and slumps over. \"You are quite strong,\" he pants. \"I have been humbled, today.\" The Golden Knight approaches you and says, \"Thank you. I believe we have gained some humility from our encounter with you. I will speak with my father and explain the complaints against us. Perhaps, we should begin apologizing to the other Habiticans.\" She mulls over in thought before turning back to you. \"Here: as our gift to you, I want you to keep my morningstar. It is yours now.\"",
- "questGoldenknight3Boss": "The Iron Knight",
- "questGoldenknight3DropHoney": "Honey (Food)",
- "questGoldenknight3DropGoldenPotion": "Golden Hatching Potion",
- "questGoldenknight3DropWeapon": "Mustaine's Milestone Mashing Morning Star (Off-hand Weapon)",
- "questGroupEarnable": "Earnable Quests",
- "questBasilistText": "The Basi-List",
- "questBasilistNotes": "There's a commotion in the marketplace--the kind that should make you run away. Being a courageous adventurer, you run towards it instead, and discover a Basi-list, coalescing from a clump of incomplete To-Dos! Nearby Habiticans are paralyzed with fear at the length of the Basi-list, unable to start working. From somewhere in the vicinity, you hear @Arcosine shout: \"Quick! Complete your To-Dos and Dailies to defang the monster, before someone gets a paper cut!\" Strike fast, adventurer, and check something off - but beware! If you leave any Dailies undone, the Basi-list will attack you and your party!",
- "questBasilistCompletion": "The Basi-list has scattered into paper scraps, which shimmer gently in rainbow colors. \"Whew!\" says @Arcosine. \"Good thing you guys were here!\" Feeling more experienced than before, you gather up some fallen gold from among the papers.",
- "questBasilistBoss": "The Basi-List",
- "questEggHuntText": "Egg Hunt",
- "questEggHuntNotes": "Overnight, strange plain eggs have appeared everywhere: in Matt's stables, behind the counter at the Tavern, and even among the pet eggs at the Marketplace! What a nuisance! \"Nobody knows where they came from, or what they might hatch into,\" says Megan, \"but we can't just leave them laying around! Work hard and search hard to help me gather up these mysterious eggs. Maybe if you collect enough, there will be some extras left over for you...\"",
- "questEggHuntCompletion": "You did it! In gratitude, Megan gives you ten of the eggs. \"I bet the hatching potions will dye them beautiful colors! And I wonder what will happen when they turn into mounts....\"",
- "questEggHuntCollectPlainEgg": "Plain Eggs",
- "questEggHuntDropPlainEgg": "Plain Egg",
- "questDilatoryText": "The Dread Drag'on of Dilatory",
- "questDilatoryNotes": "We should have heeded the warnings.
Dark shining eyes. Ancient scales. Massive jaws, and flashing teeth. We've awoken something horrifying from the crevasse: the Dread Drag'on of Dilatory! Screaming Habiticans fled in all directions when it reared out of the sea, its terrifyingly long neck extending hundreds of feet out of the water as it shattered windows with its searing roar.
\"This must be what dragged Dilatory down!\" yells Lemoness. \"It wasn't the weight of the neglected tasks - the Dark Red Dailies just attracted its attention!\"
\"It's surging with magical energy!\" @Baconsaur cries. \"To have lived this long, it must be able to heal itself! How can we defeat it?\"
Why, the same way we defeat all beasts - with productivity! Quickly, Habitica, band together and strike through your tasks, and all of us will battle this monster together. (There's no need to abandon previous quests - we believe in your ability to double-strike!) It won't attack us individually, but the more Dailies we skip, the closer we get to triggering its Neglect Strike - and I don't like the way it's eyeing the Tavern....",
- "questDilatoryBoss": "The Dread Drag'on of Dilatory",
- "questDilatoryBossRageTitle": "Neglect Strike",
- "questDilatoryBossRageDescription": "When this bar has filled up, the Dread Drag'on of Dilatory will unleash great havoc on Habitica's terrain",
- "questDilatoryDropMantisShrimpPet": "Mantis Shrimp (Pet)",
- "questDilatoryDropMantisShrimpMount": "Mantis Shrimp (Mount)",
- "questDilatoryBossRageTavern": "`Dread Drag'on Casts NEGLECT STRIKE!`\n\nOh no! Despite our best efforts, we've let some Dailies get away from us, and their dark-red color has attracted the Drag'on's rage! With its fearsome Neglect Strike attack, it has decimated the Tavern! Luckily, we've set up an Inn in a nearby city, and you're free to keep chatting on the shore... but poor Daniel the Barkeep just saw his beloved building crumble around him!\n\nI hope the beast doesn't attack again!",
- "questDilatoryBossRageStables": "`Dread Drag'on Casts NEGLECT STRIKE!`\n\nYikes! Once again we left too many Dailies undone. The Drag'on has unleashed its Neglect Strike against Matt and the stables! Pets have been fleeing in all directions. Luckily it seems like all of yours are safe!\n\nPoor Habitica! I hope this doesn't happen again. Hurry and do all your tasks!",
- "questDilatoryBossRageMarket": "`Dread Drag'on Casts NEGLECT STRIKE!`\n\nAhhh!! Alex the Merchant just had his shop smashed to smithereens by the Drag'on's Neglect Strike! But it seems like we're really wearing this beast down. I doubt it has enough energy for another strike.\n\nSo do not waver, Habitica! Let's drive this beast away from our shores!",
- "questDilatoryCompletion": "`The Defeat Of The Dread Drag'On Of Dilatory`\n\nWe've done it! With a final last roar, the Dread Drag'on collapses and swims far, far away. Crowds of cheering Habiticans line the shores! We've helped Matt, Daniel, and Alex rebuild their buildings. But what's this?\n\n`The Citizens Return!`\n\nNow that the Drag'on has fled, thousands of sparkling colors are ascending through the sea. It is a rainbow swarm of Mantis Shrimp... and among them, hundreds of merpeople!\n\n\"We are the lost citizens of Dilatory!\" explains their leader, Manta. \"When Dilatory sank, the Mantis Shrimp that lived in these waters used a spell to transform us into merpeople so that we could survive. But in its rage, the Dread Drag'on trapped us all in the dark crevasse. We have been imprisoned there for hundreds of years - but now at last we are free to rebuild our city!\"\n\n\"As a thank you,\" says his friend @Ottl, \"Please accept this Mantis Shrimp pet and Mantis Shrimp mount, as well as XP, gold, and our eternal gratitude.\"\n\n`Rewards`\n * Mantis Shrimp Pet\n * Mantis Shrimp Mount\n * Chocolate, Cotton Candy Blue, Cotton Candy Pink, Fish, Honey, Meat, Milk, Potato, Rotten Meat, Strawberry",
- "questSeahorseText": "The Dilatory Derby",
- "questSeahorseNotes": "It's Derby Day, and Habiticans from all over the continent have traveled to Dilatory to race their pet seahorses! Suddenly, a great splashing and snarling breaks out at the racetrack, and you hear Seahorse Keeper @Kiwibot shouting above the roar of the waves. \"The gathering of seahorses has attracted a fierce Sea Stallion!\" she cries. \"He's smashing through the stables and destroying the ancient track! Can anyone calm him down?\"",
- "questSeahorseCompletion": "The now-tame Sea Stallion swims docilely to your side. \"Oh, look!\" Kiwibot says. \"He wants us to take care of his children.\" She gives you three eggs. \"Raise them well,\" she says. \"You're welcome at the Dilatory Derby any day!\"",
- "questSeahorseBoss": "Sea Stallion",
- "questSeahorseDropSeahorseEgg": "Seahorse (Egg)",
- "questSeahorseUnlockText": "Unlocks purchasable Seahorse eggs in the Market",
- "questGroupAtom": "Attack of the Mundane",
- "questAtom1Text": "Attack of the Mundane, Part 1: Dish Disaster!",
- "questAtom1Notes": "You reach the shores of Washed-Up Lake for some well-earned relaxation... But the lake is polluted with unwashed dishes! How did this happen? Well, you simply cannot allow the lake to be in this state. There is only one thing you can do: clean the dishes and save your vacation spot! Better find some soap to clean up this mess. A lot of soap...",
- "questAtom1CollectSoapBars": "Bars of Soap",
- "questAtom1Drop": "The SnackLess Monster (Scroll)",
- "questAtom1Completion": "After some thorough scrubbing, all the dishes are stacked safely on the shore! You stand back and proudly survey your hard work.",
- "questAtom2Text": "Attack of the Mundane, Part 2: The SnackLess Monster",
- "questAtom2Notes": "Phew, this place is looking a lot nicer with all these dishes cleaned. Maybe, you can finally have some fun now. Oh - there seems to be a pizza box floating in the lake. Well, what's one more thing to clean really? But alas, it is no mere pizza box! With a sudden rush the box lifts from the water to reveal itself to be the head of a monster. It cannot be! The fabled SnackLess Monster?! It is said it has existed hidden in the lake since prehistoric times: a creature spawned from the leftover food and trash of the ancient Habiticans. Yuck!",
- "questAtom2Boss": "The SnackLess Monster",
- "questAtom2Drop": "The Laundromancer (Scroll)",
- "questAtom2Completion": "With a deafening cry, and five delicious types of cheese bursting from its mouth, the Snackless Monster falls to pieces. Well done, brave adventurer! But wait... is there something else wrong with the lake?",
- "questAtom3Text": "Attack of the Mundane, Part 3: The Laundromancer",
- "questAtom3Notes": "Just when you thought that your trials had ended, Washed-Up Lake begins to froth violently. “HOW DARE YOU!” booms a voice from beneath the water's surface. A robed, blue figure emerges from the water, wielding a magic toilet brush. Filthy laundry begins to bubble up to the surface of the lake. \"I am the Laundromancer!\" he angrily announces. \"You have some nerve - washing my delightfully dirty dishes, destroying my pet, and entering my domain with such clean clothes. Prepare to feel the soggy wrath of my anti-laundry magic!\"",
- "questAtom3Completion": "The wicked Laundromancer has been defeated! Clean laundry falls in piles all around you. Things are looking much better around here. As you begin to wade through the freshly pressed armor, a glint of metal catches your eye, and your gaze falls upon a gleaming helm. The original owner of this shining item may be unknown, but as you put it on, you feel the warming presence of a generous spirit. Too bad they didn't sew on a nametag.",
- "questAtom3Boss": "The Laundromancer",
- "questAtom3DropPotion": "Base Hatching Potion",
- "questOwlText": "The Night-Owl",
- "questOwlNotes": "The Tavern light is lit 'til dawn Until one eve the glow is gone! How can we see for our all-nighters? @Twitching cries, \"I need some fighters! See that Night-Owl, starry foe? Fight with haste and do not slow! We'll drive its shadow from our door, And make the night shine bright once more!\"",
- "questOwlCompletion": "The Night-Owl fades before the dawn, But even so, you feel a yawn. Perhaps it's time to get some rest? Then on your bed, you see a nest! A Night-Owl knows it can be great To finish work and stay up late, But your new pets will softly peep To tell you when it's time to sleep.",
- "questOwlBoss": "The Night-Owl",
- "questOwlDropOwlEgg": "Owl (Egg)",
- "questOwlUnlockText": "Unlocks purchasable Owl eggs in the Market",
- "questPenguinText": "The Fowl Frost",
- "questPenguinNotes": "Although it's a hot summer day in the southernmost tip of Habitica, an unnatural chill has fallen upon Lively Lake. Strong, frigid winds rush around as the shore begins to freeze over. Ice spikes jut up from the ground, pushing grass and dirt away. @Melynnrose and @Breadstrings run up to you.
\"Help!\" says @Melynnrose. \"We brought a giant penguin in to freeze the lake so we could all go ice skating, but we ran out of fish to feed him!\"
\"He got angry and is using his freeze breath on everything he sees!\" says @Breadstrings. \"Please, you have to subdue him before all of us are covered in ice!\" Looks like you need this penguin to... cool down.",
- "questPenguinCompletion": "Upon the penguin's defeat, the ice melts away. The giant penguin settles down in the sunshine, slurping up an extra bucket of fish you found. He skates off across the lake, blowing gently downwards to create smooth, sparkling ice. What an odd bird! \"It appears he left behind a few eggs, as well,\" says @Painter de Cluster.
@Rattify laughs. \"Maybe these penguins will be a little more... chill?\"",
- "questPenguinBoss": "Frost Penguin",
- "questPenguinDropPenguinEgg": "Penguin (Egg)",
- "questPenguinUnlockText": "Unlocks purchasable Penguin eggs in the Market",
- "questStressbeastText": "The Abominable Stressbeast of the Stoïkalm Steppes",
- "questStressbeastNotes": "Complete Dailies and To-Dos to damage the World Boss! Incomplete Dailies fill the Stress Strike Bar. When the Stress Strike bar is full, the World Boss will attack an NPC. A World Boss will never damage individual players or accounts in any way. Only active accounts who are not resting in the inn will have their incomplete Dailies tallied.
~*~
The first thing we hear are the footsteps, slower and more thundering than the stampede. One by one, Habiticans look outside their doors, and words fail us.
We've all seen Stressbeasts before, of course - tiny vicious creatures that attack during difficult times. But this? This towers taller than the buildings, with paws that could crush a dragon with ease. Frost swings from its stinking fur, and as it roars, the icy blast rips the roofs off our houses. A monster of this magnitude has never been mentioned outside of distant legend.
\"Beware, Habiticans!\" SabreCat cries. \"Barricade yourselves indoors - this is the Abominable Stressbeast itself!\"
\"That thing must be made of centuries of stress!\" Kiwibot says, locking the Tavern door tightly and shuttering the windows.
\"The Stoïkalm Steppes,\" Lemoness says, face grim. \"All this time, we thought they were placid and untroubled, but they must have been secretly hiding their stress somewhere. Over generations, it grew into this, and now it's broken free and attacked them - and us!\"
There's only one way to drive away a Stressbeast, Abominable or otherwise, and that's to attack it with completed Dailies and To-Dos! Let's all band together and fight off this fearsome foe - but be sure not to slack on your tasks, or our undone Dailies may enrage it so much that it lashes out...",
- "questStressbeastBoss": "The Abominable Stressbeast",
- "questStressbeastBossRageTitle": "Stress Strike",
- "questStressbeastBossRageDescription": "When this gauge fills, the Abominable Stressbeast will unleash its Stress Strike on Habitica!",
- "questStressbeastDropMammothPet": "Mammoth (Pet)",
- "questStressbeastDropMammothMount": "Mammoth (Mount)",
- "questStressbeastBossRageStables": "`Abominable Stressbeast uses STRESS STRIKE!`\n\nThe surge of stress heals Abominable Stressbeast!\n\nOh no! Despite our best efforts, we've let some Dailies get away from us, and their dark-red color has infuriated the Abominable Stressbeast and caused it to regain some of its health! The horrible creature lunges for the Stables, but Matt the Beast Master heroically leaps into the fray to protect the pets and mounts. The Stressbeast has seized Matt in its vicious grip, but at least it's distracted for the moment. Hurry! Let's keep our Dailies in check and defeat this monster before it attacks again!",
- "questStressbeastBossRageBailey": "`Abominable Stressbeast uses STRESS STRIKE!`\n\nThe surge of stress heals Abominable Stressbeast!\n\nAhh!!! Our incomplete Dailies caused the Abominable Stressbeast to become madder than ever and regain some of its health! Bailey the Town Crier was shouting for citizens to get to safety, and now it has seized her in its other hand! Look at her, valiantly reporting on the news as the Stressbeast swings her around viciously... Let's be worthy of her bravery by being as productive as we can to save our NPCs!",
- "questStressbeastBossRageGuide": "`Abominable Stressbeast uses STRESS STRIKE!`\n\nThe surge of stress heals Abominable Stressbeast!\n\nLook out! Justin the Guide is trying to distract the Stressbeast by running around its ankles, yelling productivity tips! The Abominable Stressbeast is stomping madly, but it seems like we're really wearing this beast down. I doubt it has enough energy for another strike. Don't give up... we're so close to finishing it off!",
- "questStressbeastDesperation": "`Abominable Stressbeast reaches 500K health! Abominable Stressbeast uses Desperate Defense!`\n\nWe're almost there, Habiticans! With diligence and Dailies, we've whittled the Stressbeast's health down to only 500K! The creature roars and flails in desperation, rage building faster than ever. Bailey and Matt yell in terror as it begins to swing them around at a terrifying pace, raising a blinding snowstorm that makes it harder to hit.\n\nWe'll have to redouble our efforts, but take heart - this is a sign that the Stressbeast knows it is about to be defeated. Don't give up now!",
- "questStressbeastCompletion": "The Abominable Stressbeast is DEFEATED!
We've done it! With a final bellow, the Abominable Stressbeast dissipates into a cloud of snow. The flakes twinkle down through the air as cheering Habiticans embrace their pets and mounts. Our animals and our NPCs are safe once more!
Stoïkalm is Saved!
SabreCat speaks gently to a small sabertooth. \"Please find the citizens of the Stoïkalm Steppes and bring them to us,\" he says. Several hours later, the sabertooth returns, with a herd of mammoth riders following slowly behind. You recognize the head rider as Lady Glaciate, the leader of Stoïkalm.
\"Mighty Habiticans,\" she says, \"My citizens and I owe you the deepest thanks, and the deepest apologies. In an effort to protect our Steppes from turmoil, we began to secretly banish all of our stress into the icy mountains. We had no idea that it would build up over generations into the Stressbeast that you saw! When it broke loose, it trapped all of us in the mountains in its stead and went on a rampage against our beloved animals.\" Her sad gaze follows the falling snow. \"We put everyone at risk with our foolishness. Rest assured that in the future, we will come to you with our problems before our problems come to you.\"
She turns to where @Baconsaur is snuggling with some of the baby mammoths. \"We have brought your animals an offering of food to apologize for frightening them, and as a symbol of trust, we will leave some of our pets and mounts with you. We know that you will all take care good care of them.\"",
- "questStressbeastCompletionChat": "`The Abominable Stressbeast is DEFEATED!`\n\nWe've done it! With a final bellow, the Abominable Stressbeast dissipates into a cloud of snow. The flakes twinkle down through the air as cheering Habiticans embrace their pets and mounts. Our animals and our NPCs are safe once more!\n\n`Stoïkalm is Saved!`\n\nSabreCat speaks gently to a small sabertooth. \"Please find the citizens of the Stoïkalm Steppes and bring them to us,\" he says. Several hours later, the sabertooth returns, with a herd of mammoth riders following slowly behind. You recognize the head rider as Lady Glaciate, the leader of Stoïkalm.\n\n\"Mighty Habiticans,\" she says, \"My citizens and I owe you the deepest thanks, and the deepest apologies. In an effort to protect our Steppes from turmoil, we began to secretly banish all of our stress into the icy mountains. We had no idea that it would build up over generations into the Stressbeast that you saw! When it broke loose, it trapped all of us in the mountains in its stead and went on a rampage against our beloved animals.\" Her sad gaze follows the falling snow. \"We put everyone at risk with our foolishness. Rest assured that in the future, we will come to you with our problems before our problems come to you.\"\n\nShe turns to where @Baconsaur is snuggling with some of the baby mammoths. \"We have brought your animals an offering of food to apologize for frightening them, and as a symbol of trust, we will leave some of our pets and mounts with you. We know that you will all take care good care of them.\"",
- "questTRexText": "King of the Dinosaurs",
- "questTRexNotes": "Now that ancient creatures from the Stoïkalm Steppes are roaming throughout all of Habitica, @Urse has decided to adopt a full-grown Tyrannosaur. What could go wrong?
Everything.",
- "questTRexCompletion": "The wild dinosaur finally stops its rampage and settles down to make friends with the giant roosters. @Urse beams down at it. \"They're not such terrible pets, after all! They just need a little discipline. Here, take some Tyrannosaur eggs for yourself.\"",
- "questTRexBoss": "Flesh Tyrannosaur",
- "questTRexUndeadText": "The Dinosaur Unearthed",
- "questTRexUndeadNotes": "As the ancient dinosaurs from the Stoïkalm Steppes roam through Habit City, a cry of terror emanates from the Grand Museum. @Baconsaur shouts, \"The Tyrannosaur skeleton in the museum is stirring! It must have sensed its kin!\" The bony beast bares its teeth and clatters towards you. How can you defeat a creature that is already dead? You'll have to strike fast before it heals itself!",
- "questTRexUndeadCompletion": "The Tyrannosaur's glowing eyes grow dark, and it settles back onto its familiar pedestal. Everyone sighs with relief. \"Look!\" @Baconsaur says. \"Some of the fossilized eggs are shiny and new! Maybe they'll hatch for you.\"",
- "questTRexUndeadBoss": "Skeletal Tyrannosaur",
- "questTRexUndeadRageTitle": "Skeleton Healing",
- "questTRexUndeadRageDescription": "This bar fills when you don't complete your Dailies. When it is full, the Skeletal Tyrannosaur will heal 30% of its remaining health!",
- "questTRexUndeadRageEffect": "`Skeletal Tyrannosaur uses SKELETON HEALING!`\n\nThe monster lets forth an unearthly roar, and some of its damaged bones knit back together!",
- "questTRexDropTRexEgg": "Tyrannosaur (Egg)",
- "questTRexUnlockText": "Unlocks purchasable Tyrannosaur eggs in the Market",
- "questRockText": "Escape the Cave Creature",
- "questRockNotes": "Crossing Habitica's Meandering Mountains with some friends, you make camp one night in a beautiful cave laced with shining minerals. But when you wake up the next morning, the entrance has disappeared, and the floor of the cave is shifting underneath you.
\"The mountain's alive!\" shouts your companion @pfeffernusse. \"These aren't crystals - these are teeth!\"
@Painter de Cluster grabs your hand. \"We'll have to find another way out - stay with me and don't get distracted, or we could be trapped in here forever!\"",
- "questRockBoss": "Crystal Colossus",
- "questRockCompletion": "Your diligence has allowed you to find a safe path through the living mountain. Standing in the sunshine, your friend @intune notices something glinting on the ground by the cave's exit. You stoop to pick it up, and see that it's a small rock with a vein of gold running through it. Beside it are a number of other rocks with rather peculiar shapes. They almost look like... eggs?",
- "questRockDropRockEgg": "Rock (Egg)",
- "questRockUnlockText": "Unlocks purchasable Rock eggs in the Market",
- "questBunnyText": "The Killer Bunny",
- "questBunnyNotes": "After many difficult days, you reach the peak of Mount Procrastination and stand before the imposing doors of the Fortress of Neglect. You read the inscription in the stone. \"Inside resides the creature that embodies your greatest fears, the reason for your inaction. Knock and face your demon!\" You tremble, imagining the horror within and feel the urge to flee as you have done so many times before. @Draayder holds you back. \"Steady, my friend! The time has come at last. You must do this!\"
You knock and the doors swing inward. From within the gloom you hear a deafening roar, and you draw your weapon.",
- "questBunnyBoss": "Killer Bunny",
- "questBunnyCompletion": "With one final blow the killer rabbit sinks to the ground. A sparkly mist rises from her body as she shrinks down into a tiny bunny... nothing like the cruel beast you faced a moment before. Her nose twitches adorably and she hops away, leaving some eggs behind. @Gully laughs. \"Mount Procrastination has a way of making even the smallest challenges seem insurmountable. Let's gather these eggs and head for home.\"",
- "questBunnyDropBunnyEgg": "Bunny (Egg)",
- "questBunnyUnlockText": "Unlocks purchasable Bunny eggs in the Market",
- "questSlimeText": "The Jelly Regent",
- "questSlimeNotes": "As you work on your tasks, you notice you are moving slower and slower. \"It's like walking through molasses,\" @Leephon grumbles. \"No, like walking through jelly!\" @starsystemic says. \"That slimy Jelly Regent has slathered his stuff all over Habitica. It's gumming up the works. Everybody is slowing down.\" You look around. The streets are slowly filling with clear, colorful ooze, and Habiticans are struggling to get anything done. As others flee the area, you grab a mop and prepare for battle!",
- "questSlimeBoss": "Jelly Regent",
- "questSlimeCompletion": "With a final jab, you trap the Jelly Regent in an over-sized donut, rushed in by @Overomega, @LordDarkly, and @Shaner, the quick-thinking leaders of the pastry club. As everyone is patting you on the back, you feel someone slip something into your pocket. It’s the reward for your sweet success: three Marshmallow Slime eggs.",
- "questSlimeDropSlimeEgg": "Marshmallow Slime (Egg)",
- "questSlimeUnlockText": "Unlocks purchasable Slime eggs in the Market",
- "questSheepText": "The Thunder Ram",
- "questSheepNotes": "As you wander the rural Taskan countryside with friends, taking a \"quick break\" from your obligations, you find a cozy yarn shop. You are so absorbed in your procrastination that you hardly notice the ominous clouds creep over the horizon. \"I've got a ba-a-a-ad feeling about this weather,\" mutters @Misceo, and you look up. The stormy clouds are swirling together, and they look a lot like a... \"We don't have time for cloud-gazing!\" @starsystemic shouts. \"It's attacking!\" The Thunder Ram hurtles forward, slinging bolts of lightning right at you!",
- "questSheepBoss": "Thunder Ram",
- "questSheepCompletion": "Impressed by your diligence, the Thunder Ram is drained of its fury. It launches three huge hailstones in your direction, and then fades away with a low rumble. Upon closer inspection, you discover that the hailstones are actually three fluffy eggs. You gather them up, and then stroll home under a blue sky.",
- "questSheepDropSheepEgg": "Sheep (Egg)",
- "questSheepUnlockText": "Unlocks purchasable Sheep eggs in the Market",
- "questKrakenText": "The Kraken of Inkomplete",
- "questKrakenNotes": "It's a warm, sunny day as you sail across the Inkomplete Bay, but your thoughts are clouded with worries about everything that you still need to do. It seems that as soon as you finish one task, another crops up, and then another...
Suddenly, the boat gives a horrible jolt, and slimy tentacles burst out of the water on all sides! \"We're being attacked by the Kraken of Inkomplete!\" Wolvenhalo cries.
\"Quickly!\" Lemoness calls to you. \"Strike down as many tentacles and tasks as you can, before new ones can rise up to take their place!\"",
- "questKrakenBoss": "The Kraken of Inkomplete",
- "questKrakenCompletion": "As the Kraken flees, several eggs float to the surface of the water. Lemoness examines them, and her suspicion turns to delight. \"Cuttlefish eggs!\" she says. \"Here, take them as a reward for everything you've completed.\"",
- "questKrakenDropCuttlefishEgg": "Cuttlefish (Egg)",
- "questKrakenUnlockText": "Unlocks purchasable Cuttlefish eggs in the Market",
- "questWhaleText": "Wail of the Whale",
- "questWhaleNotes": "You arrive at the Diligent Docks, hoping to take a submarine to watch the Dilatory Derby. Suddenly, a deafening bellow forces you to stop and cover your ears. \"Thar she blows!\" cries Captain @krazjega, pointing to a huge, wailing whale. \"It's not safe to send out the submarines while she's thrashing around!\"
\"Quick,\" calls @UncommonCriminal. \"Help me calm the poor creature so we can figure out why she's making all this noise!\"",
- "questWhaleBoss": "Wailing Whale",
- "questWhaleCompletion": "After much hard work, the whale finally ceases her thunderous cry. \"Looks like she was drowning in waves of negative habits,\" @zoebeagle explains. \"Thanks to your consistent effort, we were able to turn the tides!\" As you step into the submarine, several whale eggs bob towards you, and you scoop them up.",
- "questWhaleDropWhaleEgg": "Whale (Egg)",
- "questWhaleUnlockText": "Unlocks purchasable Whale eggs in the Market",
- "questGroupDilatoryDistress": "Dilatory Distress",
- "questDilatoryDistress1Text": "Dilatory Distress, Part 1: Message in a Bottle",
- "questDilatoryDistress1Notes": "A message in a bottle arrived from the newly rebuilt city of Dilatory! It reads: \"Dear Habiticans, we need your help once again. Our princess has disappeared and the city is under siege by some unknown watery demons! The mantis shrimps are holding the attackers at bay. Please aid us!\" To make the long journey to the sunken city, one must be able to breathe water. Fortunately, the alchemists @Benga and @hazel can make it all possible! You only have to find the proper ingredients.",
- "questDilatoryDistress1Completion": "You don the the finned armor and swim to Dilatory as quickly as you can. The merfolk and their mantis shrimp allies have managed to keep the monsters outside the city for the moment, but they are losing. No sooner are you within the castle walls than the horrifying siege descends!",
- "questDilatoryDistress1CollectFireCoral": "Fire Coral",
- "questDilatoryDistress1CollectBlueFins": "Blue Fins",
- "questDilatoryDistress1DropArmor": "Finned Oceanic Armor (Armor)",
- "questDilatoryDistress2Text": "Dilatory Distress, Part 2: Creatures of the Crevasse",
- "questDilatoryDistress2Notes": "The siege can be seen from miles away: thousands of disembodied skulls rushing through a portal in the crevasse walls and making their way towards Dilatory.
When you meet King Manta in his war room, his eyes seem sunken, and his face is worried. \"My daughter Adva disappeared into the Dark Crevasse just before this siege began. Please find her and bring her back home safely! I will lend you my Fire Coral Circlet to aid you. If you succeed, it is yours.\"",
- "questDilatoryDistress2Completion": "You vanquish the nightmarish horde of skulls, but you feel no closer to finding Adva. You speak to @Kiwibot, the royal tracker, to see if she has any ideas. \"The mantis shrimps that defend the city must have seen Adva escape,\" @Kiwibot says. \"Try following them into the Dark Crevasse.\"",
- "questDilatoryDistress2Boss": "Water Skull Swarm",
- "questDilatoryDistress2RageTitle": "Swarm Respawn",
- "questDilatoryDistress2RageDescription": "Swarm Respawn: This bar fills when you don't complete your Dailies. When it is full, the Water Skull Swarm will heal 30% of its remaining health!",
- "questDilatoryDistress2RageEffect": "`Water Skull Swarm uses SWARM RESPAWN!`\n\nEmboldened by their victories, more skulls pour forth from the crevasse, bolstering the swarm!",
- "questDilatoryDistress2DropSkeletonPotion": "Skeleton Hatching Potion",
- "questDilatoryDistress2DropCottonCandyBluePotion": "Cotton Candy Blue Hatching Potion",
- "questDilatoryDistress2DropHeadgear": "Fire Coral Circlet (Headgear)",
- "questDilatoryDistress3Text": "Dilatory Distress, Part 3: Not a Mere Maid",
- "questDilatoryDistress3Notes": "You follow the mantis shrimps deep into the Crevasse, and discover an underwater fortress. Princess Adva, escorted by more watery skulls, awaits you inside the main hall. \"My father has sent you, has he not? Tell him I refuse to return. I am content to stay here and practice my sorcery. Leave now, or you shall feel the wrath of the ocean's new queen!\" Adva seems very adamant, but as she speaks you notice a strange, ruby pendant on her neck glowing ominously... Perhaps her delusions would cease should you break it?",
- "questDilatoryDistress3Completion": "Finally, you manage to pull the bewitched pendant from Adva's neck and throw it away. Adva clutches her head. \"Where am I? What happened here?\" After hearing your story, she frowns. \"This necklace was given to me by a strange ambassador - a lady called 'Tzina'. I don't remember anything after that!\"
Back at Dilatory, Manta is overjoyed by your success. \"Allow me to reward you with this trident and shield! I ordered them from @aiseant and @starsystemic as a gift for Adva, but... I'd rather not put weapons in her hands any time soon.\"",
- "questDilatoryDistress3Boss": "Adva, the Usurping Mermaid",
- "questDilatoryDistress3DropFish": "Fish (Food)",
- "questDilatoryDistress3DropWeapon": "Trident of Crashing Tides (Weapon)",
- "questDilatoryDistress3DropShield": "Moonpearl Shield (Off-Hand Item)",
- "questCheetahText": "Such a Cheetah",
- "questCheetahNotes": "As you hike across the Sloensteadi Savannah with your friends @PainterProphet, @tivaquinn, @Unruly Hyena, and @Crawford, you're startled to see a Cheetah screeching past with a new Habitican clamped in its jaws. Under the Cheetah's scorching paws, tasks burn away as though complete -- before anyone has the chance to actually finish them! The Habitican sees you and yells, \"Please help me! This Cheetah is making me level too quickly, but I'm not getting anything done. I want to slow down and enjoy the game. Make it stop!\" You fondly remember your own fledgling days, and know that you have to help the newbie by stopping the Cheetah!",
- "questCheetahCompletion": "The new Habitican is breathing heavily after the wild ride, but thanks you and your friends for your help. \"I'm glad that Cheetah won't be able to grab anyone else. It did leave some Cheetah eggs for us, so maybe we can raise them into more trustworthy pets!\"",
- "questCheetahBoss": "Cheetah",
- "questCheetahDropCheetahEgg": "Cheetah (Egg)",
- "questCheetahUnlockText": "Unlocks purchasable Cheetah eggs in the Market",
- "questHorseText": "Ride the Night-Mare",
- "questHorseNotes": "While relaxing in the Tavern with @beffymaroo and @JessicaChase, the talk turns to good-natured boasting about your adventuring accomplishments. Proud of your deeds, and perhaps getting a bit carried away, you brag that you can tame any task around. A nearby stranger turns toward you and smiles. One eye twinkles as he invites you to prove your claim by riding his horse.\nAs you all head for the stables, @UncommonCriminal whispers, \"You may have bitten off more than you can chew. That's no horse - that's a Night-Mare!\" Looking at its stamping hooves, you begin to regret your words...",
- "questHorseCompletion": "It takes all your skill, but finally the horse stamps a couple of hooves and nuzzles you in the shoulder before allowing you to mount. You ride briefly but proudly around the Tavern grounds while your friends cheer. The stranger breaks into a broad grin.\n\"I can see that was no idle boast! Your determination is truly impressive. Take these eggs to raise horses of your own, and perhaps we'll meet again one day.\" You take the eggs, the stranger tips his hat... and vanishes.",
- "questHorseBoss": "Night-Mare",
- "questHorseDropHorseEgg": "Horse (Egg)",
- "questHorseUnlockText": "Unlocks purchasable Horse eggs in the Market",
- "questBurnoutText": "Burnout and the Exhaust Spirits",
- "questBurnoutNotes": "It is well past midnight, still and stiflingly hot, when Redphoenix and scout captain Kiwibot abruptly burst through the city gates. \"We need to evacuate all the wooden buildings!\" Redphoenix shouts. \"Hurry!\"
Kiwibot grips the wall as she catches her breath. \"It's draining people and turning them into Exhaust Spirits! That's why everything was delayed. That's where the missing people have gone. It's been stealing their energy!\"
\"'It'?'\" asks Lemoness.
And then the heat takes form.
It rises from the earth in a billowing, twisting mass, and the air chokes with the scent of smoke and sulphur. Flames lick across the molten ground and contort into limbs, writhing to horrific heights. Smoldering eyes snap open, and the creature lets out a deep and crackling cackle.
Kiwibot whispers a single word.
\"Burnout.\"",
- "questBurnoutCompletion": "Burnout is DEFEATED!
With a great, soft sigh, Burnout slowly releases the ardent energy that was fueling its fire. As the monster curls quietly into ashes, its stolen energy shimmers through the air, rejuvenating the Exhaust Spirits and returning them to their true forms.
Ian, Daniel, and the Seasonal Sorceress cheer as Habiticans rush to greet them, and all the missing citizens of the Flourishing Fields embrace their friends and families. The final Exhaust Spirit transforms into the Joyful Reaper herself!
\"Look!\" whispers @Baconsaur, as the ashes begin to glitter. Slowly, they resolve into hundreds of shining phoenixes!
One of the glowing birds alights on the Joyful Reaper's skeletal arm, and she grins at it. \"It has been a long time since I've had the exquisite privilege to behold a phoenix in the Flourishing Fields,\" she says. \"Although given recent occurrences, I must say, this is highly thematically appropriate!\"
Her tone sobers, although (naturally) her grin remains. \"We're known for being hard-working here, but we are also known for our feasts and festivities. Rather ironic, I suppose, that as we strove to plan a spectacular party, we refused to permit ourselves any time for fun. We certainly won't make the same mistake twice!\"
She claps her hands. \"Now - let's celebrate!\"",
- "questBurnoutCompletionChat": "`Burnout is DEFEATED!`\n\nWith a great, soft sigh, Burnout slowly releases the ardent energy that was fueling its fire. As the monster curls quietly into ashes, its stolen energy shimmers through the air, rejuvenating the Exhaust Spirits and returning them to their true forms.\n\nIan, Daniel, and the Seasonal Sorceress cheer as Habiticans rush to greet them, and all the missing citizens of the Flourishing Fields embrace their friends and families. The final Exhaust Spirit transforms into the Joyful Reaper herself!\n\n\"Look!\" whispers @Baconsaur, as the ashes begin to glitter. Slowly, they resolve into hundreds of shining phoenixes!\n\nOne of the glowing birds alights on the Joyful Reaper's skeletal arm, and she grins at it. \"It has been a long time since I've had the exquisite privilege to behold a phoenix in the Flourishing Fields,\" she says. \"Although given recent occurrences, I must say, this is highly thematically appropriate!\"\n\nHer tone sobers, although (naturally) her grin remains. \"We're known for being hard-working here, but we are also known for our feasts and festivities. Rather ironic, I suppose, that as we strove to plan a spectacular party, we refused to permit ourselves any time for fun. We certainly won't make the same mistake twice!\"\n\nShe claps her hands. \"Now - let's celebrate!\"\n\nAll Habiticans receive:\n\nPhoenix Pet\nPhoenix Mount\nAchievement: Savior of the Flourishing Fields\nBasic Candy\nVanilla Candy\nSand Candy\nCinnamon Candy\nChocolate Candy\nRotten Candy\nSour Pink Candy\nSour Blue Candy\nHoney Candy",
- "questBurnoutBoss": "Burnout",
- "questBurnoutBossRageTitle": "Exhaust Strike",
- "questBurnoutBossRageDescription": "When this gauge fills, Burnout will unleash its Exhaust Strike on Habitica!",
- "questBurnoutDropPhoenixPet": "Phoenix (Pet)",
- "questBurnoutDropPhoenixMount": "Phoenix (Mount)",
- "questBurnoutBossRageQuests": "`Burnout uses EXHAUST STRIKE!`\n\nOh no! Despite our best efforts, we've let some Dailies get away from us, and now Burnout is inflamed with energy! With a crackling snarl, it engulfs Ian the Quest Master in a surge of spectral fire. As fallen quest scrolls smolder, the smoke clears, and you see that Ian has been drained of energy and turned into a drifting Exhaust Spirit!\n\nOnly defeating Burnout can break the spell and restore our beloved Quest Master. Let's keep our Dailies in check and defeat this monster before it attacks again!",
- "questBurnoutBossRageSeasonalShop": "`Burnout uses EXHAUST STRIKE!`\n\nAhh!!! Our incomplete Dailies have fed the flames of Burnout, and now it has enough energy to strike again! It lets loose a gout of spectral flame that sears the Seasonal Shop. You're horrified to see that the cheery Seasonal Sorceress has been transformed into a drooping Exhaust Spirit.\n\nWe have to rescue our NPCs! Hurry, Habiticans, complete your tasks and defeat Burnout before it strikes for a third time!",
- "questBurnoutBossRageTavern": "`Burnout uses EXHAUST STRIKE!`\n\nMany Habiticans have been hiding from Burnout in the Tavern, but no longer! With a screeching howl, Burnout rakes the Tavern with its white-hot hands. As the Tavern patrons flee, Daniel is caught in Burnout's grip, and transforms into an Exhaust Spirit right in front of you!\n\nThis hot-headed horror has gone on for too long. Don't give up... we're so close to vanquishing Burnout for once and for all!",
- "questFrogText": "Swamp of the Clutter Frog",
- "questFrogNotes": "As you and your friends are slogging through the Swamps of Stagnation, @starsystemic points at a large sign. \"Stay on the path -- if you can.\"
\"Surely that isn't hard!\" @RosemonkeyCT says. \"It's broad and clear.\"
But as you continue, you notice that path is gradually overtaken by the muck of the swamp, laced with bits of strange blue debris and clutter, until it's impossible to proceed.
As you look around, wondering how it got this messy, @Jon Arjinborn shouts, \"Look out!\" An angry frog leaps from the sludge, clad in dirty laundry and lit by blue fire. You will have to overcome this poisonous Clutter Frog to progress!",
- "questFrogCompletion": "The frog cowers back into the muck, defeated. As it slinks away, the blue slime fades, leaving the way ahead clear.
Sitting in the middle of the path are three pristine eggs. \"You can even see the tiny tadpoles through the clear casing!\" @Breadstrings says. \"Here, you should take them.\"",
- "questFrogBoss": "Clutter Frog",
- "questFrogDropFrogEgg": "Frog (Egg)",
- "questFrogUnlockText": "Unlocks purchasable Frog eggs in the Market",
- "questSnakeText": "The Serpent of Distraction",
- "questSnakeNotes": "It takes a hardy soul to live in the Sand Dunes of Distraction. The arid desert is hardly a productive place, and the shimmering dunes have led many a traveler astray. However, something has even the locals spooked. The sands have been shifting and upturning entire villages. Residents claim a monster with an enormous serpentine body lies in wait under the sands, and they have all pooled together a reward for whomever will help them find and stop it. The much-lauded snake charmers @EmeraldOx and @PainterProphet have agreed to help you summon the beast. Can you stop the Serpent of Distraction?",
- "questSnakeCompletion": "With assistance from the charmers, you banish the Serpent of Distraction. Though you were happy to help the inhabitants of the Dunes, you can't help but feel a little sad for your fallen foe. While you contemplate the sights, @LordDarkly approaches you. \"Thank you! It's not much, but I hope this can express our gratitude properly.\" He hands you some Gold and... some Snake eggs! You will see that majestic animal again after all.",
- "questSnakeBoss": "Serpent of Distraction",
- "questSnakeDropSnakeEgg": "Snake (Egg)",
- "questSnakeUnlockText": "Unlocks purchasable Snake eggs in the Market",
- "questUnicornText": "Convincing the Unicorn Queen",
- "questUnicornNotes": "Conquest Creek has become muddied, destroying Habit City's fresh water supply! Luckily, @Lukreja knows an old legend that claims that a unicorn's horn can purify the foulest of waters. Together with your intrepid guide @UncommonCriminal, you hike through the frozen peaks of the Meandering Mountains. Finally, at the icy summit of Mount Habitica itself, you find the Unicorn Queen amid the glittering snows. \"Your pleas are compelling,\" she tells you. \"But first you must prove that you are worthy of my aid!\"",
- "questUnicornCompletion": "Impressed by your diligence and strength, the Unicorn Queen at last agrees that your cause is worthy. She allows you to ride on her back as she soars to the source of Conquest Creek. As she lowers her golden horn to the befouled waters, a brilliant blue light rises from the water’s surface. It is so blinding that you are forced to close your eyes. When you open them a moment later, the unicorn is gone. However, @rosiesully lets out a cry of delight: the water is now clear, and three shining eggs rest at the creek’s edge.",
- "questUnicornBoss": "The Unicorn Queen",
- "questUnicornDropUnicornEgg": "Unicorn (Egg)",
- "questUnicornUnlockText": "Unlocks purchasable Unicorn eggs in the Market",
- "questSabretoothText": "The Sabre Cat",
- "questSabretoothNotes": "A roaring monster is terrorizing Habitica! The creature stalks through the wilds and woods, then bursts forth to attack before vanishing again. It's been hunting innocent pandas and frightening the flying pigs into fleeing their pens to roost in the trees. @InspectorCaracal and @icefelis explain that the Zombie Sabre Cat was set free while they were excavating in the ancient, untouched ice-fields of the Stoïkalm Steppes. \"It was perfectly friendly at first – I don't know what happened. Please, you have to help us recapture it! Only a champion of Habitica can subdue this prehistoric beast!\"",
- "questSabretoothCompletion": "After a long and tiring battle, you wrestle the Zombie Sabre Cat to the ground. As you are finally able to approach, you notice a nasty cavity in one of its sabre teeth. Realising the true cause of the cat's wrath, you're able to get the cavity filled by @Fandekasp, and advise everyone to avoid feeding their friend sweets in future. The Sabre Cat flourishes, and in gratitude, its tamers send you a generous reward – a clutch of sabretooth eggs!",
- "questSabretoothBoss": "Zombie Sabre Cat",
- "questSabretoothDropSabretoothEgg": "Sabretooth (Egg)",
- "questSabretoothUnlockText": "Unlocks purchasable Sabretooth eggs in the Market",
- "questMonkeyText": "Monstrous Mandrill and the Mischief Monkeys",
- "questMonkeyNotes": "The Sloensteadi Savannah is being torn apart by the Monstrous Mandrill and his Mischief Monkeys! They shriek loudly enough to drown out the sound of approaching deadlines, encouraging everyone to avoid their duties and keep monkeying around. Alas, plenty of people ape this bad behavior. If no one stops these primates, soon everyone's tasks will be as red as the Monstrous Mandrill's face!
\"It will take a dedicated adventurer to resist them,\" says @yamato.
\"Quick, let's get this monkey off everyone's backs!\" @Oneironaut yells, and you charge into battle.",
- "questMonkeyCompletion": "You did it! No bananas for those fiends today. Overwhelmed by your diligence, the monkeys flee in panic. \"Look,\" says @Misceo. \"They left a few eggs behind.\"
@Leephon grins. \"Maybe a well-trained pet monkey can help you as much as the wild ones hinder you!\"",
- "questMonkeyBoss": "Monstrous Mandrill",
- "questMonkeyDropMonkeyEgg": "Monkey (Egg)",
- "questMonkeyUnlockText": "Unlocks purchasable Monkey eggs in the Market",
- "questSnailText": "The Snail of Drudgery Sludge",
- "questSnailNotes": "You're excited to begin questing in the abandoned Dungeons of Drudgery, but as soon as you enter, you feel the ground under your feet start to suck at your boots. You look up to the path ahead and see Habiticans mired in slime. @Overomega yells, \"They have too many unimportant tasks and dailies, and they're getting stuck on things that don't matter! Pull them out!\"
\"You need to find the source of the ooze,\" @Pfeffernusse agrees, \"or the tasks that they cannot accomplish will drag them down forever!\"
Pulling out your weapon, you wade through the gooey mud.... and encounter the fearsome Snail of Drudgery Sludge.",
- "questSnailCompletion": "You bring your weapon down on the great Snail's shell, cracking it in two, releasing a flood of water. The slime is washed away, and the Habiticans around you rejoice. \"Look!\" says @Misceo. \"There's a small group of snail eggs in the remnants of the muck.\"",
- "questSnailBoss": "Snail of Drudgery Sludge",
- "questSnailDropSnailEgg": "Snail (Egg)",
- "questSnailUnlockText": "Unlocks purchasable Snail eggs in the Market",
- "questBewilderText": "The Be-Wilder",
- "questBewilderNotes": "The party begins like any other.
The appetizers are excellent, the music is swinging, and even the dancing elephants have become routine. Habiticans laugh and frolic amid the overflowing floral centerpieces, happy to have a distraction from their least-favorite tasks, and the April Fool whirls among them, eagerly providing an amusing trick here and a witty twist there.
As the Mistiflying clock tower strikes midnight, the April Fool leaps onto the stage to give a speech.
“Friends! Enemies! Tolerant acquaintances! Lend me your ears.” The crowd chuckles as animal ears sprout from their heads, and they pose with their new accessories.
“As you know,” the Fool continues, “my confusing illusions usually only last a single day. But I’m pleased to announce that I’ve discovered a shortcut that will guarantee us non-stop fun, without having to deal with the pesky weight of our responsibilities. Charming Habiticans, meet my magical new friend... the Be-Wilder!”
Lemoness pales suddenly, dropping her hors d'oeuvres. “Wait! Don’t trust--”
But suddenly mists are pouring into the room, glittering and thick, and they swirl around the April Fool, coalescing into cloudy feathers and a stretching neck. The crowd is speechless as an monstrous bird unfolds before them, its wings shimmering with illusions. It lets out a horrible screeching laugh.
“Oh, it has been ages since a Habitican has been foolish enough to summon me! How wonderful it feels, to have a tangible form at last.”
Buzzing in terror, the magic bees of Mistiflying flee the floating city, which sags from the sky. One by one, the brilliant spring flowers wither up and wisp away.
“My dearest friends, why so alarmed?” crows the Be-Wilder, beating its wings. “There’s no need to toil for your rewards any more. I’ll just give you all the things that you desire!”
A rain of coins pours from the sky, hammering into the ground with brutal force, and the crowd screams and flees for cover. “Is this a joke?” Baconsaur shouts, as the gold smashes through windows and shatters roof shingles.
PainterProphet ducks as lightning bolts crackle overhead, and fog blots out the sun. “No! This time, I don’t think it is!”
Quickly, Habiticans, don’t let this World Boss distract us from our goals! Stay focused on the tasks that you need to complete so we can rescue Mistiflying -- and hopefully, ourselves.",
- "questBewilderCompletion": "The Be-Wilder is DEFEATED!
We've done it! The Be-Wilder lets out a ululating cry as it twists in the air, shedding feathers like falling rain. Slowly, gradually, it coils into a cloud of sparkling mist. As the newly-revealed sun pierces the fog, it burns away, revealing the coughing, mercifully human forms of Bailey, Matt, Alex.... and the April Fool himself.
Mistiflying is saved!
The April Fool has enough shame to look a bit sheepish. “Oh, hm,” he says. “Perhaps I got a little…. carried away.”
The crowd mutters. Sodden flowers wash up on sidewalks. Somewhere in the distance, a roof collapses with a spectacular splash.
“Er, yes,” the April Fool says. “That is. What I meant to say was, I’m dreadfully sorry.” He heaves a sigh. “I suppose it can’t all be fun and games, after all. It might not hurt to focus occasionally. Maybe I’ll get a head start on next year’s pranking.”
Redphoenix coughs meaningfully.
“I mean, get a head start on this year’s spring cleaning!” the April Fool says. “Nothing to fear, I’ll have Habit City in spit-shape soon. Luckily nobody is better than I at dual-wielding mops.”
Encouraged, the marching band starts up.
It isn’t long before all is back to normal in Habit City. Plus, now that the Be-Wilder has evaporated, the magical bees of Mistiflying bustle back to work, and soon the flowers are blooming and the city is floating once more.
As Habiticans cuddle the magical fuzzy bees, the April Fool’s eyes light up. “Oho, I’ve had a thought! Why don’t you all keep some of these fuzzy Bee Pets and Mounts? It’s a gift that perfectly symbolizes the balance between hard work and sweet rewards, if I’m going to get all boring and allegorical on you.” He winks. “Besides, they don’t have stingers! Fool’s honor.”",
- "questBewilderCompletionChat": "`The Be-Wilder is DEFEATED!`\n\nWe've done it! The Be-Wilder lets out a ululating cry as it twists in the air, shedding feathers like falling rain. Slowly, gradually, it coils into a cloud of sparkling mist. As the newly-revealed sun pierces the fog, it burns away, revealing the coughing, mercifully human forms of Bailey, Matt, Alex.... and the April Fool himself.\n\n`Mistiflying is saved!`\n\nThe April Fool has enough shame to look a bit sheepish. “Oh, hm,” he says. “Perhaps I got a little…. carried away.”\n\nThe crowd mutters. Sodden flowers wash up on sidewalks. Somewhere in the distance, a roof collapses with a spectacular splash.\n\n“Er, yes,” the April Fool says. “That is. What I meant to say was, I’m dreadfully sorry.” He heaves a sigh. “I suppose it can’t all be fun and games, after all. It might not hurt to focus occasionally. Maybe I’ll get a head start on next year’s pranking.”\n\nRedphoenix coughs meaningfully.\n\n“I mean, get a head start on this year’s spring cleaning!” the April Fool says. “Nothing to fear, I’ll have Habit City in spit-shape soon. Luckily nobody is better than I at dual-wielding mops.”\n\nEncouraged, the marching band starts up.\n\nIt isn’t long before all is back to normal in Habit City. Plus, now that the Be-Wilder has evaporated, the magical bees of Mistiflying bustle back to work, and soon the flowers are blooming and the city is floating once more.\n\nAs Habiticans cuddle the magical fuzzy bees, the April Fool’s eyes light up. “Oho, I’ve had a thought! Why don’t you all keep some of these fuzzy Bee Pets and Mounts? It’s a gift that perfectly symbolizes the balance between hard work and sweet rewards, if I’m going to get all boring and allegorical on you.” He winks. “Besides, they don’t have stingers! Fool’s honor.”",
- "questBewilderBossRageTitle": "Beguilement Strike",
- "questBewilderBossRageDescription": "When this gauge fills, The Be-Wilder will unleash its Beguilement Strike on Habitica!",
- "questBewilderDropBumblebeePet": "Magical Bee (Pet)",
- "questBewilderDropBumblebeeMount": "Magical Bee (Mount)",
- "questBewilderBossRageMarket": "`The Be-Wilder uses BEGUILEMENT STRIKE!`\n\nOh no! Despite our best efforts, we've gotten distracted by the Be-Wilder’s charming illusions and have forgotten to do some of our Dailies! With a cackling cry, the shining bird beats its wings, raising a swarm of mist around Alex the Merchant. When the fog clears, he has been possessed! “Have some free samples!” he shouts gleefully, and begins to hurl exploding eggs and potions at fleeing Habiticans. Not the most favorable of sales, to be sure.\n\nHurry! Let's stay focused on our Dailies to defeat this monster before it possesses someone else.",
- "questBewilderBossRageStables": "`The Be-Wilder uses BEGUILEMENT STRIKE!`\n\nAhh!!! Once again the Be-Wilder has dazzled us into neglecting our Dailies, and now it has attacked Matt the Beast Master! With a swirl of mist, Matt transforms into a terrifying winged creature, and all the pets and mounts howl sadly in their stables. Quickly, stay focused on your tasks to defeat this dastardly distraction!",
- "questBewilderBossRageBailey": "`The Be-Wilder uses BEGUILEMENT STRIKE!`\n\nLook out! In the middle of reporting the news, Bailey the Town Crier has been possessed by the Be-Wilder! She lets out an evil, uninformative screech as she rises into the air. Now how will we know what’s going on?\n\nDon't give up... we're so close to defeating this bothersome bird for once and for all!",
- "questFalconText": "The Birds of Preycrastination",
- "questFalconNotes": "Mt. Habitica is being overshadowed by a looming mountain of To-Dos. It used to be a place to picnic and enjoy a sense of accomplishment, until the neglected tasks grew out of control. Now it's home to fearsome Birds of Preycrastination, foul creatures which stop Habiticans from completing their tasks!
\"It's too hard!\" they caw at @JonArinbjorn and @Onheiron. \"It'll take too long to do right now! It won't make any difference if you wait until tomorrow! Why don't you do something fun instead?\"
No more, you vow. You will climb your personal mountain of To-Dos and defeat the Birds of Preycrastination!",
- "questFalconCompletion": "Having finally triumphed over the Birds of Preycrastination, you settle down to enjoy the view and your well-earned rest.
\"Wow!\" says @Trogdorina. \"You won!\"
@Squish adds, \"Here, take these eggs I found as a reward.\"",
- "questFalconBoss": "Birds of Preycrastination",
- "questFalconDropFalconEgg": "Falcon (Egg)",
- "questFalconUnlockText": "Unlocks purchasable Falcon eggs in the Market",
- "questTreelingText": "The Tangle Tree",
- "questTreelingNotes": "It's the annual Garden Competition, and everyone is talking about the mysterious project which @aurakami has promised to unveil. You join the crowd on the day of the big announcement, and marvel at the introduction of a moving tree. @fuzzytrees explains that the tree will help with garden maintenance, showing how it can mow the lawn, trim the hedge and prune the roses all at the same time – until the tree suddenly goes wild, turning its secateurs on its creator! The crowd panics as everyone tries to flee, but you aren't afraid – you leap forward, ready to do battle.",
- "questTreelingCompletion": "You dust yourself off as the last few leaves drift to the floor. In spite of the upset, the Garden Competition is now safe – although the tree you just reduced to a heap of wood chips won't be winning any prizes! \"Still a few kinks to work out there,\" @PainterProphet says. \"Perhaps someone else would do a better job of training the saplings. Do you fancy a go?\"",
- "questTreelingBoss": "Tangle Tree",
- "questTreelingDropTreelingEgg": "Treeling (Egg)",
- "questTreelingUnlockText": "Unlocks purchasable Treeling eggs in the Market",
- "questAxolotlText": "The Magical Axolotl",
- "questAxolotlNotes": "From the depths of Washed-Up Lake you see rising bubbles and... fire? A little axolotl rises from the murky water spewing streaks of colors. Suddenly it begins to open its mouth and @streak yells, \"Look out!\" as the Magical Axolotl starts to gulp up your willpower!
The Magical Axolotl swells with spells, taunting you. \"Have you heard of my powers of regeneration? You'll tire before I do!\"
\"We can defeat you with the good habits we've built!\" @PainterProphet defiantly shouts. You steel yourself to be productive to defeat the Magical Axolotl and regain your stolen willpower!",
- "questAxolotlCompletion": "After defeating the Magical Axolotl, you realize that you regained your willpower all on your own.
\"The willpower? The regeneration? It was all just an illusion?\" @Kiwibot asks.
\"Most magic is,\" the Magical Axolotl replies. \"I'm sorry for tricking you. Please take these eggs as an apology. I trust you to raise them to use their magic for good habits and not evil!\"
You and @hazel40 clutch your new eggs in one hand and wave goodbye with the other as the Magical Axolotl returns to the lake.",
- "questAxolotlBoss": "Magical Axolotl",
- "questAxolotlDropAxolotlEgg": "Axolotl (Egg)",
- "questAxolotlUnlockText": "Unlocks purchasable Axolotl eggs in the Market",
- "questAxolotlRageTitle": "Axolotl Regeneration",
- "questAxolotlRageDescription": "This bar fills when you don't complete your Dailies. When it is full, the Magical Axolotl will heal 30% of its remaining health!",
- "questAxolotlRageEffect": "`Magical Axolotl uses AXOLOTL REGENERATION!`\n\n`A curtain of colorful bubbles obscures the monster for a moment, and when it clears, some of its wounds have vanished!`",
- "questTurtleText": "Guide the Turtle",
- "questTurtleNotes": "Help! This giant sea turtle cannot find her way to her nesting beach. She returns there every year to lay her eggs, but this year Inkomplete Bay is filled with toxic Task Flotsam made of red dailies and unchecked to-dos. \"She's thrashing in a panic!\" @JessicaChase says.
@UncommonCriminal nods. \"It's because her guiding senses are fogged and confused.\"
@Scarabsi grabs your arm. \"Can you help clear the Task Flotsam blocking her path? It may be hazardous, but we have to help her!\"",
- "questTurtleCompletion": "Your valiant work has cleared the waters for our sea turtle to find her beach. You, @Bambin, and @JaizakAripaik watch as she buries her brood of eggs deep in the sand so they can grow and hatch into hundreds of little sea turtles. Ever the lady, she gives you three eggs each, asking that you feed and nurture them so one day they become big sea turtles themselves.",
- "questTurtleBoss": "Task Flotsam",
- "questTurtleDropTurtleEgg": "Turtle (Egg)",
- "questTurtleUnlockText": "Unlocks purchasable Turtle eggs in the Market",
- "questArmadilloText": "The Indulgent Armadillo",
- "questArmadilloNotes": "It's time to get outside and start your day. You swing open your door only to be met with what looks like a sheet of rock. \"I'm just giving you the day off!\" says a muffled voice through the blocked door. \"Don't be such a bummer, just relax today!\"
Suddenly, @Beffymaroo and @PainterProphet knock on your window. \"Looks like the Indulgent Armadillo has taken a liking to you! C'mon, we'll help you get her out of your way!\"",
- "questArmadilloCompletion": "Finally, after a long morning of convincing the Indulgent Armadillo that you do, in fact, want to work, she caves. \"I'm sorry!\" She apologizes. \"I just wanted to help. I thought everyone liked lazy days!\"
You smile, and let her know that next time you've earned a day off you'll invite her over. She grins back at you. Passers-by @Tipsy and @krajzega congratulate you on the good work as she rolls away, leaving a few eggs as an apology.",
- "questArmadilloBoss": "Indulgent Armadillo",
- "questArmadilloDropArmadilloEgg": "Armadillo (Egg)",
- "questArmadilloUnlockText": "Unlocks purchasable Armadillo eggs in the Market",
- "questCowText": "The Mootant Cow",
- "questCowNotes": "It’s been a long, hot day at Sparring Farms, and there is nothing more you want than a long sip of water and some sleep. You're standing there daydreaming when @Soloana suddenly screams, \"Everyone run! The prize cow has mootated!\"
@eevachu gulps. \"It must be our bad habits that infected it.\"
\"Quick!\" @Feralem Tau says. \"Let’s do something before the udder cows mootate, too.\"
You’ve herd enough. No more daydreaming -- it's time to get those bad habits under control!",
- "questCowCompletion": "You milk your good habits for all they are worth until the cow reverts to its original form. The cow looks over at you with her pretty brown eyes and nudges over three eggs.
@fuzzytrees laughs and hands you the eggs, \"Maybe it still is mootated if there are baby cows in these eggs. But I trust you to stick to your good habits when you raise them!\"",
- "questCowBoss": "Mootant Cow",
- "questCowDropCowEgg": "Cow (Egg)",
- "questCowUnlockText": "Unlocks purchasable Cow eggs in the Market",
- "questBeetleText": "The CRITICAL BUG",
- "questBeetleNotes": "Something in the domain of Habitica has gone awry. The Blacksmiths' forges have extinguished, and strange errors are appearing everywhere. With an ominous tremor, an insidious foe worms from the earth... a CRITICAL BUG! You brace yourself as it infects the land, and glitches begin to overtake the Habiticans around you. @starsystemic yells, \"We need to help the Blacksmiths get this Bug under control!\" It looks like you'll have to make this programmer's pest your top priority.",
- "questBeetleCompletion": "With a final attack, you crush the CRITICAL BUG. @starsystemic and the Blacksmiths rush up to you, overjoyed. \"I can't thank you enough for smashing that bug! Here, take these.\" You are presented with three shiny beetle eggs. Hopefully these little bugs will grow up to help Habitica, not hurt it.",
- "questBeetleBoss": "CRITICAL BUG",
- "questBeetleDropBeetleEgg": "Beetle (Egg)",
- "questBeetleUnlockText": "Unlocks purchasable Beetle eggs in the Market",
- "questGroupTaskwoodsTerror": "Terror in the Taskwoods",
- "questTaskwoodsTerror1Text": "Terror in the Taskwoods, Part 1: The Blaze in the Taskwoods",
- "questTaskwoodsTerror1Notes": "You have never seen the Joyful Reaper so agitated. The ruler of the Flourishing Fields lands her skeleton gryphon mount right in the middle of Productivity Plaza and shouts without dismounting. \"Lovely Habiticans, we need your help! Something is starting fires in the Taskwoods, and we still haven't fully recovered from our battle against Burnout. If it's not halted, the flames could engulf all of our wild orchards and berry bushes!\"
You quickly volunteer, and hasten to the Taskwoods. As you creep into Habitica’s biggest fruit-bearing forest, you suddenly hear clanking and cracking voices from far ahead, and catch the faint smell of smoke. Soon enough, a horde of cackling, flaming skull-creatures flies by you, biting off branches and setting the treetops on fire!",
- "questTaskwoodsTerror1Completion": "With the help of the Joyful Reaper and the renowned pyromancer @Beffymaroo, you manage to drive back the swarm. In a show of solidarity, Beffymaroo offers you her Pyromancer's Turban as you move deeper into the forest.",
- "questTaskwoodsTerror1Boss": "Fire Skull Swarm",
- "questTaskwoodsTerror1RageTitle": "Swarm Respawn",
- "questTaskwoodsTerror1RageDescription": "Swarm Respawn: This bar fills when you don't complete your Dailies. When it is full, the Fire Skull Swarm will heal 30% of its remaining health!",
- "questTaskwoodsTerror1RageEffect": "`Fire Skull Swarm uses SWARM RESPAWN!`\n\nEmboldened by their victories, more skulls swirl around you in a gout of flame!",
- "questTaskwoodsTerror1DropSkeletonPotion": "Skeleton Hatching Potion",
- "questTaskwoodsTerror1DropRedPotion": "Red Hatching Potion",
- "questTaskwoodsTerror1DropHeadgear": "Pyromancer's Turban (Headgear)",
- "questTaskwoodsTerror2Text": "Terror in the Taskwoods, Part 2: Finding the Flourishing Fairies",
- "questTaskwoodsTerror2Notes": "Having fought through the swarm of burning skulls, you reach a large group of refugee farmers at the forest's edge. \"Their village was burnt down by a renegade autumn spirit,\" says a familiar voice. It's @Kiwibot, the legendary tracker! \"I managed to gather the survivors, but there's no sign of the Flourishing Fairies who help to grow the wild fruit of the Taskwoods. Please, you have to help me rescue them!\"",
- "questTaskwoodsTerror2Completion": "You manage to locate the last dryad and lead her away from the monsters. When you return to the refugee farmers, you are greeted by the thankful faeries, who give you a robe woven of shining magic and silk. Suddenly, a deep rumbling sound echoes through the trees, shaking the very earth. \"That must be the renegade spirit,\" the Joyful Reaper says. \"Let's hurry!\"",
- "questTaskwoodsTerror2CollectPixies": "Pixies",
- "questTaskwoodsTerror2CollectBrownies": "Brownies",
- "questTaskwoodsTerror2CollectDryads": "Dryads",
- "questTaskwoodsTerror2DropArmor": "Pyromancer's Robes (Armor)",
- "questTaskwoodsTerror3Text": "Terror in the Taskwoods, Part 3: Jacko of the Lantern",
- "questTaskwoodsTerror3Notes": "Ready for battle, your group marches to the heart of the forest, where the renegade spirit is trying to destroy an ancient apple tree surrounded by fruitful berry bushes. His pumpkin-like head radiates a terrible light wherever it turns, and in his left hand he holds a long rod, with a lantern hanging from its tip. Instead of fire or flame, however, the lantern contains a dark crystal that chills you to the very bone.
The Joyful Reaper raises a bony hand to her mouth. \"That's -- that's Jacko, the Lantern Spirit! But he's a helpful harvest ghost who guides our farmers. What could possibly drive the dear soul to act this way?\"
\"I don't know,\" says @bridgetteempress. \"But it looks like that 'dear soul' is about to attack us!\"",
- "questTaskwoodsTerror3Completion": "After a long battle, you manage to land a well-aimed blow at the lantern that Jacko carries, and the crystal within shatters. Jacko suddenly snaps back to his senses and bursts into glowing tears. \"Oh, my beautiful forest! What have I done?!\" he wails. His tears extinguish the remaining fires, and the apple tree and wild berries are saved.
After you help him relax, he explains, \"I met this charming lady named Tzina, and she gave me this glowing crystal as a gift. At her urging, I put it in my lantern... but that's the last thing I recall.\" He turns to you with a golden smile. \"Perhaps you should take it for safekeeping while I help the wild orchards to regrow.\"",
- "questTaskwoodsTerror3Boss": "Jacko of the Lantern",
- "questTaskwoodsTerror3DropStrawberry": "Strawberry (Food)",
- "questTaskwoodsTerror3DropWeapon": "Taskwoods Lantern (Two-Handed Weapon)",
- "questFerretText": "The Nefarious Ferret",
- "questFerretNotes": "Walking through Habit City, you see an unhappy crowd surrounding a red-robed Ferret.
\"That productivity potion you sold me is useless!\" @Beffymaroo complains. \"I watched three hours of TV last night instead of doing my chores!\"
\"Yeah!\" shouts @Pandah. \"And today I spent an hour rearranging my books instead of reading them!\"
The Nefarious Ferret spreads his hands innocently. \"That's more TV watching and book organizing than you'd normally get done, isn't it?\"
The crowd erupts in anger.
\"No refunds!\" crows the Nefarious Ferret. He fires a bolt of magic into the crowd, preparing to escape in the smoke.
\"Please, Habitican!\" @Faye says, grabbing your arm. \"Defeat the ferret and make him refund his dishonest earnings!\"",
- "questFerretCompletion": "You defeat the soft-furred swindler and @UncommonCriminal gives the crowd their refunds. There's even a little gold left over for you. Plus, it looks like the Nefarious Ferret dropped some eggs in his hurry to get away!",
- "questFerretBoss": "Nefarious Ferret",
- "questFerretDropFerretEgg": "Ferret (Egg)",
- "questFerretUnlockText": "Unlocks purchasable Ferret eggs in the Market",
- "questDustBunniesText": "The Feral Dust Bunnies",
- "questDustBunniesNotes": "It's been a while since you've done any dusting in here, but you're not too worried—a little dust never hurt anyone, right? It's not until you stick your hand into one of the dustiest corners and feel something bite that you remember @InspectorCaracal's warning: leaving harmless dust sit too long causes it to turn into vicious dust bunnies! You'd better defeat them before they cover all of Habitica in fine particles of dirt!",
- "questDustBunniesCompletion": "The dust bunnies vanish into a puff of... well, dust. As it clears, you look around. You'd forgotten how nice this place looks when it's clean. You spy a small pile of gold where the dust used to be. Huh, you'd been wondering where that was!",
- "questDustBunniesBoss": "Feral Dust Bunnies",
- "questGroupMoon": "Lunar Battle",
- "questMoon1Text": "Lunar Battle, Part 1: Find the Mysterious Shards",
- "questMoon1Notes": "Habiticans have been distracted from their tasks by something strange: twisted shards of stone are appearing across the land. Worried, @Starsystemic the Seer summons you to her tower. She says, \"I've been reading alarming omens about these shards, which have been blighting the land and driving hardworking Habiticans to distraction. I can track the source, but first I'll need to examine the shards. Can you bring some to me?\"",
- "questMoon1Completion": "@Starsystemic disappears into her tower to examine the shards you gathered. \"This may be more complicated than we feared,\" says @Beffymaroo, her trusted assistant. \"It will take us some time to discover the cause. Keep checking in every day, and when we know more, we'll send you the next quest scroll.\"",
- "questMoon1CollectShards": "Lunar Shards",
- "questMoon1DropHeadgear": "Lunar Warrior Helm (Headgear)",
- "questMoon2Text": "Lunar Battle, Part 2: Stop the Overshadowing Stress",
- "questMoon2Notes": "After studying the shards, @Starsystemic the Seer has some bad news. \"An ancient monster is approaching Habitica, and it is causing terrible stress to befall the citizens. I can draw the shadow out of people's hearts and into this tower, where it will take physical form, but you’ll need to defeat it before it breaks loose and spreads again.\" You nod, and she starts to chant. Dancing shadows fill the room, pressing tightly together. The cold wind swirls, the darkness deepens. The Overshadowing Stress rises from the floor, grins like a nightmare made real... and strikes!",
- "questMoon2Completion": "The shadow explodes in a puff of dark air, leaving the room brighter and your hearts lighter. The stress blanketing Habitica is diminished, and you can all breathe a sigh of relief. Still, as you look up at the sky, you sense that this is not over: the monster knows someone destroyed its shadow. \"We'll keep careful watch in the coming weeks,\" says @Starsystemic, \"and I'll send you a quest scroll when it manifests.\"",
- "questMoon2Boss": "Overshadowing Stress",
- "questMoon2DropArmor": "Lunar Warrior Armor (Armor)",
- "questMoon3Text": "Lunar Battle, Part 3: The Monstrous Moon",
- "questMoon3Notes": "You get @Starsystemic's urgent scroll at the stroke of midnight and gallop to her tower. \"The monster is using the full moon to try to cross over to our realm,\" she says. \"If it succeeds, the shockwave of stress will be overwhelming!\"
To your dismay, you see that the monster is indeed using the moon to manifest. A glowing eye opens in its rocky surface, and a long tongue rolls from a gaping, fanged mouth. There's no way you'll let it fully emerge!",
- "questMoon3Completion": "The emerging monster bursts into shadow, and the moon turns silver as the danger passes. The dragons start singing again, and the stars sparkle with a soothing light. @Starsystemic the Seer bends down and picks up a lunar shard. It shines silver in her hand, before changing into a magnificent crystal scythe.",
- "questMoon3Boss": "Monstrous Moon",
- "questMoon3DropWeapon": "Lunar Scythe (Two-Handed Weapon)",
- "questSlothText": "The Somnolent Sloth",
- "questSlothNotes": "As you and your party venture through the Somnolent Snowforest, you're relieved to see a glimmering of green among the white snowdrifts... until an enormous sloth emerges from the frosty trees! Green emeralds shimmer hypnotically on its back.
\"Hello, adventurers... why don't you take it slow? You've been walking for a while... so why not... stop? Just lie down, and rest...\"
You feel your eyelids grow heavy, and you realize: It's the Somnolent Sloth! According to @JaizakAripaik, it got its name from the emeralds on its back which are rumored to... send people to... sleep...
You shake yourself awake, fighting drowsiness. In the nick of time, @awakebyjava and @PainterProphet begin to shout spells, forcing your party awake. \"Now's our chance!\" @Kiwibot yells.",
- "questSlothCompletion": "You did it! As you defeat the Somnolent Sloth, its emeralds break off. \"Thank you for freeing me of my curse,\" says the sloth. \"I can finally sleep well, without those heavy emeralds on my back. Have these eggs as thanks, and you can have the emeralds too.\" The sloth gives you three sloth eggs and heads off for warmer climates.",
- "questSlothBoss": "Somnolent Sloth",
- "questSlothDropSlothEgg": "Sloth (Egg)",
- "questSlothUnlockText": "Unlocks purchasable Sloth eggs in the Market",
- "questTriceratopsText": "The Trampling Triceratops",
- "questTriceratopsNotes": "The snow-capped Stoïkalm Volcanoes are always bustling with hikers and sight-seers. One tourist, @plumilla, calls over a crowd. \"Look! I enchanted the ground to glow so that we can play field games on it for our outdoor activity Dailies!\" Sure enough, the ground is swirling with glowing red patterns. Even some of the prehistoric pets from the area come over to play.
Suddenly, there's a loud snap -- a curious Triceratops has stepped on @plumilla's wand! It's engulfed in a burst of magic energy, and the ground starts shaking and growing hot. The Triceratops' eyes shine red, and it roars and begins to stampede!
\"That's not good,\" calls @McCoyly, pointing in the distance. Each magic-fueled stomp is causing the volcanoes to erupt, and the glowing ground is turning to lava beneath the dinosaur's feet! Quickly, you must hold off the Trampling Triceratops until someone can reverse the spell!",
- "questTriceratopsCompletion": "With quick thinking, you herd the creature towards the soothing Stoïkalm Steppes so that @*~Seraphina~* and @PainterProphet can reverse the lava spell without distraction. The calming aura of the Steppes takes effect, and the Triceratops curls up as the volcanoes go dormant once more. @PainterProphet passes you some eggs that were rescued from the lava. \"Without you, we wouldn't have been able to concentrate to stop the eruptions. Give these pets a good home.\"",
- "questTriceratopsBoss": "Trampling Triceratops",
- "questTriceratopsDropTriceratopsEgg": "Triceratops (Egg)",
- "questTriceratopsUnlockText": "Unlocks purchasable Triceratops eggs in the Market",
- "questGroupStoikalmCalamity": "Stoïkalm Calamity",
- "questStoikalmCalamity1Text": "Stoïkalm Calamity, Part 1: Earthen Enemies",
- "questStoikalmCalamity1Notes": "A terse missive arrives from @Kiwibot, and the frost-crusted scroll chills your heart as well as your fingertips. \"Visiting Stoïkalm Steppes -- monsters bursting from earth -- send help!\" You gather your party and ride north, but as soon as you venture down from the mountains, the snow beneath your feet explodes and gruesomely grinning skulls surround you!
Suddenly, a spear sails past, burying itself in a skull that was burrowing through the snow in an attempt to catch you unawares. A tall woman in finely-crafted armor gallops into the fray on the back of a mastodon, her long braid swinging as she yanks the spear unceremoniously from the crushed beast. It's time to fight off these foes with the help of Lady Glaciate, the leader of the Mammoth Riders!",
- "questStoikalmCalamity1Completion": "As you deliver a final blow to the skulls, they dissipate in a puff of magic. \"The dratted swarm may be gone,\" Lady Glaciate says, \"but we have bigger problems. Follow me.\" She tosses you a cloak to protect you from the chill air, and you ride off after her.",
- "questStoikalmCalamity1Boss": "Earth Skull Swarm",
- "questStoikalmCalamity1RageTitle": "Swarm Respawn",
- "questStoikalmCalamity1RageDescription": "Swarm Respawn: This bar fills when you don't complete your Dailies. When it is full, the Earth Skull Swarm will heal 30% of its remaining health!",
- "questStoikalmCalamity1RageEffect": "`Earth Skull Swarm uses SWARM RESPAWN!`\n\nMore skulls break free from the ground, their teeth chattering in the cold!",
- "questStoikalmCalamity1DropSkeletonPotion": "Skeleton Hatching Potion",
- "questStoikalmCalamity1DropDesertPotion": "Desert Hatching Potion",
- "questStoikalmCalamity1DropArmor": "Mammoth Rider Armor",
- "questStoikalmCalamity2Text": "Stoïkalm Calamity, Part 2: Seek the Icicle Caverns",
- "questStoikalmCalamity2Notes": "The stately hall of the Mammoth Riders is an austere masterpiece of architecture, but it is also entirely empty. There's no furniture, the weapons are missing, and even the columns were picked clean of their inlays.
\"Those skulls scoured the place,\" Lady Glaciate says, and there is a blizzard brewing in her tone. \"Humiliating. Not a soul is to mention this to the April Fool, or I will never hear the end of it.\"
\"How mysterious!\" says @Beffymaroo. \"But where did they--\"
\"The icicle drake caverns.\" Lady Glaciate gestures at shining coins spilled in the snow outside. \"Sloppy.\"
\"But aren't icicle drakes honorable creatures with their own treasure hoards?\" @Beffymaroo asks. \"Why would they possibly--\"
\"Mind control,\" says Lady Glaciate, utterly unfazed. \"Or something equally melodramatic and inconvenient.\" She begins to stride from the hall. \"Why are you just standing there?\"
Quickly, go follow the trail of Icicle Coins!",
- "questStoikalmCalamity2Completion": "The Icicle Coins lead you straight to the buried entrance of a cleverly hidden cavern. Though the weather outside is calm and lovely, with the sunlight sparkling across the expanse of snow, there is a howling within like a fierce winter wind. Lady Glaciate grimaces and hands you a Mammoth Rider helm. \"Wear this,\" she says. \"You'll need it.\"",
- "questStoikalmCalamity2CollectIcicleCoins": "Icicle Coins",
- "questStoikalmCalamity2DropHeadgear": "Mammoth Rider Helm (Headgear)",
- "questStoikalmCalamity3Text": "Stoïkalm Calamity, Part 3: Icicle Drake Quake",
- "questStoikalmCalamity3Notes": "The twining tunnels of the icicle drake caverns shimmer with frost... and with untold riches. You gape, but Lady Glaciate strides past without a glance. \"Excessively flashy,\" she says. \"Obtained admirably, though, from respectable mercenary work and prudent banking investments. Look further.\" Squinting, you spot a towering pile of stolen items hidden in the shadows.
A sibilant voice hisses as you approach. \"My delicious hoard! You shall not steal it back from me!\" A sinuous body slides from the heap: the Icicle Drake Queen herself! You have just enough time to note the strange bracelets glittering on her wrists and the wildness glinting in her eyes before she lets out a howl that shakes the earth around you.",
- "questStoikalmCalamity3Completion": "You subdue the Icicle Drake Queen, giving Lady Glaciate time to shatter the glowing bracelets. The Queen stiffens in apparent mortification, then quickly covers it with a haughty pose. \"Feel free to remove these extraneous items,\" she says. \"I'm afraid they simply don't fit our decor.\"
\"Also, you stole them,\" @Beffymaroo says. \"By summoning monsters from the earth.\"
The Icicle Drake Queen looks miffed. \"Take it up with that wretched bracelet saleswoman,\" she says. \"It's Tzina you want. I was essentially unaffiliated.\"
Lady Glaciate claps you on the arm. \"You did well today,\" she says, handing you a spear and a horn from the pile. \"Be proud.\"",
- "questStoikalmCalamity3Boss": "Icicle Drake Queen",
- "questStoikalmCalamity3DropBlueCottonCandy": "Blue Cotton Candy (Food)",
- "questStoikalmCalamity3DropShield": "Mammoth Rider's Horn (Off-Hand Item)",
- "questStoikalmCalamity3DropWeapon": "Mammoth Rider Spear (Weapon)",
- "questGuineaPigText": "The Guinea Pig Gang",
- "questGuineaPigNotes": "You're casually strolling through Habit City's famous Market when @Pandah waves you down. \"Hey, check these out!\" They're holding up a brown and beige egg you don't recognize.
Alexander the Merchant frowns at it. \"I don't remember putting that out. I wonder where it came--\" A small paw cuts him off.
\"Guinea all your gold, merchant!\" squeaks a tiny voice brimming with evil.
\"Oh no, the egg was a distraction!\" @mewrose exclaims. \"It's the gritty, greedy Guinea Pig Gang! They never do their Dailies, so they constantly steal gold to buy health potions.\"
\"Robbing the Market?\" says @emmavig. \"Not on our watch!\" Without further prompting, you leap to Alexander's aid.",
- "questGuineaPigCompletion": "\"We submit!\" The Guinea Pig Gang Boss waves his paws at you, fluffy head hanging in shame. From underneath his hat falls a list, and @snazzyorange quickly swipes it for evidence. \"Wait a minute,\" you say. \"It's no wonder you've been getting hurt! You've got way too many Dailies. You don't need health potions -- you just need help organizing.\"
\"Really?\" squeaks the Guinea Pig Gang Boss. \"We've robbed so many people because of this! Please take our eggs as an apology for our crooked ways.\"",
- "questGuineaPigBoss": "Guinea Pig Gang",
- "questGuineaPigDropGuineaPigEgg": "Guinea Pig (Egg)",
- "questGuineaPigUnlockText": "Unlocks purchasable Guinea Pig eggs in the Market",
- "questPeacockText": "The Push-and-Pull Peacock",
- "questPeacockNotes": "You trek through the Taskwoods, wondering which of the enticing new goals you should pick. As you go deeper into the forest, you realize that you're not alone in your indecision. \"I could learn a new language, or go to the gym...\" @Cecily Perez mutters. \"I could sleep more,\" muses @Lilith of Alfheim, \"or spend time with my friends...\" It looks like @PainterProphet, @Pfeffernusse, and @Draayder are equally paralyzed by the overwhelming options.
You realize that these ever-more-demanding feelings aren't really your own... you've stumbled straight into the trap of the pernicious Push-and-Pull Peacock! Before you can run, it leaps from the bushes. With each head pulling you in conflicting directions, you start to feel burnout overcoming you. You can't defeat both foes at once, so you only have one option -- concentrate on the nearest task to fight back!",
- "questPeacockCompletion": "The Push-and-Pull Peacock is caught off guard by your sudden conviction. Defeated by your single-minded drive, its heads merge back into one, revealing the most beautiful creature you've ever seen. \"Thank you,\" the peacock says. \"I’ve spent so long pulling myself in different directions that I lost sight of what I truly wanted. Please accept these eggs as a token of my gratitude.\"",
- "questPeacockBoss": "Push-and-Pull Peacock",
- "questPeacockDropPeacockEgg": "Peacock (Egg)",
- "questPeacockUnlockText": "Unlocks purchasable Peacock eggs in the Market",
- "questButterflyText": "Bye, Bye, Butterfry",
- "questButterflyNotes": "Your gardener friend @Megan sends you an invitation: “These warm days are the perfect time to visit Habitica’s butterfly garden in the Taskan countryside. Come see the butterflies migrate!” When you arrive, however, the garden is in shambles -- little more than scorched grass and dried-out weeds. It’s been so hot that the Habiticans haven’t come out to water the flowers, and the dark-red Dailies have turned it into a dry, sun-baked, fire-hazard. There's only one butterfly there, and there's something odd about it...
“Oh no! This is the perfect hatching ground for the Flaming Butterfry,” cries @Leephon.
“If we don’t catch it, it’ll destroy everything!” gasps @Eevachu.
Time to say bye, bye to Butterfry!",
- "questButterflyCompletion": "After a blazing battle, the Flaming Butterfry is captured. “Great job catching the that would-be arsonist,” says @Megan with a sigh of relief. “Still, it’s hard to vilify even the vilest butterfly. We’d better free this Butterfry someplace safe…like the desert.”
One of the other gardeners, @Beffymaroo, comes up to you, singed but smiling. “Will you help raise these foundling chrysalises we found? Perhaps next year we’ll have a greener garden for them.”",
- "questButterflyBoss": "Flaming Butterfry",
- "questButterflyDropButterflyEgg": "Caterpillar (Egg)",
- "questButterflyUnlockText": "Unlocks purchasable Caterpillar eggs in the Market",
- "questGroupMayhemMistiflying": "Mayhem in Mistiflying",
- "questMayhemMistiflying1Text": "Mayhem in Mistiflying, Part 1: In Which Mistiflying Experiences a Dreadful Bother",
- "questMayhemMistiflying1Notes": "Although local soothsayers predicted pleasant weather, the afternoon is extremely breezy, so you gratefully follow your friend @Kiwibot into their house to escape the blustery day.
Neither of you expects to find the April Fool lounging at the kitchen table.
“Oh, hello,” he says. “Fancy seeing you here. Please, let me offer you some of this delicious tea.”
“That’s…” @Kiwibot begins. “That’s MY—“
“Yes, yes, of course,” says the April Fool, helping himself to some cookies. “Just thought I’d pop indoors and get a nice reprieve from all the tornado-summoning skulls.” He takes a casual sip from his teacup. “Incidentally, the city of Mistiflying is under attack.”
Horrified, you and your friends race to the Stables and saddle your fastest winged mounts. As you soar towards the floating city, you see that a swarm of chattering, flying skulls are laying siege to the city… and several turn their attentions towards you!",
- "questMayhemMistiflying1Completion": "The final skull drops from the sky, a shimmering set of rainbow robes clasped in its jaws, but the steady wind has not slackened. Something else is at play here. And where is that slacking April Fool? You pick up the robes, then swoop into the city.",
- "questMayhemMistiflying1Boss": "Air Skull Swarm",
- "questMayhemMistiflying1RageTitle": "Swarm Respawn",
- "questMayhemMistiflying1RageDescription": "Swarm Respawn: This bar fills when you don't complete your Dailies. When it is full, the Air Skull Swarm will heal 30% of its remaining health!",
- "questMayhemMistiflying1RageEffect": "`Air Skull Swarm uses SWARM RESPAWN!`\n\nEmboldened by their victories, more skulls come whirling out of the clouds!",
- "questMayhemMistiflying1DropSkeletonPotion": "Skeleton Hatching Potion",
- "questMayhemMistiflying1DropWhitePotion": "White Hatching Potion",
- "questMayhemMistiflying1DropArmor": "Roguish Rainbow Messenger Robes (Armor)",
- "questMayhemMistiflying2Text": "Mayhem in Mistiflying, Part 2: In Which the Wind Worsens",
- "questMayhemMistiflying2Notes": "Mistiflying dips and rocks as the magical bees keeping it afloat are buffeted by the gale. After a desperate search for the April Fool, you find him inside a cottage, blithely playing cards with an angry, trussed-up skull.
@Katy133 raises their voice over the whistling wind. “What’s causing this? We defeated the skulls, but it’s getting worse!”
“That is a pickle,” the April Fool agrees. “Please be a dear and don’t mention it to Lady Glaciate. She’s always threatening to call off our courtship on the grounds that I am ‘catastrophically irresponsible,’ and I fear that she might misread this situation.” He shuffles the deck. “Perhaps you might follow the Mistiflies? They’re immaterial, so the wind can’t blow them away, and they tend to swarm around threats.” He nods out the window, where several of the city’s patron creatures are fluttering towards the east. “Now let me concentrate — my opponent has quite the poker face.”",
- "questMayhemMistiflying2Completion": "You follow the Mistiflies to the site of a tornado, too stormy for you to enter.
“This should help,” says a voice directly in your ear, and you nearly fall off of your mount. The April Fool is somehow sitting directly behind you in the saddle. “I hear these messenger hoods emit an aura that guards against inclement weather — very useful to avoid losing missives as you fly around. Perhaps give it a try?”",
- "questMayhemMistiflying2CollectRedMistiflies": "Red Mistiflies",
- "questMayhemMistiflying2CollectBlueMistiflies": "Blue Mistiflies",
- "questMayhemMistiflying2CollectGreenMistiflies": "Green Mistiflies",
- "questMayhemMistiflying2DropHeadgear": "Roguish Rainbow Messenger Hood (Headgear)",
- "questMayhemMistiflying3Text": "Mayhem in Mistiflying, Part 3: In Which a Mailman is Extremely Rude",
- "questMayhemMistiflying3Notes": "The Mistiflies are whirling so thickly through the tornado that it’s hard to see. Squinting, you spot a many-winged silhouette floating at the center of the tremendous storm.
“Oh, dear,” the April Fool sighs, nearly drowned out by the howl of the weather. “Looks like Winny went and got himself possessed. Very relatable problem, that. Could happen to anybody.”
“The Wind-Worker!” @Beffymaroo hollers at you. “He’s Mistiflying’s most talented messenger-mage, since he’s so skilled with weather magic. Normally he’s a very polite mailman!”
As if to counteract this statement, the Wind-Worker lets out a scream of fury, and even with your magic robes, the storm nearly rips you from your mount.
“That gaudy mask is new,” the April Fool remarks. “Perhaps you should relieve him of it?”
It’s a good idea… but the enraged mage isn’t going to give it up without a fight.",
- "questMayhemMistiflying3Completion": "Just as you think you can’t withstand the wind any longer, you manage to snatch the mask from the Wind-Worker’s face. Instantly, the tornado is sucked away, leaving only balmy breezes and sunshine. The Wind-Worker looks around in bemusement. “Where did she go?”
“Who?” your friend @khdarkwolf asks.
“That sweet woman who offered to deliver a package for me. Tzina.” As he takes in the wind-swept city below him, his expression darkens. “Then again, maybe she wasn’t so sweet…”
The April Fool pats him on the back, then hands you two shimmering envelopes. “Here. Why don’t you let this distressed fellow rest, and take charge of the mail for a bit? I hear the magic in those envelopes will make them worth your while.”",
- "questMayhemMistiflying3Boss": "The Wind-Worker",
- "questMayhemMistiflying3DropPinkCottonCandy": "Pink Cotton Candy (Food)",
- "questMayhemMistiflying3DropShield": "Roguish Rainbow Message (Off-Hand Item)",
- "questMayhemMistiflying3DropWeapon": "Roguish Rainbow Message (Main-Hand Item)",
- "featheredFriendsText": "Feathered Friends Quest Bundle",
- "featheredFriendsNotes": "Contains 'Help! Harpy!,' 'The Night-Owl,' and 'The Birds of Preycrastination.' Available until May 31.",
- "questNudibranchText": "Infestation of the NowDo Nudibranches",
- "questNudibranchNotes": "You finally get around to checking your To-dos on a lazy day in Habitica. Bright against your deepest red tasks are a gaggle of vibrant blue sea slugs. You are entranced! Their sapphire colors make your most intimidating tasks look as easy as your best Habits. In a feverish stupor you get to work, tackling one task after the other in a ceaseless frenzy...
The next thing you know, @LilithofAlfheim is pouring cold water over you. “The NowDo Nudibranches have been stinging you all over! You need to take a break!”
Shocked, you see that your skin is as bright red as your To-Do list was. \"Being productive is one thing,\" @beffymaroo says, \"but you've also got to take care of yourself. Hurry, let's get rid of them!\"",
- "questNudibranchCompletion": "You see the last of the NowDo Nudibranches sliding off of a pile of completed tasks as @amadshade washes them away. One leaves behind a cloth bag, and you open it to reveal some gold and a few little ellipsoids you guess are eggs.",
- "questNudibranchBoss": "NowDo Nudibranch",
- "questNudibranchDropNudibranchEgg": "Nudibranch (Egg)",
- "questNudibranchUnlockText": "Unlocks purchasable Nudibranch eggs in the Market",
- "splashyPalsText": "Splashy Pals Quest Bundle",
- "splashyPalsNotes": "Contains 'The Dilatory Derby', 'Guide the Turtle', and 'Wail of the Whale'. Available until July 31.",
- "questHippoText": "What a Hippo-Crite",
- "questHippoNotes": "You and @awesomekitty collapse into the shade of a palm tree, exhausted. The sun beats down over the Sloensteadi Savannah, scorching the ground below. It’s been a productive day so far, conquering your Dailies, and this oasis looks like a nice place to take a break and refresh. Stooping near the water to get a drink, you stumble back in shock as a massive hippopotamus rises. “Resting so soon? Don’t be so lazy, get back to work.” You try and protest that you’ve been working hard and need a break, but the hippo isn’t having any of it.
@khdarkwolf whispers to you, “Notice how it’s lounging around all day but has the nerve to call you lazy? It’s the Hippo-Crite!”
Your friend @jumorales nods. “Let’s show it what hard work looks like!”",
- "questHippoCompletion": "The hippo bows in surrender. “I underestimated you. It seems you weren’t being lazy. My apologies. Truth be told, I may have been projecting a bit. Perhaps I should get some work done myself. Here, take these eggs as a sign of my gratitude.” Grabbing them, you settle down by the water, ready to relax at last.",
- "questHippoBoss": "The Hippo-Crite",
- "questHippoDropHippoEgg": "Hippo (Egg)",
- "questHippoUnlockText": "Unlocks purchasable Hippo eggs in the Market",
- "farmFriendsText": "Farm Friends Quest Bundle",
- "farmFriendsNotes": "Contains 'The Mootant Cow', 'Ride the Night-Mare', and 'The Thunder Ram'. Available until September 30.",
- "witchyFamiliarsText": "Witchy Familiars Quest Bundle",
- "witchyFamiliarsNotes": "Contains 'The Rat King', 'The Icy Arachnid', and 'Swamp of the Clutter Frog'. Available until October 31.",
- "questGroupLostMasterclasser": "Mystery of the Masterclassers",
- "questUnlockLostMasterclasser": "To unlock this quest, complete the final quests of these quest chains: 'Dilatory Distress', 'Mayhem in Mistiflying', 'Stoïkalm Calamity', and 'Terror in the Taskwoods'.",
- "questLostMasterclasser1Text": "The Mystery of the Masterclassers, Part 1: Read Between the Lines",
- "questLostMasterclasser1Notes": "You’re unexpectedly summoned by @beffymaroo and @Lemoness to Habit Hall, where you’re astonished to find all four of Habitica’s Masterclassers awaiting you in the wan light of dawn. Even the Joyful Reaper looks somber.
“Oho, you’re here,” says the April Fool. “Now, we would not rouse you from your rest without a truly dire—”
“Help us investigate the recent bout of possessions,” interrupts Lady Glaciate. “All the victims blamed someone named Tzina.”
The April Fool is clearly affronted by the summary. “What about my speech?” he hisses to her. “With the fog and thunderstorm effects?”
“We’re in a hurry,” she mutters back. “And my mammoths are still soggy from your incessant practicing.”
“I’m afraid that the esteemed Master of Warriors is correct,” says King Manta. “Time is of the essence. Will you aid us?”
When you nod, he waves his hands to open a portal, revealing an underwater room. “Swim down with me to Dilatory, and we will scour my library for any references that might give us a clue.” At your look of confusion, he adds, “Don’t worry, the paper was enchanted long before Dilatory sank. None of the books are the slightest bit damp!” He winks.“Unlike Lady Glaciate’s mammoths.”
“I heard that, Manta.”
As you dive into the water after the Master of Mages, your legs magically fuse into fins. Though your body is buoyant, your heart sinks when you see the thousands of bookshelves. Better start reading…",
- "questLostMasterclasser1Completion": "After hours of poring through volumes, you still haven’t found any useful information.
“It seems impossible that there isn’t even the tiniest reference to anything relevant,” says head librarian @Tuqjoi, and their assistant @stefalupagus nods in frustration.
King Manta’s eyes narrow. “Not impossible…” he says. “Intentional.” For a moment, the water glows around his hands, and several of the books shudder. “Something is obscuring information,” he says. “Not just a static spell, but something with a will of its own. Something… alive.” He swims up from the table. “The Joyful Reaper needs to hear about this. Let’s pack a meal for the road.”",
- "questLostMasterclasser1CollectAncientTomes": "Ancient Tomes",
- "questLostMasterclasser1CollectForbiddenTomes": "Forbidden Tomes",
- "questLostMasterclasser1CollectHiddenTomes": "Hidden Tomes",
- "questLostMasterclasser2Text": "The Mystery of the Masterclassers, Part 2: Assembling the a'Voidant",
- "questLostMasterclasser2Notes": "The Joyful Reaper drums her bony fingers on some of the books that you brought. “Oh, dear,” the Master of Healers says. “There is a malevolent life essence at work. I might have guessed, considering the attacks by reanimated skulls during each incident.” Her assistant @tricksy.fox brings in a chest, and you are startled to see the contents that @beffymaroo unloads: the very same objects once used by this mysterious Tzina to possess people.
“I’m going to use resonant healing magic to try to make this creature manifest,” the Joyful Reaper says, reminding you that the skeleton is a somewhat unconventional Healer. “You’ll need to read the revealed information quickly, in case it breaks loose.”
As she concentrates, a twisting mist begins to siphon from the books and twine around the objects. Quickly, you flip through the pages, trying to read the new lines of text that are writhing into view. You catch only a few snippets: “Sands of the Timewastes” — “the Great Disaster” —“split into four”— “permanently corrupted”— before a single name catches your eye: Zinnya.
Abruptly, the pages wrench free from your fingers and shred themselves as a howling creature explodes into being, coalescing around the possessed objects.
“It’s an a’Voidant!” the Joyful Reaper shouts, throwing up a protection spell. “They’re ancient creatures of confusion and obscurity. If this Tzina can control one, she must have a frightening command over life magic. Quickly, attack it before it escapes back into the books!”
",
- "questLostMasterclasser2Completion": "The a’Voidant succumbs at last, and you share the snippets that you read.
“None of those references sound familiar, even for someone as old as I,” the Joyful Reaper says. “Except… the Timewastes are a distant desert at the most hostile edge of Habitica. Portals often fail nearby, but swift mounts could get you there in no time. Lady Glaciate will be glad to assist.” Her voice grows amused. “Which means that the enamored Master of Rogues will undoubtedly tag along.” She hands you the glimmering mask. “Perhaps you should try to track the lingering magic in these items to its source. I’ll go harvest some sustenance for your journey.”",
- "questLostMasterclasser2Boss": "The a'Voidant",
- "questLostMasterclasser2DropEyewear": "Aether Mask (Eyewear)",
- "questLostMasterclasser3Text": "The Mystery of the Masterclassers, Part 3: City in the Sands",
- "questLostMasterclasser3Notes": "As night unfurls over the scorching sands of the Timewastes, your guides @AnnDeLune, @Kiwibot, and @Katy133 lead you forward. Some bleached pillars poke from the shadowed dunes, and as you approach them, a strange skittering sound echoes across the seemingly-abandoned expanse.
“Invisible creatures!” says the April Fool, clearly covetous. “Oho! Just imagine the possibilities. This must be the work of a truly stealthy Rogue.”
“A Rogue who could be watching us,” says Lady Glaciate, dismounting and raising her spear. “If there’s a head-on attack, try not to irritate our opponent. I don’t want a repeat of the volcano incident.”
He beams at her. “But it was one of your most resplendent rescues.”
To your surprise, Lady Glaciate turns very pink at the compliment. She hastily stomps away to examine the ruins.
“Looks like the wreck of an ancient city,” says @AnnDeLune. “I wonder what…”
Before she can finish her sentence, a portal roars open in the sky. Wasn’t that magic supposed to be nearly impossible here? The hoofbeats of the invisible animals thunder as they flee in panic, and you steady yourself against the onslaught of shrieking skulls that flood the skies.",
- "questLostMasterclasser3Completion": "The April Fool surprises the final skull with a spray of sand, and it blunders backwards into Lady Glaciate, who smashes it expertly. As you catch your breath and look up, you see a single flash of someone’s silhouette moving on the other side of the closing portal. Thinking quickly, you snatch up the amulet from the chest of previously-possessed items, and sure enough, it’s drawn towards the unseen person. Ignoring the shouts of alarm from Lady Glaciate and the April Fool, you leap through the portal just as it snaps shut, plummeting into an inky swath of nothingness.",
- "questLostMasterclasser3Boss": "Void Skull Swarm",
- "questLostMasterclasser3RageTitle": "Swarm Respawn",
- "questLostMasterclasser3RageDescription": "Swarm Respawn: This bar fills when you don't complete your Dailies. When it is full, the Void Skull Swarm will heal 30% of its remaining health!",
- "questLostMasterclasser3RageEffect": "`Void Skull Swarm uses SWARM RESPAWN!`\n\nEmboldened by their victories, more skulls scream down from the heavens, bolstering the swarm!",
- "questLostMasterclasser3DropBodyAccessory": "Aether Amulet (Body Accessory)",
- "questLostMasterclasser3DropBasePotion": "Base Hatching Potion",
- "questLostMasterclasser3DropGoldenPotion": "Golden Hatching Potion",
- "questLostMasterclasser3DropPinkPotion": "Cotton Candy Pink Hatching Potion",
- "questLostMasterclasser3DropShadePotion": "Shade Hatching Potion",
- "questLostMasterclasser3DropZombiePotion": "Zombie Hatching Potion",
- "questLostMasterclasser4Text": "The Mystery of the Masterclassers, Part 4: The Lost Masterclasser",
- "questLostMasterclasser4Notes": "You surface from the portal, but you’re still suspended in a strange, shifting netherworld. “That was bold,” says a cold voice. “I have to admit, I hadn’t planned for a direct confrontation yet.” A woman rises from the churning whirlpool of darkness. “Welcome to the Realm of Void.”
You try to fight back your rising nausea. “Are you Zinnya?” you ask.
“That old name for a young idealist,” she says, mouth twisting, and the world writhes beneath you. “No. If anything, you should call me the Anti’zinnya now, given all that I have done and undone.”
Suddenly, the portal reopens behind you, and as the four Masterclassers burst out, bolting towards you, Anti’zinnya’s eyes flash with hatred. “I see that my pathetic replacements have managed to follow you.”
You stare. “Replacements?”
“As the Master Aethermancer, I was the first Masterclasser — the only Masterclasser. These four are a mockery, each possessing only a fragment of what I once had! I commanded every spell and learned every skill. I shaped your very world to my whim — until the traitorous aether itself collapsed under the weight of my talents and my perfectly reasonable expectations. I have been trapped for millennia in this resulting void, recuperating. Imagine my disgust when I learned how my legacy had been corrupted.” She lets out a low, echoing laugh. “My plan was to destroy their domains before destroying them, but I suppose the order is irrelevant.” With a burst of uncanny strength, she charges forward, and the Realm of Void explodes into chaos.",
- "questLostMasterclasser4Completion": "Under the onslaught of your final attack, the Lost Masterclasser screams in frustration, her body flickering into translucence. The thrashing void stills around her as she slumps forward, and for a moment, she seems to change, becoming younger, calmer, with an expression of peace upon her face… but then everything melts away with scarcely a whisper, and you’re kneeling once more in the desert sand.
“It seems that we have much to learn about our own history,” King Manta says, staring at the broken ruins. “After the Master Aethermancer grew overwhelmed and lost control of her abilities, the outpouring of void must have leached the life from the entire land. Everything probably became deserts like this.”
“No wonder the ancients who founded Habitica stressed a balance of productivity and wellness,” the Joyful Reaper murmurs. “Rebuilding their world would have been a daunting task requiring considerable hard work, but they would have wanted to prevent such a catastrophe from happening again.”
“Oho, look at those formerly possessed items!” says the April Fool. Sure enough, all of them shimmer with a pale, glimmering translucence from the final burst of aether released when you laid Anti’zinnya’s spirit to rest. “What a dazzling effect. I must take notes.”
“The concentrated remnants of aether in this area probably caused these animals to go invisible, too,” says Lady Glaciate, scratching a patch of emptiness behind the ears. You feel an unseen fluffy head nudge your hand, and suspect that you’ll have to do some explaining at the Stables back home. As you look at the ruins one last time, you spot all that remains of the first Masterclasser: her shimmering cloak. Lifting it onto your shoulders, you head back to Habit City, pondering everything that you have learned.
",
- "questLostMasterclasser4Boss": "Anti'zinnya",
- "questLostMasterclasser4RageTitle": "Siphoning Void",
- "questLostMasterclasser4RageDescription": "Siphoning Void: This bar fills when you don't complete your Dailies. When it is full, Anti'zinnya will remove the party's Mana!",
- "questLostMasterclasser4RageEffect": "`Anti'zinnya uses SIPHONING VOID!` In a twisted inversion of the Ethereal Surge spell, you feel your magic drain away into the darkness!",
- "questLostMasterclasser4DropBackAccessory": "Aether Cloak (Back Accessory)",
- "questLostMasterclasser4DropWeapon": "Aether Crystals (Two-Handed Weapon)",
- "questLostMasterclasser4DropMount": "Invisible Aether Mount",
- "questYarnText": "A Tangled Yarn",
- "questYarnNotes": "It’s such a pleasant day that you decide to take a walk through the Taskan Countryside. As you pass by its famous yarn shop, a piercing scream startles the birds into flight and scatters the butterflies into hiding. You run towards the source and see @Arcosine running up the path towards you. Behind him, a horrifying creature consisting of yarn, pins, and knitting needles is clicking and clacking ever closer.
The shopkeepers race after him, and @stefalupagus grabs your arm, out of breath. \"Looks like all of his unfinished projects\" gasp gasp \"have transformed the yarn from our Yarn Shop\" gasp gasp \"into a tangled mass of Yarnghetti!\"
\"Sometimes, life gets in the way and a project is abandoned, becoming ever more tangled and confused,\" says @khdarkwolf. \"The confusion can even spread to other projects, until there are so many half-finished works running around that no one gets anything done!\"
It’s time to make a choice: complete your stalled projects… or decide to unravel them for good. Either way, you'll have to increase your productivity quickly before the Dread Yarnghetti spreads confusion and discord to the rest of Habitica!",
- "questYarnCompletion": "With a feeble swipe of a pin-riddled appendage and a weak roar, the Dread Yarnghetti finally unravels into a pile of yarn balls.
\"Take care of this yarn,\" shopkeeper @JinjooHat says, handing them to you. \"If you feed them and care for them properly, they'll grow into new and exciting projects that just might make your heart take flight…\"",
- "questYarnBoss": "The Dread Yarnghetti",
- "questYarnDropYarnEgg": "Yarn (Egg)",
- "questYarnUnlockText": "Unlocks purchasable Yarn eggs in the Market",
- "winterQuestsText": "Winter Quest Bundle",
- "winterQuestsNotes": "Contains 'Trapper Santa', 'Find the Cub', and 'The Fowl Frost'. Available until December 31.",
- "questPterodactylText": "The Pterror-dactyl",
- "questPterodactylNotes": "You're taking a stroll along the peaceful Stoïkalm Cliffs when an evil screech rends the air. You turn to find a hideous creature flying towards you and are overcome by a powerful terror. As you turn to flee, @Lilith of Alfheim grabs you. \"Don't panic! It's just a Pterror-dactyl.\"
@Procyon P nods. \"They nest nearby, but they're attracted to the scent of negative Habits and undone Dailies.\"
\"Don't worry,\" @Katy133 says. \"We just need to be extra productive to defeat it!\" You are filled with a renewed sense of purpose and turn to face your foe.",
- "questPterodactylCompletion": "With one last screech the Pterror-dactyl plummets over the side of the cliff. You run forward to watch it soar away over the distant steppes. \"Phew, I'm glad that's over,\" you say. \"Me too,\" replies @GeraldThePixel. \"But look! It's left some eggs behind for us.\" @Edge passes you three eggs, and you vow to raise them in tranquility, surrounded by positive Habits and blue Dailies.",
- "questPterodactylBoss": "Pterror-dactyl",
- "questPterodactylDropPterodactylEgg": "Pterodactyl (Egg)",
- "questPterodactylUnlockText": "Unlocks purchasable Pterodactyl eggs in the Market",
- "questBadgerText": "Stop Badgering Me!",
- "questBadgerNotes": "Ah, winter in the Taskwoods. The softly falling snow, the branches sparkling with frost, the Flourishing Fairies… still not snoozing?
“Why are they still awake?” cries @LilithofAlfheim. “If they don't hibernate soon, they'll never have the energy for planting season.”
As you and @Willow the Witty hurry to investigate, a furry head pops up from the ground. Before you can yell, “It’s the Badgering Bother!” it’s back in its burrow—but not before snatching up the Fairies' “Hibernate” To-Dos and dropping a giant list of pesky tasks in their place!
“No wonder the fairies aren't resting, if they're constantly being badgered like that!” @plumilla says. Can you chase off this beast and save the Taskwood’s harvest this year?",
- "questBadgerCompletion": "You finally drive away the the Badgering Bother and hurry into its burrow. At the end of a tunnel, you find its hoard of the faeries’ “Hibernate” To-Dos. The den is otherwise abandoned, except for three eggs that look ready to hatch.",
- "questBadgerBoss": "The Badgering Bother",
- "questBadgerDropBadgerEgg": "Badger (Egg)",
- "questBadgerUnlockText": "Unlocks purchasable Badger eggs in the Market",
- "questDysheartenerText": "The Dysheartener",
- "questDysheartenerNotes": "The sun is rising on Valentine’s Day when a shocking crash splinters the air. A blaze of sickly pink light lances through all the buildings, and bricks crumble as a deep crack rips through Habit City’s main street. An unearthly shrieking rises through the air, shattering windows as a hulking form slithers forth from the gaping earth.
Mandibles snap and a carapace glitters; legs upon legs unfurl in the air. The crowd begins to scream as the insectoid creature rears up, revealing itself to be none other than that cruelest of creatures: the fearsome Dysheartener itself. It howls in anticipation and lunges forward, hungering to gnaw on the hopes of hard-working Habiticans. With each rasping scrape of its spiny forelegs, you feel a vise of despair tightening in your chest.
“Take heart, everyone!” Lemoness shouts. “It probably thinks that we’re easy targets because so many of us have daunting New Year’s Resolutions, but it’s about to discover that Habiticans know how to stick to their goals!”
AnnDeLune raises her staff. “Let’s tackle our tasks and take this monster down!”",
- "questDysheartenerCompletion": "The Dysheartener is DEFEATED!
Together, everyone in Habitica strikes a final blow to their tasks, and the Dysheartener rears back, shrieking with dismay. “What's wrong, Dysheartener?” AnnDeLune calls, eyes sparkling. “Feeling discouraged?”
Glowing pink fractures crack across the Dysheartener's carapace, and it shatters in a puff of pink smoke. As a renewed sense of vigor and determination sweeps across the land, a flurry of delightful sweets rains down upon everyone.
The crowd cheers wildly, hugging each other as their pets happily chew on the belated Valentine's treats. Suddenly, a joyful chorus of song cascades through the air, and gleaming silhouettes soar across the sky.
Our newly-invigorated optimism has attracted a flock of Hopeful Hippogriffs! The graceful creatures alight upon the ground, ruffling their feathers with interest and prancing about. “It looks like we've made some new friends to help keep our spirits high, even when our tasks are daunting,” Lemoness says.
Beffymaroo already has her arms full with feathered fluffballs. “Maybe they'll help us rebuild the damaged areas of Habitica!”
Crooning and singing, the Hippogriffs lead the way as all the Habitcans work together to restore our beloved home.",
- "questDysheartenerCompletionChat": "`The Dysheartener is DEFEATED!`\n\nTogether, everyone in Habitica strikes a final blow to their tasks, and the Dysheartener rears back, shrieking with dismay. “What's wrong, Dysheartener?” AnnDeLune calls, eyes sparkling. “Feeling discouraged?”\n\nGlowing pink fractures crack across the Dysheartener's carapace, and it shatters in a puff of pink smoke. As a renewed sense of vigor and determination sweeps across the land, a flurry of delightful sweets rains down upon everyone.\n\nThe crowd cheers wildly, hugging each other as their pets happily chew on the belated Valentine's treats. Suddenly, a joyful chorus of song cascades through the air, and gleaming silhouettes soar across the sky.\n\nOur newly-invigorated optimism has attracted a flock of Hopeful Hippogriffs! The graceful creatures alight upon the ground, ruffling their feathers with interest and prancing about. “It looks like we've made some new friends to help keep our spirits high, even when our tasks are daunting,” Lemoness says.\n\nBeffymaroo already has her arms full with feathered fluffballs. “Maybe they'll help us rebuild the damaged areas of Habitica!”\n\nCrooning and singing, the Hippogriffs lead the way as all the Habitcans work together to restore our beloved home.",
- "questDysheartenerBossRageTitle": "Shattering Heartbreak",
- "questDysheartenerBossRageDescription": "The Rage Attack gauge fills when Habiticans miss their Dailies. If it fills up, the Dysheartener will unleash its Shattering Heartbreak attack on one of Habitica's shopkeepers, so be sure to do your tasks!",
- "questDysheartenerBossRageSeasonal": "`The Dysheartener uses SHATTERING HEARTBREAK!`\n\nOh, no! After feasting on our undone Dailies, the Dysheartener has gained the strength to unleash its Shattering Heartbreak attack. With a shrill shriek, it brings its spiny forelegs down upon the pavilion that houses the Seasonal Shop! The concussive blast of magic shreds the wood, and the Seasonal Sorceress is overcome by sorrow at the sight.\n\nQuickly, let's keep doing our Dailies so that the beast won't strike again!",
- "seasonalShopRageStrikeHeader": "The Seasonal Shop was Attacked!",
- "seasonalShopRageStrikeLead": "Leslie is Heartbroken!",
- "seasonalShopRageStrikeRecap": "On February 21, our beloved Leslie the Seasonal Sorceress was devastated when the Dysheartener shattered the Seasonal Shop. Quickly, tackle your tasks to defeat the monster and help rebuild!",
- "marketRageStrikeHeader": "The Market was Attacked!",
- "marketRageStrikeLead": "Alex is Heartbroken!",
- "marketRageStrikeRecap": "On February 28, our marvelous Alex the Merchant was horrified when the Dysheartener shattered the Market. Quickly, tackle your tasks to defeat the monster and help rebuild!",
- "questsRageStrikeHeader": "The Quest Shop was Attacked!",
- "questsRageStrikeLead": "Ian is Heartbroken!",
- "questsRageStrikeRecap": "On March 6, our wonderful Ian the Quest Guide was deeply shaken when the Dysheartener shattered the ground around the Quest Shop. Quickly, tackle your tasks to defeat the monster and help rebuild!",
- "questDysheartenerBossRageMarket": "`The Dysheartener uses SHATTERING HEARTBREAK!`\n\nHelp! After feasting on our incomplete Dailies, the Dysheartener lets out another Shattering Heartbreak attack, smashing the walls and floor of the Market! As stone rains down, Alex the Merchant weeps at his crushed merchandise, stricken by the destruction.\n\nWe can't let this happen again! Be sure to do all our your Dailies to prevent the Dysheartener from using its final strike.",
- "questDysheartenerBossRageQuests": "`The Dysheartener uses SHATTERING HEARTBREAK!`\n\nAaaah! We've left our Dailies undone again, and the Dysheartener has mustered the energy for one final blow against our beloved shopkeepers. The countryside around Ian the Quest Master is ripped apart by its Shattering Heartbreak attack, and Ian is struck to the core by the horrific vision. We're so close to defeating this monster.... Hurry! Don't stop now!",
- "questDysheartenerDropHippogriffPet": "Hopeful Hippogriff (Pet)",
- "questDysheartenerDropHippogriffMount": "Hopeful Hippogriff (Mount)",
- "dysheartenerArtCredit": "Artwork by @AnnDeLune",
- "hugabugText": "Hug a Bug Quest Bundle",
- "hugabugNotes": "Contains 'The CRITICAL BUG,' 'The Snail of Drudgery Sludge,' and 'Bye, Bye, Butterfry.' Available until March 31.",
- "questSquirrelText": "The Sneaky Squirrel",
- "questSquirrelNotes": "You wake up and find you’ve overslept! Why didn’t your alarm go off? … How did an acorn get stuck in the ringer?
When you try to make breakfast, the toaster is stuffed with acorns. When you go to retrieve your mount, @Shtut is there, trying unsuccessfully to unlock their stable. They look into the keyhole. “Is that an acorn in there?”
@randomdaisy cries out, “Oh no! I knew my pet squirrels had gotten out, but I didn’t know they’d made such trouble! Can you help me round them up before they make any more of a mess?”
Following the trail of mischievously placed oak nuts, you track and catch the wayward sciurines, with @Cantras helping secure each one safely at home. But just when you think your task is almost complete, an acorn bounces off your helm! You look up to see a mighty beast of a squirrel, crouched in defense of a prodigious pile of seeds.
“Oh dear,” says @randomdaisy, softly. “She’s always been something of a resource guarder. We’ll have to proceed very carefully!” You circle up with your party, ready for trouble!",
- "questSquirrelCompletion": "With a gentle approach, offers of trade, and a few soothing spells, you’re able to coax the squirrel away from its hoard and back to the stables, which @Shtut has just finished de-acorning. They’ve set aside a few of the acorns on a worktable. “These ones are squirrel eggs! Maybe you can raise some that don’t play with their food quite so much.”",
- "questSquirrelBoss": "Sneaky Squirrel",
- "questSquirrelDropSquirrelEgg": "Squirrel (Egg)",
- "questSquirrelUnlockText": "Unlocks purchasable Squirrel eggs in the Market",
- "cuddleBuddiesText": "Cuddle Buddies Quest Bundle",
- "cuddleBuddiesNotes": "Contains 'The Killer Bunny', 'The Nefarious Ferret', and 'The Guinea Pig Gang'. Available until May 31.",
- "aquaticAmigosText": "Aquatic Amigos Quest Bundle",
- "aquaticAmigosNotes": "Contains 'The Magical Axolotl', 'The Kraken of Inkomplete', and 'The Call of Octothulu'. Available until June 30.",
- "questSeaSerpentText": "Danger in the Depths: Sea Serpent Strike!",
- "questSeaSerpentNotes": "Your streaks have you feeling lucky—it’s the perfect time for a trip to the seahorse racetrack. You board the submarine at Diligent Docks and settle in for the trip to Dilatory, but you’ve barely submerged when an impact rocks the sub, sending its occupants tumbling. “What’s going on?” @AriesFaries shouts.
You glance through a nearby porthole and are shocked by the wall of shimmering scales passing by it. “Sea serpent!” Captain @Witticaster calls through the intercom. “Brace yourselves, it’s coming ‘round again!” As you grip the arms of your seat, your unfinished tasks flash before your eyes. ‘Maybe if we work together and complete them,’ you think, ‘we can drive this monster away!’",
- "questSeaSerpentCompletion": "Battered by your commitment, the sea serpent flees, disappearing into the depths. When you arrive in Dilatory, you breathe a sigh of relief before noticing @*~Seraphina~ approaching with three translucent eggs cradled in her arms. “Here, you should have these,” she says. “You know how to handle a sea serpent!” As you accept the eggs, you vow anew to remain steadfast in completing your tasks to ensure that there’s not a repeat occurrence.",
- "questSeaSerpentBoss": "The Mighty Sea Serpent",
- "questSeaSerpentDropSeaSerpentEgg": "Sea Serpent (Egg)",
- "questSeaSerpentUnlockText": "Unlocks purchasable Sea Serpent eggs in the Market",
- "questKangarooText": "Kangaroo Catastrophe",
- "questKangarooNotes": "Maybe you should have finished that last task… you know, the one you keep avoiding, even though it always comes back around? But @Mewrose and @LilithofAlfheim invited you and @stefalupagus to see a rare kangaroo troop hopping through the Sloensteadi Savannah; how could you say no?! As the troop comes into view, something hits you on the back of the head with a mighty whack!
Shaking the stars from your vision, you pick up the responsible object--a dark red boomerang, with the very task you continually push back etched into its surface. A quick glance around confirms the rest of your party met a similar fate. One larger kangaroo looks at you with a smug grin, like she’s daring you to face her and that dreaded task once and for all!",
- "questKangarooCompletion": "“NOW!” You signal your party to throw the boomerangs back at the kangaroo. The beast hops further away with each hit until she flees, leaving nothing more than a dark red cloud of dust, a few eggs, and some gold coins.
@Mewrose walks forward to where the kangaroo once stood. “Hey, where did the boomerangs go?”
“They probably dissolved into dust, making that dark red cloud, when we finished our respective tasks,” @stefalupagus speculates.
@LilithofAlfheim squints at the horizon. “Is that another kangaroo troop heading our way?”
You all break into a run back to Habit City. Better to face your difficult tasks than take another lump to the back of the head!",
- "questKangarooBoss": "Catastrophic Kangaroo",
- "questKangarooDropKangarooEgg": "Kangaroo (Egg)",
- "questKangarooUnlockText": "Unlocks purchasable Kangaroo eggs in the Market",
- "forestFriendsText": "Forest Friends Quest Bundle",
- "forestFriendsNotes": "Contains 'The Spirit of Spring', 'The Hedgebeast', and 'The Tangle Tree'. Available until September 30.",
- "questAlligatorText": "The Insta-Gator",
- "questAlligatorNotes": "“Crikey!” exclaims @gully. “An Insta-Gator in its natural habitat! Careful, it distracts its prey with things that seem urgent THIS INSTANT, and it feeds on the unchecked Dailies that result.” You fall silent to avoid attracting its attention, but to no avail. The Insta-Gator spots you and charges! Distracting voices rise up from Swamps of Stagnation, grabbing for your attention: “Read this post! See this photo! Pay attention to me THIS INSTANT!” You scramble to mount a counterattack, completing your Dailies and bolstering your good Habits to fight off the dreaded Insta-Gator.",
- "questAlligatorCompletion": "With your attention focused on what’s important and not the Insta-Gator’s distractions, the Insta-Gator flees. Victory! “Are those eggs? They look like gator eggs to me,” asks @mfonda. “If we care for them correctly, they’ll be loyal pets or faithful steeds,” answers @UncommonCriminal, handing you three to care for. Let’s hope so, or else the Insta-Gator might make a return…",
- "questAlligatorBoss": "Insta-Gator",
- "questAlligatorDropAlligatorEgg": "Alligator (Egg)",
- "questAlligatorUnlockText": "Unlocks purchasable Alligator eggs in the Market",
- "oddballsText": "Oddballs Quest Bundle",
- "oddballsNotes": "Contains 'The Jelly Regent,' 'Escape the Cave Creature,' and 'A Tangled Yarn.' Available until December 3.",
- "birdBuddiesText": "Bird Buddies Quest Bundle",
- "birdBuddiesNotes": "Contains 'The Fowl Frost,' 'Rooster Rampage,' and 'The Push-and-Pull Peacock.' Available until December 31.",
- "questVelociraptorText": "The Veloci-Rapper",
- "questVelociraptorNotes": "You’re sharing honey cakes with @*~Seraphina~*, @Procyon P, and @Lilith of Alfheim by a lake in the Stoïkalm Steppes. Suddenly, a mournful voice interrupts your picnic.
My Habits took a hit, I missed my Dailies, I’m losing it, sinking with doubt and maybes, At the top of my game I used to be so fly, But now I just let my Due Dates go by.
@*~Seraphina~* peers behind a stand of grass. “It’s the Veloci-Rapper. It seems... distraught?”
You pump a fist in determination. “There's only one thing to do. Rap battle time!”",
- "questVelociraptorCompletion": "You burst through the grass, confronting the Veloci-Rapper.
See here, rapper, you’re no quitter, You’re Bad Habits' hardest hitter! Check off your To-Dos like a boss, Don’t mourn over one day’s loss!
Filled with renewed confidence, it bounds off to freestyle another day, leaving behind three eggs where it sat.",
- "questVelociraptorBoss": "Veloci-Rapper",
- "questVelociraptorDropVelociraptorEgg": "Velociraptor (Egg)",
- "questVelociraptorUnlockText": "Unlocks purchasable Velociraptor eggs in the Market"
-}
\ No newline at end of file
+ "questEvilSantaText": "",
+ "questEvilSantaNotes": "",
+ "questEvilSantaCompletion": "",
+ "questEvilSantaBoss": "",
+ "questEvilSantaDropBearCubPolarMount": "",
+ "questEvilSanta2Text": "",
+ "questEvilSanta2Notes": "",
+ "questEvilSanta2Completion": "",
+ "questEvilSanta2CollectTracks": "",
+ "questEvilSanta2CollectBranches": "",
+ "questEvilSanta2DropBearCubPolarPet": "",
+ "questGryphonText": "",
+ "questGryphonNotes": "",
+ "questGryphonCompletion": "",
+ "questGryphonBoss": "",
+ "questGryphonDropGryphonEgg": "",
+ "questGryphonUnlockText": "",
+ "questHedgehogText": "",
+ "questHedgehogNotes": "",
+ "questHedgehogCompletion": "",
+ "questHedgehogBoss": "",
+ "questHedgehogDropHedgehogEgg": "",
+ "questHedgehogUnlockText": "",
+ "questGhostStagText": "",
+ "questGhostStagNotes": "",
+ "questGhostStagCompletion": "",
+ "questGhostStagBoss": "",
+ "questGhostStagDropDeerEgg": "",
+ "questGhostStagUnlockText": "",
+ "questRatText": "",
+ "questRatNotes": "",
+ "questRatCompletion": "",
+ "questRatBoss": "",
+ "questRatDropRatEgg": "",
+ "questRatUnlockText": "",
+ "questOctopusText": "",
+ "questOctopusNotes": "",
+ "questOctopusCompletion": "",
+ "questOctopusBoss": "",
+ "questOctopusDropOctopusEgg": "",
+ "questOctopusUnlockText": "",
+ "questHarpyText": "",
+ "questHarpyNotes": "",
+ "questHarpyCompletion": "",
+ "questHarpyBoss": "",
+ "questHarpyDropParrotEgg": "",
+ "questHarpyUnlockText": "",
+ "questRoosterText": "",
+ "questRoosterNotes": "",
+ "questRoosterCompletion": "",
+ "questRoosterBoss": "",
+ "questRoosterDropRoosterEgg": "",
+ "questRoosterUnlockText": "",
+ "questSpiderText": "",
+ "questSpiderNotes": "",
+ "questSpiderCompletion": "",
+ "questSpiderBoss": "",
+ "questSpiderDropSpiderEgg": "",
+ "questSpiderUnlockText": "",
+ "questGroupVice": "",
+ "questVice1Text": "",
+ "questVice1Notes": "",
+ "questVice1Boss": "",
+ "questVice1Completion": "",
+ "questVice1DropVice2Quest": "",
+ "questVice2Text": "",
+ "questVice2Notes": "",
+ "questVice2CollectLightCrystal": "",
+ "questVice2Completion": "",
+ "questVice2DropVice3Quest": "",
+ "questVice3Text": "",
+ "questVice3Notes": "",
+ "questVice3Completion": "",
+ "questVice3Boss": "",
+ "questVice3DropWeaponSpecial2": "",
+ "questVice3DropDragonEgg": "",
+ "questVice3DropShadeHatchingPotion": "",
+ "questGroupMoonstone": "",
+ "questMoonstone1Text": "",
+ "questMoonstone1Notes": "",
+ "questMoonstone1CollectMoonstone": "",
+ "questMoonstone1Completion": "",
+ "questMoonstone1DropMoonstone2Quest": "",
+ "questMoonstone2Text": "",
+ "questMoonstone2Notes": "",
+ "questMoonstone2Boss": "",
+ "questMoonstone2Completion": "",
+ "questMoonstone2DropMoonstone3Quest": "",
+ "questMoonstone3Text": "",
+ "questMoonstone3Notes": "",
+ "questMoonstone3Completion": "",
+ "questMoonstone3Boss": "",
+ "questMoonstone3DropRottenMeat": "",
+ "questMoonstone3DropZombiePotion": "",
+ "questGroupGoldenknight": "",
+ "questGoldenknight1Text": "",
+ "questGoldenknight1Notes": "",
+ "questGoldenknight1CollectTestimony": "",
+ "questGoldenknight1Completion": "",
+ "questGoldenknight1DropGoldenknight2Quest": "",
+ "questGoldenknight2Text": "",
+ "questGoldenknight2Notes": "",
+ "questGoldenknight2Boss": "",
+ "questGoldenknight2Completion": "",
+ "questGoldenknight2DropGoldenknight3Quest": "",
+ "questGoldenknight3Text": "",
+ "questGoldenknight3Notes": "",
+ "questGoldenknight3Completion": "",
+ "questGoldenknight3Boss": "",
+ "questGoldenknight3DropHoney": "",
+ "questGoldenknight3DropGoldenPotion": "",
+ "questGoldenknight3DropWeapon": "",
+ "questGroupEarnable": "",
+ "questBasilistText": "",
+ "questBasilistNotes": "",
+ "questBasilistCompletion": "",
+ "questBasilistBoss": "",
+ "questEggHuntText": "",
+ "questEggHuntNotes": "",
+ "questEggHuntCompletion": "",
+ "questEggHuntCollectPlainEgg": "",
+ "questEggHuntDropPlainEgg": "",
+ "questDilatoryText": "",
+ "questDilatoryNotes": "",
+ "questDilatoryBoss": "",
+ "questDilatoryBossRageTitle": "",
+ "questDilatoryBossRageDescription": "",
+ "questDilatoryDropMantisShrimpPet": "",
+ "questDilatoryDropMantisShrimpMount": "",
+ "questDilatoryBossRageTavern": "",
+ "questDilatoryBossRageStables": "",
+ "questDilatoryBossRageMarket": "",
+ "questDilatoryCompletion": "",
+ "questSeahorseText": "",
+ "questSeahorseNotes": "",
+ "questSeahorseCompletion": "",
+ "questSeahorseBoss": "",
+ "questSeahorseDropSeahorseEgg": "",
+ "questSeahorseUnlockText": "",
+ "questGroupAtom": "",
+ "questAtom1Text": "",
+ "questAtom1Notes": "",
+ "questAtom1CollectSoapBars": "",
+ "questAtom1Drop": "",
+ "questAtom1Completion": "",
+ "questAtom2Text": "",
+ "questAtom2Notes": "",
+ "questAtom2Boss": "",
+ "questAtom2Drop": "",
+ "questAtom2Completion": "",
+ "questAtom3Text": "",
+ "questAtom3Notes": "",
+ "questAtom3Completion": "",
+ "questAtom3Boss": "",
+ "questAtom3DropPotion": "",
+ "questOwlText": "",
+ "questOwlNotes": "",
+ "questOwlCompletion": "",
+ "questOwlBoss": "",
+ "questOwlDropOwlEgg": "",
+ "questOwlUnlockText": "",
+ "questPenguinText": "",
+ "questPenguinNotes": "",
+ "questPenguinCompletion": "",
+ "questPenguinBoss": "",
+ "questPenguinDropPenguinEgg": "",
+ "questPenguinUnlockText": "",
+ "questStressbeastText": "",
+ "questStressbeastNotes": "",
+ "questStressbeastBoss": "",
+ "questStressbeastBossRageTitle": "",
+ "questStressbeastBossRageDescription": "",
+ "questStressbeastDropMammothPet": "",
+ "questStressbeastDropMammothMount": "",
+ "questStressbeastBossRageStables": "",
+ "questStressbeastBossRageBailey": "",
+ "questStressbeastBossRageGuide": "",
+ "questStressbeastDesperation": "",
+ "questStressbeastCompletion": "",
+ "questStressbeastCompletionChat": "",
+ "questTRexText": "",
+ "questTRexNotes": "",
+ "questTRexCompletion": "",
+ "questTRexBoss": "",
+ "questTRexUndeadText": "",
+ "questTRexUndeadNotes": "",
+ "questTRexUndeadCompletion": "",
+ "questTRexUndeadBoss": "",
+ "questTRexUndeadRageTitle": "",
+ "questTRexUndeadRageDescription": "",
+ "questTRexUndeadRageEffect": "",
+ "questTRexDropTRexEgg": "",
+ "questTRexUnlockText": "",
+ "questRockText": "",
+ "questRockNotes": "",
+ "questRockBoss": "",
+ "questRockCompletion": "",
+ "questRockDropRockEgg": "",
+ "questRockUnlockText": "",
+ "questBunnyText": "",
+ "questBunnyNotes": "",
+ "questBunnyBoss": "",
+ "questBunnyCompletion": "",
+ "questBunnyDropBunnyEgg": "",
+ "questBunnyUnlockText": "",
+ "questSlimeText": "",
+ "questSlimeNotes": "",
+ "questSlimeBoss": "",
+ "questSlimeCompletion": "",
+ "questSlimeDropSlimeEgg": "",
+ "questSlimeUnlockText": "",
+ "questSheepText": "",
+ "questSheepNotes": "",
+ "questSheepBoss": "",
+ "questSheepCompletion": "",
+ "questSheepDropSheepEgg": "",
+ "questSheepUnlockText": "",
+ "questKrakenText": "",
+ "questKrakenNotes": "",
+ "questKrakenBoss": "",
+ "questKrakenCompletion": "",
+ "questKrakenDropCuttlefishEgg": "",
+ "questKrakenUnlockText": "",
+ "questWhaleText": "",
+ "questWhaleNotes": "",
+ "questWhaleBoss": "",
+ "questWhaleCompletion": "",
+ "questWhaleDropWhaleEgg": "",
+ "questWhaleUnlockText": "",
+ "questGroupDilatoryDistress": "",
+ "questDilatoryDistress1Text": "",
+ "questDilatoryDistress1Notes": "",
+ "questDilatoryDistress1Completion": "",
+ "questDilatoryDistress1CollectFireCoral": "",
+ "questDilatoryDistress1CollectBlueFins": "",
+ "questDilatoryDistress1DropArmor": "",
+ "questDilatoryDistress2Text": "",
+ "questDilatoryDistress2Notes": "",
+ "questDilatoryDistress2Completion": "",
+ "questDilatoryDistress2Boss": "",
+ "questDilatoryDistress2RageTitle": "",
+ "questDilatoryDistress2RageDescription": "",
+ "questDilatoryDistress2RageEffect": "",
+ "questDilatoryDistress2DropSkeletonPotion": "",
+ "questDilatoryDistress2DropCottonCandyBluePotion": "",
+ "questDilatoryDistress2DropHeadgear": "",
+ "questDilatoryDistress3Text": "",
+ "questDilatoryDistress3Notes": "",
+ "questDilatoryDistress3Completion": "",
+ "questDilatoryDistress3Boss": "",
+ "questDilatoryDistress3DropFish": "",
+ "questDilatoryDistress3DropWeapon": "",
+ "questDilatoryDistress3DropShield": "",
+ "questCheetahText": "",
+ "questCheetahNotes": "",
+ "questCheetahCompletion": "",
+ "questCheetahBoss": "",
+ "questCheetahDropCheetahEgg": "",
+ "questCheetahUnlockText": "",
+ "questHorseText": "",
+ "questHorseNotes": "",
+ "questHorseCompletion": "",
+ "questHorseBoss": "",
+ "questHorseDropHorseEgg": "",
+ "questHorseUnlockText": "",
+ "questBurnoutText": "",
+ "questBurnoutNotes": "",
+ "questBurnoutCompletion": "",
+ "questBurnoutCompletionChat": "",
+ "questBurnoutBoss": "",
+ "questBurnoutBossRageTitle": "",
+ "questBurnoutBossRageDescription": "",
+ "questBurnoutDropPhoenixPet": "",
+ "questBurnoutDropPhoenixMount": "",
+ "questBurnoutBossRageQuests": "",
+ "questBurnoutBossRageSeasonalShop": "",
+ "questBurnoutBossRageTavern": "",
+ "questFrogText": "",
+ "questFrogNotes": "",
+ "questFrogCompletion": "",
+ "questFrogBoss": "",
+ "questFrogDropFrogEgg": "",
+ "questFrogUnlockText": "",
+ "questSnakeText": "",
+ "questSnakeNotes": "",
+ "questSnakeCompletion": "",
+ "questSnakeBoss": "",
+ "questSnakeDropSnakeEgg": "",
+ "questSnakeUnlockText": "",
+ "questUnicornText": "",
+ "questUnicornNotes": "",
+ "questUnicornCompletion": "",
+ "questUnicornBoss": "",
+ "questUnicornDropUnicornEgg": "",
+ "questUnicornUnlockText": "",
+ "questSabretoothText": "",
+ "questSabretoothNotes": "",
+ "questSabretoothCompletion": "",
+ "questSabretoothBoss": "",
+ "questSabretoothDropSabretoothEgg": "",
+ "questSabretoothUnlockText": "",
+ "questMonkeyText": "",
+ "questMonkeyNotes": "",
+ "questMonkeyCompletion": "",
+ "questMonkeyBoss": "",
+ "questMonkeyDropMonkeyEgg": "",
+ "questMonkeyUnlockText": "",
+ "questSnailText": "",
+ "questSnailNotes": "",
+ "questSnailCompletion": "",
+ "questSnailBoss": "",
+ "questSnailDropSnailEgg": "",
+ "questSnailUnlockText": "",
+ "questBewilderText": "",
+ "questBewilderNotes": "",
+ "questBewilderCompletion": "",
+ "questBewilderCompletionChat": "",
+ "questBewilderBossRageTitle": "",
+ "questBewilderBossRageDescription": "",
+ "questBewilderDropBumblebeePet": "",
+ "questBewilderDropBumblebeeMount": "",
+ "questBewilderBossRageMarket": "",
+ "questBewilderBossRageStables": "",
+ "questBewilderBossRageBailey": "",
+ "questFalconText": "",
+ "questFalconNotes": "",
+ "questFalconCompletion": "",
+ "questFalconBoss": "",
+ "questFalconDropFalconEgg": "",
+ "questFalconUnlockText": "",
+ "questTreelingText": "",
+ "questTreelingNotes": "",
+ "questTreelingCompletion": "",
+ "questTreelingBoss": "",
+ "questTreelingDropTreelingEgg": "",
+ "questTreelingUnlockText": "",
+ "questAxolotlText": "",
+ "questAxolotlNotes": "",
+ "questAxolotlCompletion": "",
+ "questAxolotlBoss": "",
+ "questAxolotlDropAxolotlEgg": "",
+ "questAxolotlUnlockText": "",
+ "questAxolotlRageTitle": "",
+ "questAxolotlRageDescription": "",
+ "questAxolotlRageEffect": "",
+ "questTurtleText": "",
+ "questTurtleNotes": "",
+ "questTurtleCompletion": "",
+ "questTurtleBoss": "",
+ "questTurtleDropTurtleEgg": "",
+ "questTurtleUnlockText": "",
+ "questArmadilloText": "",
+ "questArmadilloNotes": "",
+ "questArmadilloCompletion": "",
+ "questArmadilloBoss": "",
+ "questArmadilloDropArmadilloEgg": "",
+ "questArmadilloUnlockText": "",
+ "questCowText": "",
+ "questCowNotes": "",
+ "questCowCompletion": "",
+ "questCowBoss": "",
+ "questCowDropCowEgg": "",
+ "questCowUnlockText": "",
+ "questBeetleText": "",
+ "questBeetleNotes": "",
+ "questBeetleCompletion": "",
+ "questBeetleBoss": "",
+ "questBeetleDropBeetleEgg": "",
+ "questBeetleUnlockText": "",
+ "questGroupTaskwoodsTerror": "",
+ "questTaskwoodsTerror1Text": "",
+ "questTaskwoodsTerror1Notes": "",
+ "questTaskwoodsTerror1Completion": "",
+ "questTaskwoodsTerror1Boss": "",
+ "questTaskwoodsTerror1RageTitle": "",
+ "questTaskwoodsTerror1RageDescription": "",
+ "questTaskwoodsTerror1RageEffect": "",
+ "questTaskwoodsTerror1DropSkeletonPotion": "",
+ "questTaskwoodsTerror1DropRedPotion": "",
+ "questTaskwoodsTerror1DropHeadgear": "",
+ "questTaskwoodsTerror2Text": "",
+ "questTaskwoodsTerror2Notes": "",
+ "questTaskwoodsTerror2Completion": "",
+ "questTaskwoodsTerror2CollectPixies": "",
+ "questTaskwoodsTerror2CollectBrownies": "",
+ "questTaskwoodsTerror2CollectDryads": "",
+ "questTaskwoodsTerror2DropArmor": "",
+ "questTaskwoodsTerror3Text": "",
+ "questTaskwoodsTerror3Notes": "",
+ "questTaskwoodsTerror3Completion": "",
+ "questTaskwoodsTerror3Boss": "",
+ "questTaskwoodsTerror3DropStrawberry": "",
+ "questTaskwoodsTerror3DropWeapon": "",
+ "questFerretText": "",
+ "questFerretNotes": "",
+ "questFerretCompletion": "",
+ "questFerretBoss": "",
+ "questFerretDropFerretEgg": "",
+ "questFerretUnlockText": "",
+ "questDustBunniesText": "",
+ "questDustBunniesNotes": "",
+ "questDustBunniesCompletion": "",
+ "questDustBunniesBoss": "",
+ "questGroupMoon": "",
+ "questMoon1Text": "",
+ "questMoon1Notes": "",
+ "questMoon1Completion": "",
+ "questMoon1CollectShards": "",
+ "questMoon1DropHeadgear": "",
+ "questMoon2Text": "",
+ "questMoon2Notes": "",
+ "questMoon2Completion": "",
+ "questMoon2Boss": "",
+ "questMoon2DropArmor": "",
+ "questMoon3Text": "",
+ "questMoon3Notes": "",
+ "questMoon3Completion": "",
+ "questMoon3Boss": "",
+ "questMoon3DropWeapon": "",
+ "questSlothText": "",
+ "questSlothNotes": "",
+ "questSlothCompletion": "",
+ "questSlothBoss": "",
+ "questSlothDropSlothEgg": "",
+ "questSlothUnlockText": "",
+ "questTriceratopsText": "",
+ "questTriceratopsNotes": "",
+ "questTriceratopsCompletion": "",
+ "questTriceratopsBoss": "",
+ "questTriceratopsDropTriceratopsEgg": "",
+ "questTriceratopsUnlockText": "",
+ "questGroupStoikalmCalamity": "",
+ "questStoikalmCalamity1Text": "",
+ "questStoikalmCalamity1Notes": "",
+ "questStoikalmCalamity1Completion": "",
+ "questStoikalmCalamity1Boss": "",
+ "questStoikalmCalamity1RageTitle": "",
+ "questStoikalmCalamity1RageDescription": "",
+ "questStoikalmCalamity1RageEffect": "",
+ "questStoikalmCalamity1DropSkeletonPotion": "",
+ "questStoikalmCalamity1DropDesertPotion": "",
+ "questStoikalmCalamity1DropArmor": "",
+ "questStoikalmCalamity2Text": "",
+ "questStoikalmCalamity2Notes": "",
+ "questStoikalmCalamity2Completion": "",
+ "questStoikalmCalamity2CollectIcicleCoins": "",
+ "questStoikalmCalamity2DropHeadgear": "",
+ "questStoikalmCalamity3Text": "",
+ "questStoikalmCalamity3Notes": "",
+ "questStoikalmCalamity3Completion": "",
+ "questStoikalmCalamity3Boss": "",
+ "questStoikalmCalamity3DropBlueCottonCandy": "",
+ "questStoikalmCalamity3DropShield": "",
+ "questStoikalmCalamity3DropWeapon": "",
+ "questGuineaPigText": "",
+ "questGuineaPigNotes": "",
+ "questGuineaPigCompletion": "",
+ "questGuineaPigBoss": "",
+ "questGuineaPigDropGuineaPigEgg": "",
+ "questGuineaPigUnlockText": "",
+ "questPeacockText": "",
+ "questPeacockNotes": "",
+ "questPeacockCompletion": "",
+ "questPeacockBoss": "",
+ "questPeacockDropPeacockEgg": "",
+ "questPeacockUnlockText": "",
+ "questButterflyText": "",
+ "questButterflyNotes": "",
+ "questButterflyCompletion": "",
+ "questButterflyBoss": "",
+ "questButterflyDropButterflyEgg": "",
+ "questButterflyUnlockText": "",
+ "questGroupMayhemMistiflying": "",
+ "questMayhemMistiflying1Text": "",
+ "questMayhemMistiflying1Notes": "",
+ "questMayhemMistiflying1Completion": "",
+ "questMayhemMistiflying1Boss": "",
+ "questMayhemMistiflying1RageTitle": "",
+ "questMayhemMistiflying1RageDescription": "",
+ "questMayhemMistiflying1RageEffect": "",
+ "questMayhemMistiflying1DropSkeletonPotion": "",
+ "questMayhemMistiflying1DropWhitePotion": "",
+ "questMayhemMistiflying1DropArmor": "",
+ "questMayhemMistiflying2Text": "",
+ "questMayhemMistiflying2Notes": "",
+ "questMayhemMistiflying2Completion": "",
+ "questMayhemMistiflying2CollectRedMistiflies": "",
+ "questMayhemMistiflying2CollectBlueMistiflies": "",
+ "questMayhemMistiflying2CollectGreenMistiflies": "",
+ "questMayhemMistiflying2DropHeadgear": "",
+ "questMayhemMistiflying3Text": "",
+ "questMayhemMistiflying3Notes": "",
+ "questMayhemMistiflying3Completion": "",
+ "questMayhemMistiflying3Boss": "",
+ "questMayhemMistiflying3DropPinkCottonCandy": "",
+ "questMayhemMistiflying3DropShield": "",
+ "questMayhemMistiflying3DropWeapon": "",
+ "featheredFriendsText": "",
+ "featheredFriendsNotes": "",
+ "questNudibranchText": "",
+ "questNudibranchNotes": "",
+ "questNudibranchCompletion": "",
+ "questNudibranchBoss": "",
+ "questNudibranchDropNudibranchEgg": "",
+ "questNudibranchUnlockText": "",
+ "splashyPalsText": "",
+ "splashyPalsNotes": "",
+ "questHippoText": "",
+ "questHippoNotes": "",
+ "questHippoCompletion": "",
+ "questHippoBoss": "",
+ "questHippoDropHippoEgg": "",
+ "questHippoUnlockText": "",
+ "farmFriendsText": "",
+ "farmFriendsNotes": "",
+ "witchyFamiliarsText": "",
+ "witchyFamiliarsNotes": "",
+ "questGroupLostMasterclasser": "",
+ "questUnlockLostMasterclasser": "",
+ "questLostMasterclasser1Text": "",
+ "questLostMasterclasser1Notes": "",
+ "questLostMasterclasser1Completion": "",
+ "questLostMasterclasser1CollectAncientTomes": "",
+ "questLostMasterclasser1CollectForbiddenTomes": "",
+ "questLostMasterclasser1CollectHiddenTomes": "",
+ "questLostMasterclasser2Text": "",
+ "questLostMasterclasser2Notes": "",
+ "questLostMasterclasser2Completion": "",
+ "questLostMasterclasser2Boss": "",
+ "questLostMasterclasser2DropEyewear": "",
+ "questLostMasterclasser3Text": "",
+ "questLostMasterclasser3Notes": "",
+ "questLostMasterclasser3Completion": "",
+ "questLostMasterclasser3Boss": "",
+ "questLostMasterclasser3RageTitle": "",
+ "questLostMasterclasser3RageDescription": "",
+ "questLostMasterclasser3RageEffect": "",
+ "questLostMasterclasser3DropBodyAccessory": "",
+ "questLostMasterclasser3DropBasePotion": "",
+ "questLostMasterclasser3DropGoldenPotion": "",
+ "questLostMasterclasser3DropPinkPotion": "",
+ "questLostMasterclasser3DropShadePotion": "",
+ "questLostMasterclasser3DropZombiePotion": "",
+ "questLostMasterclasser4Text": "",
+ "questLostMasterclasser4Notes": "",
+ "questLostMasterclasser4Completion": "",
+ "questLostMasterclasser4Boss": "",
+ "questLostMasterclasser4RageTitle": "",
+ "questLostMasterclasser4RageDescription": "",
+ "questLostMasterclasser4RageEffect": "",
+ "questLostMasterclasser4DropBackAccessory": "",
+ "questLostMasterclasser4DropWeapon": "",
+ "questLostMasterclasser4DropMount": "",
+ "questYarnText": "",
+ "questYarnNotes": "",
+ "questYarnCompletion": "",
+ "questYarnBoss": "",
+ "questYarnDropYarnEgg": "",
+ "questYarnUnlockText": "",
+ "winterQuestsText": "",
+ "winterQuestsNotes": "",
+ "questPterodactylText": "",
+ "questPterodactylNotes": "",
+ "questPterodactylCompletion": "",
+ "questPterodactylBoss": "",
+ "questPterodactylDropPterodactylEgg": "",
+ "questPterodactylUnlockText": "",
+ "questBadgerText": "",
+ "questBadgerNotes": "",
+ "questBadgerCompletion": "",
+ "questBadgerBoss": "",
+ "questBadgerDropBadgerEgg": "",
+ "questBadgerUnlockText": "",
+ "questDysheartenerText": "",
+ "questDysheartenerNotes": "",
+ "questDysheartenerCompletion": "",
+ "questDysheartenerCompletionChat": "",
+ "questDysheartenerBossRageTitle": "",
+ "questDysheartenerBossRageDescription": "",
+ "questDysheartenerBossRageSeasonal": "",
+ "seasonalShopRageStrikeHeader": "",
+ "seasonalShopRageStrikeLead": "",
+ "seasonalShopRageStrikeRecap": "",
+ "marketRageStrikeHeader": "",
+ "marketRageStrikeLead": "",
+ "marketRageStrikeRecap": "",
+ "questsRageStrikeHeader": "",
+ "questsRageStrikeLead": "",
+ "questsRageStrikeRecap": "",
+ "questDysheartenerBossRageMarket": "",
+ "questDysheartenerBossRageQuests": "",
+ "questDysheartenerDropHippogriffPet": "",
+ "questDysheartenerDropHippogriffMount": "",
+ "dysheartenerArtCredit": "",
+ "hugabugText": "",
+ "hugabugNotes": "",
+ "questSquirrelText": "",
+ "questSquirrelNotes": "",
+ "questSquirrelCompletion": "",
+ "questSquirrelBoss": "",
+ "questSquirrelDropSquirrelEgg": "",
+ "questSquirrelUnlockText": "",
+ "cuddleBuddiesText": "",
+ "cuddleBuddiesNotes": "",
+ "aquaticAmigosText": "",
+ "aquaticAmigosNotes": "",
+ "questSeaSerpentText": "",
+ "questSeaSerpentNotes": "",
+ "questSeaSerpentCompletion": "",
+ "questSeaSerpentBoss": "",
+ "questSeaSerpentDropSeaSerpentEgg": "",
+ "questSeaSerpentUnlockText": "",
+ "questKangarooText": "",
+ "questKangarooNotes": "",
+ "questKangarooCompletion": "",
+ "questKangarooBoss": "",
+ "questKangarooDropKangarooEgg": "",
+ "questKangarooUnlockText": "",
+ "forestFriendsText": "",
+ "forestFriendsNotes": "",
+ "questAlligatorText": "",
+ "questAlligatorNotes": "",
+ "questAlligatorCompletion": "",
+ "questAlligatorBoss": "",
+ "questAlligatorDropAlligatorEgg": "",
+ "questAlligatorUnlockText": "",
+ "oddballsText": "",
+ "oddballsNotes": "",
+ "birdBuddiesText": "",
+ "birdBuddiesNotes": "",
+ "questVelociraptorText": "",
+ "questVelociraptorNotes": "",
+ "questVelociraptorCompletion": "",
+ "questVelociraptorBoss": "",
+ "questVelociraptorDropVelociraptorEgg": "",
+ "questVelociraptorUnlockText": ""
+}
diff --git a/website/common/locales/eu/rebirth.json b/website/common/locales/eu/rebirth.json
index 18d022a6a0..bd097139f9 100755
--- a/website/common/locales/eu/rebirth.json
+++ b/website/common/locales/eu/rebirth.json
@@ -1,29 +1,29 @@
{
- "rebirthNew": "Rebirth: New Adventure Available!",
- "rebirthUnlock": "You've unlocked Rebirth! This special Market item allows you to begin a new game at level 1 while keeping your tasks, achievements, pets, and more. Use it to breathe new life into Habitica if you feel you've achieved it all, or to experience new features with the fresh eyes of a beginning character!",
- "rebirthBegin": "Rebirth: Begin a New Adventure",
- "rebirthStartOver": "Rebirth starts your character over from Level 1.",
- "rebirthAdvList1": "You return to full Health.",
- "rebirthAdvList2": "You have no Experience or Gold.",
- "rebirthAdvList3": "Your Habits, Dailies, and To-Dos reset to yellow, and streaks reset, except for challenge tasks.",
- "rebirthAdvList4": "You have the starting class of Warrior until you earn a new class.",
- "rebirthInherit": "Your new character inherits a few things from their predecessor:",
- "rebirthInList1": "Tasks, history, equipment, and settings remain.",
- "rebirthInList2": "Challenge, Guild, and Party memberships remain.",
- "rebirthInList3": "Gems, backer tiers, and contributor levels remain.",
- "rebirthInList4": "Items obtained from Gems or drops (such as pets and mounts) remain.",
- "rebirthEarnAchievement": "You also earn an Achievement for beginning a new adventure!",
- "beReborn": "Be Reborn",
- "rebirthAchievement": "You've begun a new adventure! This is Rebirth <%= number %> for you, and the highest Level you've attained is <%= level %>. To stack this Achievement, begin your next new adventure when you've reached an even higher Level!",
- "rebirthAchievement100": "You've begun a new adventure! This is Rebirth <%= number %> for you, and the highest Level you've attained is 100 or higher. To stack this Achievement, begin your next new adventure when you've reached at least 100!",
- "rebirthBegan": "Began a New Adventure",
- "rebirthText": "Began <%= rebirths %> New Adventures",
- "rebirthOrb": "Used an Orb of Rebirth to start over after attaining Level <%= level %>.",
- "rebirthOrb100": "Used an Orb of Rebirth to start over after attaining Level 100 or higher.",
- "rebirthOrbNoLevel": "Used an Orb of Rebirth to start over.",
- "rebirthPop": "Instantly restart your character as a Level 1 Warrior while retaining achievements, collectibles, and equipment. Your tasks and their history will remain but they will be reset to yellow. Your streaks will be removed except from challenge tasks. Your Gold, Experience, Mana, and the effects of all Skills will be removed. All of this will take effect immediately. For more information, see the wiki's Orb of Rebirth page.",
- "rebirthName": "Orb of Rebirth",
- "reborn": "Reborn, max level <%= reLevel %>",
- "confirmReborn": "Are you sure?",
- "rebirthComplete": "You have been reborn!"
-}
\ No newline at end of file
+ "rebirthNew": "",
+ "rebirthUnlock": "",
+ "rebirthBegin": "",
+ "rebirthStartOver": "",
+ "rebirthAdvList1": "",
+ "rebirthAdvList2": "",
+ "rebirthAdvList3": "",
+ "rebirthAdvList4": "",
+ "rebirthInherit": "",
+ "rebirthInList1": "",
+ "rebirthInList2": "",
+ "rebirthInList3": "",
+ "rebirthInList4": "",
+ "rebirthEarnAchievement": "",
+ "beReborn": "",
+ "rebirthAchievement": "",
+ "rebirthAchievement100": "",
+ "rebirthBegan": "",
+ "rebirthText": "",
+ "rebirthOrb": "",
+ "rebirthOrb100": "",
+ "rebirthOrbNoLevel": "",
+ "rebirthPop": "",
+ "rebirthName": "",
+ "reborn": "",
+ "confirmReborn": "",
+ "rebirthComplete": ""
+}
diff --git a/website/common/locales/eu/settings.json b/website/common/locales/eu/settings.json
index ae849ba7da..7a4d118d9e 100755
--- a/website/common/locales/eu/settings.json
+++ b/website/common/locales/eu/settings.json
@@ -1,208 +1,208 @@
{
- "settings": "Settings",
- "language": "Language",
- "americanEnglishGovern": "In the event of a discrepancy in the translations, the American English version governs.",
- "helpWithTranslation": "Would you like to help with the translation of Habitica? Great! Then visit this Trello card.",
- "showHeaderPop": "Show your avatar, Health/Experience bars, and party.",
- "stickyHeader": "Sticky header",
- "stickyHeaderPop": "Affix the header to the top of the screen. Unchecked means it scrolls out of view.",
- "newTaskEdit": "Open new tasks in edit mode",
- "newTaskEditPop": "With this option set, new tasks will immediately open for you to add details like notes and tags.",
- "dailyDueDefaultView": "Set Dailies default to 'due' tab",
- "dailyDueDefaultViewPop": "With this option set, the Dailies tasks will default to 'due' instead of 'all'",
- "reverseChatOrder": "Show chat messages in reverse order",
- "startAdvCollapsed": "Advanced Settings in tasks start collapsed",
- "startAdvCollapsedPop": "With this option set, Advanced Settings will be hidden when you first open a task for editing.",
- "dontShowAgain": "Don't show this again",
- "suppressLevelUpModal": "Don't show popup when gaining a level",
- "suppressHatchPetModal": "Don't show popup when hatching a pet",
- "suppressRaisePetModal": "Don't show popup when raising a pet into a mount",
- "suppressStreakModal": "Don't show popup when attaining a Streak achievement",
- "showTour": "Show Tour",
- "restartTour": "Restart the introductory tour from when you first joined Habitica.",
- "showBailey": "Show Bailey",
- "showBaileyPop": "Bring Bailey the Town Crier out of hiding so you can review past news.",
- "fixVal": "Fix Character Values",
- "fixValPop": "Manually change values like Health, Level, and Gold.",
- "invalidLevel": "Invalid value: Level must be 1 or greater.",
- "enableClass": "Enable Class System",
- "enableClassPop": "You opted out of the class system initially. Would you like now to opt-in?",
- "classTourPop": "Show the tour for using the class system.",
- "resetAccount": "Reset Account",
- "resetAccPop": "Start over, removing all levels, gold, gear, history, and tasks.",
- "deleteAccount": "Delete Account",
- "deleteAccPop": "Cancel and remove your Habitica account.",
- "feedback": "If you'd like to give us feedback, please enter it below - we'd love to know what you liked or didn't like about Habitica! Don't speak English well? No problem! Use the language you prefer.",
- "qrCode": "QR Code",
- "dataExport": "Data Export",
- "saveData": "Here are a few options for saving your data.",
- "habitHistory": "Habit History",
- "exportHistory": "Export History:",
- "csv": "(CSV)",
- "userData": "User Data",
- "exportUserData": "Export User Data:",
- "export": "Export",
- "xml": "(XML)",
- "json": "(JSON)",
- "customDayStart": "Custom Day Start",
- "sureChangeCustomDayStartTime": "Are you sure you want to change your Custom Day Start time? Your Dailies will next reset the first time you use Habitica after <%= time %>. Make sure you have completed your Dailies before then!",
- "changeCustomDayStart": "Change Custom Day Start?",
- "sureChangeCustomDayStart": "Are you sure you want to change your custom day start?",
- "customDayStartHasChanged": "Your custom day start has changed.",
- "nextCron": "Your Dailies will next reset the first time you use Habitica after <%= time %>. Make sure you have completed your Dailies before this time!",
- "customDayStartInfo1": "Habitica defaults to check and reset your Dailies at midnight in your own time zone each day. You can customize that time here.",
- "misc": "Misc",
- "showHeader": "Show Header",
- "changePass": "Change Password",
- "changeUsername": "Change Username",
- "changeEmail": "Change Email Address",
- "newEmail": "New Email Address",
- "oldPass": "Old Password",
- "newPass": "New Password",
- "confirmPass": "Confirm New Password",
- "newUsername": "New Username",
- "dangerZone": "Danger Zone",
- "resetText1": "WARNING! This resets many parts of your account. This is highly discouraged, but some people find it useful in the beginning after playing with the site for a short time.",
- "resetText2": "You will lose all your levels, Gold, and Experience points. All your tasks (except those from challenges) will be deleted permanently and you will lose all of their historical data. You will lose all your equipment but you will be able to buy it all back, including all limited edition equipment or subscriber Mystery items that you already own (you will need to be in the correct class to re-buy class-specific gear). You will keep your current class and your pets and mounts. You might prefer to use an Orb of Rebirth instead, which is a much safer option and which will preserve your tasks and equipment.",
- "deleteLocalAccountText": "Are you sure? This will delete your account forever, and it can never be restored! You will need to register a new account to use Habitica again. Banked or spent Gems will not be refunded. If you're absolutely certain, type your password into the text box below.",
- "deleteSocialAccountText": "Are you sure? This will delete your account forever, and it can never be restored! You will need to register a new account to use Habitica again. Banked or spent Gems will not be refunded. If you're absolutely certain, type \"<%= magicWord %>\" into the text box below.",
- "API": "API",
- "APIv3": "API v3",
- "APIText": "Copy these for use in third party applications. However, think of your API Token like a password, and do not share it publicly. You may occasionally be asked for your User ID, but never post your API Token where others can see it, including on Github.",
- "APIToken": "API Token (this is a password - see warning above!)",
- "showAPIToken": "Show API Token",
- "hideAPIToken": "Hide API Token",
- "APITokenWarning": "If you need a new API Token (e.g., if you accidentally shared it), email <%= hrefTechAssistanceEmail %> with your User ID and current Token. Once it is reset you will need to re-authorize everything by logging out of the website and mobile app and by providing the new Token to any other Habitica tools that you use.",
- "thirdPartyApps": "Third Party Apps",
- "dataToolDesc": "A webpage that shows you certain information from your Habitica account, such as statistics about your tasks, equipment, and skills.",
- "beeminder": "Beeminder",
- "beeminderDesc": "Let Beeminder automatically monitor your Habitica To-Dos. You can commit to maintaining a target number of To-Dos completed per day or per week, or you can commit to gradually reducing your remaining number of uncompleted To-Dos. (By \"commit\" Beeminder means under threat of paying actual money! But you may also just like Beeminder's fancy graphs.)",
- "chromeChatExtension": "Chrome Chat Extension",
- "chromeChatExtensionDesc": "The Chrome Chat Extension for Habitica adds an intuitive chat box to all of habitica.com. It allows users to chat in the Tavern, their party, and any guilds they are in.",
- "otherExtensions": "Other Extensions",
- "otherDesc": "Find other apps, extensions, and tools on the Habitica wiki.",
- "resetDo": "Do it, reset my account!",
- "resetComplete": "Reset complete!",
- "fixValues": "Fix Values",
- "fixValuesText1": "If you've encountered a bug or made a mistake that unfairly changed your character (damage you shouldn't have taken, Gold you didn't really earn, etc.), you can manually correct your numbers here. Yes, this makes it possible to cheat: use this feature wisely, or you'll sabotage your own habit-building!",
- "fixValuesText2": "Note that you cannot restore Streaks on individual tasks here. To do that, edit the Daily and go to Advanced Settings, where you will find a Restore Streak field.",
- "disabledWinterEvent": "Disabled during Winter Wonderland Event Pt.4 (since the rewards are gold-purchaseable).",
- "fix21Streaks": "21-Day Streaks",
- "discardChanges": "Discard Changes",
- "deleteDo": "Do it, delete my account!",
- "enterNumber": "Please enter a number between 0 and 24",
- "fillAll": "Please fill out all fields",
- "invalidPasswordResetCode": "The supplied password reset code is invalid or has expired.",
- "passwordChangeSuccess": "Your password was successfully changed to the one you just chose. You can now use it to access your account.",
- "passwordSuccess": "Password successfully changed",
- "usernameSuccess": "Username successfully changed",
- "displayNameSuccess": "Display name successfully changed",
- "emailSuccess": "Email successfully changed",
- "detachSocial": "De-register <%= network %>",
- "detachedSocial": "Successfully removed <%= network %> authentication from your account",
- "addedLocalAuth": "Successfully added local authentication",
- "data": "Data",
- "exportData": "Export Data",
- "usernameOrEmail": "Username or Email",
- "email": "Email",
- "registerWithSocial": "Register with <%= network %>",
- "registeredWithSocial": "Registered with <%= network %>",
- "loginNameDescription": "This is what you use to log in to Habitica. To change it, use the form below. If instead you want to change the Display Name that appears on your avatar and in chat messages, go to the User Icon > Profile and click the Edit button.",
- "emailNotifications": "Email Notifications",
- "wonChallenge": "You won a Challenge!",
- "newPM": "Received Private Message",
+ "settings": "",
+ "language": "",
+ "americanEnglishGovern": "",
+ "helpWithTranslation": "",
+ "showHeaderPop": "",
+ "stickyHeader": "",
+ "stickyHeaderPop": "",
+ "newTaskEdit": "",
+ "newTaskEditPop": "",
+ "dailyDueDefaultView": "",
+ "dailyDueDefaultViewPop": "",
+ "reverseChatOrder": "",
+ "startAdvCollapsed": "",
+ "startAdvCollapsedPop": "",
+ "dontShowAgain": "",
+ "suppressLevelUpModal": "",
+ "suppressHatchPetModal": "",
+ "suppressRaisePetModal": "",
+ "suppressStreakModal": "",
+ "showTour": "",
+ "restartTour": "",
+ "showBailey": "",
+ "showBaileyPop": "",
+ "fixVal": "",
+ "fixValPop": "",
+ "invalidLevel": "",
+ "enableClass": "",
+ "enableClassPop": "",
+ "classTourPop": "",
+ "resetAccount": "",
+ "resetAccPop": "",
+ "deleteAccount": "",
+ "deleteAccPop": "",
+ "feedback": "",
+ "qrCode": "",
+ "dataExport": "",
+ "saveData": "",
+ "habitHistory": "",
+ "exportHistory": "",
+ "csv": "",
+ "userData": "",
+ "exportUserData": "",
+ "export": "",
+ "xml": "",
+ "json": "",
+ "customDayStart": "",
+ "sureChangeCustomDayStartTime": "",
+ "changeCustomDayStart": "",
+ "sureChangeCustomDayStart": "",
+ "customDayStartHasChanged": "",
+ "nextCron": "",
+ "customDayStartInfo1": "",
+ "misc": "",
+ "showHeader": "",
+ "changePass": "",
+ "changeUsername": "",
+ "changeEmail": "",
+ "newEmail": "",
+ "oldPass": "",
+ "newPass": "",
+ "confirmPass": "",
+ "newUsername": "",
+ "dangerZone": "",
+ "resetText1": "",
+ "resetText2": "",
+ "deleteLocalAccountText": "",
+ "deleteSocialAccountText": "",
+ "API": "",
+ "APIv3": "",
+ "APIText": "",
+ "APIToken": "",
+ "showAPIToken": "",
+ "hideAPIToken": "",
+ "APITokenWarning": "",
+ "thirdPartyApps": "",
+ "dataToolDesc": "",
+ "beeminder": "",
+ "beeminderDesc": "",
+ "chromeChatExtension": "",
+ "chromeChatExtensionDesc": "",
+ "otherExtensions": "",
+ "otherDesc": "",
+ "resetDo": "",
+ "resetComplete": "",
+ "fixValues": "",
+ "fixValuesText1": "",
+ "fixValuesText2": "",
+ "disabledWinterEvent": "",
+ "fix21Streaks": "",
+ "discardChanges": "",
+ "deleteDo": "",
+ "enterNumber": "",
+ "fillAll": "",
+ "invalidPasswordResetCode": "",
+ "passwordChangeSuccess": "",
+ "passwordSuccess": "",
+ "usernameSuccess": "",
+ "displayNameSuccess": "",
+ "emailSuccess": "",
+ "detachSocial": "",
+ "detachedSocial": "",
+ "addedLocalAuth": "",
+ "data": "",
+ "exportData": "",
+ "usernameOrEmail": "",
+ "email": "",
+ "registerWithSocial": "",
+ "registeredWithSocial": "",
+ "loginNameDescription": "",
+ "emailNotifications": "",
+ "wonChallenge": "",
+ "newPM": "",
"newPMInfo": "New Message from <%= name %>: <%= message %>",
- "giftedGems": "Gifted Gems",
- "giftedGemsInfo": "<%= name %> gifted you <%= amount %> Gems",
- "giftedGemsFull": "Hello <%= username %>, <%= sender %> has sent you <%= gemAmount %> gems!",
- "giftedSubscription": "Gifted Subscription",
- "giftedSubscriptionInfo": "<%= name %> gifted you a <%= months %> month subscription",
- "giftedSubscriptionFull": "Hello <%= username %>, <%= sender %> has sent you <%= monthCount %> months of subscription!",
- "giftedSubscriptionWinterPromo": "Hello <%= username %>, you received <%= monthCount %> months of subscription as part of our holiday gift-giving promotion!",
- "invitedParty": "Invited To Party",
- "invitedGuild": "Invited To Guild",
- "importantAnnouncements": "Reminders to check in to complete tasks and receive prizes",
- "weeklyRecaps": "Summaries of your account activity in the past week (Note: this is currently disabled due to performance issues, but we hope to have this back up and sending e-mails again soon!)",
- "onboarding": "Guidance with setting up your Habitica account",
- "majorUpdates": "Important announcements",
- "questStarted": "Your Quest has Begun",
- "invitedQuest": "Invited to Quest",
- "kickedGroup": "Kicked from group",
- "remindersToLogin": "Reminders to check in to Habitica",
- "subscribeUsing": "Subscribe using",
- "unsubscribedSuccessfully": "Unsubscribed successfully!",
- "unsubscribedTextUsers": "You have successfully unsubscribed from all Habitica emails. You can enable only the emails you want to receive from Settings > > Notifications (requires login).",
- "unsubscribedTextOthers": "You won't receive any other email from Habitica.",
- "unsubscribeAllEmails": "Check to Unsubscribe from Emails",
- "unsubscribeAllEmailsText": "By checking this box, I certify that I understand that by unsubscribing from all emails, Habitica will never be able to notify me via email about important changes to the site or my account.",
- "unsubscribeAllPush": "Check to Unsubscribe from all Push Notifications",
- "correctlyUnsubscribedEmailType": "Correctly unsubscribed from \"<%= emailType %>\" emails.",
- "subscriptionRateText": "Recurring $<%= price %> USD every <%= months %> months",
- "recurringText": "recurring",
- "benefits": "Benefits",
- "coupon": "Coupon",
- "couponPlaceholder": "Enter Coupon Code",
- "couponText": "We sometimes have events and give out coupon codes for special gear. (eg, those who stop by our Wondercon booth)",
- "apply": "Apply",
- "resubscribe": "Resubscribe",
- "promoCode": "Promo Code",
- "promoCodeApplied": "Promo Code Applied! Check your inventory",
- "promoPlaceholder": "Enter Promotion Code",
- "displayInviteToPartyWhenPartyIs1": "Display Invite To Party button when party has 1 member.",
- "saveCustomDayStart": "Save Custom Day Start",
- "registration": "Registration",
- "addLocalAuth": "Add Email and Password Login",
- "generateCodes": "Generate Codes",
- "generate": "Generate",
- "getCodes": "Get Codes",
- "webhooks": "Webhooks",
- "webhooksInfo": "Habitica provides webhooks so that when certain actions occur in your account, information can be sent to a script on another website. You can specify those scripts here. Be careful with this feature because specifying an incorrect URL can cause errors or slowness in Habitica. For more information, see the wiki's Webhooks page.",
- "enabled": "Enabled",
- "webhookURL": "Webhook URL",
- "invalidUrl": "invalid url",
- "invalidEnabled": "the \"enabled\" parameter should be a boolean.",
- "invalidWebhookId": "the \"id\" parameter should be a valid UUID.",
- "missingWebhookId": "The webhook's id is required.",
- "invalidWebhookType": "\"<%= type %>\" is not a valid value for the parameter \"type\".",
- "webhookBooleanOption": "\"<%= option %>\" must be a Boolean value.",
- "webhookIdAlreadyTaken": "A webhook with the id <%= id %> already exists.",
- "noWebhookWithId": "There is no webhook with the id <%= id %>.",
- "regIdRequired": "RegId is required",
- "invalidPushClient": "Invalid client. Only Official Habitica clients can receive push notifications.",
- "pushDeviceAdded": "Push device added successfully",
- "pushDeviceAlreadyAdded": "The user already has the push device",
- "pushDeviceNotFound": "The user has no push device with this id.",
- "pushDeviceRemoved": "Push device removed successfully.",
- "buyGemsGoldCap": "Cap raised to <%= amount %>",
- "mysticHourglass": "<%= amount %> Mystic Hourglass",
- "mysticHourglassText": "Mystic Hourglasses allow purchasing a previous month's Mystery Item set.",
- "purchasedPlanId": "Recurring $<%= price %> USD each <%= months %> Month(s) (<%= plan %>)",
- "purchasedPlanExtraMonths": "You have <%= months %> months of extra subscription credit.",
- "consecutiveSubscription": "Consecutive Subscription",
- "consecutiveMonths": "Consecutive Months:",
- "gemCapExtra": "Gem Cap Extra:",
- "mysticHourglasses": "Mystic Hourglasses:",
- "mysticHourglassesTooltip": "Mystic Hourglasses",
- "paypal": "PayPal",
- "amazonPayments": "Amazon Payments",
- "amazonPaymentsRecurring": "Ticking the checkbox below is necessary for your subscription to be created. It allows your Amazon account to be used for ongoing payments for this subscription. It will not cause your Amazon account to be automatically used for any future purchases.",
- "timezone": "Time Zone",
- "timezoneUTC": "Habitica uses the time zone set on your PC, which is: <%= utc %>",
- "timezoneInfo": "If that time zone is wrong, first reload this page using your browser's reload or refresh button to ensure that Habitica has the most recent information. If it is still wrong, adjust the time zone on your PC and then reload this page again.
If you use Habitica on other PCs or mobile devices, the time zone must be the same on them all. If your Dailies have been resetting at the wrong time, repeat this check on all other PCs and on a browser on your mobile devices.",
- "push": "Push",
- "about": "About",
- "setUsernameNotificationTitle": "Confirm your username!",
- "setUsernameNotificationBody": "We will be transitioning login names to unique, public usernames soon. This username will be used for invitations, @mentions in chat, and messaging.",
- "usernameIssueSlur": "Usernames may not contain inappropriate language.",
- "usernameIssueForbidden": "Usernames may not contain restricted words.",
- "usernameIssueLength": "Usernames must be between 1 and 20 characters.",
- "usernameIssueInvalidCharacters": "Usernames can only contain letters a to z, numbers 0 to 9, hyphens, or underscores.",
- "currentUsername": "Current username:",
- "displaynameIssueLength": "Display Names must be between 1 and 30 characters.",
- "displaynameIssueSlur": "Display Names may not contain inappropriate language.",
- "goToSettings": "Go to Settings",
- "usernameVerifiedConfirmation": "Your username, <%= username %>, is confirmed!",
- "usernameNotVerified": "Please confirm your username.",
- "changeUsernameDisclaimer": "We will be transitioning login names to unique, public usernames soon. This username will be used for invitations, @mentions in chat, and messaging.",
- "verifyUsernameVeteranPet": "One of these Veteran Pets will be waiting for you after you've finished confirming!"
-}
\ No newline at end of file
+ "giftedGems": "",
+ "giftedGemsInfo": "",
+ "giftedGemsFull": "",
+ "giftedSubscription": "",
+ "giftedSubscriptionInfo": "",
+ "giftedSubscriptionFull": "",
+ "giftedSubscriptionWinterPromo": "",
+ "invitedParty": "",
+ "invitedGuild": "",
+ "importantAnnouncements": "",
+ "weeklyRecaps": "",
+ "onboarding": "",
+ "majorUpdates": "",
+ "questStarted": "",
+ "invitedQuest": "",
+ "kickedGroup": "",
+ "remindersToLogin": "",
+ "subscribeUsing": "",
+ "unsubscribedSuccessfully": "",
+ "unsubscribedTextUsers": "",
+ "unsubscribedTextOthers": "",
+ "unsubscribeAllEmails": "",
+ "unsubscribeAllEmailsText": "",
+ "unsubscribeAllPush": "",
+ "correctlyUnsubscribedEmailType": "",
+ "subscriptionRateText": "",
+ "recurringText": "",
+ "benefits": "",
+ "coupon": "",
+ "couponPlaceholder": "",
+ "couponText": "",
+ "apply": "",
+ "resubscribe": "",
+ "promoCode": "",
+ "promoCodeApplied": "",
+ "promoPlaceholder": "",
+ "displayInviteToPartyWhenPartyIs1": "",
+ "saveCustomDayStart": "",
+ "registration": "",
+ "addLocalAuth": "",
+ "generateCodes": "",
+ "generate": "",
+ "getCodes": "",
+ "webhooks": "",
+ "webhooksInfo": "",
+ "enabled": "",
+ "webhookURL": "",
+ "invalidUrl": "",
+ "invalidEnabled": "",
+ "invalidWebhookId": "",
+ "missingWebhookId": "",
+ "invalidWebhookType": "",
+ "webhookBooleanOption": "",
+ "webhookIdAlreadyTaken": "",
+ "noWebhookWithId": "",
+ "regIdRequired": "",
+ "invalidPushClient": "",
+ "pushDeviceAdded": "",
+ "pushDeviceAlreadyAdded": "",
+ "pushDeviceNotFound": "",
+ "pushDeviceRemoved": "",
+ "buyGemsGoldCap": "",
+ "mysticHourglass": "",
+ "mysticHourglassText": "",
+ "purchasedPlanId": "",
+ "purchasedPlanExtraMonths": "",
+ "consecutiveSubscription": "",
+ "consecutiveMonths": "",
+ "gemCapExtra": "",
+ "mysticHourglasses": "",
+ "mysticHourglassesTooltip": "",
+ "paypal": "",
+ "amazonPayments": "",
+ "amazonPaymentsRecurring": "",
+ "timezone": "",
+ "timezoneUTC": "",
+ "timezoneInfo": "",
+ "push": "",
+ "about": "",
+ "setUsernameNotificationTitle": "",
+ "setUsernameNotificationBody": "",
+ "usernameIssueSlur": "",
+ "usernameIssueForbidden": "",
+ "usernameIssueLength": "",
+ "usernameIssueInvalidCharacters": "",
+ "currentUsername": "",
+ "displaynameIssueLength": "",
+ "displaynameIssueSlur": "",
+ "goToSettings": "",
+ "usernameVerifiedConfirmation": "",
+ "usernameNotVerified": "",
+ "changeUsernameDisclaimer": "",
+ "verifyUsernameVeteranPet": ""
+}
diff --git a/website/common/locales/eu/spells.json b/website/common/locales/eu/spells.json
index f4f1f4ab35..b42aa56fd2 100755
--- a/website/common/locales/eu/spells.json
+++ b/website/common/locales/eu/spells.json
@@ -1,59 +1,59 @@
{
- "spellWizardFireballText": "Burst of Flames",
- "spellWizardFireballNotes": "You summon XP and deal fiery damage to Bosses! (Based on: INT)",
- "spellWizardMPHealText": "Ethereal Surge",
- "spellWizardMPHealNotes": "You sacrifice Mana so the rest of your Party, except Mages, gains MP! (Based on: INT)",
- "spellWizardEarthText": "Earthquake",
- "spellWizardEarthNotes": "Your mental power shakes the earth and buffs your Party's Intelligence! (Based on: Unbuffed INT)",
- "spellWizardFrostText": "Chilling Frost",
- "spellWizardFrostNotes": "With one cast, ice freezes all your streaks so they won't reset to zero tomorrow!",
- "spellWizardFrostAlreadyCast": "You have already cast this today. Your streaks are frozen, and there's no need to cast this again.",
- "spellWarriorSmashText": "Brutal Smash",
- "spellWarriorSmashNotes": "You make a task more blue/less red and deal extra damage to Bosses! (Based on: STR)",
- "spellWarriorDefensiveStanceText": "Defensive Stance",
- "spellWarriorDefensiveStanceNotes": "You crouch low and gain a buff to Constitution! (Based on: Unbuffed CON)",
- "spellWarriorValorousPresenceText": "Valorous Presence",
- "spellWarriorValorousPresenceNotes": "Your boldness buffs your whole Party's Strength! (Based on: Unbuffed STR)",
- "spellWarriorIntimidateText": "Intimidating Gaze",
- "spellWarriorIntimidateNotes": "Your fierce stare buffs your whole Party's Constitution! (Based on: Unbuffed CON)",
- "spellRoguePickPocketText": "Pickpocket",
- "spellRoguePickPocketNotes": "You rob a nearby task and gain gold! (Based on: PER)",
- "spellRogueBackStabText": "Backstab",
- "spellRogueBackStabNotes": "You betray a foolish task and gain gold and XP! (Based on: STR)",
- "spellRogueToolsOfTradeText": "Tools of the Trade",
- "spellRogueToolsOfTradeNotes": "Your tricky talents buff your whole Party's Perception! (Based on: Unbuffed PER)",
- "spellRogueStealthText": "Stealth",
- "spellRogueStealthNotes": "With each cast, a few of your undone Dailies won't cause damage tonight. Their streaks and colors won't change. (Based on: PER)",
- "spellRogueStealthDaliesAvoided": "<%= originalText %> Number of dailies avoided: <%= number %>.",
- "spellRogueStealthMaxedOut": "You have already avoided all your dailies; there's no need to cast this again.",
- "spellHealerHealText": "Healing Light",
- "spellHealerHealNotes": "Shining light restores your health! (Based on: CON and INT)",
- "spellHealerBrightnessText": "Searing Brightness",
- "spellHealerBrightnessNotes": "A burst of light makes your tasks more blue/less red! (Based on: INT)",
- "spellHealerProtectAuraText": "Protective Aura",
- "spellHealerProtectAuraNotes": "You shield your Party by buffing their Constitution! (Based on: Unbuffed CON)",
- "spellHealerHealAllText": "Blessing",
- "spellHealerHealAllNotes": "Your soothing spell restores your whole Party's health! (Based on: CON and INT)",
- "spellSpecialSnowballAuraText": "Snowball",
- "spellSpecialSnowballAuraNotes": "Turn a friend into a frosty snowman!",
- "spellSpecialSaltText": "Salt",
- "spellSpecialSaltNotes": "Reverse the spell that made you a snowman.",
- "spellSpecialSpookySparklesText": "Spooky Sparkles",
- "spellSpecialSpookySparklesNotes": "Turn your friend into a transparent pal!",
- "spellSpecialOpaquePotionText": "Opaque Potion",
- "spellSpecialOpaquePotionNotes": "Reverse the spell that made you transparent.",
- "spellSpecialShinySeedText": "Shiny Seed",
- "spellSpecialShinySeedNotes": "Turn a friend into a joyous flower!",
- "spellSpecialPetalFreePotionText": "Petal-Free Potion",
- "spellSpecialPetalFreePotionNotes": "Reverse the spell that made you a flower.",
- "spellSpecialSeafoamText": "Seafoam",
- "spellSpecialSeafoamNotes": "Turn a friend into a sea creature!",
- "spellSpecialSandText": "Sand",
- "spellSpecialSandNotes": "Reverse the spell that made you a sea star.",
- "partyNotFound": "Party not found",
- "targetIdUUID": "\"targetId\" must be a valid User ID.",
- "challengeTasksNoCast": "Casting a skill on challenge tasks is not allowed.",
- "groupTasksNoCast": "Casting a skill on group tasks is not allowed.",
- "spellNotOwned": "You don't own this skill.",
- "spellLevelTooHigh": "You must be level <%= level %> to use this skill."
-}
\ No newline at end of file
+ "spellWizardFireballText": "",
+ "spellWizardFireballNotes": "",
+ "spellWizardMPHealText": "",
+ "spellWizardMPHealNotes": "",
+ "spellWizardEarthText": "",
+ "spellWizardEarthNotes": "",
+ "spellWizardFrostText": "",
+ "spellWizardFrostNotes": "",
+ "spellWizardFrostAlreadyCast": "",
+ "spellWarriorSmashText": "",
+ "spellWarriorSmashNotes": "",
+ "spellWarriorDefensiveStanceText": "",
+ "spellWarriorDefensiveStanceNotes": "",
+ "spellWarriorValorousPresenceText": "",
+ "spellWarriorValorousPresenceNotes": "",
+ "spellWarriorIntimidateText": "",
+ "spellWarriorIntimidateNotes": "",
+ "spellRoguePickPocketText": "",
+ "spellRoguePickPocketNotes": "",
+ "spellRogueBackStabText": "",
+ "spellRogueBackStabNotes": "",
+ "spellRogueToolsOfTradeText": "",
+ "spellRogueToolsOfTradeNotes": "",
+ "spellRogueStealthText": "",
+ "spellRogueStealthNotes": "",
+ "spellRogueStealthDaliesAvoided": "",
+ "spellRogueStealthMaxedOut": "",
+ "spellHealerHealText": "",
+ "spellHealerHealNotes": "",
+ "spellHealerBrightnessText": "",
+ "spellHealerBrightnessNotes": "",
+ "spellHealerProtectAuraText": "",
+ "spellHealerProtectAuraNotes": "",
+ "spellHealerHealAllText": "",
+ "spellHealerHealAllNotes": "",
+ "spellSpecialSnowballAuraText": "",
+ "spellSpecialSnowballAuraNotes": "",
+ "spellSpecialSaltText": "",
+ "spellSpecialSaltNotes": "",
+ "spellSpecialSpookySparklesText": "",
+ "spellSpecialSpookySparklesNotes": "",
+ "spellSpecialOpaquePotionText": "",
+ "spellSpecialOpaquePotionNotes": "",
+ "spellSpecialShinySeedText": "",
+ "spellSpecialShinySeedNotes": "",
+ "spellSpecialPetalFreePotionText": "",
+ "spellSpecialPetalFreePotionNotes": "",
+ "spellSpecialSeafoamText": "",
+ "spellSpecialSeafoamNotes": "",
+ "spellSpecialSandText": "",
+ "spellSpecialSandNotes": "",
+ "partyNotFound": "",
+ "targetIdUUID": "",
+ "challengeTasksNoCast": "",
+ "groupTasksNoCast": "",
+ "spellNotOwned": "",
+ "spellLevelTooHigh": ""
+}
diff --git a/website/common/locales/eu/subscriber.json b/website/common/locales/eu/subscriber.json
index 32733f5476..c3a778549a 100755
--- a/website/common/locales/eu/subscriber.json
+++ b/website/common/locales/eu/subscriber.json
@@ -1,217 +1,217 @@
{
- "subscription": "Subscription",
- "subscriptions": "Subscriptions",
- "subDescription": "Buy Gems with gold, get monthly mystery items, retain progress history, double daily drop-caps, support the devs. Click for more info.",
- "sendGems": "Send Gems",
- "buyGemsGold": "Buy Gems with Gold",
- "buyGemsGoldText": "Alexander the Merchant will sell you Gems at a cost of 20 Gold per Gem. His monthly shipments are initially capped at 25 Gems per month, but for every 3 consecutive months that you are subscribed, this cap increases by 5 Gems, up to a maximum of 50 Gems per month!",
- "mustSubscribeToPurchaseGems": "Must subscribe to purchase gems with GP",
- "reachedGoldToGemCap": "You've reached the Gold=>Gem conversion cap <%= convCap %> for this month. We have this to prevent abuse / farming. The cap resets within the first three days of each month.",
- "reachedGoldToGemCapQuantity": "Your requested amount <%= quantity %> exceeds the Gold=>Gem conversion cap <%= convCap %> for this month. We have this to prevent abuse / farming. The cap resets within the first three days of each month.",
- "retainHistory": "Retain additional history entries",
- "retainHistoryText": "Makes completed To-Dos and task history available for longer.",
- "doubleDrops": "Daily drop caps doubled",
- "doubleDropsText": "Complete your stable faster!",
- "mysteryItem": "Exclusive monthly items",
- "mysteryItemText": "Each month you will receive a unique cosmetic item for your avatar! Plus, for every three months of consecutive subscription, the Mysterious Time Travelers will grant you access to historic (and futuristic!) cosmetic items.",
- "supportDevs": "Supports the developers",
- "supportDevsText": "Your subscription helps keep Habitica thriving and helps fund the development of new features. Thank you for your generosity!",
- "exclusiveJackalopePet": "Exclusive pet",
- "exclusiveJackalopePetText": "Get the Royal Purple Jackalope pet, available only to subscribers!",
- "giftSubscription": "Want to gift a subscription to someone?",
- "giftSubscriptionText1": "Open their profile! You can do this by clicking on their avatar in your party header or by clicking on their name in chat.",
- "giftSubscriptionText2": "Click on the gift icon in the top right of their profile.",
- "giftSubscriptionText3": "Select \"subscription\" and enter your payment information.",
- "giftSubscriptionText4": "Thanks for supporting Habitica!",
- "monthUSD": "USD / Month",
- "organization": "Organization",
- "groupPlans": "Group Plans",
- "indivPlan1": "For individuals, Habitica is free to play. Even for small interest groups, free (or cheap)",
- "indivPlan2": "can be used to motivate participants in behavioral modification. Think writing groups, art challenges, and more.",
- "groupText1": "But some group leaders will want more control, privacy, security, and support. Examples of such groups are families, health and wellness groups, employee groups, and more. These plans provide private instances of Habitica for your group or organization, secure and independent of",
- "groupText2": "See below for additional plan perks, and contact us for more information!",
- "planFamily": "Family (Coming Soon)",
- "planGroup": "Group (Coming Soon)",
- "dedicatedHost": "Dedicated Hosting",
- "dedicatedHostText": "Dedicated Hosting: you get your own database and server hosted by Habitica, or optionally we'll install it in your organization's network. If not checked, the plan uses \"Shared Hosting\": your organization uses the same database as Habitica proper while performing independently Habitica. Your members are shielded from Tavern & Guilds, but still on the same server/database.",
- "individualSub": "Individual Subscription",
- "subscribe": "Subscribe",
- "subscribed": "Subscribed",
- "nowSubscribed": "You are now subscribed to Habitica!",
- "manageSub": "Click to manage subscription",
- "cancelSub": "Cancel Subscription",
- "cancelSubInfoGoogle": "Please go to the \"Account\" > \"Subscriptions\" section of the Google Play Store app to cancel your subscription or to see your subscription's termination date if you have already cancelled it. This screen is not able to show you whether your subscription has been cancelled.",
- "cancelSubInfoApple": "Please follow Apple's official instructions to cancel your subscription or to see your subscription's termination date if you have already cancelled it. This screen is not able to show you whether your subscription has been cancelled.",
- "cancelSubInfoGroupPlan": "Because you have a free subscription from a Group Plan, you cannot cancel it. It will end when you are no longer in the Group. If you are the Group leader and want to cancel the entire Group Plan, you can do that from the group's \"Payment Details\" tab.",
- "canceledSubscription": "Canceled Subscription",
- "cancelingSubscription": "Canceling the subscription",
- "adminSub": "Administrator Subscriptions",
- "morePlans": "More Plans Coming Soon",
- "organizationSub": "Private Organization",
- "organizationSubText": "Members of the organization participate outside of Habitica proper, providing focus for your participants.",
- "hostingType": "Hosting Type",
- "hostingTypeText": "Shared hosting means your organization uses the same database as Habitica proper even though you don't interact with Habitica. Dedicated means you get your own database and server. You can choose to have Habitica host your server/db, or we can install it on your own servers.",
- "dedicated": "Dedicated",
- "customDomain": "Custom Domain",
- "customDomainText": "We can optionally give you your own domain for the installation.",
- "maxPlayers": "Max Participants",
- "maxPlayersText": "The maximum number of players in your private organization.",
- "unlimited": "Unlimited",
- "priSupport": "Priority Support On Tickets & Hosting",
- "priSupportText": "First to be provided for with support.",
- "timeSupport": "Support Hours / Month",
- "timeSupportText": "We will provide support for training, bugs, installation, and feature requests.",
- "gameFeatures": "Game features",
- "gold2Gem": "Gems purchasable with gold",
- "gold2GemText": "Members will be able to purchase Gems with gold, meaning none of your participants need to buy anything with real money.",
- "infiniteGem": "Infinite leader Gems",
- "infiniteGemText": "We will provide the organization leaders with as many Gems as they need, for things like challenge prizes, guild-creation, etc.",
- "notYetPlan": "Plan not yet available, but click to contact us and we'll keep you updated.",
- "contactUs": "Contact Us",
- "checkout": "Checkout",
+ "subscription": "",
+ "subscriptions": "",
+ "subDescription": "",
+ "sendGems": "",
+ "buyGemsGold": "",
+ "buyGemsGoldText": "",
+ "mustSubscribeToPurchaseGems": "",
+ "reachedGoldToGemCap": "",
+ "reachedGoldToGemCapQuantity": "",
+ "retainHistory": "",
+ "retainHistoryText": "",
+ "doubleDrops": "",
+ "doubleDropsText": "",
+ "mysteryItem": "",
+ "mysteryItemText": "",
+ "supportDevs": "",
+ "supportDevsText": "",
+ "exclusiveJackalopePet": "",
+ "exclusiveJackalopePetText": "",
+ "giftSubscription": "",
+ "giftSubscriptionText1": "",
+ "giftSubscriptionText2": "",
+ "giftSubscriptionText3": "",
+ "giftSubscriptionText4": "",
+ "monthUSD": "",
+ "organization": "",
+ "groupPlans": "",
+ "indivPlan1": "",
+ "indivPlan2": "",
+ "groupText1": "",
+ "groupText2": "",
+ "planFamily": "",
+ "planGroup": "",
+ "dedicatedHost": "",
+ "dedicatedHostText": "",
+ "individualSub": "",
+ "subscribe": "",
+ "subscribed": "",
+ "nowSubscribed": "",
+ "manageSub": "",
+ "cancelSub": "",
+ "cancelSubInfoGoogle": "",
+ "cancelSubInfoApple": "",
+ "cancelSubInfoGroupPlan": "",
+ "canceledSubscription": "",
+ "cancelingSubscription": "",
+ "adminSub": "",
+ "morePlans": "",
+ "organizationSub": "",
+ "organizationSubText": "",
+ "hostingType": "",
+ "hostingTypeText": "",
+ "dedicated": "",
+ "customDomain": "",
+ "customDomainText": "",
+ "maxPlayers": "",
+ "maxPlayersText": "",
+ "unlimited": "",
+ "priSupport": "",
+ "priSupportText": "",
+ "timeSupport": "",
+ "timeSupportText": "",
+ "gameFeatures": "",
+ "gold2Gem": "",
+ "gold2GemText": "",
+ "infiniteGem": "",
+ "infiniteGemText": "",
+ "notYetPlan": "",
+ "contactUs": "",
+ "checkout": "",
"sureCancelSub": "Are you sure you want to cancel your subscription?",
- "subCanceled": "Subscription will become inactive on",
- "buyGemsGoldTitle": "To Buy Gems with Gold",
- "becomeSubscriber": "Become a Subscriber",
- "subGemPop": "Because you subscribe to Habitica, you can purchase a number of Gems each month using Gold.",
- "subGemName": "Subscriber Gems",
- "freeGemsTitle": "Obtain Gems for Free",
- "maxBuyGems": "You have bought all the Gems you can this month. More become available within the first three days of each month. Thanks for subscribing!",
- "buyGemsAllow1": "You can buy",
- "buyGemsAllow2": "more Gems this month",
- "purchaseGemsSeparately": "Purchase Additional Gems",
- "subFreeGemsHow": "Habitica players can earn Gems for free by winning challenges that award Gems as a prize, or as a contributor reward by helping the development of Habitica.",
- "seeSubscriptionDetails": "Go to Settings > Subscription to see your subscription details!",
- "timeTravelers": "Time Travelers",
- "timeTravelersTitleNoSub": "<%= linkStartTyler %>Tyler<%= linkEnd %> and <%= linkStartVicky %>Vicky<%= linkEnd %>",
- "timeTravelersTitle": "Mysterious Time Travelers",
- "timeTravelersPopoverNoSub": "You'll need a Mystic Hourglass to summon the mysterious Time Travelers! <%= linkStart %>Subscribers<%= linkEnd %> earn one Mystic Hourglass for every three months of consecutive subscribing. Come back when you have a Mystic Hourglass, and the Time Travelers will fetch you a rare pet, mount, or Subscriber Item Set from the past... or maybe even the future.",
- "timeTravelersPopoverNoSubMobile": "Looks like you’ll need a Mystic Hourglass to open the time portal and summon the Mysterious Time Travelers.",
- "timeTravelersPopover": "Your Mystic Hourglass has opened our time portal! Choose what you’d like us to fetch from the past or future.",
- "timeTravelersAlreadyOwned": "Congratulations! You already own everything the Time Travelers currently offer. Thanks for supporting the site!",
- "mysticHourglassPopover": "A Mystic Hourglass allows you to purchase certain limited-time items, such as monthly Mystery Item Sets and awards from world bosses, from the past!",
- "mysterySetNotFound": "Mystery set not found, or set already owned.",
- "mysteryItemIsEmpty": "Mystery items are empty",
- "mysteryItemOpened": "Mystery item opened.",
- "mysterySet201402": "Winged Messenger Set",
- "mysterySet201403": "Forest Walker Set",
- "mysterySet201404": "Twilight Butterfly Set",
- "mysterySet201405": "Flame Wielder Set",
- "mysterySet201406": "Octomage Set",
- "mysterySet201407": "Undersea Explorer Set",
- "mysterySet201408": "Sun Sorcerer Set",
- "mysterySet201409": "Autumn Strider Set",
- "mysterySet201410": "Winged Goblin Set",
- "mysterySet201411": "Feast and Fun Set",
- "mysterySet201412": "Penguin Set",
- "mysterySet201501": "Starry Knight Set",
- "mysterySet201502": "Winged Enchanter Set",
- "mysterySet201503": "Aquamarine Set",
- "mysterySet201504": "Busy Bee Set",
- "mysterySet201505": "Green Knight Set",
- "mysterySet201506": "Neon Snorkeler Set",
- "mysterySet201507": "Rad Surfer Set",
- "mysterySet201508": "Cheetah Costume Set",
- "mysterySet201509": "Werewolf Set",
- "mysterySet201510": "Horned Goblin Set",
- "mysterySet201511": "Wood Warrior Set",
- "mysterySet201512": "Winter Flame Set",
- "mysterySet201601": "Champion of Resolution Set",
- "mysterySet201602": "Heartbreaker Set",
- "mysterySet201603": "Lucky Clover Set",
- "mysterySet201604": "Leaf Warrior Set",
- "mysterySet201605": "Marching Bard Set",
- "mysterySet201606": "Selkie Robes Set",
- "mysterySet201607": "Seafloor Rogue Set",
- "mysterySet201608": "Thunderstormer Set",
- "mysterySet201609": "Cow Costume Set",
- "mysterySet201610": "Spectral Flame Set",
- "mysterySet201611": "Cornucopia Set",
- "mysterySet201612": "Nutcracker Set",
- "mysterySet201701": "Time-Freezer Set",
- "mysterySet201702": "Heartstealer Set",
- "mysterySet201703": "Shimmer Set",
- "mysterySet201704": "Fairytale Set",
- "mysterySet201705": "Feathered Fighter Set",
- "mysterySet201706": "Pirate Pioneer Set",
- "mysterySet201707": "Jellymancer Set",
- "mysterySet201708": "Lava Warrior Set",
- "mysterySet201709": "Sorcery Student Set",
- "mysterySet201710": "Imperious Imp Set",
- "mysterySet201711": "Carpet Rider Set",
- "mysterySet201712": "Candlemancer Set",
- "mysterySet201801": "Frost Sprite Set",
- "mysterySet201802": "Love Bug Set",
- "mysterySet201803": "Daring Dragonfly Set",
- "mysterySet201804": "Spiffy Squirrel Set",
- "mysterySet201805": "Phenomenal Peacock Set",
- "mysterySet201806": "Alluring Anglerfish Set",
- "mysterySet201807": "Sea Serpent Set",
- "mysterySet201808": "Lava Dragon Set",
- "mysterySet201809": "Autumnal Armor Set",
- "mysterySet201810": "Dark Forest Set",
- "mysterySet201811": "Splendid Sorcerer Set",
- "mysterySet201812": "Arctic Fox Set",
- "mysterySet301404": "Steampunk Standard Set",
- "mysterySet301405": "Steampunk Accessories Set",
- "mysterySet301703": "Peacock Steampunk Set",
- "mysterySet301704": "Pheasant Steampunk Set",
- "mysterySetwondercon": "Wondercon",
- "subUpdateCard": "Update Card",
- "subUpdateTitle": "Update",
- "subUpdateDescription": "Update the card to be charged.",
- "notEnoughHourglasses": "You don't have enough Mystic Hourglasses.",
- "hourglassBuyEquipSetConfirm": "Buy this full set of items for 1 Mystic Hourglass?",
- "hourglassBuyItemConfirm": "Buy this item for 1 Mystic Hourglass?",
- "petsAlreadyOwned": "Pet already owned.",
- "mountsAlreadyOwned": "Mount already owned.",
- "typeNotAllowedHourglass": "Item type not supported for purchase with Mystic Hourglass. Allowed types: <%= allowedTypes %>",
- "petsNotAllowedHourglass": "Pet not available for purchase with Mystic Hourglass.",
- "mountsNotAllowedHourglass": "Mount not available for purchase with Mystic Hourglass.",
- "hourglassPurchase": "Purchased an item using a Mystic Hourglass!",
- "hourglassPurchaseSet": "Purchased an item set using a Mystic Hourglass!",
- "missingUnsubscriptionCode": "Missing unsubscription code.",
- "missingSubscription": "User does not have a plan subscription",
- "missingSubscriptionCode": "Missing subscription code. Possible values: basic_earned, basic_3mo, basic_6mo, google_6mo, basic_12mo.",
- "missingReceipt": "Missing Receipt.",
- "cannotDeleteActiveAccount": "You have an active subscription, cancel your plan before deleting your account.",
- "paymentNotSuccessful": "The payment was not successful",
- "planNotActive": "The plan hasn't activated yet (due to a PayPal bug). It will begin <%= nextBillingDate %>, after which you can cancel to retain your full benefits",
- "notAllowedHourglass": "Pet/Mount not available for purchase with Mystic Hourglass.",
- "readCard": "<%= cardType %> has been read",
- "cardTypeRequired": "Card type required",
- "cardTypeNotAllowed": "Unknown card type.",
- "invalidCoupon": "Invalid coupon code.",
- "couponUsed": "Coupon code already used.",
- "couponCodeRequired": "The coupon code is required.",
+ "subCanceled": "",
+ "buyGemsGoldTitle": "",
+ "becomeSubscriber": "",
+ "subGemPop": "",
+ "subGemName": "",
+ "freeGemsTitle": "",
+ "maxBuyGems": "",
+ "buyGemsAllow1": "",
+ "buyGemsAllow2": "",
+ "purchaseGemsSeparately": "",
+ "subFreeGemsHow": "",
+ "seeSubscriptionDetails": "",
+ "timeTravelers": "",
+ "timeTravelersTitleNoSub": "",
+ "timeTravelersTitle": "",
+ "timeTravelersPopoverNoSub": "",
+ "timeTravelersPopoverNoSubMobile": "",
+ "timeTravelersPopover": "",
+ "timeTravelersAlreadyOwned": "",
+ "mysticHourglassPopover": "",
+ "mysterySetNotFound": "",
+ "mysteryItemIsEmpty": "",
+ "mysteryItemOpened": "",
+ "mysterySet201402": "",
+ "mysterySet201403": "",
+ "mysterySet201404": "",
+ "mysterySet201405": "",
+ "mysterySet201406": "",
+ "mysterySet201407": "",
+ "mysterySet201408": "",
+ "mysterySet201409": "",
+ "mysterySet201410": "",
+ "mysterySet201411": "",
+ "mysterySet201412": "",
+ "mysterySet201501": "",
+ "mysterySet201502": "",
+ "mysterySet201503": "",
+ "mysterySet201504": "",
+ "mysterySet201505": "",
+ "mysterySet201506": "",
+ "mysterySet201507": "",
+ "mysterySet201508": "",
+ "mysterySet201509": "",
+ "mysterySet201510": "",
+ "mysterySet201511": "",
+ "mysterySet201512": "",
+ "mysterySet201601": "",
+ "mysterySet201602": "",
+ "mysterySet201603": "",
+ "mysterySet201604": "",
+ "mysterySet201605": "",
+ "mysterySet201606": "",
+ "mysterySet201607": "",
+ "mysterySet201608": "",
+ "mysterySet201609": "",
+ "mysterySet201610": "",
+ "mysterySet201611": "",
+ "mysterySet201612": "",
+ "mysterySet201701": "",
+ "mysterySet201702": "",
+ "mysterySet201703": "",
+ "mysterySet201704": "",
+ "mysterySet201705": "",
+ "mysterySet201706": "",
+ "mysterySet201707": "",
+ "mysterySet201708": "",
+ "mysterySet201709": "",
+ "mysterySet201710": "",
+ "mysterySet201711": "",
+ "mysterySet201712": "",
+ "mysterySet201801": "",
+ "mysterySet201802": "",
+ "mysterySet201803": "",
+ "mysterySet201804": "",
+ "mysterySet201805": "",
+ "mysterySet201806": "",
+ "mysterySet201807": "",
+ "mysterySet201808": "",
+ "mysterySet201809": "",
+ "mysterySet201810": "",
+ "mysterySet201811": "",
+ "mysterySet201812": "",
+ "mysterySet301404": "",
+ "mysterySet301405": "",
+ "mysterySet301703": "",
+ "mysterySet301704": "",
+ "mysterySetwondercon": "",
+ "subUpdateCard": "",
+ "subUpdateTitle": "",
+ "subUpdateDescription": "",
+ "notEnoughHourglasses": "",
+ "hourglassBuyEquipSetConfirm": "",
+ "hourglassBuyItemConfirm": "",
+ "petsAlreadyOwned": "",
+ "mountsAlreadyOwned": "",
+ "typeNotAllowedHourglass": "",
+ "petsNotAllowedHourglass": "",
+ "mountsNotAllowedHourglass": "",
+ "hourglassPurchase": "",
+ "hourglassPurchaseSet": "",
+ "missingUnsubscriptionCode": "",
+ "missingSubscription": "",
+ "missingSubscriptionCode": "",
+ "missingReceipt": "",
+ "cannotDeleteActiveAccount": "",
+ "paymentNotSuccessful": "",
+ "planNotActive": "",
+ "notAllowedHourglass": "",
+ "readCard": "",
+ "cardTypeRequired": "",
+ "cardTypeNotAllowed": "",
+ "invalidCoupon": "",
+ "couponUsed": "",
+ "couponCodeRequired": "",
"paypalCanceled": "Your subscription has been canceled",
- "earnGemsMonthly": "Earn up to **<%= cap %> Gems** per month",
- "receiveMysticHourglass": "Receive a Mystic Hourglass!",
- "receiveMysticHourglasses": "Receive **<%= amount %> Mystic Hourglasses**!",
- "everyMonth": "Every Month",
- "everyXMonths": "Every <%= interval %> Months",
- "everyYear": "Every Year",
- "choosePaymentMethod": "Choose your payment method",
- "subscribeSupportsDevs": "Subscribing supports the developers and helps keep Habitica running",
- "buyGemsSupportsDevs": "Purchasing Gems supports the developers and helps keep Habitica running",
- "support": "SUPPORT",
- "gemBenefitLeadin": "Gems allow you to buy fun extras for your account, including:",
- "gemBenefit1": "Unique and fashionable costumes for your avatar.",
- "gemBenefit2": "Backgrounds to immerse your avatar in the world of Habitica!",
- "gemBenefit3": "Exciting Quest chains that drop pet eggs.",
- "gemBenefit4": "Reset your avatar's Stat Points and change its Class.",
- "subscriptionBenefitLeadin": "Support Habitica by becoming a subscriber and you'll receive these useful benefits!",
- "subscriptionBenefit1": "Alexander the Merchant will sell you Gems, for 20 Gold each!",
- "subscriptionBenefit2": "Completed To-Dos and task history are available for longer.",
- "subscriptionBenefit3": "Discover more items in Habitica with a doubled daily drop cap.",
- "subscriptionBenefit4": "Unique cosmetic items for your avatar each month.",
- "subscriptionBenefit5": "Receive the exclusive Royal Purple Jackalope pet!",
- "subscriptionBenefit6": "Earn Mystic Hourglasses for use in the Time Travelers' Shop!",
- "haveCouponCode": "Do you have a coupon code?",
- "subscriptionAlreadySubscribedLeadIn": "Thanks for subscribing!",
- "subscriptionAlreadySubscribed1": "To see your subscription details and cancel, renew, or change your subscription, please go to User icon > Settings > Subscription.",
- "purchaseAll": "Purchase Set",
- "gemsPurchaseNote": "Subscribers can buy gems for gold in the Market! For easy access, you can also pin the gem to your Rewards column.",
- "gemsRemaining": "gems remaining",
- "notEnoughGemsToBuy": "You are unable to buy that amount of gems"
-}
\ No newline at end of file
+ "earnGemsMonthly": "",
+ "receiveMysticHourglass": "",
+ "receiveMysticHourglasses": "",
+ "everyMonth": "",
+ "everyXMonths": "",
+ "everyYear": "",
+ "choosePaymentMethod": "",
+ "subscribeSupportsDevs": "",
+ "buyGemsSupportsDevs": "",
+ "support": "",
+ "gemBenefitLeadin": "",
+ "gemBenefit1": "",
+ "gemBenefit2": "",
+ "gemBenefit3": "",
+ "gemBenefit4": "",
+ "subscriptionBenefitLeadin": "",
+ "subscriptionBenefit1": "",
+ "subscriptionBenefit2": "",
+ "subscriptionBenefit3": "",
+ "subscriptionBenefit4": "",
+ "subscriptionBenefit5": "",
+ "subscriptionBenefit6": "",
+ "haveCouponCode": "",
+ "subscriptionAlreadySubscribedLeadIn": "",
+ "subscriptionAlreadySubscribed1": "",
+ "purchaseAll": "",
+ "gemsPurchaseNote": "",
+ "gemsRemaining": "",
+ "notEnoughGemsToBuy": ""
+}
diff --git a/website/common/locales/eu/tasks.json b/website/common/locales/eu/tasks.json
index aa88d7025f..7fce216911 100755
--- a/website/common/locales/eu/tasks.json
+++ b/website/common/locales/eu/tasks.json
@@ -1,213 +1,213 @@
{
- "clearCompleted": "Delete Completed",
- "clearCompletedDescription": "Completed To-Dos are deleted after 30 days for non-subscribers and 90 days for subscribers.",
- "clearCompletedConfirm": "Are you sure you want to delete your completed To-Dos?",
- "sureDeleteCompletedTodos": "Are you sure you want to delete your completed To-Dos?",
- "lotOfToDos": "Your most recent 30 completed To-Dos are shown here. You can see older completed To-Dos from Data > Data Display Tool or Data > Export Data > User Data.",
- "deleteToDosExplanation": "If you click the button below, all of your completed To-Dos and archived To-Dos will be permanently deleted, except for To-Dos from active challenges and Group Plans. Export them first if you want to keep a record of them.",
- "addMultipleTip": "Tip: To add multiple <%= taskType %>, separate each one using a line break (Shift + Enter) and then press \"Enter.\"",
- "addsingle": "Add Single",
- "addATask": "Add a <%= type %>",
- "editATask": "Edit a <%= type %>",
- "createTask": "Create <%= type %>",
- "addTaskToUser": "Add Task",
- "scheduled": "Scheduled",
- "theseAreYourTasks": "These are your <%= taskType %>",
- "habit": "Habit",
- "habits": "Habits",
- "newHabit": "New Habit",
- "newHabitBulk": "New Habits (one per line)",
- "habitsDesc": "Habits don't have a rigid schedule. You can check them off multiple times per day.",
- "positive": "Positive",
- "negative": "Negative",
- "yellowred": "Weak",
- "greenblue": "Strong",
- "edit": "Edit",
- "save": "Save",
- "addChecklist": "Add Checklist",
- "checklist": "Checklist",
- "checklistText": "Break a task into smaller pieces! Checklists increase the Experience and Gold gained from a To-Do, and reduce the damage caused by a Daily.",
- "newChecklistItem": "New checklist item",
- "expandChecklist": "Expand Checklist",
- "collapseChecklist": "Collapse Checklist",
- "text": "Title",
- "extraNotes": "Extra Notes",
- "notes": "Notes",
- "direction/Actions": "Direction/Actions",
- "advancedSettings": "Advanced Settings",
- "taskAlias": "Task Alias",
- "taskAliasPopover": "This task alias can be used when integrating with 3rd party integrations. Only dashes, underscores, and alphanumeric characters are supported. The task alias must be unique among all your tasks.",
- "taskAliasPlaceholder": "your-task-alias-here",
- "taskAliasPopoverWarning": "WARNING: Changing this value will break any 3rd party integrations that rely on the task alias.",
- "difficulty": "Difficulty",
- "difficultyHelp": "Difficulty describes how challenging a Habit, Daily, or To-Do is for you to complete. A higher difficulty results in greater rewards when a Task is completed, but also greater damage when a Daily is missed or a negative Habit is clicked.",
- "trivial": "Trivial",
- "easy": "Easy",
- "medium": "Medium",
- "hard": "Hard",
- "attributes": "Stats",
- "attributeAllocation": "Stat Allocation",
- "attributeAllocationHelp": "Stat allocation is an option that provides methods for Habitica to automatically assign an earned Stat Point to a Stat immediately upon level-up.
You can set your Automatic Allocation method to Task Based in the Stats section of your profile.",
- "progress": "Progress",
- "daily": "Daily",
- "dailies": "Dailies",
- "newDaily": "New Daily",
- "newDailyBulk": "New Dailies (one per line)",
- "dailysDesc": "Dailies repeat on a regular basis. Choose the schedule that works best for you!",
- "streakCounter": "Streak Counter",
- "repeat": "Repeat",
- "repeats": "Repeats",
- "repeatEvery": "Repeat Every",
- "repeatOn": "Repeat On",
- "repeatHelpTitle": "How often should this task be repeated?",
- "dailyRepeatHelpContent": "This task will be due every X days. You can set that value below.",
- "weeklyRepeatHelpContent": "This task will be due on the highlighted days below. Click on a day to activate/deactivate it.",
- "repeatDays": "Every X Days",
- "repeatWeek": "On Certain Days of the Week",
- "day": "Day",
- "days": "Days",
- "restoreStreak": "Adjust Streak",
- "resetStreak": "Reset Streak",
- "todo": "To-Do",
- "todos": "To-Dos",
- "newTodo": "New To-Do",
- "newTodoBulk": "New To-Dos (one per line)",
- "todosDesc": "To-Dos need to be completed once. Add checklists to your To-Dos to increase their value.",
- "dueDate": "Due Date",
- "remaining": "Active",
- "complete": "Done",
- "complete2": "Complete",
- "dated": "Dated",
- "today": "Today",
- "dueIn": "Due <%= dueIn %>",
- "due": "Due",
- "notDue": "Not Due",
- "grey": "Grey",
- "score": "Score",
- "reward": "Reward",
- "rewards": "Rewards",
- "rewardsDesc": "Rewards are a great way to use Habitica and complete your tasks. Try adding a few today!",
- "ingamerewards": "Equipment & Skills",
- "gold": "Gold",
- "silver": "Silver (100 silver = 1 gold)",
- "newReward": "New Reward",
- "newRewardBulk": "New Rewards (one per line)",
- "price": "Price",
- "tags": "Tags",
- "editTags": "Edit",
- "newTag": "New Tag",
- "clearTags": "Clear",
- "hideTags": "Hide",
- "showTags": "Show",
- "editTags2": "Edit Tags",
- "toRequired": "You must supply a \"to\" property",
- "startDate": "Start Date",
- "startDateHelpTitle": "When should this task start?",
- "startDateHelp": "Set the date for which this task takes effect. Will not be due on earlier days.",
- "streaks": "Streak Achievements",
- "streakName": "<%= count %> Streak Achievements",
- "streakText": "Has performed <%= count %> 21-day streaks on Dailies",
- "streakSingular": "Streaker",
- "streakSingularText": "Has performed a 21-day streak on a Daily",
- "perfectName": "<%= count %> Perfect Days",
- "perfectText": "Completed all active Dailies on <%= count %> days. With this achievement you get a +level/2 buff to all Stats for the next day. Levels greater than 100 don't have any additional effects on buffs.",
- "perfectSingular": "Perfect Day",
- "perfectSingularText": "Completed all active Dailies in one day. With this achievement you get a +level/2 buff to all Stats for the next day. Levels greater than 100 don't have any additional effects on buffs.",
- "streakerAchievement": "You have attained the \"Streaker\" Achievement! The 21-day mark is a milestone for habit formation. You can continue to stack this Achievement for every additional 21 days, on this Daily or any other!",
- "fortifyName": "Fortify Potion",
- "fortifyPop": "Return all tasks to neutral value (yellow color), and restore all lost Health.",
- "fortify": "Fortify",
- "fortifyText": "Fortify will return all your tasks, except challenge tasks, to a neutral (yellow) state, as if you'd just added them, and top your Health off to full. This is great if all your red tasks are making the game too hard, or all your blue tasks are making the game too easy. If starting fresh sounds much more motivating, spend the Gems and catch a reprieve!",
- "confirmFortify": "Are you sure?",
- "fortifyComplete": "Fortify complete!",
- "deleteTask": "Delete this Task",
- "sureDelete": "Are you sure you want to delete this task?",
- "streakCoins": "Streak Bonus!",
- "taskToTop": "To top",
- "taskToBottom": "To bottom",
- "emptyTask": "Enter the task's title first.",
- "dailiesRestingInInn": "You're Resting in the Inn! Your Dailies will NOT hurt you tonight, but they WILL still refresh every day. If you're in a quest, you won't deal damage/collect items until you check out of the Inn, but you can still be injured by a Boss if your Party mates skip their own Dailies.",
- "habitHelp1": "Good Habits are things that you do often. They award Gold and Experience every time you click the <%= plusIcon %>.",
- "habitHelp2": "Bad Habits are things you want to avoid doing. They remove Health every time you click the <%= minusIcon %>.",
- "habitHelp3": "For inspiration, check out these sample Habits!",
- "newbieGuild": "More questions? Ask in the <%= linkStart %>Habitica Help guild<%= linkEnd %>!",
- "dailyHelp1": "Dailies repeat <%= emphasisStart %>every day<%= emphasisEnd %> that they are active. Click the <%= pencilIcon %> to change the days a Daily is active.",
- "dailyHelp2": "If you don't complete active Dailies, you lose Health when your day rolls over.",
- "dailyHelp3": "Dailies turn <%= emphasisStart %>redder<%= emphasisEnd %> when you miss them, and <%= emphasisStart %>bluer<%= emphasisEnd %> when you complete them. The redder the Daily, the more it will reward you... or hurt you.",
- "dailyHelp4": "To change when your day rolls over, go to <%= linkStart %> Settings > Site<%= linkEnd %> > Custom Day Start.",
- "dailyHelp5": "For inspiration, check out these sample Dailies!",
- "toDoHelp1": "To-Dos start yellow, and get redder (more valuable) the longer it takes to complete them.",
- "toDoHelp2": "To-Dos never hurt you! They only award Gold and Experience.",
- "toDoHelp3": "Breaking a To-Do down into a checklist of smaller items will make it less scary, and will increase your points!",
- "toDoHelp4": "For inspiration, check out these sample To-Dos!",
- "rewardHelp1": "The Equipment you buy for your avatar is stored in <%= linkStart %>Inventory > Equipment<%= linkEnd %>.",
- "rewardHelp2": "Equipment affects your Stats (<%= linkStart %>Avatar > Stats<%= linkEnd %>).",
- "rewardHelp3": "Special equipment will appear here during World Events.",
- "rewardHelp4": "Don't be afraid to set custom Rewards! Check out some samples here.",
- "clickForHelp": "Click for help",
- "taskAliasAlreadyUsed": "Task alias already used on another task.",
- "taskNotFound": "Task not found.",
- "invalidTaskType": "Task type must be one of \"habit\", \"daily\", \"todo\", \"reward\".",
- "invalidTasksType": "Task type must be one of \"habits\", \"dailys\", \"todos\", \"rewards\".",
- "invalidTasksTypeExtra": "Task type must be one of \"habits\", \"dailys\", \"todos\", \"rewards\", \"completedTodos\".",
- "cantDeleteChallengeTasks": "A task belonging to a challenge can't be deleted.",
- "checklistOnlyDailyTodo": "Checklists are supported only on Dailies and To-Dos",
- "checklistItemNotFound": "No checklist item was found with given id.",
- "itemIdRequired": "\"itemId\" must be a valid UUID.",
- "tagNotFound": "No tag item was found with given id.",
- "tagIdRequired": "\"tagId\" must be a valid UUID corresponding to a tag belonging to the user.",
- "positionRequired": "\"position\" is required and must be a number.",
- "cantMoveCompletedTodo": "Can't move a completed todo.",
- "directionUpDown": "\"direction\" is required and must be 'up' or 'down'.",
- "alreadyTagged": "The task is already tagged with given tag.",
- "strengthExample": "Relating to exercise and activity",
- "intelligenceExample": "Relating to academic or mentally challenging pursuits",
- "perceptionExample": "Relating to work or financial tasks",
- "constitutionExample": "Relating to health, wellness, and social interaction",
- "counterPeriod": "Counter Resets Every",
- "counterPeriodDay": "Day",
- "counterPeriodWeek": "Week",
- "counterPeriodMonth": "Month",
- "habitCounter": "Counter (Resets <%= frequency %>)",
- "habitCounterUp": "Positive Counter (Resets <%= frequency %>)",
- "habitCounterDown": "Negative Counter (Resets <%= frequency %>)",
- "taskRequiresApproval": "This task must be approved before you can complete it. Approval has already been requested",
- "taskApprovalHasBeenRequested": "Approval has been requested",
- "taskApprovalWasNotRequested": "Only a task waiting for approval can be marked as needing more work",
- "approvals": "Approvals",
- "approvalRequired": "Needs Approval",
- "repeatZero": "Daily is never due",
- "repeatType": "Repeat Type",
- "repeatTypeHelpTitle": "What kind of repeat is this?",
- "repeatTypeHelp": "Select \"Daily\" if you want this task to repeat every day or every third day, etc. Select \"Weekly\"if you want it to repeat on certain days of the week. If you select \"Monthly\" or \"Yearly\", adjust the Start Date to control which day of the month or year the task will be due on.",
- "weekly": "Weekly",
- "monthly": "Monthly",
- "yearly": "Yearly",
- "onDays": "On Days",
- "summary": "Summary",
- "repeatsOn": "Repeats On",
- "dayOfWeek": "Day of the Week",
- "dayOfMonth": "Day of the Month",
- "month": "Month",
- "months": "Months",
- "week": "Week",
- "weeks": "Weeks",
- "year": "Year",
- "years": "Years",
- "groupTasksByChallenge": "Group tasks by challenge title",
- "taskNotes": "Task Notes",
- "monthlyRepeatHelpContent": "This task will be due every X months",
- "yearlyRepeatHelpContent": "This task will be due every X years",
- "resets": "Resets",
- "summaryStart": "Repeats <%= frequency %> every <%= everyX %> <%= frequencyPlural %>",
- "nextDue": "Next Due Dates",
- "checkOffYesterDailies": "Check off any Dailies you did yesterday:",
- "yesterDailiesTitle": "You left these Dailies unchecked yesterday! Do you want to check off any of them now?",
- "yesterDailiesCallToAction": "Start My New Day!",
- "yesterDailiesOptionTitle": "Confirm that this Daily wasn't done before applying damage",
- "yesterDailiesDescription": "If this setting is applied, Habitica will ask you if you meant to leave the Daily undone before calculating and applying damage to your avatar. This can protect you against unintentional damage.",
- "repeatDayError": "Please ensure that you have at least one day of the week selected.",
- "searchTasks": "Search titles and descriptions...",
- "sessionOutdated": "Your session is outdated. Please refresh or sync.",
- "errorTemporaryItem": "This item is temporary and cannot be pinned."
-}
\ No newline at end of file
+ "clearCompleted": "",
+ "clearCompletedDescription": "",
+ "clearCompletedConfirm": "",
+ "sureDeleteCompletedTodos": "",
+ "lotOfToDos": "",
+ "deleteToDosExplanation": "",
+ "addMultipleTip": "",
+ "addsingle": "",
+ "addATask": "",
+ "editATask": "",
+ "createTask": "",
+ "addTaskToUser": "",
+ "scheduled": "",
+ "theseAreYourTasks": "",
+ "habit": "",
+ "habits": "",
+ "newHabit": "",
+ "newHabitBulk": "",
+ "habitsDesc": "",
+ "positive": "",
+ "negative": "",
+ "yellowred": "",
+ "greenblue": "",
+ "edit": "",
+ "save": "",
+ "addChecklist": "",
+ "checklist": "",
+ "checklistText": "",
+ "newChecklistItem": "",
+ "expandChecklist": "",
+ "collapseChecklist": "",
+ "text": "",
+ "extraNotes": "",
+ "notes": "",
+ "direction/Actions": "",
+ "advancedSettings": "",
+ "taskAlias": "",
+ "taskAliasPopover": "",
+ "taskAliasPlaceholder": "",
+ "taskAliasPopoverWarning": "",
+ "difficulty": "",
+ "difficultyHelp": "",
+ "trivial": "",
+ "easy": "",
+ "medium": "",
+ "hard": "",
+ "attributes": "",
+ "attributeAllocation": "",
+ "attributeAllocationHelp": "",
+ "progress": "",
+ "daily": "",
+ "dailies": "",
+ "newDaily": "",
+ "newDailyBulk": "",
+ "dailysDesc": "",
+ "streakCounter": "",
+ "repeat": "",
+ "repeats": "",
+ "repeatEvery": "",
+ "repeatOn": "",
+ "repeatHelpTitle": "",
+ "dailyRepeatHelpContent": "",
+ "weeklyRepeatHelpContent": "",
+ "repeatDays": "",
+ "repeatWeek": "",
+ "day": "",
+ "days": "",
+ "restoreStreak": "",
+ "resetStreak": "",
+ "todo": "",
+ "todos": "",
+ "newTodo": "",
+ "newTodoBulk": "",
+ "todosDesc": "",
+ "dueDate": "",
+ "remaining": "",
+ "complete": "",
+ "complete2": "",
+ "dated": "",
+ "today": "",
+ "dueIn": "",
+ "due": "",
+ "notDue": "",
+ "grey": "",
+ "score": "",
+ "reward": "",
+ "rewards": "",
+ "rewardsDesc": "",
+ "ingamerewards": "",
+ "gold": "",
+ "silver": "",
+ "newReward": "",
+ "newRewardBulk": "",
+ "price": "",
+ "tags": "",
+ "editTags": "",
+ "newTag": "",
+ "clearTags": "",
+ "hideTags": "",
+ "showTags": "",
+ "editTags2": "",
+ "toRequired": "",
+ "startDate": "",
+ "startDateHelpTitle": "",
+ "startDateHelp": "",
+ "streaks": "",
+ "streakName": "",
+ "streakText": "",
+ "streakSingular": "",
+ "streakSingularText": "",
+ "perfectName": "",
+ "perfectText": "",
+ "perfectSingular": "",
+ "perfectSingularText": "",
+ "streakerAchievement": "",
+ "fortifyName": "",
+ "fortifyPop": "",
+ "fortify": "",
+ "fortifyText": "",
+ "confirmFortify": "",
+ "fortifyComplete": "",
+ "deleteTask": "",
+ "sureDelete": "",
+ "streakCoins": "",
+ "taskToTop": "",
+ "taskToBottom": "",
+ "emptyTask": "",
+ "dailiesRestingInInn": "",
+ "habitHelp1": "",
+ "habitHelp2": "",
+ "habitHelp3": "",
+ "newbieGuild": "",
+ "dailyHelp1": "",
+ "dailyHelp2": "",
+ "dailyHelp3": "",
+ "dailyHelp4": "",
+ "dailyHelp5": "",
+ "toDoHelp1": "",
+ "toDoHelp2": "",
+ "toDoHelp3": "",
+ "toDoHelp4": "",
+ "rewardHelp1": "",
+ "rewardHelp2": "",
+ "rewardHelp3": "",
+ "rewardHelp4": "",
+ "clickForHelp": "",
+ "taskAliasAlreadyUsed": "",
+ "taskNotFound": "",
+ "invalidTaskType": "",
+ "invalidTasksType": "",
+ "invalidTasksTypeExtra": "",
+ "cantDeleteChallengeTasks": "",
+ "checklistOnlyDailyTodo": "",
+ "checklistItemNotFound": "",
+ "itemIdRequired": "",
+ "tagNotFound": "",
+ "tagIdRequired": "",
+ "positionRequired": "",
+ "cantMoveCompletedTodo": "",
+ "directionUpDown": "",
+ "alreadyTagged": "",
+ "strengthExample": "",
+ "intelligenceExample": "",
+ "perceptionExample": "",
+ "constitutionExample": "",
+ "counterPeriod": "",
+ "counterPeriodDay": "",
+ "counterPeriodWeek": "",
+ "counterPeriodMonth": "",
+ "habitCounter": "",
+ "habitCounterUp": "",
+ "habitCounterDown": "",
+ "taskRequiresApproval": "",
+ "taskApprovalHasBeenRequested": "",
+ "taskApprovalWasNotRequested": "",
+ "approvals": "",
+ "approvalRequired": "",
+ "repeatZero": "",
+ "repeatType": "",
+ "repeatTypeHelpTitle": "",
+ "repeatTypeHelp": "",
+ "weekly": "",
+ "monthly": "",
+ "yearly": "",
+ "onDays": "",
+ "summary": "",
+ "repeatsOn": "",
+ "dayOfWeek": "",
+ "dayOfMonth": "",
+ "month": "",
+ "months": "",
+ "week": "",
+ "weeks": "",
+ "year": "",
+ "years": "",
+ "groupTasksByChallenge": "",
+ "taskNotes": "",
+ "monthlyRepeatHelpContent": "",
+ "yearlyRepeatHelpContent": "",
+ "resets": "",
+ "summaryStart": "",
+ "nextDue": "",
+ "checkOffYesterDailies": "",
+ "yesterDailiesTitle": "",
+ "yesterDailiesCallToAction": "",
+ "yesterDailiesOptionTitle": "",
+ "yesterDailiesDescription": "",
+ "repeatDayError": "",
+ "searchTasks": "",
+ "sessionOutdated": "",
+ "errorTemporaryItem": ""
+}
diff --git a/website/common/locales/fi/challenge.json b/website/common/locales/fi/challenge.json
index 1f506d04a8..a4231c6289 100755
--- a/website/common/locales/fi/challenge.json
+++ b/website/common/locales/fi/challenge.json
@@ -69,9 +69,9 @@
"prizeValue": "<%= gemcount %> <%= gemicon %> palkinto",
"clone": "Kopioi",
"challengeNotEnoughGems": "Sinulla ei ole tarpeeksi jalokiviä tämän haasteen luomiseen.",
- "noPermissionEditChallenge": "Sinulla ei ole oikeutta muokata tätä haastetta.",
- "noPermissionDeleteChallenge": "Sinulla ei ole oikeutta poistaa tätä haastetta.",
- "noPermissionCloseChallenge": "Sinulla ei ole oikeutta sulkea tätä haastetta.",
+ "noPermissionEditChallenge": "Sinulla ei ole oikeutta muokata tätä haastetta",
+ "noPermissionDeleteChallenge": "Sinulla ei ole oikeutta poistaa tätä haastetta",
+ "noPermissionCloseChallenge": "Sinulla ei ole oikeutta sulkea tätä haastetta",
"congratulations": "Onnea!",
"hurray": "Hurraa!",
"noChallengeOwner": "ei omistajaa",
@@ -80,8 +80,8 @@
"onlyGroupLeaderChal": "Ainoastaan ryhmän johtaja voi luoda haasteita",
"tavChalsMinPrize": "Julkisissa haasteissa palkinnon tulee olla vähintään 1 jalokivi.",
"cantAfford": "Sinulla ei ole varaa tähän palkintoon. Osta lisää jalokiviä tai pienennä palkintosummaa.",
- "challengeIdRequired": "\"challengeId\" on oltava pätevä käyttäjä-ID",
- "winnerIdRequired": "\"winnerId\" on oltava pätevä käyttäjä-ID",
+ "challengeIdRequired": "\"challengeId\" on oltava pätevä käyttäjä-ID.",
+ "winnerIdRequired": "\"winnerId\" on oltava pätevä käyttäjä-ID.",
"challengeNotFound": "Haastetta ei löydy tai sinulla ei ole pääsyoikeutta.",
"onlyLeaderDeleteChal": "Ainoastaan haasteen johtaja voi poistaa sen.",
"onlyLeaderUpdateChal": "Ainoastaan haasteen johtaja voi päivittää sen.",
@@ -136,4 +136,4 @@
"selectMember": "Valitse jäsen",
"confirmKeepChallengeTasks": "Haluatko pitää haasteen tehtävät?",
"selectParticipant": "Valitse osallistuja"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/fi/gear.json b/website/common/locales/fi/gear.json
index dc462281ba..afa6497c99 100755
--- a/website/common/locales/fi/gear.json
+++ b/website/common/locales/fi/gear.json
@@ -1741,5 +1741,6 @@
"eyewearArmoirePlagueDoctorMaskNotes": "An authentic mask worn by the doctors who battle the Plague of Procrastination. Increases Constitution and Intelligence by <%= attrs %> each. Enchanted Armoire: Plague Doctor Set (Item 2 of 3).",
"eyewearArmoireGoofyGlassesText": "Goofy Glasses",
"eyewearArmoireGoofyGlassesNotes": "Perfect for going incognito or just making your partymates giggle. Increases Perception by <%= per %>. Enchanted Armoire: Independent Item.",
- "twoHandedItem": "Two-handed item."
-}
\ No newline at end of file
+ "twoHandedItem": "Two-handed item.",
+ "weaponSpecialKS2019Text": "Myyttinen Griippiglaive"
+}
diff --git a/website/common/locales/fi/subscriber.json b/website/common/locales/fi/subscriber.json
index e7ed503094..815a15a780 100755
--- a/website/common/locales/fi/subscriber.json
+++ b/website/common/locales/fi/subscriber.json
@@ -55,7 +55,7 @@
"customDomain": "Mukautettu domain",
"customDomainText": "We can optionally give you your own domain for the installation.",
"maxPlayers": "Maksimiosallistujamäärä",
- "maxPlayersText": "Suurin mahdollinen pelaajamäärä yksityisessä yhdistyksessäsi",
+ "maxPlayersText": "Suurin mahdollinen pelaajamäärä yksityisessä yhdistyksessäsi.",
"unlimited": "Rajoittamaton",
"priSupport": "Priority Support On Tickets & Hosting",
"priSupportText": "First to be provided for with support.",
@@ -160,13 +160,13 @@
"subUpdateCard": "Päivityskortti",
"subUpdateTitle": "Päivitä",
"subUpdateDescription": "Update the card to be charged.",
- "notEnoughHourglasses": "Sinulla ei ole tarpeeksi Mystisiä tiimalaseja",
+ "notEnoughHourglasses": "Sinulla ei ole tarpeeksi Mystisiä tiimalaseja.",
"hourglassBuyEquipSetConfirm": "Osta koko paketti 1 Mystisellä tiimalasilla?",
"hourglassBuyItemConfirm": "Osta esine 1 Mystisellä tiimalasilla?",
"petsAlreadyOwned": "Omistat jo tämän lemmikin.",
"mountsAlreadyOwned": "Omistat jo tämän ratsun.",
"typeNotAllowedHourglass": "Item type not supported for purchase with Mystic Hourglass. Allowed types: <%= allowedTypes %>",
- "petsNotAllowedHourglass": "Lemmikki ei ole ostettavissa Mystisillä tiimalaseilla",
+ "petsNotAllowedHourglass": "Lemmikki ei ole ostettavissa Mystisillä tiimalaseilla.",
"mountsNotAllowedHourglass": "Ratsu ei ole ostettavissa Mystisillä tiimalaseilla.",
"hourglassPurchase": "Purchased an item using a Mystic Hourglass!",
"hourglassPurchaseSet": "Purchased an item set using a Mystic Hourglass!",
@@ -214,4 +214,4 @@
"gemsPurchaseNote": "Subscribers can buy gems for gold in the Market! For easy access, you can also pin the gem to your Rewards column.",
"gemsRemaining": "gems remaining",
"notEnoughGemsToBuy": "You are unable to buy that amount of gems"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/fr/achievements.json b/website/common/locales/fr/achievements.json
index 8c621dac24..b215b39357 100644
--- a/website/common/locales/fr/achievements.json
+++ b/website/common/locales/fr/achievements.json
@@ -24,5 +24,15 @@
"achievementJustAddWater": "Ajoutez un peu d'eau",
"achievementMindOverMatterText": "A achevé les quêtes des pierres, des boules de gomme, et des pelotes.",
"achievementMindOverMatter": "L'esprit sur la matière",
- "achievementLostMasterclasserModalText": "Vous avez achevé les 16 quêtes de la série de quêtes de la maîtresse des classes, et résolu le mystère de la maîtresse des classes oubliée !"
+ "achievementLostMasterclasserModalText": "Vous avez achevé les 16 quêtes de la série de quêtes de la maîtresse des classes, et résolu le mystère de la maîtresse des classes oubliée !",
+ "achievementKickstarter2019Text": "A soutenu le projet Kickstarter de pin's en 2019",
+ "achievementKickstarter2019": "Soutien du Kickstarter de pin's",
+ "achievementUndeadUndertakerModalText": "Vous avez dompté toutes les montures zombies !",
+ "achievementUndeadUndertakerText": "A dompté toutes les montures zombies.",
+ "achievementUndeadUndertaker": "Le croque-mort-vivant",
+ "achievementMonsterMagusModalText": "Vous avez collecté tous les familiers zombies !",
+ "achievementMonsterMagusText": "A collecté tous les familiers zombies.",
+ "achievementMonsterMagus": "La foire aux monstres",
+ "achievementPartyOn": "Votre équipe a grandi jusqu'à 4 membres !",
+ "achievementPartyUp": "Vous avez collaboré avec un membre de l'équipe !"
}
diff --git a/website/common/locales/fr/backgrounds.json b/website/common/locales/fr/backgrounds.json
index dd88d72979..803d260626 100644
--- a/website/common/locales/fr/backgrounds.json
+++ b/website/common/locales/fr/backgrounds.json
@@ -464,5 +464,12 @@
"backgroundInAnAncientTombNotes": "Bravez les mystères d'un ancien tombeau.",
"backgroundInAnAncientTombText": "Ancien tombeau",
"backgroundAutumnFlowerGardenNotes": "Profitez de la chaleur d'un jardin fleuri d'automne.",
- "backgroundAutumnFlowerGardenText": "Jardin fleuri d'automne"
+ "backgroundAutumnFlowerGardenText": "Jardin fleuri d'automne",
+ "backgroundMonsterMakersWorkshopNotes": "Expérimentez les sciences interdites dans l'atelier d'un fabriquant de monstres.",
+ "backgroundMonsterMakersWorkshopText": "Atelier du fabriquant de monstres",
+ "backgroundPumpkinCarriageNotes": "Embarquez dans une carriole citrouille enchantée avant les douze coups de minuit.",
+ "backgroundPumpkinCarriageText": "Carriole citrouille",
+ "backgroundFoggyMoorNotes": "Faites attention à où vous mettez les pieds en traversant une tourbière brumeuse.",
+ "backgroundFoggyMoorText": "Tourbière brumeuse",
+ "backgrounds102019": "Ensemble 65 : sorti en octobre 2019"
}
diff --git a/website/common/locales/fr/character.json b/website/common/locales/fr/character.json
index a1edabef1d..8e03a18035 100644
--- a/website/common/locales/fr/character.json
+++ b/website/common/locales/fr/character.json
@@ -76,7 +76,7 @@
"useCostume": "Utiliser un costume",
"useCostumeInfo1": "Cliquez sur \"Utiliser un costume\" pour mettre des vêtements à votre avatar sans modifier les attributs de votre tenue de combat ! Vous pouvez donc vous armer des meilleurs attributs à gauche et déguiser votre avatar avec l'équipement à droite.",
"useCostumeInfo2": "Lorsque vous cliquez sur \"Utiliser un costume\", votre avatar aura l'air plutôt basique... mais pas d'inquiétude ! Si vous regardez à gauche, vous verrez que votre tenue de combat est toujours active. Ensuite, vous pouvez faire jouer votre imagination ! Tout ce que vous activez à droite ne modifiera pas vos attributs mais peut vous donner un look d'enfer. Essayez différentes associations en mélangeant les ensembles et en accordant votre costume avec vos familiers, montures et arrière-plans.
Vous avez d'autres questions ? Allez voir la page sur les costumes sur le wiki. Vous avez trouvé l'ensemble parfait ? Exhibez-le sur la guilde du festival des costumes ou fanfaronnez à la taverne !",
- "costumePopoverText": "Sélectionnez \"Utiliser un costume\" pour équiper votre avatar sans modifier les atrributs de votre tenue de combat ! Cela signifie que vous pouvez habiller votre avatar de n'importe quelle tenue que vous aimez, tout en conservant votre meilleure tenue de combat.",
+ "costumePopoverText": "Sélectionnez \"Utiliser un costume\" pour équiper votre avatar sans modifier les attributs de votre tenue de combat ! Cela signifie que vous pouvez habiller votre avatar de n'importe quelle tenue que vous aimez, tout en conservant votre meilleure tenue de combat.",
"autoEquipPopoverText": "Sélectionnez cette option pour vous équiper automatiquement d'une tenue dès que vous l'achetez.",
"costumeDisabled": "Vous avez désactivé l'utilisation du costume.",
"gearAchievement": "Vous avez gagné le succès \"Armé jusqu'aux dents\" pour avoir atteint le niveau maximal de l'ensemble d'équipement de votre classe ! Vous avez acquis les ensembles complets suivants :",
@@ -94,34 +94,34 @@
"mana": "Mana",
"hp": "Vie",
"mp": "PM",
- "xp": "XP",
+ "xp": "Exp",
"health": "Santé",
- "allocateStr": "Points alloués en Force :",
- "allocateStrPop": "Ajouter un point à votre attribut de Force",
- "allocateCon": "Points alloués en Constitution :",
- "allocateConPop": "Ajouter un point à votre attribut de Constitution",
- "allocatePer": "Points alloués en Perception :",
- "allocatePerPop": "Ajouter un point à votre attribut de Perception",
- "allocateInt": "Points alloués en Intelligence :",
- "allocateIntPop": "Ajouter un point à votre attribut d'Intelligence",
+ "allocateStr": "Points alloués en force :",
+ "allocateStrPop": "Ajouter un point à votre attribut de force",
+ "allocateCon": "Points alloués en constitution :",
+ "allocateConPop": "Ajouter un point à votre attribut de constitution",
+ "allocatePer": "Points alloués en perception :",
+ "allocatePerPop": "Ajouter un point à votre attribut de perception",
+ "allocateInt": "Points alloués en intelligence :",
+ "allocateIntPop": "Ajouter un point à votre attribut d'intelligence",
"noMoreAllocate": "Maintenant que vous avez atteint le niveau 100, vous ne gagnerez plus de points d'attribut. Vous pouvez continuer à progresser, ou commencer une nouvelle aventure au niveau 1 en utilisant l'orbe de renaissance, maintenant disponible gratuitement au marché.",
"stats": "Attributs",
"achievs": "Succès",
"strength": "Force",
"strText": "La force augmente votre chance de réaliser un \"coup critique\" aléatoire et d'obtenir l'or, l'expérience, et le butin qui vont avec. Elle aide également à infliger des dégâts aux boss.",
"constitution": "Constitution",
- "conText": "La Constitution réduit les dommages infligés par les habitudes négatives et les tâches Quotidiennes non complétées.",
+ "conText": "La constitution réduit les dommages infligés par les habitudes négatives et les tâches quotidiennes non complétées.",
"perception": "Perception",
- "perText": "La Perception augmente les gains en or et, une fois que vous avez débloqué le marché, augmente les chances de trouver des objets en complétant des tâches.",
+ "perText": "La perception augmente les gains en or et, une fois que vous avez débloqué le marché, augmente les chances de trouver des objets en complétant des tâches.",
"intelligence": "Intelligence",
- "intText": "L'Intelligence augmente la quantité d'expérience gagnée et, une fois les classes débloquées, détermine le maximum de mana disponible pour les compétences de classes.",
+ "intText": "L'intelligence augmente la quantité d'expérience gagnée et, une fois les classes débloquées, détermine le maximum de mana disponible pour les compétences de classes.",
"levelBonus": "Bonus de niveau",
"levelBonusText": "Chaque attribut reçoit un bonus égal à la moitié de (votre niveau moins 1).",
"allocatedPoints": "Points alloués",
- "allocatedPointsText": "Points d'attribut que vous avez gagnés et assignés. Assignez des points en utilisant la colonne Caractéristiques.",
+ "allocatedPointsText": "Points d'attribut que vous avez gagnés et assignés. Assignez des points en utilisant la colonne caractéristiques.",
"allocated": "Alloué(s)",
"buffs": "Bonus",
- "buffsText": "Bonus d'attributs temporairement alloué par des compétences ou des succès. Ils vous sont retirés à la fin de votre journée. Les compétences que vous avez débloquées apparaissent dans la colonne Récompenses de votre page de tâches.",
+ "buffsText": "Bonus d'attributs temporairement alloué par des compétences ou des succès. Ils vous sont retirés à la fin de votre journée. Les compétences que vous avez débloquées apparaissent dans la colonne récompenses de votre page de tâches.",
"characterBuild": "Développement du personnage",
"class": "Classe",
"experience": "Expérience",
@@ -134,7 +134,7 @@
"changeClass": "Changer de classe et rembourser les points d'attribut",
"lvl10ChangeClass": "Vous devez être au moins au niveau 10 pour changer de classe.",
"changeClassConfirmCost": "Confirmez-vous vouloir changer de classe pour 3 gemmes ?",
- "invalidClass": "Classe invalide. Veuillez préciser 'warrior,' 'rogue,' 'wizard,' ou 'healer'.",
+ "invalidClass": "Classe invalide. Veuillez préciser 'guerrier,' 'voleur,' 'mage,' ou 'guérisseur'.",
"levelPopover": "Chaque niveau vous donne un point à assigner à un attribut de votre choix. Vous pouvez le faire manuellement, ou laisser le jeu décider pour vous en utilisant l'une des options d'attribution automatique.",
"unallocated": "Points d'attribut non alloués",
"haveUnallocated": "Vous avez <%= points %> point(s) d'attribut non alloué(s)",
@@ -145,14 +145,14 @@
"classAllocation": "Distribue les points en fonction de la classe",
"classAllocationPop": "Affecte plus de points aux attributs importants pour votre classe.",
"taskAllocation": "Distribuer les points en fonction des catégories des tâches",
- "taskAllocationPop": "Alloue les points en fonction des catégories Force, Intelligence, Constitution et Perception associées aux tâches que vous complétez.",
+ "taskAllocationPop": "Alloue les points en fonction des catégories force, intelligence, constitution et perception associées aux tâches que vous complétez.",
"distributePoints": "Distribuer les points non-alloués",
"distributePointsPop": "Affecte tous vos points d'attribut non alloués selon le choix d'attribution sélectionné.",
- "warriorText": "Les Guerriers réalisent des \"coups critiques\" plus nombreux et plus efficaces qui augmentent aléatoirement l'or et l'expérience obtenus ainsi que les chances de trouver du butin en complétant une tâche. Ils infligent aussi des dommages lourds aux boss. Jouez un Guerrier si des récompenses imprévisibles du genre jackpot vous motivent ou si vous voulez distribuer des coups pendant les quêtes !",
- "wizardText": "Les Mages apprennent vite, gagnant de l'expérience et des niveaux plus rapidement que les autres classes. Ils et elles ont aussi de grandes réserves de mana à disposition pour utiliser leurs capacités spéciales. Jouez en tant que Mage si vous appréciez le côté tactique d'Habitica, ou si vous vous réjouissez à l'idée de monter de niveau et de débloquer de nouvelles fonctionnalités !",
- "mageText": "Les Mages apprennent rapidement, et gagnent de l'expérience et des niveaux plus rapidement que les autres classes. Ils disposent également de beaucoup de mana pour utiliser des compétences spéciales. Jouez un Mage si vous aimez les aspects tactiques du jeu, ou si gagner des niveaux et débloquer des fonctionnalités avancées vous motive fortement !",
- "rogueText": "Les Voleurs adorent accumuler les richesses, ils gagnent plus d'Or que n'importe qui d'autre et trouvent souvent des objets par hasard. Leur faculté iconique de Furtivité leur permet d'esquiver les conséquences de tâches Quotidiennes manquées. Choisissez le Voleur si les Récompenses et les Succès vous motivent et si vous convoitez le butin et les badges !",
- "healerText": "Les Guérisseurs se montrent insensibles aux blessures et ils partagent cette protection avec les autres. Les Quotidiennes manquées et les mauvaises habitudes ne les gênent pas beaucoup et ils ont les moyens de récupérer leur santé après un échec. Jouez en tant que Guérisseur si vous aimez soutenir les membres de votre équipe ou si l'idée de tromper la Mort par votre dur labeur vous inspire !",
+ "warriorText": "Les guerriers réalisent des \"coups critiques\" plus nombreux et plus efficaces qui augmentent aléatoirement l'or et l'expérience obtenus ainsi que les chances de trouver du butin en complétant une tâche. Ils infligent aussi des dommages lourds aux boss. Jouez un guerrier si des récompenses imprévisibles du genre jackpot vous motivent ou si vous voulez distribuer des coups pendant les quêtes !",
+ "wizardText": "Les mages apprennent vite, gagnant de l'expérience et des niveaux plus rapidement que les autres classes. Ils et elles ont aussi de grandes réserves de mana à disposition pour utiliser leurs capacités spéciales. Jouez en tant que mage si vous appréciez le côté tactique d'Habitica, ou si vous vous réjouissez à l'idée de monter de niveau et de débloquer de nouvelles fonctionnalités !",
+ "mageText": "Les mages apprennent rapidement, et gagnent de l'expérience et des niveaux plus rapidement que les autres classes. Ils disposent également de beaucoup de mana pour utiliser des compétences spéciales. Jouez un mage si vous aimez les aspects tactiques du jeu, ou si gagner des niveaux et débloquer des fonctionnalités avancées vous motive fortement !",
+ "rogueText": "Les voleurs adorent accumuler les richesses, ils gagnent plus d'or que n'importe qui d'autre et trouvent souvent des objets par hasard. Leur faculté iconique de furtivité leur permet d'esquiver les conséquences de tâches quotidiennes manquées. Choisissez le voleur si les récompenses et les succès vous motivent et si vous convoitez le butin et les badges !",
+ "healerText": "Les guérisseurs se montrent insensibles aux blessures et ils partagent cette protection avec les autres. Les quotidiennes manquées et les mauvaises habitudes ne les gênent pas beaucoup et ils ont les moyens de récupérer leur santé après un échec. Jouez en tant que guérisseur si vous aimez soutenir les membres de votre équipe ou si l'idée de tromper la mort par votre dur labeur vous inspire !",
"optOutOfClasses": "Désactiver",
"optOutOfPMs": "Désactiver",
"chooseClass": "Choisissez votre classe",
@@ -161,12 +161,12 @@
"selectClass": "Sélectionner <%= heroClass %>",
"select": "Sélectionner",
"stealth": "Furtivité",
- "stealthNewDay": "Quand un nouveau jour commence, vous éviterez les dommages causés par les tâches Quotidiennes manquées.",
+ "stealthNewDay": "Quand un nouveau jour commence, vous éviterez les dommages causés par les tâches quotidiennes manquées.",
"streaksFrozen": "Combos gelés",
- "streaksFrozenText": "Les combos sur les tâches Quotidiennes manquées ne seront pas remis à zéro à la fin de la journée.",
+ "streaksFrozenText": "Les combos sur les tâches quotidiennes manquées ne seront pas remis à zéro à la fin de la journée.",
"respawn": "Résurrection !",
"youDied": "Vous êtes mort !",
- "dieText": "Vous avez perdu un niveau, tout votre or et une pièce d'équipement aléatoire. Relevez-vous, membre d'Habitica, et essayez encore ! Mettez un frein à ces habitudes négatives, complétez vos tâches Quotidiennes avec vigilance et tenez la mort à distance avec une potion de santé si vous fléchissez !",
+ "dieText": "Vous avez perdu un niveau, tout votre or et une pièce d'équipement aléatoire. Relevez-vous, membre d'Habitica, et essayez encore ! Mettez un frein à ces habitudes négatives, complétez vos tâches quotidiennes avec vigilance et tenez la mort à distance avec une potion de santé si vous fléchissez !",
"sureReset": "Confirmez-vous ? Ceci réinitialisera la classe de votre personnage ainsi que vos points alloués (vous les récupérerez tous pour les ré-allouer), et vous coûtera 3 gemmes.",
"purchaseFor": "Acheter pour <%= cost %> gemmes ?",
"purchaseForHourglasses": "Acheter pour <%= cost %> sabliers ?",
diff --git a/website/common/locales/fr/content.json b/website/common/locales/fr/content.json
index 2a41f70068..58f1b8c31c 100644
--- a/website/common/locales/fr/content.json
+++ b/website/common/locales/fr/content.json
@@ -350,5 +350,6 @@
"questEggRobotAdjective": "un futuriste",
"questEggRobotMountText": "Robot",
"questEggRobotText": "Robot",
- "hatchingPotionShadow": "d'ombre"
+ "hatchingPotionShadow": "d'ombre",
+ "premiumPotionUnlimitedNotes": "Ne peut pas être utilisé sur des œufs de familiers de quête."
}
diff --git a/website/common/locales/fr/gear.json b/website/common/locales/fr/gear.json
index 1ba9086459..428bf02452 100644
--- a/website/common/locales/fr/gear.json
+++ b/website/common/locales/fr/gear.json
@@ -14,266 +14,266 @@
"tierLockedItem": "Cet article n'est disponible qu'une fois que vous avez acheté en séquence les articles précédents. Continuez à progresser !",
"sortByType": "Type",
"sortByPrice": "Prix",
- "sortByCon": "CON.",
- "sortByPer": "PER.",
- "sortByStr": "FOR.",
- "sortByInt": "INT.",
+ "sortByCon": "CON",
+ "sortByPer": "PER",
+ "sortByStr": "FOR",
+ "sortByInt": "INT",
"weapon": "arme",
"weaponCapitalized": "Équipement de main principale",
"weaponBase0Text": "Pas d'arme",
"weaponBase0Notes": "Pas d'arme.",
"weaponWarrior0Text": "Epée d'entraînement",
- "weaponWarrior0Notes": "Une arme d'entraînement. N'apporte aucun bonus.",
+ "weaponWarrior0Notes": "Une arme d'entraînement. Ne confère aucun bonus.",
"weaponWarrior1Text": "Epée",
- "weaponWarrior1Notes": "Une banale lame de soldat. Augmente la Force de <%= str %>.",
+ "weaponWarrior1Notes": "Une banale lame de soldat. Augmente la force de <%= str %>.",
"weaponWarrior2Text": "Hache",
- "weaponWarrior2Notes": "Une arme à double-tranchant. Augmente la Force de <%= str %>",
+ "weaponWarrior2Notes": "Une arme à double-tranchant. Augmente la force de <%= str %>",
"weaponWarrior3Text": "Morgenstern",
- "weaponWarrior3Notes": "Une lourde massue hérissée de pointes acérées. Augmente la Force de <%= str %>.",
+ "weaponWarrior3Notes": "Une lourde massue hérissée de pointes acérées. Augmente la force de <%= str %>.",
"weaponWarrior4Text": "Lame de saphir",
- "weaponWarrior4Notes": "Une épée au tranchant aussi mordant que le vent du Nord. Augmente la Force de <%= str %>.",
+ "weaponWarrior4Notes": "Une épée au tranchant aussi mordant que le vent du Nord. Augmente la force de <%= str %>.",
"weaponWarrior5Text": "Épée de rubis",
- "weaponWarrior5Notes": "Une arme qui reste aussi étincelante qu'au moment où elle a été forgée. Augmente la Force de <%= str %>.",
+ "weaponWarrior5Notes": "Une arme qui reste aussi étincelante qu'au moment où elle a été forgée. Augmente la force de <%= str %>.",
"weaponWarrior6Text": "Épée d'or",
- "weaponWarrior6Notes": "Le fléau des créatures des ténèbres. Augmente la Force de <%= str %>.",
+ "weaponWarrior6Notes": "Le fléau des créatures des ténèbres. Augmente la force de <%= str %>.",
"weaponRogue0Text": "Dague",
- "weaponRogue0Notes": "L'arme la plus basique d'un voleur. N'apporte aucun bonus.",
+ "weaponRogue0Notes": "L'arme la plus basique d'un voleur. Ne confère aucun bonus.",
"weaponRogue1Text": "Épée courte",
- "weaponRogue1Notes": "Une lame légère, facile à cacher. Augmente la Force de <%= str %>.",
+ "weaponRogue1Notes": "Une lame légère, facile à cacher. Augmente la force de <%= str %>.",
"weaponRogue2Text": "Cimeterre",
- "weaponRogue2Notes": "Une épée tranchante, prompte à délivrer un coup mortel. Augmente la Force de <%= str %>.",
+ "weaponRogue2Notes": "Une épée tranchante, prompte à délivrer un coup mortel. Augmente la force de <%= str %>.",
"weaponRogue3Text": "Kukri",
- "weaponRogue3Notes": "Le couteau distinctif du guérillero, à la fois arme et outil de survie. Augmente la Force de <%= str %>.",
+ "weaponRogue3Notes": "Le couteau distinctif du guérillero, à la fois arme et outil de survie. Augmente la force de <%= str %>.",
"weaponRogue4Text": "Nunchaku",
- "weaponRogue4Notes": "De lourds bâtons qui tournoient, reliés par une chaîne. Augmente la Force de <%= str %>.",
+ "weaponRogue4Notes": "De lourds bâtons qui tournoient, reliés par une chaîne. Augmente la force de <%= str %>.",
"weaponRogue5Text": "Ninjato",
- "weaponRogue5Notes": "Aussi fine et mortelle que les ninja eux-mêmes. Augmente la Force de <%= str %>.",
+ "weaponRogue5Notes": "Aussi fine et mortelle que les ninja eux-mêmes. Augmente la force de <%= str %>.",
"weaponRogue6Text": "Crochet du tigre",
- "weaponRogue6Notes": "Une arme complexe, apte à prendre les opposants au piège pour les désarmer. Augmente la Force de <%= str %>.",
+ "weaponRogue6Notes": "Une arme complexe, apte à prendre les opposants au piège pour les désarmer. Augmente la force de <%= str %>.",
"weaponWizard0Text": "Bâton d'apprenti",
- "weaponWizard0Notes": "Un bâton d'entraînement. N'apporte aucun bonus.",
+ "weaponWizard0Notes": "Un bâton d'entraînement. Ne confère aucun bonus.",
"weaponWizard1Text": "Bâton de bois",
- "weaponWizard1Notes": "Un simple outil en bois taillé. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>.",
+ "weaponWizard1Notes": "Un simple outil en bois taillé. Augmente l'intelligence de <%= int %> et la perception de <%= per %>.",
"weaponWizard2Text": "Bâton orné",
- "weaponWizard2Notes": "Concentre le pouvoir dans une pierre précieuse. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %> .",
+ "weaponWizard2Notes": "Concentre le pouvoir dans une pierre précieuse. Augmente l'intelligence de <%= int %> et la perception de <%= per %> .",
"weaponWizard3Text": "Bâton de fer",
- "weaponWizard3Notes": "Recouvert de métal pour conduire la chaleur, le froid et la foudre. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>.",
+ "weaponWizard3Notes": "Recouvert de métal pour conduire la chaleur, le froid et la foudre. Augmente l'intelligence de <%= int %> et la perception de <%= per %>.",
"weaponWizard4Text": "Bâton de laiton",
- "weaponWizard4Notes": "Aussi puissant qu'il est lourd. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>.",
+ "weaponWizard4Notes": "Aussi puissant qu'il est lourd. Augmente l'intelligence de <%= int %> et la perception de <%= per %>.",
"weaponWizard5Text": "Bâton d'archimage",
- "weaponWizard5Notes": "Aide à jeter les sorts les plus compliqués. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>.",
+ "weaponWizard5Notes": "Aide à jeter les sorts les plus compliqués. Augmente l'intelligence de <%= int %> et la perception de <%= per %>.",
"weaponWizard6Text": "Bâton d'or",
- "weaponWizard6Notes": "Moulé à partir d'orichalque, l'or alchimique, puissant et rare. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>.",
+ "weaponWizard6Notes": "Moulé à partir d'orichalque, l'or alchimique, puissant et rare. Augmente l'intelligence de <%= int %> et la perception de <%= per %>.",
"weaponHealer0Text": "Baguette de novice",
- "weaponHealer0Notes": "Pour les guérisseurs en apprentissage. N'apporte aucun bonus.",
+ "weaponHealer0Notes": "Pour les guérisseurs en apprentissage. Ne confère aucun bonus.",
"weaponHealer1Text": "Baguette d'acolyte",
- "weaponHealer1Notes": "Conçue pendant l'initiation d'un guérisseur. Augmente l'Intelligence de <%= int %>.",
+ "weaponHealer1Notes": "Conçue pendant l'initiation d'un guérisseur. Augmente l'intelligence de <%= int %>.",
"weaponHealer2Text": "Baguette de quartz",
- "weaponHealer2Notes": "Surmonté par une gemme aux propriétés curatives. Augmente l'Intelligence de <%= int %>.",
+ "weaponHealer2Notes": "Surmonté par une gemme aux propriétés curatives. Augmente l'intelligence de <%= int %>.",
"weaponHealer3Text": "Baguette d’améthyste",
- "weaponHealer3Notes": "Élimine le poison par simple contact. Augmente l'Intelligence de <%= int %>.",
+ "weaponHealer3Notes": "Élimine le poison par simple contact. Augmente l'intelligence de <%= int %>.",
"weaponHealer4Text": "Baguette de médecin",
- "weaponHealer4Notes": "La marque d'une fonction aussi bien qu'un outil de guérison. Augmente l'Intelligence de <%= int %>.",
+ "weaponHealer4Notes": "La marque d'une fonction aussi bien qu'un outil de guérison. Augmente l'intelligence de <%= int %>.",
"weaponHealer5Text": "Sceptre royal",
- "weaponHealer5Notes": "Prévu pour orner la main d'un monarque ou celle de celui qui se tient à sa droite. Augmente l'Intelligence de <%= int %>.",
+ "weaponHealer5Notes": "Prévu pour orner la main d'un monarque ou celle de celui qui se tient à sa droite. Augmente l'intelligence de <%= int %>.",
"weaponHealer6Text": "Sceptre d'or",
- "weaponHealer6Notes": "Soulage la douleur de tous ceux qui y portent le regard. Augmente l'Intelligence de <%= int %>.",
+ "weaponHealer6Notes": "Soulage la douleur de tous ceux qui y portent le regard. Augmente l'intelligence de <%= int %>.",
"weaponSpecial0Text": "Lame des âmes sombres",
- "weaponSpecial0Notes": "Se nourrit de l'essence vitale des ennemis pour alimenter ses frappes diaboliques. Augmente la Force de <%= str %>.",
+ "weaponSpecial0Notes": "Se nourrit de l'essence vitale des ennemis pour alimenter ses frappes diaboliques. Augmente la force de <%= str %>.",
"weaponSpecial1Text": "Lame de cristal",
"weaponSpecial1Notes": "Ses facettes scintillantes racontent l'histoire d'un héros. Augmente tous les attributs de <%= attrs %>.",
"weaponSpecial2Text": "Hampe du dragon de Stephen Weber",
- "weaponSpecial2Notes": "Ressentez de l'intérieur la force du souffle du dragon ! Augmente la Force et la Perception de <%= attrs %> chacune.",
+ "weaponSpecial2Notes": "Ressentez de l'intérieur la force du souffle du dragon ! Augmente la force et la perception de <%= attrs %> chacune.",
"weaponSpecial3Text": "Masse massacreuse majeure de Mustaine",
- "weaponSpecial3Notes": "Réunions, monstres, malaises : vous gérez ! Vous en faites de la purée ! Augmente la Force, l'Intelligence et la Constitution de <%= attrs %>.",
+ "weaponSpecial3Notes": "Réunions, monstres, malaises : vous gérez ! Vous en faites de la purée ! Augmente la force, l'intelligence et la constitution de <%= attrs %>.",
"weaponSpecialCriticalText": "Marteau critique du broyeur de bug",
- "weaponSpecialCriticalNotes": "Ce champion a vaincu un ennemi crucial sur Github alors que beaucoup de guerriers avaient échoué avant lui. Façonné à partir des os du bug assassiné, ce marteau inflige des coups critiques surpuissants. Augmente la Force et la Perception de <%= attrs %> chacune.",
+ "weaponSpecialCriticalNotes": "Ce champion a vaincu un ennemi crucial sur Github alors que beaucoup de guerriers avaient échoué avant lui. Façonné à partir des os du bug assassiné, ce marteau inflige des coups critiques surpuissants. Augmente la force et la perception de <%= attrs %> chacune.",
"weaponSpecialTakeThisText": "Épée Take This",
"weaponSpecialTakeThisNotes": "Cette épée a été gagnée en participant à un défi sponsorisé par Take This. Toutes nos félicitations ! Augmente tous les attributs de <%= attrs %>.",
"weaponSpecialTridentOfCrashingTidesText": "Trident des marées déferlantes",
- "weaponSpecialTridentOfCrashingTidesNotes": "Confère la capacité de contrôler les poissons et poignarde également violemment vos tâches. Augmente l'Intelligence de <%= int %>.",
+ "weaponSpecialTridentOfCrashingTidesNotes": "Confère la capacité de contrôler les poissons et poignarde également violemment vos tâches. Augmente l'intelligence de <%= int %>.",
"weaponSpecialTaskwoodsLanternText": "Lanterne du bois des Tâches",
- "weaponSpecialTaskwoodsLanternNotes": "Donnée à l'aube des temps par le gardien fantôme des vergers du bois des Tâches, cette lanterne peut illuminer la plus profonde obscurité et tisser de puissants sorts. Augmente la Perception et l'Intelligence de <%= attrs %> chacune.",
+ "weaponSpecialTaskwoodsLanternNotes": "Donnée à l'aube des temps par le gardien fantôme des vergers du bois des Tâches, cette lanterne peut illuminer la plus profonde obscurité et tisser de puissants sorts. Augmente la perception et l'intelligence de <%= attrs %> chacune.",
"weaponSpecialBardInstrumentText": "Luth de barde",
- "weaponSpecialBardInstrumentNotes": "Grattez un air sympathique sur ce luth magique ! Augmente l'Intelligence et la Perception de <%= attrs %> chacune.",
+ "weaponSpecialBardInstrumentNotes": "Grattez un air sympathique sur ce luth magique ! Augmente l'intelligence et la perception de <%= attrs %> chacune.",
"weaponSpecialLunarScytheText": "Faux lunaire",
- "weaponSpecialLunarScytheNotes": "Graissez cette faux régulièrement, ou son pouvoir s'estompera. Augmente la Force et la Perception de <%= attrs %> chacune.",
+ "weaponSpecialLunarScytheNotes": "Graissez cette faux régulièrement, ou son pouvoir s'estompera. Augmente la force et la perception de <%= attrs %> chacune.",
"weaponSpecialMammothRiderSpearText": "Lance de chevaucheur de mammouths",
- "weaponSpecialMammothRiderSpearNotes": "Cette lance surmontée d'un quartz rose vous enveloppera de la puissance de sorts antiques. Augmente l'Intelligence de <%= int %>.",
+ "weaponSpecialMammothRiderSpearNotes": "Cette lance surmontée d'un quartz rose vous enveloppera de la puissance de sorts antiques. Augmente l'intelligence de <%= int %>.",
"weaponSpecialPageBannerText": "Étendard de page",
- "weaponSpecialPageBannerNotes": "Brandissez votre étendard bien haut, et insufflez du courage ! Augmente la Force de <%= str %>.",
+ "weaponSpecialPageBannerNotes": "Brandissez votre étendard bien haut, et insufflez du courage ! Augmente la force de <%= str %>.",
"weaponSpecialRoguishRainbowMessageText": "Missive arc-en-ciel",
- "weaponSpecialRoguishRainbowMessageNotes": "Cette enveloppe scintillante contient des messages d'encouragement rédigés par des Habiticiennes et des Habiticiens, ainsi qu'une pointe de magie pour vous aider dans vos livraisons ! Augmente la Perception de <%= per %>.",
+ "weaponSpecialRoguishRainbowMessageNotes": "Cette enveloppe scintillante contient des messages d'encouragement rédigés par des Habiticiennes et des Habiticiens, ainsi qu'une pointe de magie pour vous aider dans vos livraisons ! Augmente la perception de <%= per %>.",
"weaponSpecialSkeletonKeyText": "Clé squelette",
- "weaponSpecialSkeletonKeyNotes": "Les meilleurs chapardeurs ont tous sur eux une clé capable d'ouvrir n'importe quelle serrure ! Augmente la Constitution de <%= con %>.",
+ "weaponSpecialSkeletonKeyNotes": "Les meilleurs chapardeurs ont tous sur eux une clé capable d'ouvrir n'importe quelle serrure ! Augmente la constitution de <%= con %>.",
"weaponSpecialNomadsScimitarText": "Cimeterre de nomade",
- "weaponSpecialNomadsScimitarNotes": "La lame courbée de cette cimeterre est idéale pour s'attaquer à des tâches tout en chevauchant une monture ! Augmente l'Intelligence de <%= int %>.",
+ "weaponSpecialNomadsScimitarNotes": "La lame courbée de cette cimeterre est idéale pour s'attaquer à des tâches tout en chevauchant une monture ! Augmente l'intelligence de <%= int %>.",
"weaponSpecialFencingFoilText": "Fleuret d'escrime",
- "weaponSpecialFencingFoilNotes": "Quiconque oserait salir votre honneur trouverait ce fleuret sur son chemin. Augmente la Force de <%= str %>.",
+ "weaponSpecialFencingFoilNotes": "Quiconque oserait salir votre honneur trouverait ce fleuret sur son chemin. Augmente la force de <%= str %>.",
"weaponSpecialTachiText": "Tachi de samouraï",
- "weaponSpecialTachiNotes": "Cette lame courbe et fine va couper vos tâches en petits rubans ! Augmente la Force de <%= str %>.",
+ "weaponSpecialTachiNotes": "Cette lame courbe et fine va couper vos tâches en petits rubans ! Augmente la force de <%= str %>.",
"weaponSpecialAetherCrystalsText": "Cristaux d’éther",
"weaponSpecialAetherCrystalsNotes": "Ces bracelets et cristaux appartenaient autrefois à la maîtresse des classes oubliée. Augmente tous les attributs de <%= attrs %>.",
"weaponSpecialYetiText": "Lance du dresseur de yéti",
- "weaponSpecialYetiNotes": "Cette lance permet à son porteur de contrôler n'importe quel yéti. Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2013-2014.",
+ "weaponSpecialYetiNotes": "Cette lance permet à son porteur de contrôler n'importe quel yéti. Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2013-2014.",
"weaponSpecialSkiText": "Bâton de ski-ssassin",
- "weaponSpecialSkiNotes": "Une arme capable de détruire des hordes d'ennemis ! Elle permet aussi à son porteur d'effectuer de jolis virages parallèles. Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2013-2014.",
+ "weaponSpecialSkiNotes": "Une arme capable de détruire des hordes d'ennemis ! Elle permet aussi à son porteur d'effectuer de jolis virages parallèles. Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2013-2014.",
"weaponSpecialCandycaneText": "Bâton en sucre d'orge",
- "weaponSpecialCandycaneNotes": "Un puissant bâton de mage. Puissamment DÉLICIEUX, en vérité ! Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2013-2014.",
+ "weaponSpecialCandycaneNotes": "Un puissant bâton de mage. Puissamment DÉLICIEUX, en vérité ! Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l'hiver 2013-2014.",
"weaponSpecialSnowflakeText": "Baguette flocon-de-neige",
- "weaponSpecialSnowflakeNotes": "Cette baguette brille d'un pouvoir de guérison illimité. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2013-2014.",
+ "weaponSpecialSnowflakeNotes": "Cette baguette brille d'un pouvoir de guérison illimité. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2013-2014.",
"weaponSpecialSpringRogueText": "Griffes-crochet",
- "weaponSpecialSpringRogueNotes": "Idéal pour escalader de grands immeubles, mais aussi pour déchirer les carpettes. Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2014.",
+ "weaponSpecialSpringRogueNotes": "Idéal pour escalader de grands immeubles, mais aussi pour déchirer les carpettes. Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2014.",
"weaponSpecialSpringWarriorText": "Épée carotte",
- "weaponSpecialSpringWarriorNotes": "Cette puissante épée peut facilement trancher les ennemis ! Elle fera également un très bon en-cas au milieu d'un combat. Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2014.",
+ "weaponSpecialSpringWarriorNotes": "Cette puissante épée peut facilement trancher les ennemis ! Elle fera également un très bon en-cas au milieu d'un combat. Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2014.",
"weaponSpecialSpringMageText": "Bâton en fromage à trous",
- "weaponSpecialSpringMageNotes": "Seuls les rongeurs les plus coriaces peuvent braver leur faim pour brandir ce puissant bâton. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée du printemps 2014.",
+ "weaponSpecialSpringMageNotes": "Seuls les rongeurs les plus coriaces peuvent braver leur faim pour brandir ce puissant bâton. Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée du printemps 2014.",
"weaponSpecialSpringHealerText": "Os ravissant",
- "weaponSpecialSpringHealerNotes": "VA CHERCHER ! Augmente l'Intelligence de <%= int %>. Équipement en édition limitée du printemps 2014.",
+ "weaponSpecialSpringHealerNotes": "VA CHERCHER ! Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2014.",
"weaponSpecialSummerRogueText": "Coutelas de pirate",
- "weaponSpecialSummerRogueNotes": "Arrêtez ! Vous allez mettre ces tâches Quotidiennes au supplice de la planche ! Augmente la Force de <%= str %>. Équipement en édition limitée de l’été 2014.",
+ "weaponSpecialSummerRogueNotes": "Arrêtez ! Vous allez mettre ces tâches quotidiennes au supplice de la planche ! Augmente la force de <%= str %>. Équipement en édition limitée de l’été 2014.",
"weaponSpecialSummerWarriorText": "Tranchoir des mers",
- "weaponSpecialSummerWarriorNotes": "Quelle que soit la liste, il n'est pas une tâche qui se frotterait à cette dangereuse lame ! Augmente la Force de <%= str %>. Équipement en édition limitée de l’été 2014.",
+ "weaponSpecialSummerWarriorNotes": "Quelle que soit la liste, il n'est pas une tâche qui se frotterait à cette dangereuse lame ! Augmente la force de <%= str %>. Équipement en édition limitée de l’été 2014.",
"weaponSpecialSummerMageText": "Récolteur de varech",
- "weaponSpecialSummerMageNotes": "Ce trident est utilisé pour harponner les algues avec efficacité, idéal pour les récoltes de varech extra-productives ! Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l’été 2014.",
+ "weaponSpecialSummerMageNotes": "Ce trident est utilisé pour harponner les algues avec efficacité, idéal pour les récoltes de varech extra-productives ! Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l’été 2014.",
"weaponSpecialSummerHealerText": "Baguette des bas-fonds",
- "weaponSpecialSummerHealerNotes": "Cette baguette d'aigue-marine et de corail vivant est très attrayante pour les bancs de poissons. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l’été 2014.",
+ "weaponSpecialSummerHealerNotes": "Cette baguette d'aigue-marine et de corail vivant est très attrayante pour les bancs de poissons. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l’été 2014.",
"weaponSpecialFallRogueText": "Pieu en argent",
- "weaponSpecialFallRogueNotes": "Liquide les morts-vivants. Accorde aussi un bonus contre les loup-garous, parce qu'on n'est jamais trop prudent. Augmente la Force de <%= str %>. Équipement en édition limitée de l'automne 2014.",
+ "weaponSpecialFallRogueNotes": "Liquide les morts-vivants. Accorde aussi un bonus contre les loup-garous, parce qu'on n'est jamais trop prudent. Augmente la force de <%= str %>. Équipement en édition limitée de l'automne 2014.",
"weaponSpecialFallWarriorText": "Pince avide de science",
- "weaponSpecialFallWarriorNotes": "Cette pince avide est à la pointe de la technologie. Augmente la Force de <%= str %>. Équipement en édition limitée de l'automne 2014.",
+ "weaponSpecialFallWarriorNotes": "Cette pince avide est à la pointe de la technologie. Augmente la force de <%= str %>. Équipement en édition limitée de l'automne 2014.",
"weaponSpecialFallMageText": "Balai magique",
- "weaponSpecialFallMageNotes": "Ce balai enchanté vole plus vite que les dragons ! Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l'automne 2014.",
+ "weaponSpecialFallMageNotes": "Ce balai enchanté vole plus vite que les dragons ! Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l'automne 2014.",
"weaponSpecialFallHealerText": "Baguette de scarabée",
- "weaponSpecialFallHealerNotes": "Le scarabée qui orne cette baguette protège et guérit son porteur . Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'automne 2014.",
+ "weaponSpecialFallHealerNotes": "Le scarabée qui orne cette baguette protège et guérit son porteur. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'automne 2014.",
"weaponSpecialWinter2015RogueText": "Stalagmite gelé",
- "weaponSpecialWinter2015RogueNotes": "Vous venez vraiment, sérieusement, absolument, de les ramasser par terre. Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2014-2015.",
+ "weaponSpecialWinter2015RogueNotes": "Vous venez vraiment, sérieusement, absolument, de les ramasser par terre. Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2014-2015.",
"weaponSpecialWinter2015WarriorText": "Épée gélatineuse",
- "weaponSpecialWinter2015WarriorNotes": "Cette épée délicieuse attire probablement les monstres... mais ça ne vous fait pas peur ! Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2014-2015.",
+ "weaponSpecialWinter2015WarriorNotes": "Cette épée délicieuse attire probablement les monstres... mais ça ne vous fait pas peur ! Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2014-2015.",
"weaponSpecialWinter2015MageText": "Bâton aux couleurs hivernales",
- "weaponSpecialWinter2015MageNotes": "Ce bâton de cristal illumine et réchauffe le cœur. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2014-2015.",
+ "weaponSpecialWinter2015MageNotes": "Ce bâton de cristal illumine et réchauffe le cœur. Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l'hiver 2014-2015.",
"weaponSpecialWinter2015HealerText": "Sceptre apaisant",
- "weaponSpecialWinter2015HealerNotes": "Cette sceptre réchauffe les muscles endoloris et fait disparaître le stress. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2014-2015.",
+ "weaponSpecialWinter2015HealerNotes": "Cette sceptre réchauffe les muscles endoloris et fait disparaître le stress. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2014-2015.",
"weaponSpecialSpring2015RogueText": "Couinement explosif",
- "weaponSpecialSpring2015RogueNotes": "Ne vous laissez pas duper par le son - ces explosifs font mal. Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2015.",
+ "weaponSpecialSpring2015RogueNotes": "Ne vous laissez pas duper par le son - ces explosifs font mal. Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2015.",
"weaponSpecialSpring2015WarriorText": "Matraque en os",
- "weaponSpecialSpring2015WarriorNotes": "C'est une vraie matraque en os pour chien vraiment féroce, et absolument pas un jouet à mastiquer que la sorcière saisonnière vous aurait donné parce que vous êtes un bon toutou. Qui c'est le bon toutou ? C'est vous !! Vous êtes un bon toutou !! Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2015.",
+ "weaponSpecialSpring2015WarriorNotes": "C'est une vraie matraque en os pour chien vraiment féroce, et absolument pas un jouet à mastiquer que la sorcière saisonnière vous aurait donné parce que vous êtes un bon toutou. Qui c'est le bon toutou ? C'est vous !! Vous êtes un bon toutou !! Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2015.",
"weaponSpecialSpring2015MageText": "Baguette de magicien",
- "weaponSpecialSpring2015MageNotes": "Faites apparaître une carotte pour vous avec cette baguette distinguée. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée du printemps 2015.",
+ "weaponSpecialSpring2015MageNotes": "Faites apparaître une carotte pour vous avec cette baguette distinguée. Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée du printemps 2015.",
"weaponSpecialSpring2015HealerText": "Hochet de chat",
- "weaponSpecialSpring2015HealerNotes": "Lorsque vous l'agitez, il fait un drôle de cliquetis qui amuserait N'IMPORTE QUI pendant des heures. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée du printemps 2015.",
+ "weaponSpecialSpring2015HealerNotes": "Lorsque vous l'agitez, il fait un drôle de cliquetis qui amuserait N'IMPORTE QUI pendant des heures. Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2015.",
"weaponSpecialSummer2015RogueText": "Corail flamboyant",
- "weaponSpecialSummer2015RogueNotes": "Cette variété de corail de feu a la capacité de propulser son venin dans l'eau. Augmente la Force de <%= str %>. Équipement en édition limitée de l’été 2015.",
+ "weaponSpecialSummer2015RogueNotes": "Cette variété de corail de feu a la capacité de propulser son venin dans l'eau. Augmente la force de <%= str %>. Équipement en édition limitée de l’été 2015.",
"weaponSpecialSummer2015WarriorText": "Espadon solaire",
- "weaponSpecialSummer2015WarriorNotes": "L'Espadon solaire est une arme redoutable, sous réserve que l'on puisse l'empêcher de frétiller. Augmente la Force de <%= str %>. Équipement en édition limitée de l’été 2015.",
+ "weaponSpecialSummer2015WarriorNotes": "L'Espadon solaire est une arme redoutable, sous réserve que l'on puisse l'empêcher de frétiller. Augmente la force de <%= str %>. Équipement en édition limitée de l’été 2015.",
"weaponSpecialSummer2015MageText": "Bâton de devin",
- "weaponSpecialSummer2015MageNotes": "Une puissance cachée luit dans les joyaux de ce bâton. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l’été 2015.",
+ "weaponSpecialSummer2015MageNotes": "Une puissance cachée luit dans les joyaux de ce bâton. Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l’été 2015.",
"weaponSpecialSummer2015HealerText": "Baguette des vagues",
- "weaponSpecialSummer2015HealerNotes": "Guérit le mal de mer et le mal des mers ! Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l’été 2015.",
+ "weaponSpecialSummer2015HealerNotes": "Guérit le mal de mer et le mal des mers ! Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l’été 2015.",
"weaponSpecialFall2015RogueText": "Hache de bat-aille",
- "weaponSpecialFall2015RogueNotes": "De redoutables tâches À Faire s'enfuient devant le battement d'ailes de cette hache. Augmente la Force de <%= str %>. Équipement en édition limitée de l'automne 2015.",
+ "weaponSpecialFall2015RogueNotes": "De redoutables tâches s'enfuient devant le battement d'ailes de cette hache. Augmente la force de <%= str %>. Équipement en édition limitée de l'automne 2015.",
"weaponSpecialFall2015WarriorText": "Planche de bois",
- "weaponSpecialFall2015WarriorNotes": "Parfait pour surélever quelque chose dans un champ de maïs et / ou frapper les tâches. Augmente la Force de <%= str %>. Équipement en édition limitée de l'automne 2015.",
+ "weaponSpecialFall2015WarriorNotes": "Parfait pour surélever quelque chose dans un champ de maïs et/ou frapper les tâches. Augmente la force de <%= str %>. Équipement en édition limitée de l'automne 2015.",
"weaponSpecialFall2015MageText": "Fil enchanté",
- "weaponSpecialFall2015MageNotes": "Une puissante Sorcière couturière peut contrôler ce fil enchanté sans même le toucher ! Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l'automne 2015.",
+ "weaponSpecialFall2015MageNotes": "Une puissante Sorcière couturière peut contrôler ce fil enchanté sans même le toucher ! Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l'automne 2015.",
"weaponSpecialFall2015HealerText": "Potion de bave des marais",
- "weaponSpecialFall2015HealerNotes": "Brassée à la perfection ! Vous n'avez à présent plus qu'à vous convaincre de la boire. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'automne 2015.",
+ "weaponSpecialFall2015HealerNotes": "Brassée à la perfection ! Vous n'avez à présent plus qu'à vous convaincre de la boire. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'automne 2015.",
"weaponSpecialWinter2016RogueText": "Chocolat chaud",
- "weaponSpecialWinter2016RogueNotes": "Boisson chaude ou projectile bouillant ? C'est votre choix... Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2015-2016.",
+ "weaponSpecialWinter2016RogueNotes": "Boisson chaude ou projectile bouillant ? C'est votre choix... Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2015-2016.",
"weaponSpecialWinter2016WarriorText": "Pelle robuste",
- "weaponSpecialWinter2016WarriorNotes": "Dégagez les tâches en attente d'un coup de pelle ! Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2015-2016.",
+ "weaponSpecialWinter2016WarriorNotes": "Dégagez les tâches en attente d'un coup de pelle ! Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2015-2016.",
"weaponSpecialWinter2016MageText": "Snowboard sorcier",
- "weaponSpecialWinter2016MageNotes": "Vous bougez tellement bien, ce doit être magique ! Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2015-2016.",
+ "weaponSpecialWinter2016MageNotes": "Vous bougez tellement bien, ce doit être magique ! Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l'hiver 2015-2016.",
"weaponSpecialWinter2016HealerText": "Canon à confetti",
- "weaponSpecialWinter2016HealerNotes": "YOUPI !!! C'EST LE TEMPS DES MERVEILLES D'HIVER !!! Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2015-2016.",
+ "weaponSpecialWinter2016HealerNotes": "YOUPI !!! C'EST LE TEMPS DES MERVEILLES D'HIVER !!! Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2015-2016.",
"weaponSpecialSpring2016RogueText": "Bolas enflammés",
- "weaponSpecialSpring2016RogueNotes": "Vous maîtrisez les balles, les massues et les couteaux. Maintenant, vous allez pouvoir jongler avec le feu ! Yeah ! Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2016.",
+ "weaponSpecialSpring2016RogueNotes": "Vous maîtrisez les balles, les massues et les couteaux. Maintenant, vous allez pouvoir jongler avec le feu ! Yeah ! Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2016.",
"weaponSpecialSpring2016WarriorText": "Maillet en fromage",
- "weaponSpecialSpring2016WarriorNotes": "Personne n'a autant d'amis que la souris qui a de tendres fromages. Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2016.",
+ "weaponSpecialSpring2016WarriorNotes": "Personne n'a autant d'amis que la souris qui a de tendres fromages. Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2016.",
"weaponSpecialSpring2016MageText": "Bâton des cloches",
- "weaponSpecialSpring2016MageNotes": "Abra-chat-da-bra ! C'est si éblouissant que vous pourriez bien vous hypnotiser vous-même ! Oh... ça tinte... Augmente l'Intelligence de <%= int%> et la Perception de <%= per%>. Équipement en édition limitée du printemps 2016.",
+ "weaponSpecialSpring2016MageNotes": "Abra-chat-da-bra ! C'est si éblouissant que vous pourriez bien vous hypnotiser vous-même ! Oh... ça tinte... Augmente l'intelligence de <%= int%> et la perception de <%= per%>. Équipement en édition limitée du printemps 2016.",
"weaponSpecialSpring2016HealerText": "Baguette fleur-de-printemps",
- "weaponSpecialSpring2016HealerNotes": "D'un geste et d'un clin d’œil, vous faites fleurir les champs et les forêts ! Ou donnez un coup sur la tête des souris pénibles. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée du printemps 2016.",
+ "weaponSpecialSpring2016HealerNotes": "D'un geste et d'un clin d’œil, vous faites fleurir les champs et les forêts ! Ou donnez un coup sur la tête des souris pénibles. Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2016.",
"weaponSpecialSummer2016RogueText": "Baguette électrique",
- "weaponSpecialSummer2016RogueNotes": "Ceux et celles qui se trouvent face à vous auront le droit à une surprise assez choquante... Augmente la Force de <%= str %>. Équipement en édition limitée de l’été 2016.",
+ "weaponSpecialSummer2016RogueNotes": "Ceux et celles qui se trouvent face à vous auront le droit à une surprise assez choquante... Augmente la force de <%= str %>. Équipement en édition limitée de l’été 2016.",
"weaponSpecialSummer2016WarriorText": "Épée crochue",
- "weaponSpecialSummer2016WarriorNotes": "Croquez les tâches difficiles avec cette épée crochue ! Augmente la Force de <%= str %>. Équipement en édition limitée de l’été 2016.",
+ "weaponSpecialSummer2016WarriorNotes": "Croquez les tâches difficiles avec cette épée crochue ! Augmente la force de <%= str %>. Équipement en édition limitée de l’été 2016.",
"weaponSpecialSummer2016MageText": "Bâton d'écume",
- "weaponSpecialSummer2016MageNotes": "Toute la puissance des océans traverse ce bâton. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l’été 2016.",
+ "weaponSpecialSummer2016MageNotes": "Toute la puissance des océans traverse ce bâton. Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l’été 2016.",
"weaponSpecialSummer2016HealerText": "Trident de guérison",
- "weaponSpecialSummer2016HealerNotes": "Une pointe fait du mal, l'autre guérit. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l’été 2016.",
+ "weaponSpecialSummer2016HealerNotes": "Une pointe fait du mal, l'autre guérit. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l’été 2016.",
"weaponSpecialFall2016RogueText": "Dague de morsure d'araignée",
- "weaponSpecialFall2016RogueNotes": "Sentez la piqûre de la morsure de l'araignée ! Augmente la Force de <%=str %>. Équipement en édition limitée de l’automne 2016.",
+ "weaponSpecialFall2016RogueNotes": "Sentez la piqûre de la morsure de l'araignée ! Augmente la force de <%=str %>. Équipement en édition limitée de l’automne 2016.",
"weaponSpecialFall2016WarriorText": "Racines offensives",
- "weaponSpecialFall2016WarriorNotes": "Attaquez vos tâches avec ces racines tortueuses ! Augmente la Force de <%=str %>. Équipement en édition limitée de l’automne 2016.",
+ "weaponSpecialFall2016WarriorNotes": "Attaquez vos tâches avec ces racines tortueuses ! Augmente la force de <%=str %>. Équipement en édition limitée de l’automne 2016.",
"weaponSpecialFall2016MageText": "Orbe de mauvais augure",
- "weaponSpecialFall2016MageNotes": "Ne demandez pas à cet orbe de vous dire votre avenir... Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l’automne 2016.",
+ "weaponSpecialFall2016MageNotes": "Ne demandez pas à cet orbe de vous dire votre avenir... Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l’automne 2016.",
"weaponSpecialFall2016HealerText": "Serpent venimeux",
- "weaponSpecialFall2016HealerNotes": "Une morsure blesse, une autre soigne. Augmente l'Intelligence de <%=int %>. Équipement en édition limitée de l’automne 2016.",
+ "weaponSpecialFall2016HealerNotes": "Une morsure blesse, une autre soigne. Augmente l'intelligence de <%=int %>. Équipement en édition limitée de l’automne 2016.",
"weaponSpecialWinter2017RogueText": "Piolet",
- "weaponSpecialWinter2017RogueNotes": "Ce piolet est idéal pour attaquer, se défendre et pour escalader des cascades de glace ! Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2016-2017.",
+ "weaponSpecialWinter2017RogueNotes": "Ce piolet est idéal pour attaquer, se défendre et pour escalader des cascades de glace ! Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2016-2017.",
"weaponSpecialWinter2017WarriorText": "Bâton de puissance",
- "weaponSpecialWinter2017WarriorNotes": "Atteignez vos objectifs en les pulvérisant avec ce puissant bâton ! Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2016-2017.",
+ "weaponSpecialWinter2017WarriorNotes": "Atteignez vos objectifs en les pulvérisant avec ce puissant bâton ! Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2016-2017.",
"weaponSpecialWinter2017MageText": "Bâton cristallin du Loup hiémal",
- "weaponSpecialWinter2017MageNotes": "L'embout lumineux en cristal bleu de ce bâton porte le nom d'Œil du Loup hiémal ! Il tire ses pouvoirs magiques de la neige et de la glace. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2016-2017.",
+ "weaponSpecialWinter2017MageNotes": "L'embout lumineux en cristal bleu de ce bâton porte le nom d'Œil du Loup hiémal ! Il tire ses pouvoirs magiques de la neige et de la glace. Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l'hiver 2016-2017.",
"weaponSpecialWinter2017HealerText": "Baguette en sucre filé",
- "weaponSpecialWinter2017HealerNotes": "Cette baguette peut pénétrer vos rêves et y faire apparaître des dragées qui dansent. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2016-2017.",
+ "weaponSpecialWinter2017HealerNotes": "Cette baguette peut pénétrer vos rêves et y faire apparaître des dragées qui dansent. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2016-2017.",
"weaponSpecialSpring2017RogueText": "Karottana",
- "weaponSpecialSpring2017RogueNotes": "Cette lame se chargera bien vite de vos tâches, mais est également efficace pour couper des légumes ! Miam ! Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2017.",
+ "weaponSpecialSpring2017RogueNotes": "Cette lame se chargera bien vite de vos tâches, mais est également efficace pour couper des légumes ! Miam ! Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2017.",
"weaponSpecialSpring2017WarriorText": "Fouet plumeux",
- "weaponSpecialSpring2017WarriorNotes": "Ce redoutable fouet matera la plus rebelle des tâches. Mais... il est aussi... très AMUSANT ET DISTRAYANT ! Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2017.",
+ "weaponSpecialSpring2017WarriorNotes": "Ce redoutable fouet matera la plus rebelle des tâches. Mais... il est aussi... très AMUSANT ET DISTRAYANT ! Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2017.",
"weaponSpecialSpring2017MageText": "Bâton à rapporter magique",
- "weaponSpecialSpring2017MageNotes": "Quand vous ne l'utilisez pas pour jeter des sorts, vous pouvez le lancer au loin, puis le rapporter ! Amusant ! Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée du printemps 2017.",
+ "weaponSpecialSpring2017MageNotes": "Quand vous ne l'utilisez pas pour jeter des sorts, vous pouvez le lancer au loin, puis le rapporter ! Amusant ! Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée du printemps 2017.",
"weaponSpecialSpring2017HealerText": "Baguette-œuf",
- "weaponSpecialSpring2017HealerNotes": "La véritable magie de cette baguette réside dans sa coquille colorée, qui détient le secret d'une vie nouvelle. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée du printemps 2017.",
+ "weaponSpecialSpring2017HealerNotes": "La véritable magie de cette baguette réside dans sa coquille colorée, qui détient le secret d'une vie nouvelle. Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2017.",
"weaponSpecialSummer2017RogueText": "Nageoires de dragon de mer",
- "weaponSpecialSummer2017RogueNotes": "Le bord de ces nageoires est tranchant comme un rasoir. Augmente la Force de <%= str %>. Équipement en édition limitée de l'été 2017.",
+ "weaponSpecialSummer2017RogueNotes": "Le bord de ces nageoires est tranchant comme un rasoir. Augmente la force de <%= str %>. Équipement en édition limitée de l'été 2017.",
"weaponSpecialSummer2017WarriorText": "Le plus puissant des parasols",
- "weaponSpecialSummer2017WarriorNotes": "Tous le craignent. Augmente la Force de <%= str %>. Équipement en édition limitée de l'été 2017.",
+ "weaponSpecialSummer2017WarriorNotes": "Tous le craignent. Augmente la force de <%= str %>. Équipement en édition limitée de l'été 2017.",
"weaponSpecialSummer2017MageText": "Fouets tourbillon",
- "weaponSpecialSummer2017MageNotes": "Invoquez des tourbillons magiques d'eau bouillante pour abattre vos tâches ! Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l'été 2017.",
+ "weaponSpecialSummer2017MageNotes": "Invoquez des tourbillons magiques d'eau bouillante pour abattre vos tâches ! Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l'été 2017.",
"weaponSpecialSummer2017HealerText": "Baguette de perle",
- "weaponSpecialSummer2017HealerNotes": "Un simple contact de cette baguette magique surmontée d'une perle guérit toutes les plaies. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'été 2017.",
+ "weaponSpecialSummer2017HealerNotes": "Un simple contact de cette baguette magique surmontée d'une perle guérit toutes les plaies. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'été 2017.",
"weaponSpecialFall2017RogueText": "Masse en pomme d'amour",
- "weaponSpecialFall2017RogueNotes": "Terrassez vos ennemis par la douceur ! Augmente la Force de <%= str %>. %>. Équipement en édition limitée de l’automne 2017.",
+ "weaponSpecialFall2017RogueNotes": "Terrassez vos ennemis par la douceur ! Augmente la force de <%= str %>. Équipement en édition limitée de l’automne 2017.",
"weaponSpecialFall2017WarriorText": "Lance en sucre d'orge",
- "weaponSpecialFall2017WarriorNotes": "Tous vos ennemis vont battre en retraite devant cette lance appétissante, qu'importe qu'il s'agisse de fantômes, de monstres ou de tâches À Faire. Augmente la Force de <%= str %>. Équipement en édition limitée de l'automne 2017.",
+ "weaponSpecialFall2017WarriorNotes": "Tous vos ennemis vont battre en retraite devant cette lance appétissante, qu'importe qu'il s'agisse de fantômes, de monstres ou de tâches. Augmente la force de <%= str %>. Équipement en édition limitée de l'automne 2017.",
"weaponSpecialFall2017MageText": "Bâton effrayant",
- "weaponSpecialFall2017MageNotes": "La magie et le mystère irradient des yeux du crâne brillant à l'extrémité de ce bâton. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l'automne 2017.",
+ "weaponSpecialFall2017MageNotes": "La magie et le mystère irradient des yeux du crâne brillant à l'extrémité de ce bâton. Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l'automne 2017.",
"weaponSpecialFall2017HealerText": "Candélabre horrifique",
- "weaponSpecialFall2017HealerNotes": "Cette lumière désamorce la peur et fait savoir aux autres que vous êtes là pour les aider. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'automne 2017.",
+ "weaponSpecialFall2017HealerNotes": "Cette lumière désamorce la peur et fait savoir aux autres que vous êtes là pour les aider. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'automne 2017.",
"weaponSpecialWinter2018RogueText": "Crochet menthe poivrée",
- "weaponSpecialWinter2018RogueNotes": "Parfait pour grimper les murs ou distraire vos ennemis avec des bonbons tout doux. Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2017-2018.",
+ "weaponSpecialWinter2018RogueNotes": "Parfait pour grimper les murs ou distraire vos ennemis avec des bonbons tout doux. Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2017-2018.",
"weaponSpecialWinter2018WarriorText": "Marteau de fête à nœud",
- "weaponSpecialWinter2018WarriorNotes": "L'apparence brillante de cette arme lumineuse éblouira vos ennemis pendant que vous l'agiterez ! Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2017-2018.",
+ "weaponSpecialWinter2018WarriorNotes": "L'apparence brillante de cette arme lumineuse éblouira vos ennemis pendant que vous l'agiterez ! Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2017-2018.",
"weaponSpecialWinter2018MageText": "Confetti de fêtes",
- "weaponSpecialWinter2018MageNotes": "La magie et les paillettes sont dans l'air ! Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2017-2018.",
+ "weaponSpecialWinter2018MageNotes": "La magie et les paillettes sont dans l'air ! Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l'hiver 2017-2018.",
"weaponSpecialWinter2018HealerText": "Baguette de gui",
- "weaponSpecialWinter2018HealerNotes": "Cette boule de gui enchantera et ravira les passants à coup sûr ! Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2017-2018.",
+ "weaponSpecialWinter2018HealerNotes": "Cette boule de gui enchantera et ravira les passants à coup sûr ! Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2017-2018.",
"weaponSpecialSpring2018RogueText": "Jonc flottant",
- "weaponSpecialSpring2018RogueNotes": "Ce qui semble être une jolie canne est en fait une arme plutôt efficace entre de bonnes mains. Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2018.",
+ "weaponSpecialSpring2018RogueNotes": "Ce qui semble être une jolie canne est en fait une arme plutôt efficace entre de bonnes mains. Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2018.",
"weaponSpecialSpring2018WarriorText": "Hache de l'aube",
- "weaponSpecialSpring2018WarriorNotes": "Fabriquée en or massif, cette hache est suffisamment puissante pour s'attaquer aux plus mauvaises habitudes ! Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2018.",
+ "weaponSpecialSpring2018WarriorNotes": "Fabriquée en or massif, cette hache est suffisamment puissante pour s'attaquer aux plus mauvaises habitudes ! Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2018.",
"weaponSpecialSpring2018MageText": "Baguette tulipe",
- "weaponSpecialSpring2018MageNotes": "Cette fleur magique ne se flétrit jamais ! Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée du printemps 2018.",
+ "weaponSpecialSpring2018MageNotes": "Cette fleur magique ne se flétrit jamais ! Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée du printemps 2018.",
"weaponSpecialSpring2018HealerText": "Bâton de grenat",
"weaponSpecialSpring2018HealerNotes": "Les pierres de ce bâton concentreront votre puissance lorsque vous lancerez des sorts de guérison ! Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2018.",
"weaponSpecialSummer2018RogueText": "Canne à pêche",
- "weaponSpecialSummer2018RogueNotes": "Cette canne à pêche, légère et pratiquement incassable, peut-être utilisée avec une autre canne à pêche pour optimiser votre DPS (poisson-Dragon Par Saison). Augmente la Force de <%= str %>. Équipement en édition limitée de l’été 2018.",
+ "weaponSpecialSummer2018RogueNotes": "Cette canne à pêche, légère et pratiquement incassable, peut-être utilisée avec une autre canne à pêche pour optimiser votre DPS (poisson-Dragon Par Saison). Augmente la force de <%= str %>. Équipement en édition limitée de l’été 2018.",
"weaponSpecialSummer2018WarriorText": "Harpon à Betta Splendens",
- "weaponSpecialSummer2018WarriorNotes": "Suffisamment puissant pour le combat, suffisamment élégante pour les cérémonies, cette lance fabriquée avec minutie montre que vous allez protéger votre surf, peu importe le reste ! Augmente la Force de <%= str %>. Équipement en édition limitée de l’été 2018.",
+ "weaponSpecialSummer2018WarriorNotes": "Suffisamment puissant pour le combat, suffisamment élégante pour les cérémonies, cette lance fabriquée avec minutie montre que vous allez protéger votre surf, peu importe le reste ! Augmente la force de <%= str %>. Équipement en édition limitée de l’été 2018.",
"weaponSpecialSummer2018MageText": "Nageoire à rayon de pterois",
- "weaponSpecialSummer2018MageNotes": "Sous l’eau, la magie du feu, de la glace ou de l’électricité peut être dangereuse pour le mage qui la détient. Soigner le poison des vives, par contre, est très utile ! Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement en édition limitée de l’été 2018.",
+ "weaponSpecialSummer2018MageNotes": "Sous l’eau, la magie du feu, de la glace ou de l’électricité peut être dangereuse pour le mage qui la détient. Soigner le poison des vives, par contre, est très utile ! Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée de l’été 2018.",
"weaponSpecialSummer2018HealerText": "Trident de Sirène Monarque",
"weaponSpecialSummer2018HealerNotes": "D'un geste bienveillant, vous commandez aux eaux revigorantes de couler en vagues à travers votre équipement. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'été 2018.",
"weaponSpecialFall2018RogueText": "Fiole de clarté",
- "weaponSpecialFall2018RogueNotes": "Quand vous avez besoin de revenir à la raison, quand vous avez besoin d'un petit coup de pouce, prenez une grande inspiration et une gorgée. Ça va aller ! Augmente la Force de<%= str %>. Équipement d'Automne en édition limitée 2018.",
+ "weaponSpecialFall2018RogueNotes": "Quand vous avez besoin de revenir à la raison, quand vous avez besoin d'un petit coup de pouce, prenez une grande inspiration et une gorgée. Ça va aller ! Augmente la force de<%= str %>. Équipement d'Automne en édition limitée 2018.",
"weaponSpecialFall2018WarriorText": "Fouet de Minos",
- "weaponSpecialFall2018WarriorNotes": "Pas vraiment assez long pour se dérouler derrière vous et vous aider à trouver votre chemin dans un labyrinthe. Enfin, peut-être dans un très petit labyrinthe. Augmente la Force de<%= str %>. Équipement d'Automne en édition limitée 2018.",
+ "weaponSpecialFall2018WarriorNotes": "Pas vraiment assez long pour se dérouler derrière vous et vous aider à trouver votre chemin dans un labyrinthe. Enfin, peut-être dans un très petit labyrinthe. Augmente la force de <%= str %>. Équipement d'Automne en édition limitée 2018.",
"weaponSpecialFall2018MageText": "Bâton du Délice",
- "weaponSpecialFall2018MageNotes": "C'est loin d'être une sucette ordinaire ! L'orbe rougeoyante de sucre magique perchée en haut de ce bâton possède le pouvoir de coller les bonnes habitudes à vous. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Équipement d'Automne en édition limitée 2018.",
+ "weaponSpecialFall2018MageNotes": "C'est loin d'être une sucette ordinaire ! L'orbe rougeoyante de sucre magique perchée en haut de ce bâton possède le pouvoir de coller les bonnes habitudes à vous. Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement d'Automne en édition limitée 2018.",
"weaponSpecialFall2018HealerText": "Bâton glouton",
- "weaponSpecialFall2018HealerNotes": "Il suffit de nourrir ce bâton, et celui-ci accordera des bénédictions. Si vous oubliez de le nourrir, attention à vos doigts. Augmente l'Intelligence de <%= int %>. Équipement d'Automne en édition limitée 2018.",
+ "weaponSpecialFall2018HealerNotes": "Il suffit de nourrir ce bâton, et celui-ci accordera des bénédictions. Si vous oubliez de le nourrir, attention à vos doigts. Augmente l'intelligence de <%= int %>. Équipement d'Automne en édition limitée 2018.",
"weaponSpecialWinter2019RogueText": "Bouquet de poinsettia",
"weaponSpecialWinter2019RogueNotes": "Utilisez ce bouquet festif pour vous camoufler encore mieux, ou pour l'offrir et égayer la journée d'un ami. Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2018-2019.",
"weaponSpecialWinter2019WarriorText": "Hallebarde flocon-de-neige",
@@ -297,57 +297,57 @@
"weaponMystery301404Text": "Canne steampunk",
"weaponMystery301404Notes": "Parfaite pour faire un tour en ville. N'apporte aucun bonus. Équipement d'abonnement de mars 3015.",
"weaponArmoireBasicCrossbowText": "Arbalète basique",
- "weaponArmoireBasicCrossbowNotes": "Cette arbalète peut percer l'armure d'une tâche de très loin ! Augmente la Force de <%= str %>, la Perception de <%= per %> et la Constitution de <%= con %>. Armoire enchantée : objet indépendant.",
+ "weaponArmoireBasicCrossbowNotes": "Cette arbalète peut percer l'armure d'une tâche de très loin ! Augmente la force de <%= str %>, la perception de <%= per %> et la constitution de <%= con %>. Armoire enchantée : objet indépendant.",
"weaponArmoireLunarSceptreText": "Sceptre lunaire apaisant",
- "weaponArmoireLunarSceptreNotes": "Le pouvoir guérisseur de cette baguette croît et décroit. Augmente la Constitution de <%= con %> et l'Intelligence de <%= int %>. Armoire enchantée : ensemble lunaire apaisant (objet 3 sur 3).",
+ "weaponArmoireLunarSceptreNotes": "Le pouvoir guérisseur de cette baguette croît et décroît. Augmente la constitution de <%= con %> et l'intelligence de <%= int %>. Armoire enchantée : ensemble lunaire apaisant (objet 3 sur 3).",
"weaponArmoireRancherLassoText": "Lasso d'éleveur",
- "weaponArmoireRancherLassoNotes": "Les lassos : l'outil idéal pour rassembler et maîtriser vos animaux. Augmente la Force de <%= str %>, la Perception de <%= per %> et l'Intelligence de <%= int %>. Armoire enchantée : ensemble de l'éleveur (objet 3 sur 3).",
+ "weaponArmoireRancherLassoNotes": "Les lassos : l'outil idéal pour rassembler et maîtriser vos animaux. Augmente la force de <%= str %>, la perception de <%= per %> et l'intelligence de <%= int %>. Armoire enchantée : ensemble de l'éleveur (objet 3 sur 3).",
"weaponArmoireMythmakerSwordText": "Epée mythologique",
- "weaponArmoireMythmakerSwordNotes": "Bien qu'elle puisse sembler humble, cette épée a formé bien des héros mythiques. Augmente la Perception et la Force de <%= attrs %> chacune. Armoire enchantée : ensemble de la toge dorée (objet 3 sur 3).",
+ "weaponArmoireMythmakerSwordNotes": "Bien qu'elle puisse sembler humble, cette épée a formé bien des héros mythiques. Augmente la perception et la force de <%= attrs %> chacune. Armoire enchantée : ensemble de la toge dorée (objet 3 sur 3).",
"weaponArmoireIronCrookText": "Crochet de fer",
- "weaponArmoireIronCrookNotes": "Férocement forgé dans le fer, ce crochet en fer est bon pour rassembler les moutons. Augmente la Perception et la Force de <%= attrs %> chacune. Armoire enchantée : ensemble des cornes de fer (objet 3 sur 3).",
+ "weaponArmoireIronCrookNotes": "Férocement forgé dans le fer, ce crochet en fer est bon pour rassembler les moutons. Augmente la perception et la force de <%= attrs %> chacune. Armoire enchantée : ensemble des cornes de fer (objet 3 sur 3).",
"weaponArmoireGoldWingStaffText": "Bâton aux ailes d'or",
"weaponArmoireGoldWingStaffNotes": "Les ailes de ce bâton s'agitent et se tordent en permanence. Augmente tous les attributs de <%= attrs %> chacun. Armoire enchantée : objet indépendant.",
"weaponArmoireBatWandText": "Baguette chauve-souris",
- "weaponArmoireBatWandNotes": "Cette baguette peut transformer n'importe quelle tâche en chauve-souris! Agitez-la dans tous les sens et regardez-les s'envoler. Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Armoire enchantée: objet indépendant.",
+ "weaponArmoireBatWandNotes": "Cette baguette peut transformer n'importe quelle tâche en chauve-souris! Agitez-la dans tous les sens et regardez-les s'envoler. Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Armoire enchantée: objet indépendant.",
"weaponArmoireShepherdsCrookText": "Houlette de berger",
- "weaponArmoireShepherdsCrookNotes": "Utile pour rassembler les griffons. Augmente la Constitution de <%= con %>. Armoire enchantée : ensemble du berger (objet 1 sur 3).",
+ "weaponArmoireShepherdsCrookNotes": "Utile pour rassembler les griffons. Augmente la constitution de <%= con %>. Armoire enchantée : ensemble du berger (objet 1 sur 3).",
"weaponArmoireCrystalCrescentStaffText": "Bâton du croissant de cristal",
- "weaponArmoireCrystalCrescentStaffNotes": "Invoquez le pouvoir du croissant de lune grâce à ce bâton étincelant ! Augmente l'Intelligence et la Force de <%= attrs %> chacune. Armoire enchantée : ensemble du croissant de cristal (objet 3 sur 3).",
+ "weaponArmoireCrystalCrescentStaffNotes": "Invoquez le pouvoir du croissant de lune grâce à ce bâton étincelant ! Augmente l'intelligence et la force de <%= attrs %> chacune. Armoire enchantée : ensemble du croissant de cristal (objet 3 sur 3).",
"weaponArmoireBlueLongbowText": "Arc long bleu",
- "weaponArmoireBlueLongbowNotes": "Prêts... Visez... Feu ! Cet arc a une très longue portée. Augmente la Perception de <%= per %>, la Constitution de <%= con %> et la Force de <%= str %>. Armoire enchantée : ensemble de l'archer d'acier (objet 3 sur 3).",
+ "weaponArmoireBlueLongbowNotes": "Prêts... Visez... Feu ! Cet arc a une très longue portée. Augmente la perception de <%= per %>, la constitution de <%= con %> et la force de <%= str %>. Armoire enchantée : ensemble de l'archer d'acier (objet 3 sur 3).",
"weaponArmoireGlowingSpearText": "Lance rayonnante",
- "weaponArmoireGlowingSpearNotes": "Cette lance hypnotise les tâches sauvages afin que vous les attaquiez. Augmente la Force de <%= str %>. Armoire enchantée : objet indépendant.",
+ "weaponArmoireGlowingSpearNotes": "Cette lance hypnotise les tâches sauvages afin que vous les attaquiez. Augmente la force de <%= str %>. Armoire enchantée : objet indépendant.",
"weaponArmoireBarristerGavelText": "Marteau d'avocat",
- "weaponArmoireBarristerGavelNotes": "De l'ordre ! Augmente la Force et la Constitution de <%= attrs %> chacune. Armoire enchantée : ensemble de l'avocat (objet 3 sur 3).",
+ "weaponArmoireBarristerGavelNotes": "De l'ordre ! Augmente la force et la constitution de <%= attrs %> chacune. Armoire enchantée : ensemble de l'avocat (objet 3 sur 3).",
"weaponArmoireJesterBatonText": "Bâton de bouffon",
- "weaponArmoireJesterBatonNotes": "Avec un geste de votre bâton et une répartie saillante, même les situations les plus compliquées deviennent simples. Augmente l'Intelligence et la Perception de <%= attrs %> chacune. Armoire enchantée : ensemble du bouffon (objet 3 sur 3).",
+ "weaponArmoireJesterBatonNotes": "Avec un geste de votre bâton et une répartie saillante, même les situations les plus compliquées deviennent simples. Augmente l'intelligence et la perception de <%= attrs %> chacune. Armoire enchantée : ensemble du bouffon (objet 3 sur 3).",
"weaponArmoireMiningPickaxText": "Pioche de minage",
- "weaponArmoireMiningPickaxNotes": "Minez la quantité maximale d'or de vos tâches ! Augmente la Perception de <%= per %>. Armoire enchantée : ensemble du mineur (objet 3 sur 3).",
+ "weaponArmoireMiningPickaxNotes": "Minez la quantité maximale d'or de vos tâches ! Augmente la perception de <%= per %>. Armoire enchantée : ensemble du mineur (objet 3 sur 3).",
"weaponArmoireBasicLongbowText": "Arc long de base",
- "weaponArmoireBasicLongbowNotes": "Un arc facile à prendre en main. Augmente la Force de <%= str %>. Armoire enchantée : ensemble de l'archer de base (objet 1 sur 3).",
+ "weaponArmoireBasicLongbowNotes": "Un arc facile à prendre en main. Augmente la force de <%= str %>. Armoire enchantée : ensemble de l'archer de base (objet 1 sur 3).",
"weaponArmoireHabiticanDiplomaText": "Diplôme d'Habitica",
- "weaponArmoireHabiticanDiplomaNotes": "Le certificat d'un succès significatif. Bravo ! Augmente l'Intelligence de <%= int %>. Armoire enchantée : ensemble des diplômés (objet 1 sur 3).",
+ "weaponArmoireHabiticanDiplomaNotes": "Le certificat d'un succès significatif. Bravo ! Augmente l'intelligence de <%= int %>. Armoire enchantée : ensemble des diplômés (objet 1 sur 3).",
"weaponArmoireSandySpadeText": "Pelle sablonneuse",
- "weaponArmoireSandySpadeNotes": "Un outil pour creuser, mais aussi pour envoyer du sable dans les yeux des monstres ennemis. Augmente la Force de <%= str %>. Armoire enchantée : ensemble du bord de mer (objet 1 sur 3).",
+ "weaponArmoireSandySpadeNotes": "Un outil pour creuser, mais aussi pour envoyer du sable dans les yeux des monstres ennemis. Augmente la force de <%= str %>. Armoire enchantée : ensemble du bord de mer (objet 1 sur 3).",
"weaponArmoireCannonText": "Canon",
- "weaponArmoireCannonNotes": "Arr ! Visez avec détermination. Augmente la Force de <%= str %>. Armoire enchantée : ensemble du canonnier (objet 1 sur 3).",
+ "weaponArmoireCannonNotes": "Arr ! Visez avec détermination. Augmente la force de <%= str %>. Armoire enchantée : ensemble du canonnier (objet 1 sur 3).",
"weaponArmoireVermilionArcherBowText": "Arc de l'archer vermillon",
- "weaponArmoireVermilionArcherBowNotes": "Votre flèche s'élancera comme une étoile filante de ce brillant arc rouge ! Augmente la Force de <%= str %>. Armoire enchantée : ensemble de l'archer vermillon (objet 1 sur 3).",
+ "weaponArmoireVermilionArcherBowNotes": "Votre flèche s'élancera comme une étoile filante de ce brillant arc rouge ! Augmente la force de <%= str %>. Armoire enchantée : ensemble de l'archer vermillon (objet 1 sur 3).",
"weaponArmoireOgreClubText": "Matraque d'ogre",
- "weaponArmoireOgreClubNotes": "Cette matraque a été récupérée dans une vraie tanière d'ogre. Augmente la Force de <%= str %>. Armoire enchantée : costume d'ogre (objet 2 sur 3).",
+ "weaponArmoireOgreClubNotes": "Cette matraque a été récupérée dans une vraie tanière d'ogre. Augmente la force de <%= str %>. Armoire enchantée : costume d'ogre (objet 2 sur 3).",
"weaponArmoireWoodElfStaffText": "Bâton d'elfe des bois",
- "weaponArmoireWoodElfStaffNotes": "Sculpté dans une branche tombée d'un arbre millénaire, ce bâton vous permettra de communiquer avec tous les habitants de la forêt, des plus petits aux plus grands. Augmente l'Intelligence de <%= int %>. Armoire enchantée : ensemble de l'elfe des bois (objet 3 sur 3).",
+ "weaponArmoireWoodElfStaffNotes": "Sculpté dans une branche tombée d'un arbre millénaire, ce bâton vous permettra de communiquer avec tous les habitants de la forêt, des plus petits aux plus grands. Augmente l'intelligence de <%= int %>. Armoire enchantée : ensemble de l'elfe des bois (objet 3 sur 3).",
"weaponArmoireWandOfHeartsText": "Baguette de cœur",
- "weaponArmoireWandOfHeartsNotes": "Cette baguette magique étincelle d'une chaleureuse lueur rouge. Elle insufflera également de la sagesse dans votre cœur. Augmente l'Intelligence de <%= int %>. Armoire enchantée : ensemble de la reine de cœur (objet 3 sur 3).",
+ "weaponArmoireWandOfHeartsNotes": "Cette baguette magique étincelle d'une chaleureuse lueur rouge. Elle insufflera également de la sagesse dans votre cœur. Augmente l'intelligence de <%= int %>. Armoire enchantée : ensemble de la reine de cœur (objet 3 sur 3).",
"weaponArmoireForestFungusStaffText": "Bâton de champignon forestier",
- "weaponArmoireForestFungusStaffNotes": "Utilisez ce bâton noueux pour faire de la magie mycologique ! Augmente l'Intelligence de <%= int %> et la Perception de <%= per %>. Armoire enchantée : objet indépendant.",
+ "weaponArmoireForestFungusStaffNotes": "Utilisez ce bâton noueux pour faire de la magie mycologique ! Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Armoire enchantée : objet indépendant.",
"weaponArmoireFestivalFirecrackerText": "Pétard de festival",
- "weaponArmoireFestivalFirecrackerNotes": "Regardez autour de vous avant d'allumer ce cierge magique. Augmente la Perception de <%= per %>. Armoire enchantée : ensemble du festivalier (objet 3 sur 3).",
+ "weaponArmoireFestivalFirecrackerNotes": "Regardez autour de vous avant d'allumer ce cierge magique. Augmente la perception de <%= per %>. Armoire enchantée : ensemble du festivalier (objet 3 sur 3).",
"weaponArmoireMerchantsDisplayTrayText": "Présentoir de marchand",
- "weaponArmoireMerchantsDisplayTrayNotes": "Servez-vous de ce présentoir laqué pour exposer les marchandises raffinées que vous proposez à la vente. Augmente l'Intelligence de <%= int %>. Armoire enchantée : ensemble du marchand (objet 3 sur 3).",
+ "weaponArmoireMerchantsDisplayTrayNotes": "Servez-vous de ce présentoir laqué pour exposer les marchandises raffinées que vous proposez à la vente. Augmente l'intelligence de <%= int %>. Armoire enchantée : ensemble du marchand (objet 3 sur 3).",
"weaponArmoireBattleAxeText": "Hache ancienne",
- "weaponArmoireBattleAxeNotes": "Cette hache en fer est parfaitement adaptée au combat contre vos adversaires les plus féroces ou vos tâches les plus ardues. Augmente l'Intelligence de <%= int %> et la Constitution de <%= con %>. Armoire enchantée : objet indépendant.",
+ "weaponArmoireBattleAxeNotes": "Cette hache en fer est parfaitement adaptée au combat contre vos adversaires les plus féroces ou vos tâches les plus ardues. Augmente l'intelligence de <%= int %> et la constitution de <%= con %>. Armoire enchantée : objet indépendant.",
"weaponArmoireHoofClippersText": "Pince à parer",
"weaponArmoireHoofClippersNotes": "Taillez les sabots de vos montures de somme, pour les aider à rester en bonne santé tandis qu'elles vous amènent à l'aventure ! Augmente la Force, l'Intelligence et la Constitution de <%= attrs %> chacune. Armoire enchantée : ensemble du maréchal-ferrant (objet 1 sur 3).",
"weaponArmoireWeaversCombText": "Peigne de tisserand",
@@ -355,7 +355,7 @@
"weaponArmoireLamplighterText": "Allumeur de réverbères",
"weaponArmoireLamplighterNotes": "Ce long mât possède une mèche sur une extrémité pour allumer des lampes, et un crochet sur l'autre extrémité pour les éteindre. Augmente la Constitution de <%= con %> et la Perception de <%= per %>. Armoire enchantée : ensemble de l'éclaireur (objet 1 sur 4)",
"weaponArmoireCoachDriversWhipText": "Fouet du cocher",
- "weaponArmoireCoachDriversWhipNotes": "Vos montures savent ce qu'elles font, donc le fouet n'est là que pour le spectacle (et le bruit net du claquement !). Augmente l'Intelligence de<%= int %> et la Force de <%= str %>. Armoire enchantée : ensemble du cocher (objet 3 sur 3).",
+ "weaponArmoireCoachDriversWhipNotes": "Vos montures savent ce qu'elles font, donc le fouet n'est là que pour le spectacle (et le bruit net du claquement !). Augmente l'Intelligence de <%= int %> et la Force de <%= str %>. Armoire enchantée : ensemble du cocher (objet 3 sur 3).",
"weaponArmoireScepterOfDiamondsText": "Sceptre de carreau",
"weaponArmoireScepterOfDiamondsNotes": "Ce sceptre brille d'une chaude lueur rouge alors qu'il accroît votre volonté. Augmente la Force de <%= str %>. Armoire enchantée : ensemble du roi de carreau (objet 3 sur 4).",
"weaponArmoireFlutteryArmyText": "Armée papillonnante",
@@ -367,101 +367,101 @@
"weaponArmoirePoisonedGobletText": "Gobelet empoisonné",
"weaponArmoirePoisonedGobletNotes": "Servez-vous de ceci pour augmenter votre résistance à l'iocane en poudre et autres poisons incroyablement dangereux. Augmente l'Intelligence de <%= int %>. Armoire enchantée : ensemble de princesse de la piraterie (objet 3 sur 4).",
"weaponArmoireJeweledArcherBowText": "Arc en joyaux",
- "weaponArmoireJeweledArcherBowNotes": "Cet arc en or et en gemmes enverra vos flèches sur leurs cibles à des vitesses incroyables. Augmente l'intelligence de <%= int %>. Armoire enchantée : Ensemble de l'Archer aux joyaux (Objet 3 de 3).",
+ "weaponArmoireJeweledArcherBowNotes": "Cet arc en or et en gemmes enverra vos flèches sur leurs cibles à des vitesses incroyables. Augmente l'intelligence de <%= int %>. Armoire enchantée : ensemble de l'archer aux joyaux (Objet 3 de 3).",
"weaponArmoireNeedleOfBookbindingText": "Aiguille de reliure",
- "weaponArmoireNeedleOfBookbindingNotes": "La robustesse des livres est étonnante. Mais cette aiguille peu percer le cœur de vos corvées. Augmente la force de <%= str %>. Armoire enchantée : Ensemble du relieur (Objet 3 de 4).",
+ "weaponArmoireNeedleOfBookbindingNotes": "La robustesse des livres est étonnante. Mais cette aiguille peu percer le cœur de vos corvées. Augmente la force de <%= str %>. Armoire enchantée : ensemble du relieur (Objet 3 de 4).",
"weaponArmoireSpearOfSpadesText": "Lance de Pique",
- "weaponArmoireSpearOfSpadesNotes": "Cette lance chevaleresque est parfaite pour attaquer vos Habitudes et vos Quotidiennes les plus rouges. Augmente la Constitution de <%= con %>. Armoire enchantée : Set As de Pique (objet 3 sur 3).",
+ "weaponArmoireSpearOfSpadesNotes": "Cette lance chevaleresque est parfaite pour attaquer vos habitudes et vos quotidiennes les plus rouges. Augmente la Constitution de <%= con %>. Armoire enchantée : ensemble de l'as de pique (objet 3 sur 3).",
"weaponArmoireArcaneScrollText": "Parchemin arcanique",
- "weaponArmoireArcaneScrollNotes": "Cette ancienne liste de tâches est remplie d'étranges symboles et de sorts d'un âge oublié. Augmente l'intelligence de <%= int %>. Armoire enchantée : Ensemble du scribe (objet 3 de 3).",
+ "weaponArmoireArcaneScrollNotes": "Cette ancienne liste de tâches est remplie d'étranges symboles et de sorts d'un âge oublié. Augmente l'intelligence de <%= int %>. Armoire enchantée : ensemble du scribe (objet 3 de 3).",
"armor": "armure",
"armorCapitalized": "Armure",
"armorBase0Text": "Habit simple",
"armorBase0Notes": "Un vêtement ordinaire. N'apporte aucun bonus.",
"armorWarrior1Text": "Armure de cuir",
- "armorWarrior1Notes": "Un gilet fait de peaux tannées solides. Augmente la Constitution de <%= con %>.",
+ "armorWarrior1Notes": "Un gilet fait de peaux tannées solides. Augmente la constitution de <%= con %>.",
"armorWarrior2Text": "Cotte de mailles",
- "armorWarrior2Notes": "Une armure faite d'anneaux métalliques entrecroisés. Augmente la Constitution de <%= con %>.",
+ "armorWarrior2Notes": "Une armure faite d'anneaux métalliques entrecroisés. Augmente la constitution de <%= con %>.",
"armorWarrior3Text": "Armure de plaques",
- "armorWarrior3Notes": "Tenue recouverte d'acier, la fierté des chevaliers. Augmente la Constitution de <%= con %>.",
+ "armorWarrior3Notes": "Tenue recouverte d'acier, la fierté des chevaliers. Augmente la constitution de <%= con %>.",
"armorWarrior4Text": "Armure rouge",
- "armorWarrior4Notes": "Plaque lourde rendue brillante par des enchantements défensifs. Augmente la Constitution de <%= con %>.",
+ "armorWarrior4Notes": "Plaque lourde rendue brillante par des enchantements défensifs. Augmente la constitution de <%= con %>.",
"armorWarrior5Text": "Armure d'or",
- "armorWarrior5Notes": "D'aspect cérémonial, mais aucune lame connue ne peut la transpercer. Augmente la Constitution de <%= con %>.",
+ "armorWarrior5Notes": "D'aspect cérémonial, mais aucune lame connue ne peut la transpercer. Augmente la constitution de <%= con %>.",
"armorRogue1Text": "Cuir huilé",
- "armorRogue1Notes": "Armure de cuir traitée pour réduire le bruit. Augmente la Perception de <%= per %>.",
+ "armorRogue1Notes": "Armure de cuir traitée pour réduire le bruit. Augmente la perception de <%= per %>.",
"armorRogue2Text": "Cuir noir",
- "armorRogue2Notes": "Colorée avec une teinture foncée pour se fondre dans les ombres. Augmente la Perception de <%= per %>.",
+ "armorRogue2Notes": "Colorée avec une teinture foncée pour se fondre dans les ombres. Augmente la perception de <%= per %>.",
"armorRogue3Text": "Gilet de camouflage",
- "armorRogue3Notes": "Aussi discret dans les donjons que dans la nature. Augmente la Perception de <%= per %>.",
+ "armorRogue3Notes": "Aussi discret dans les donjons que dans la nature. Augmente la perception de <%= per %>.",
"armorRogue4Text": "Armure de pénombre",
- "armorRogue4Notes": "Enveloppe le porteur d'un voile de crépuscule. Augmente la Perception de <%= per %>.",
+ "armorRogue4Notes": "Enveloppe le porteur d'un voile de crépuscule. Augmente la perception de <%= per %>.",
"armorRogue5Text": "Armure des ombres",
- "armorRogue5Notes": "Permet la furtivité à découvert et en pleine lumière. Augmente la Perception de <%= per %>.",
+ "armorRogue5Notes": "Permet la furtivité à découvert et en pleine lumière. Augmente la perception de <%= per %>.",
"armorWizard1Text": "Robe de magicien",
- "armorWizard1Notes": "La tenue du mage de protection. Augmente l'Intelligence de <%= int %>.",
+ "armorWizard1Notes": "La tenue du mage de protection. Augmente l'intelligence de <%= int %>.",
"armorWizard2Text": "Robe de sorcier",
- "armorWizard2Notes": "La tenue d'un faiseur de prodiges ambulant. Augmente l'Intelligence de <%= int %>.",
+ "armorWizard2Notes": "La tenue d'un faiseur de prodiges ambulant. Augmente l'intelligence de <%= int %>.",
"armorWizard3Text": "Robe de mystères",
- "armorWizard3Notes": "La marque de l'initiation aux secrets de l'élite. Augmente l'Intelligence de <%= int %>.",
+ "armorWizard3Notes": "La marque de l'initiation aux secrets de l'élite. Augmente l'intelligence de <%= int %>.",
"armorWizard4Text": "Robe d'archimage",
- "armorWizard4Notes": "Les esprits et les élémentaires s'inclinent devant elle. Augmente l'Intelligence de <%= int %>.",
+ "armorWizard4Notes": "Les esprits et les élémentaires s'inclinent devant elle. Augmente l'intelligence de <%= int %>.",
"armorWizard5Text": "Robe de mage royal",
- "armorWizard5Notes": "Symbole du pouvoir derrière le trône. Augmente l'Intelligence de <%= int %>.",
+ "armorWizard5Notes": "Symbole du pouvoir derrière le trône. Augmente l'intelligence de <%= int %>.",
"armorHealer1Text": "Robe d'acolyte",
- "armorHealer1Notes": "Un vêtement pratique et humble. Augmente la Constitution de <%= con %>.",
+ "armorHealer1Notes": "Un vêtement pratique et humble. Augmente la constitution de <%= con %>.",
"armorHealer2Text": "Robe de soigneur",
- "armorHealer2Notes": "Porté par ceux qui s'occupent des blessés sur le champs de bataille. Augmente la Constitution de <%= con %>.",
+ "armorHealer2Notes": "Porté par ceux qui s'occupent des blessés sur le champs de bataille. Augmente la constitution de <%= con %>.",
"armorHealer3Text": "Manteau de défenseur",
- "armorHealer3Notes": "Concentre la magie du soigneur afin de parer les blessures. Augmente la Constitution de <%= con %>.",
+ "armorHealer3Notes": "Concentre la magie du soigneur afin de parer les blessures. Augmente la constitution de <%= con %>.",
"armorHealer4Text": "Manteau de médecin",
- "armorHealer4Notes": "Inspire l'autorité et dissipe les malédictions. Augmente la Constitution de <%= con %>.",
+ "armorHealer4Notes": "Inspire l'autorité et dissipe les malédictions. Augmente la constitution de <%= con %>.",
"armorHealer5Text": "Manteau royal",
- "armorHealer5Notes": "L'habit de ceux qui ont sauvé des vies de rois. Augmente la Constitution de <%= con %>.",
+ "armorHealer5Notes": "L'habit de ceux qui ont sauvé des vies de rois. Augmente la constitution de <%= con %>.",
"armorSpecial0Text": "Armure d'ombre",
- "armorSpecial0Notes": "Hurle quand on la frappe car elle ressent la douleur de son porteur à sa place. Augmente la Constitution de <%= con %>.",
+ "armorSpecial0Notes": "Hurle quand on la frappe car elle ressent la douleur de son porteur à sa place. Augmente la constitution de <%= con %>.",
"armorSpecial1Text": "Armure de cristal",
"armorSpecial1Notes": "Son pouvoir inlassable habitue son porteur à l'inconfort ordinaire. Augmente tous les attributs de <%= attrs %>.",
"armorSpecial2Text": "Tunique noble de Jean Chalard",
- "armorSpecial2Notes": "Vous rend super moelleux ! Augmente la Consitution et l'Intelligence de <%= attrs %>.",
+ "armorSpecial2Notes": "Vous rend super moelleux ! Augmente la constitution et l'intelligence de <%= attrs %>.",
"armorSpecialTakeThisText": "Armure Take This",
"armorSpecialTakeThisNotes": "Cette armure a été obtenue en participant à un défi sponsorisé créé par Take This. Félicitations ! Augmente tous les attributs de <%= attrs %>.",
"armorSpecialFinnedOceanicArmorText": "Armure océanique à nageoire",
- "armorSpecialFinnedOceanicArmorNotes": "Bien qu'elle soit délicate, cette armure rend votre peau aussi dangereuse à toucher qu'un corail de feu. Augmente la Force de <%= str %>.",
+ "armorSpecialFinnedOceanicArmorNotes": "Bien qu'elle soit délicate, cette armure rend votre peau aussi dangereuse à toucher qu'un corail de feu. Augmente la force de <%= str %>.",
"armorSpecialPyromancersRobesText": "Robe de pyromancienne",
- "armorSpecialPyromancersRobesNotes": "Cette élégante robe ajoute une explosion de feu éthéré à chaque coup et sortilège. Augmente la Constitution de <%= con %>.",
+ "armorSpecialPyromancersRobesNotes": "Cette élégante robe ajoute une explosion de feu éthéré à chaque coup et sortilège. Augmente la constitution de <%= con %>.",
"armorSpecialBardRobesText": "Robes de barde",
- "armorSpecialBardRobesNotes": "Ces robes colorées peuvent paraître voyantes, mais elles vous permettront de vous sortir de n'importe quelle situation en chantant. Augmente la Perception de <%= per %>.",
+ "armorSpecialBardRobesNotes": "Ces robes colorées peuvent paraître voyantes, mais elles vous permettront de vous sortir de n'importe quelle situation en chantant. Augmente la perception de <%= per %>.",
"armorSpecialLunarWarriorArmorText": "Armure de guerrier lunaire",
- "armorSpecialLunarWarriorArmorNotes": "Cette armure est forgée en pierres de lune et en acier magique. Augmente la Force et la Constitution de <%= attrs %> chacune.",
+ "armorSpecialLunarWarriorArmorNotes": "Cette armure est forgée en pierres de lune et en acier magique. Augmente la force et la constitution de <%= attrs %> chacune.",
"armorSpecialMammothRiderArmorText": "Armure de chevaucheur de mammouths",
- "armorSpecialMammothRiderArmorNotes": "Cette tenue de fourrure et de cuir s'accompagne d'une cape très chic, cloutée de quartz roses. Elle vous protégera des vents glaciaux sous les cieux les plus froids. Augmente la Constitution de <%= con %>.",
+ "armorSpecialMammothRiderArmorNotes": "Cette tenue de fourrure et de cuir s'accompagne d'une cape très chic, cloutée de quartz roses. Elle vous protégera des vents glaciaux sous les cieux les plus froids. Augmente la constitution de <%= con %>.",
"armorSpecialPageArmorText": "Armure de page",
- "armorSpecialPageArmorNotes": "Portez tout ce dont vous avez besoin dans votre sac parfait ! Augmente la Constitution de <%= con %>.",
+ "armorSpecialPageArmorNotes": "Portez tout ce dont vous avez besoin dans votre sac parfait ! Augmente la constitution de <%= con %>.",
"armorSpecialRoguishRainbowMessengerRobesText": "Tunique du malicieux messager arc-en-ciel",
- "armorSpecialRoguishRainbowMessengerRobesNotes": "Cette tunique bariolée vous permettra de franchir les vents les plus tempétueux, tout en douceur et tout en sécurité. Augmente la Force de <%= str %>.",
+ "armorSpecialRoguishRainbowMessengerRobesNotes": "Cette tunique bariolée vous permettra de franchir les vents les plus tempétueux, tout en douceur et tout en sécurité. Augmente la force de <%= str %>.",
"armorSpecialSneakthiefRobesText": "Tenue de chapardeur",
- "armorSpecialSneakthiefRobesNotes": "Cette tenue vous aidera à rester tapi dans l'ombre de la nuit, et préservera votre liberté de mouvements tandis que vous vous faufilez partout ! Augmente l'Intelligence de <%= int %>.",
+ "armorSpecialSneakthiefRobesNotes": "Cette tenue vous aidera à rester tapi dans l'ombre de la nuit, et préservera votre liberté de mouvements tandis que vous vous faufilez partout ! Augmente l'intelligence de <%= int %>.",
"armorSpecialSnowSovereignRobesText": "Tenue hivernale de souverain",
- "armorSpecialSnowSovereignRobesNotes": "Cette modeste est suffisamment élégante pour être portée à la cour, et suffisamment chaude pour vous protéger des jours les plus froids. Augmente la Perception de <%= per %>.",
+ "armorSpecialSnowSovereignRobesNotes": "Cette modeste est suffisamment élégante pour être portée à la cour, et suffisamment chaude pour vous protéger des jours les plus froids. Augmente la perception de <%= per %>.",
"armorSpecialNomadsCuirassText": "Cuirasse de nomade",
- "armorSpecialNomadsCuirassNotes": "Cette armure est équipée d'un plastron qui protège votre cœur ! Augmente la Constitution de <%= con %>.",
+ "armorSpecialNomadsCuirassNotes": "Cette armure est équipée d'un plastron qui protège votre cœur ! Augmente la constitution de <%= con %>.",
"armorSpecialDandySuitText": "Complet de dandy",
- "armorSpecialDandySuitNotes": "Il n'y a pas photo, vous êtes superbe ! Augmente la Perception de <%= per %>.",
+ "armorSpecialDandySuitNotes": "Il n'y a pas photo, vous êtes superbe ! Augmente la perception de <%= per %>.",
"armorSpecialSamuraiArmorText": "Armure de samouraï",
- "armorSpecialSamuraiArmorNotes": "Cette armure épaisse est maintenue par d'élégants cordons en soie. Augmente la Perception de <%= per %>.",
+ "armorSpecialSamuraiArmorNotes": "Cette armure épaisse est maintenue par d'élégants cordons en soie. Augmente la perception de <%= per %>.",
"armorSpecialTurkeyArmorBaseText": "Armure de dindon",
"armorSpecialTurkeyArmorBaseNotes": "Gardez vos baguettes bien au chaud dans cette armure de plumes ! Ne confère aucun bonus.",
"armorSpecialTurkeyArmorGildedText": "Armure de dinde dorée",
"armorSpecialTurkeyArmorGildedNotes": "Pavanez votre garniture dans cette brillante armure saisonnière ! Ne confère aucun bonus.",
"armorSpecialYetiText": "Tunique du dresseur de yéti",
- "armorSpecialYetiNotes": "Flou et féroce. Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'hiver 2013-2014.",
+ "armorSpecialYetiNotes": "Flou et féroce. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'hiver 2013-2014.",
"armorSpecialSkiText": "Parka de ski-sassin",
- "armorSpecialSkiNotes": "Rempli de dagues secrètes et de cartes des pistes de ski. Augmente la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2013-2014.",
+ "armorSpecialSkiNotes": "Rempli de dagues secrètes et de cartes des pistes de ski. Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2013-2014.",
"armorSpecialCandycaneText": "Tunique en sucre d'orge",
- "armorSpecialCandycaneNotes": "Filée à partir de sucre et de soie. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2013-2014.",
+ "armorSpecialCandycaneNotes": "Filée à partir de sucre et de soie. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2013-2014.",
"armorSpecialSnowflakeText": "Tunique flocon-de-neige",
- "armorSpecialSnowflakeNotes": "Une robe qui vous maintient au chaud, même en pleine tempête. Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'hiver 2013-2014.",
+ "armorSpecialSnowflakeNotes": "Une robe qui vous maintient au chaud, même en pleine tempête. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'hiver 2013-2014.",
"armorSpecialBirthdayText": "Tenue de soirée absurde",
"armorSpecialBirthdayNotes": "Joyeux anniversaire Habitica ! Portez cette tenue de soirée absurde pour célébrer cette journée magnifique ! N'apporte aucun bonus.",
"armorSpecialBirthday2015Text": "Tenue de soirée rigolote",
@@ -477,141 +477,141 @@
"armorSpecialGaymerxText": "Armure de guerrier arc-en-ciel",
"armorSpecialGaymerxNotes": "En l'honneur de la conférence GaymerX, cette armure spéciale est décorée avec un motif arc-en-ciel aussi radieux que coloré ! GaymerX est une convention célébrant les LGBTQ et les jeux, et est ouverte à tous.",
"armorSpecialSpringRogueText": "Costume de chat élégant",
- "armorSpecialSpringRogueNotes": "Soigné à la perfection ! Augmente la Perception de <%= per %>. Équipement en édition limitée du printemps 2014.",
+ "armorSpecialSpringRogueNotes": "Soigné à la perfection ! Augmente la perception de <%= per %>. Équipement en édition limitée du printemps 2014.",
"armorSpecialSpringWarriorText": "Armure aux trèfles d'acier",
- "armorSpecialSpringWarriorNotes": "Soyeux comme le trèfle et résistant comme l'acier ! Augmente la Constitution de <%= con %>. Équipement en édition limitée du printemps 2014.",
+ "armorSpecialSpringWarriorNotes": "Soyeux comme le trèfle et résistant comme l'acier ! Augmente la constitution de <%= con %>. Équipement en édition limitée du printemps 2014.",
"armorSpecialSpringMageText": "Bure de rodentia",
- "armorSpecialSpringMageNotes": "Les souris vous sourient ! Augmente l'Intelligence de <%= int %>. Équipement en édition limitée du printemps 2014.",
+ "armorSpecialSpringMageNotes": "Les souris vous sourient ! Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2014.",
"armorSpecialSpringHealerText": "Robe de chiot touffu",
- "armorSpecialSpringHealerNotes": "Chaude et confortable, mais protège quand même son propriétaire des blessures. Augmente la Constitution de <%= con %>. Équipement en édition limitée du printemps 2014.",
+ "armorSpecialSpringHealerNotes": "Chaude et confortable, mais protège quand même son propriétaire des blessures. Augmente la constitution de <%= con %>. Équipement en édition limitée du printemps 2014.",
"armorSpecialSummerRogueText": "Tunique de pirate",
- "armorSpecialSummerRogueNotes": "Cette tunique être très confortable, yarrrr ! Augmente la Perception de <%= per %>. Équipement en édition limitée de l’été 2014.",
+ "armorSpecialSummerRogueNotes": "Cette tunique être très confortable, yarrrr ! Augmente la perception de <%= per %>. Équipement en édition limitée de l’été 2014.",
"armorSpecialSummerWarriorText": "Tunique de bretteur",
- "armorSpecialSummerWarriorNotes": "À compléter avec une boucle de ceinture arborant votre sceau. Augmente la Constitution de <%= con %>. Équipement en édition limitée de l’été 2014.",
+ "armorSpecialSummerWarriorNotes": "À compléter avec une boucle de ceinture arborant votre sceau. Augmente la constitution de <%= con %>. Équipement en édition limitée de l’été 2014.",
"armorSpecialSummerMageText": "Nageoire d'émeraude",
- "armorSpecialSummerMageNotes": "Cet habit d'écailles scintillantes transforme son porteur en un véritable Sorcirène ! Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l’été 2014.",
+ "armorSpecialSummerMageNotes": "Cet habit d'écailles scintillantes transforme son porteur en un véritable Sorcirène ! Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l’été 2014.",
"armorSpecialSummerHealerText": "Nageoire de poissoigneur",
- "armorSpecialSummerHealerNotes": "Cet habit d'écailles scintillantes transforme son porteur en véritable Poissoigneur ! Augmente la Constitution de <%= con %>. Équipement en édition limitée de l’été 2014.",
+ "armorSpecialSummerHealerNotes": "Cet habit d'écailles scintillantes transforme son porteur en véritable Poissoigneur ! Augmente la constitution de <%= con %>. Équipement en édition limitée de l’été 2014.",
"armorSpecialFallRogueText": "Tunique rouge sang",
- "armorSpecialFallRogueNotes": "Vive. Veloutée. Vampirique. Augmente la Perception de <%= per %>. Équipement en édition limitée de l'automne 2014.",
+ "armorSpecialFallRogueNotes": "Vive. Veloutée. Vampirique. Augmente la perception de <%= per %>. Équipement en édition limitée de l'automne 2014.",
"armorSpecialFallWarriorText": "Blouse de labo de science",
- "armorSpecialFallWarriorNotes": "Vous protège des éclaboussures de potions mystérieuses. Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'automne 2014.",
+ "armorSpecialFallWarriorNotes": "Vous protège des éclaboussures de potions mystérieuses. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'automne 2014.",
"armorSpecialFallMageText": "Robes de sorcière",
- "armorSpecialFallMageNotes": "Cette robe dispose de nombreuses poches pour stocker un supplément d'yeux de tritons et de langues de grenouille. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'automne 2014.",
+ "armorSpecialFallMageNotes": "Cette robe dispose de nombreuses poches pour stocker un supplément d'yeux de tritons et de langues de grenouille. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'automne 2014.",
"armorSpecialFallHealerText": "Armure de gaze",
- "armorSpecialFallHealerNotes": "Jetez-vous dans la mêlée en ayant déjà des bandages sur le corps ! Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'automne 2014.",
+ "armorSpecialFallHealerNotes": "Jetez-vous dans la mêlée en ayant déjà des bandages sur le corps ! Augmente la constitution de <%= con %>. Équipement en édition limitée de l'automne 2014.",
"armorSpecialWinter2015RogueText": "Armure de guivre-givre",
- "armorSpecialWinter2015RogueNotes": "Cette armure est gelée, mais il ne fait aucun doute qu'elle en vaudra la chandelle, quand les richesses enfouies dans les tréfonds des cavernes des guivres-givres s'offriront à vous. Non pas que vous convoitiez ces richesses inouïes – non non bien-sûr ! – car vous êtes vraiment, sérieusement, absolument une guivre-givre, n'est-ce pas ?! Arrêtez de poser des questions ! Augmente la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2014-2015.",
+ "armorSpecialWinter2015RogueNotes": "Cette armure est gelée, mais il ne fait aucun doute qu'elle en vaudra la chandelle, quand les richesses enfouies dans les tréfonds des cavernes des guivres-givres s'offriront à vous. Non pas que vous convoitiez ces richesses inouïes – non non bien-sûr ! – car vous êtes vraiment, sérieusement, absolument une guivre-givre, n'est-ce pas ?! Arrêtez de poser des questions ! Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2014-2015.",
"armorSpecialWinter2015WarriorText": "Armure en pain d’épice",
- "armorSpecialWinter2015WarriorNotes": "Bien douillet et bien chaud, tout droit sorti du four ! Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'hiver 2014-2015.",
+ "armorSpecialWinter2015WarriorNotes": "Bien douillet et bien chaud, tout droit sorti du four ! Augmente la constitution de <%= con %>. Équipement en édition limitée de l'hiver 2014-2015.",
"armorSpecialWinter2015MageText": "Robe boréale",
- "armorSpecialWinter2015MageNotes": "Vous percevez les scintillements du nord dans cette robe. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2014-2015.",
+ "armorSpecialWinter2015MageNotes": "Vous percevez les scintillements du nord dans cette robe. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2014-2015.",
"armorSpecialWinter2015HealerText": "Tenue de patinage",
- "armorSpecialWinter2015HealerNotes": "Le patinage, c'est vraiment relaxant, mais vous devriez tout de même porter cette tenue de protection, en cas d'attaque de guivres-givres. Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'hiver 2014-2015.",
+ "armorSpecialWinter2015HealerNotes": "Le patinage, c'est vraiment relaxant, mais vous devriez tout de même porter cette tenue de protection, en cas d'attaque de guivres-givres. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'hiver 2014-2015.",
"armorSpecialSpring2015RogueText": "Robes de rongeur",
- "armorSpecialSpring2015RogueNotes": "Velu, doux, et définitivement pas inflammable. Augmente la Perception de <%= per %>. Équipement en édition limitée du printemps 2015.",
+ "armorSpecialSpring2015RogueNotes": "Velu, doux, et définitivement pas inflammable. Augmente la perception de <%= per %>. Équipement en édition limitée du printemps 2015.",
"armorSpecialSpring2015WarriorText": "Armure de mise en garde",
- "armorSpecialSpring2015WarriorNotes": "Seul le chien le plus féroce est autorisé à être aussi doux et soyeux. Augmente la Constitution de <%= con %>. Équipement en édition limitée du printemps 2015.",
+ "armorSpecialSpring2015WarriorNotes": "Seul le chien le plus féroce est autorisé à être aussi doux et soyeux. Augmente la constitution de <%= con %>. Équipement en édition limitée du printemps 2015.",
"armorSpecialSpring2015MageText": "Costume de lapin de magicien",
- "armorSpecialSpring2015MageNotes": "Plus besoin de patte de lapin, vous en portez deux ! Augmente l'Intelligence de <%= int %>. Équipement en édition limitée du printemps 2015.",
+ "armorSpecialSpring2015MageNotes": "Plus besoin de patte de lapin, vous en portez deux ! Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2015.",
"armorSpecialSpring2015HealerText": "Combinaison réconfortante",
- "armorSpecialSpring2015HealerNotes": "Cette douce combinaison est confortable, et aussi réconfortante qu'un thé à la menthe. Augmente la Constitution de <%= con %>. Équipement en édition limitée du printemps 2015.",
+ "armorSpecialSpring2015HealerNotes": "Cette douce combinaison est confortable, et aussi réconfortante qu'un thé à la menthe. Augmente la constitution de <%= con %>. Équipement en édition limitée du printemps 2015.",
"armorSpecialSummer2015RogueText": "Nageoire de rubis",
- "armorSpecialSummer2015RogueNotes": "Cet habit d'écailles scintillantes transforme son porteur en véritable renégat de corail ! Augmente la Perception de <%= per %>. Équipement en édition limitée de l’été 2015.",
+ "armorSpecialSummer2015RogueNotes": "Cet habit d'écailles scintillantes transforme son porteur en véritable renégat de corail ! Augmente la perception de <%= per %>. Équipement en édition limitée de l’été 2015.",
"armorSpecialSummer2015WarriorText": "Nageoire dorée",
- "armorSpecialSummer2015WarriorNotes": "Cet habit d'écailles scintillantes transforme son porteur en véritable guerrier-lune ! Augmente la Constitution de <%= con %>. Équipement en édition limitée de l’été 2015.",
+ "armorSpecialSummer2015WarriorNotes": "Cet habit d'écailles scintillantes transforme son porteur en véritable guerrier-lune ! Augmente la constitution de <%= con %>. Équipement en édition limitée de l’été 2015.",
"armorSpecialSummer2015MageText": "Robe de devin",
- "armorSpecialSummer2015MageNotes": "Un pouvoir caché réside dans ces manches bouffantes. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l’été 2015.",
+ "armorSpecialSummer2015MageNotes": "Un pouvoir caché réside dans ces manches bouffantes. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l’été 2015.",
"armorSpecialSummer2015HealerText": "Armure de matelot",
- "armorSpecialSummer2015HealerNotes": "Cette armure montre à tout le monde que vous êtes un honnête marchand maritime qui ne se comporterait jamais en voyou. Même pas en rêve ! Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'été 2015.",
+ "armorSpecialSummer2015HealerNotes": "Cette armure montre à tout le monde que vous êtes un honnête marchand maritime qui ne se comporterait jamais en voyou. Même pas en rêve ! Augmente la constitution de <%= con %>. Équipement en édition limitée de l'été 2015.",
"armorSpecialFall2015RogueText": "Armure de bat-aille",
- "armorSpecialFall2015RogueNotes": "Volez vers la bat-aille ! Augmente la Perception de <%= per %>. Équipement en édition limitée de l'automne 2015.",
+ "armorSpecialFall2015RogueNotes": "Volez vers la bat-aille ! Augmente la perception de <%= per %>. Équipement en édition limitée de l'automne 2015.",
"armorSpecialFall2015WarriorText": "Armure d'épouvantail",
- "armorSpecialFall2015WarriorNotes": "Bien qu'elle soit bourrée de paille, cette armure est extrêmement résistante! Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'automne 2015.",
+ "armorSpecialFall2015WarriorNotes": "Bien qu'elle soit bourrée de paille, cette armure est extrêmement résistante! Augmente la constitution de <%= con %>. Équipement en édition limitée de l'automne 2015.",
"armorSpecialFall2015MageText": "Robe rapiécée",
- "armorSpecialFall2015MageNotes": "Chaque couture de cette armure scintille d'un enchantement. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'automne 2015.",
+ "armorSpecialFall2015MageNotes": "Chaque couture de cette armure scintille d'un enchantement. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'automne 2015.",
"armorSpecialFall2015HealerText": "Robe d'alchimiste",
- "armorSpecialFall2015HealerNotes": "Quoi ? Mais bien sûr que c'était une potion de constitution. Non, vous n'êtes sûrement pas en train de vous transformer en grenouille ! Allons, c'est ridicule. Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'automne 2015.",
+ "armorSpecialFall2015HealerNotes": "Quoi ? Mais bien sûr que c'était une potion de constitution. Non, vous n'êtes sûrement pas en train de vous transformer en grenouille ! Allons, c'est ridicule. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'automne 2015.",
"armorSpecialWinter2016RogueText": "Armure cacao",
- "armorSpecialWinter2016RogueNotes": "Cette armure de cuir vous garde bien au chaud. Est-elle réellement faite de cacao ? Vous ne saurez dire. Augmente la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2015-2016.",
+ "armorSpecialWinter2016RogueNotes": "Cette armure de cuir vous garde bien au chaud. Est-elle réellement faite de cacao ? Vous ne saurez dire. Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2015-2016.",
"armorSpecialWinter2016WarriorText": "Équipement de bonhomme de neige",
- "armorSpecialWinter2016WarriorNotes": "Brr ! Cette armure matelassée est super... jusqu'à ce qu'elle fonde. Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'hiver 2015-2016.",
+ "armorSpecialWinter2016WarriorNotes": "Brr ! Cette armure matelassée est super... jusqu'à ce qu'elle fonde. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'hiver 2015-2016.",
"armorSpecialWinter2016MageText": "Anorak de snowboardeur",
- "armorSpecialWinter2016MageNotes": "Un Sorcier avisé reste bien couvert pour affronter le vent d'hiver. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2015-2016.",
+ "armorSpecialWinter2016MageNotes": "Un Sorcier avisé reste bien couvert pour affronter le vent d'hiver. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2015-2016.",
"armorSpecialWinter2016HealerText": "Cape festive féerique",
- "armorSpecialWinter2016HealerNotes": "Les fées festives se protègent en s'enveloppant des ailes de leur corps, utilisent celles de leur tête pour se laisser porter par les vents et volent tout autour d'Habitica à des vitesses montant jusqu'à 150 km/h, livrant leurs présents et recouvrant tout le monde de confettis. C'est tellement drôle. Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'hiver 2015-2016.",
+ "armorSpecialWinter2016HealerNotes": "Les fées festives se protègent en s'enveloppant des ailes de leur corps, utilisent celles de leur tête pour se laisser porter par les vents et volent tout autour d'Habitica à des vitesses montant jusqu'à 150 km/h, livrant leurs présents et recouvrant tout le monde de confettis. C'est tellement drôle. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'hiver 2015-2016.",
"armorSpecialSpring2016RogueText": "Tenue de camouflage canine",
- "armorSpecialSpring2016RogueNotes": "Un chiot malin sait choisir un déguisement plus éclatant afin de se camoufler quand tout est vert et vif. Augmente la Perception de <%= per %>. Équipement en édition limitée du printemps 2016.",
+ "armorSpecialSpring2016RogueNotes": "Un chiot malin sait choisir un déguisement plus éclatant afin de se camoufler quand tout est vert et vif. Augmente la perception de <%= per %>. Équipement en édition limitée du printemps 2016.",
"armorSpecialSpring2016WarriorText": "Cotte de mailles de puissance",
- "armorSpecialSpring2016WarriorNotes": "Toute petite que vous êtes, vous est féroce ! Augmente la Constitution de <%= con %>. Équipement en édition limitée du printemps 2016.",
+ "armorSpecialSpring2016WarriorNotes": "Toute petite que vous êtes, vous est féroce ! Augmente la constitution de <%= con %>. Équipement en édition limitée du printemps 2016.",
"armorSpecialSpring2016MageText": "Robes de grand matou",
- "armorSpecialSpring2016MageNotes": "Hautement colorée, afin que vous ne soyez pas confondu avec un nécromancien. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée du printemps 2016.",
+ "armorSpecialSpring2016MageNotes": "Hautement colorée, afin que vous ne soyez pas confondu avec un nécromancien. Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2016.",
"armorSpecialSpring2016HealerText": "Culotte de lapin touffu",
- "armorSpecialSpring2016HealerNotes": "Hopla hop ! Bondissez de colline colline, soignant ceux qui en ont besoin. Augmente la Constitution de <%= con %>. Équipement en édition limitée du printemps 2016.",
+ "armorSpecialSpring2016HealerNotes": "Hopla hop ! Bondissez de colline colline, soignant ceux qui en ont besoin. Augmente la constitution de <%= con %>. Équipement en édition limitée du printemps 2016.",
"armorSpecialSummer2016RogueText": "Queue d'anguille",
- "armorSpecialSummer2016RogueNotes": "Cet habit électrifiant transforme son porteur en véritable Voleur Anguille ! Augmente la Perception de <%= per %>. Équipement en édition limitée de l’été 2016.",
+ "armorSpecialSummer2016RogueNotes": "Cet habit électrifiant transforme son porteur en véritable voleur anguille ! Augmente la perception de <%= per %>. Équipement en édition limitée de l’été 2016.",
"armorSpecialSummer2016WarriorText": "Nageoire de requin",
- "armorSpecialSummer2016WarriorNotes": "Cet habit rugueux transforme son porteur en véritable Guerrier Requin ! Augmente la Constitution de <%= con %>. Équipement en édition limitée de l’été 2016.",
+ "armorSpecialSummer2016WarriorNotes": "Cet habit rugueux transforme son porteur en véritable guerrier requin ! Augmente la constitution de <%= con %>. Équipement en édition limitée de l’été 2016.",
"armorSpecialSummer2016MageText": "Nageoire de dauphin",
- "armorSpecialSummer2016MageNotes": "Cet habit glissant transforme son porteur en véritable Mage dauphin ! Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l’été 2016.",
+ "armorSpecialSummer2016MageNotes": "Cet habit glissant transforme son porteur en véritable mage dauphin ! Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l’été 2016.",
"armorSpecialSummer2016HealerText": "Queue d'hippocampe",
- "armorSpecialSummer2016HealerNotes": "Cet habit piquant transforme son porteur en véritable Guérisseur Hippocampe ! Augmente la Constitution de <%= con %>. Équipement en édition limitée de l’été 2016.",
+ "armorSpecialSummer2016HealerNotes": "Cet habit piquant transforme son porteur en véritable guérisseur hippocampe ! Augmente la constitution de <%= con %>. Équipement en édition limitée de l’été 2016.",
"armorSpecialFall2016RogueText": "Armure de veuve-noire",
- "armorSpecialFall2016RogueNotes": "Les yeux sur cette armure clignent en permanence. Augmente la Perception de <%=per %>. Équipement en édition limitée de l’automne 2016.",
+ "armorSpecialFall2016RogueNotes": "Les yeux sur cette armure clignent en permanence. Augmente la perception de <%=per %>. Équipement en édition limitée de l’automne 2016.",
"armorSpecialFall2016WarriorText": "Armure gluante",
- "armorSpecialFall2016WarriorNotes": "Mystérieusement humide et moussue ! Augmente la Constitution de <%=con %>. Équipement en édition limitée de l’automne 2016.",
+ "armorSpecialFall2016WarriorNotes": "Mystérieusement humide et moussue ! Augmente la constitution de <%=con %>. Équipement en édition limitée de l’automne 2016.",
"armorSpecialFall2016MageText": "Cape de malice",
- "armorSpecialFall2016MageNotes": "Quand votre cape vole, vous entendez des ricanements. Augmente l'Intelligence de <%=int %>. Équipement en édition limitée de l’automne 2016.",
+ "armorSpecialFall2016MageNotes": "Quand votre cape vole, vous entendez des ricanements. Augmente l'intelligence de <%=int %>. Équipement en édition limitée de l’automne 2016.",
"armorSpecialFall2016HealerText": "Robe de gorgone",
- "armorSpecialFall2016HealerNotes": "Ces robes sont en réalité faites de pierre. Comment peuvent-elles être si confortable ? Augmente la Constitution de <%=con %>. Équipement en édition limitée de l’automne 2016.",
+ "armorSpecialFall2016HealerNotes": "Ces robes sont en réalité faites de pierre. Comment peuvent-elles être si confortable ? Augmente la constitution de <%=con %>. Équipement en édition limitée de l’automne 2016.",
"armorSpecialWinter2017RogueText": "Armure givrée",
- "armorSpecialWinter2017RogueNotes": "Ce costume furtif reflète la lumière et éblouit les tâches sans méfiance tandis que vous obtenez d'elles vos justes récompenses ! Augmente la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2016-2017.",
+ "armorSpecialWinter2017RogueNotes": "Ce costume furtif reflète la lumière et éblouit les tâches sans méfiance tandis que vous obtenez d'elles vos justes récompenses ! Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2016-2017.",
"armorSpecialWinter2017WarriorText": "Armure de hockey sur glace",
- "armorSpecialWinter2017WarriorNotes": "Montrez votre esprit d'équipe et votre force avec cette armure chaude et rembourrée. Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'hiver 2016-2017.",
+ "armorSpecialWinter2017WarriorNotes": "Montrez votre esprit d'équipe et votre force avec cette armure chaude et rembourrée. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'hiver 2016-2017.",
"armorSpecialWinter2017MageText": "Armure louveteuse",
- "armorSpecialWinter2017MageNotes": "Fabriquée à partir de la plus chaude des laines d'hiver et tissée de sorts par le mystique Loup hiémal, ces habits vous gardent à l'abri du froid et vous rendent vigilant ! Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2016-2017.",
+ "armorSpecialWinter2017MageNotes": "Fabriquée à partir de la plus chaude des laines d'hiver et tissée de sorts par le mystique Loup hiémal, ces habits vous gardent à l'abri du froid et vous rendent vigilant ! Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2016-2017.",
"armorSpecialWinter2017HealerText": "Armure de pétales chatoyants",
- "armorSpecialWinter2017HealerNotes": "Douce et soyeuse, cette armure de pétales a pourtant des capacités de protection exceptionnelles ! Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'hiver 2016-2017.",
+ "armorSpecialWinter2017HealerNotes": "Douce et soyeuse, cette armure de pétales a pourtant des capacités de protection exceptionnelles ! Augmente la constitution de <%= con %>. Équipement en édition limitée de l'hiver 2016-2017.",
"armorSpecialSpring2017RogueText": "Combinaison du lapin masqué",
- "armorSpecialSpring2017RogueNotes": "Souple mais résistante, cette combinaison vous aide à passer de jardin en jardin avec furtivité. Augmente la Perception de <%= per %>. Équipement en édition limitée du printemps 2017.",
+ "armorSpecialSpring2017RogueNotes": "Souple mais résistante, cette combinaison vous aide à passer de jardin en jardin avec furtivité. Augmente la perception de <%= per %>. Équipement en édition limitée du printemps 2017.",
"armorSpecialSpring2017WarriorText": "Super plastron-ron",
- "armorSpecialSpring2017WarriorNotes": "Cette belle armure brille autant que le plus soigné de vos manteaux, tout en résistant aux attaques. Augmente la Constitution de <%= con %>. Équipement en édition limitée du printemps 2017.",
+ "armorSpecialSpring2017WarriorNotes": "Cette belle armure brille autant que le plus soigné de vos manteaux, tout en résistant aux attaques. Augmente la constitution de <%= con %>. Équipement en édition limitée du printemps 2017.",
"armorSpecialSpring2017MageText": "Robe de conjurateur canin",
- "armorSpecialSpring2017MageNotes": "Magique par nature, duveteux par choix. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée du printemps 2017.",
+ "armorSpecialSpring2017MageNotes": "Magique par nature, duveteux par choix. Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2017.",
"armorSpecialSpring2017HealerText": "Robe de repos",
- "armorSpecialSpring2017HealerNotes": "La douceur de cette robe vous réconforte, vous et les personnes qui ont besoin de votre aide magique ! Augmente la Constitution de <%= con %>. Équipement en édition limitée du printemps 2017.",
+ "armorSpecialSpring2017HealerNotes": "La douceur de cette robe vous réconforte, vous et les personnes qui ont besoin de votre aide magique ! Augmente la constitution de <%= con %>. Équipement en édition limitée du printemps 2017.",
"armorSpecialSummer2017RogueText": "Queue de dragon de mer",
- "armorSpecialSummer2017RogueNotes": "Cet habit coloré transforme son porteur en un véritable dragon de mer ! Augmente la Perception de <%= per %>. Équipement en édition limitée de l'été 2017.",
+ "armorSpecialSummer2017RogueNotes": "Cet habit coloré transforme son porteur en un véritable dragon de mer ! Augmente la perception de <%= per %>. Équipement en édition limitée de l'été 2017.",
"armorSpecialSummer2017WarriorText": "Armure de sable",
- "armorSpecialSummer2017WarriorNotes": "Ne vous laissez pas tromper par son aspect friable : cette armure est plus dure que l'acier. Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'été 2017.",
+ "armorSpecialSummer2017WarriorNotes": "Ne vous laissez pas tromper par son aspect friable : cette armure est plus dure que l'acier. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'été 2017.",
"armorSpecialSummer2017MageText": "Tunique tourbillon",
- "armorSpecialSummer2017MageNotes": "Attention à ne pas vous faire éclabousser par cette tunique tissée d'eau enchantée. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'été 2017.",
+ "armorSpecialSummer2017MageNotes": "Attention à ne pas vous faire éclabousser par cette tunique tissée d'eau enchantée. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'été 2017.",
"armorSpecialSummer2017HealerText": "Nageoire des mers d'argent",
- "armorSpecialSummer2017HealerNotes": "Ce vêtement fait d'écailles argentées transforme son porteur en véritable guérisseur des mers ! Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'été 2017.",
+ "armorSpecialSummer2017HealerNotes": "Ce vêtement fait d'écailles argentées transforme son porteur en véritable guérisseur des mers ! Augmente la constitution de <%= con %>. Équipement en édition limitée de l'été 2017.",
"armorSpecialFall2017RogueText": "Tunique champ-de-citrouilles",
- "armorSpecialFall2017RogueNotes": "Besoin de passer incognito ? Rampez parmi les lanternes citrouilles et cette tunique vous cachera ! Augmente la Perception de <%= per %>. Équipement en édition limitée de l'automne 2017.",
+ "armorSpecialFall2017RogueNotes": "Besoin de passer incognito ? Rampez parmi les lanternes citrouilles et cette tunique vous cachera ! Augmente la perception de <%= per %>. Équipement en édition limitée de l'automne 2017.",
"armorSpecialFall2017WarriorText": "Armure solide et sucrée",
- "armorSpecialFall2017WarriorNotes": "Cette armure vous protégera comme une délicieuse coquille de sucre. Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'automne 2017.",
+ "armorSpecialFall2017WarriorNotes": "Cette armure vous protégera comme une délicieuse coquille de sucre. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'automne 2017.",
"armorSpecialFall2017MageText": "Tunique de mascarade",
"armorSpecialFall2017MageNotes": "Quelle mascarade serait complète sans cette large tunique dramatique ? Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'automne 2017.",
"armorSpecialFall2017HealerText": "Armure de maison hantée",
- "armorSpecialFall2017HealerNotes": "Votre cœur est une porte ouverte. Et vos épaules sont des tuiles ! Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'automne 2017.",
+ "armorSpecialFall2017HealerNotes": "Votre cœur est une porte ouverte. Et vos épaules sont des tuiles ! Augmente la constitution de <%= con %>. Équipement en édition limitée de l'automne 2017.",
"armorSpecialWinter2018RogueText": "Costume de renne",
- "armorSpecialWinter2018RogueNotes": "Avec votre air mignon et duveteux, qui pourrait vous suspecter après le pillage des fêtes ? Augmente la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2017-2018.",
+ "armorSpecialWinter2018RogueNotes": "Avec votre air mignon et duveteux, qui pourrait vous suspecter après le pillage des fêtes ? Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2017-2018.",
"armorSpecialWinter2018WarriorText": "Armure en papier cadeau",
- "armorSpecialWinter2018WarriorNotes": "Ne vous faites pas avoir par la texture de papier de cette armure. Elle est quasiment indéchirable ! Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'hiver 2017-2018.",
+ "armorSpecialWinter2018WarriorNotes": "Ne vous faites pas avoir par la texture de papier de cette armure. Elle est quasiment indéchirable ! Augmente la constitution de <%= con %>. Équipement en édition limitée de l'hiver 2017-2018.",
"armorSpecialWinter2018MageText": "Smoking brillant",
- "armorSpecialWinter2018MageNotes": "Le summum de la tenue de cérémonie magique. Augmente l'Intelligence de<%= int %>. Équipement de l'édition limitée de l'hiver 2017-2018.",
+ "armorSpecialWinter2018MageNotes": "Le summum de la tenue de cérémonie magique. Augmente l'intelligence de<%= int %>. Équipement de l'édition limitée de l'hiver 2017-2018.",
"armorSpecialWinter2018HealerText": "Tunique en gui",
- "armorSpecialWinter2018HealerNotes": "Cette tunique est tissée avec des sortilèges suscitant plus de joie pendant les fêtes. Augmente la Constitution de <%= con %>. Équipement en édition limitée de l'hiver 2017-2018.",
+ "armorSpecialWinter2018HealerNotes": "Cette tunique est tissée avec des sortilèges suscitant plus de joie pendant les fêtes. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'hiver 2017-2018.",
"armorSpecialSpring2018RogueText": "Costume de plumes",
- "armorSpecialSpring2018RogueNotes": "Ce costume jaune tout doux fera croire à vos ennemis que vous n'êtes qu'un petit canard sans défense. Augmente la Perception de <%= per %>Équipement en édition limitée du printemps 2018.",
+ "armorSpecialSpring2018RogueNotes": "Ce costume jaune tout doux fera croire à vos ennemis que vous n'êtes qu'un petit canard sans défense. Augmente la perception de <%= per %>. Équipement en édition limitée du printemps 2018.",
"armorSpecialSpring2018WarriorText": "Armure de l'aube",
- "armorSpecialSpring2018WarriorNotes": "Cette armure colorée est forgée avec le feu du lever de soleil. Augmente la Constitution de <%= con %>. Équipement en édition limitée du printemps 2018.",
+ "armorSpecialSpring2018WarriorNotes": "Cette armure colorée est forgée avec le feu du lever de soleil. Augmente la constitution de <%= con %>. Équipement en édition limitée du printemps 2018.",
"armorSpecialSpring2018MageText": "Robe tulipe",
- "armorSpecialSpring2018MageNotes": "Son lancer de sort ne peut que s'améliorer quand on est enveloppé dans ces pétales doux et soyeux. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée du printemps 2018.",
+ "armorSpecialSpring2018MageNotes": "Son lancer de sort ne peut que s'améliorer quand on est enveloppé dans ces pétales douces et soyeux. Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2018.",
"armorSpecialSpring2018HealerText": "Armure de grenat",
- "armorSpecialSpring2018HealerNotes": "Laissez cette brillante armure infuser votre cœur avec la puissance de la guérison. Augmente la Constitution de <%= con %>. Équipement en édition limitée du printemps 2018.",
+ "armorSpecialSpring2018HealerNotes": "Laissez cette brillante armure infuser votre cœur avec la puissance de la guérison. Augmente la constitution de <%= con %>. Équipement en édition limitée du printemps 2018.",
"armorSpecialSummer2018RogueText": "Veste de pêcheur à poches",
"armorSpecialSummer2018RogueNotes": "Des flotteurs ? Des boîtes de crochets ? Une ligne de rechange ? Un nécessaire de crochetage ? Des bombes fumigènes ? Tout ce dont vous avez besoin pour votre escapade de pêche estivale, il y a une pochette pour cela ! Augmente la perception de <%= per %>. Équipement en édition limitée de l'été 2018.",
"armorSpecialSummer2018WarriorText": "Armure en queue de poisson combattant",
@@ -621,15 +621,15 @@
"armorSpecialSummer2018HealerText": "Robes de sirène monarque",
"armorSpecialSummer2018HealerNotes": "Ces robes céruléennes révèles que vous avez des pieds terrestres... certes. Même un monarque peut ne pas être parfait. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'été 2018.",
"armorSpecialFall2018RogueText": "Redingote Alter Ego",
- "armorSpecialFall2018RogueNotes": "Du style pendant la journée, du confort et de la protection pendant la nuit. Augmente la Perception de <%= per %>. Équipement d'Automne en édition limitée 2018.",
- "armorSpecialFall2018WarriorText": "Côte de mailles Minotaure",
- "armorSpecialFall2018WarriorNotes": "Elle inclut des sabots pour tambouriner une cadence apaisante tandis que vous parcourez votre labyrinthe méditatif. Augmente la Constitution de <%= con %>. Équipement d'Automne en édition limitée 2018.",
+ "armorSpecialFall2018RogueNotes": "Du style pendant la journée, du confort et de la protection pendant la nuit. Augmente la perception de <%= per %>. Équipement d'automne en édition limitée 2018.",
+ "armorSpecialFall2018WarriorText": "Côte de mailles minotaure",
+ "armorSpecialFall2018WarriorNotes": "Elle inclut des sabots pour tambouriner une cadence apaisante tandis que vous parcourez votre labyrinthe méditatif. Augmente la constitution de <%= con %>. Équipement d'automne en édition limitée 2018.",
"armorSpecialFall2018MageText": "Habits de sucromancien",
- "armorSpecialFall2018MageNotes": "Des bonbons magiques sont tissés dans l'étoffe même de cette tunique. Par contre, nous vous recommandons de ne pas chercher à les manger. Augmente l'Intelligence de <%= int %>. Équipement d'Automne en édition limitée 2018.",
+ "armorSpecialFall2018MageNotes": "Des bonbons magiques sont tissés dans l'étoffe même de cette tunique. Par contre, nous vous recommandons de ne pas chercher à les manger. Augmente l'intelligence de <%= int %>. Équipement d'automne en édition limitée 2018.",
"armorSpecialFall2018HealerText": "Habits de carnivorie",
- "armorSpecialFall2018HealerNotes": "Elle est constituée de plantes, mais ça ne veut pas dire qu'elle est végétarienne. Les mauvaises habitudes ont peur d'approcher à moins d'un kilomètre de cette tunique. Augmente la Constitution de <%= con %>. Équipement d'Automne en édition limitée 2018.",
+ "armorSpecialFall2018HealerNotes": "Elle est constituée de plantes, mais ça ne veut pas dire qu'elle est végétarienne. Les mauvaises habitudes ont peur d'approcher à moins d'un kilomètre de cette tunique. Augmente la constitution de <%= con %>. Équipement d'automne en édition limitée 2018.",
"armorSpecialWinter2019RogueText": "Armure de poinsettia",
- "armorSpecialWinter2019RogueNotes": "Avec la verdure des Fêtes, personne ne remarquera la présence d'un arbuste supplémentaire ! Vous pouvez vous déplacer à travers les rassemblements saisonniers avec aisance et furtivité. Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2018-2019.",
+ "armorSpecialWinter2019RogueNotes": "Avec la verdure des fêtes, personne ne remarquera la présence d'un arbuste supplémentaire ! Vous pouvez vous déplacer à travers les rassemblements saisonniers avec aisance et furtivité. Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2018-2019.",
"armorSpecialWinter2019WarriorText": "Armure glaciale",
"armorSpecialWinter2019WarriorNotes": "Au cœur de la bataille, cette armure vous aidera à garder votre sang froid et sur le qui-vive. Augmente la constitution de <%= con %>. Équipement en édition limitée de l'hiver 2018-2019.",
"armorSpecialWinter2019MageText": "Tunique de brûlante inspiration",
@@ -708,7 +708,7 @@
"armorMystery201808Notes": "Cette armure est faite des écailles perdues par l'insaisissable (et très chaud) dragon de lave. Ne confère aucun bonus. Équipement d'abonnement d'août 2018.",
"armorMystery201809Text": "Armure de feuilles d'automne",
"armorMystery201809Notes": "Non seulement vous êtes un petit et redoutable pousse, mais en plus vous portez les plus jolies couleurs de la saison ! N'accorde aucun avantage. Équipement d'abonnement de septembre 2018.",
- "armorMystery201810Text": "Tunique Sylvestre Sombre",
+ "armorMystery201810Text": "Tunique sylvestre sombre",
"armorMystery201810Notes": "La doublure de cette tunique vous protège du froid fantômatique des royaumes hantés. N'apporte aucun Bonus. Équipement d'abonnement d'octobre 2018.",
"armorMystery301404Text": "Tenue steampunk",
"armorMystery301404Notes": "Pimpant et fringuant ! N'apporte aucun bonus. Équipement d'abonnement de février 3015.",
@@ -717,97 +717,97 @@
"armorMystery301704Text": "Robe du faisan steampunk",
"armorMystery301704Notes": "Cet équipement est parfait pour une virée nocturne ou une journée dans votre atelier de fabrication de gadgets ! N'apporte aucun bonus. Équipement d'abonnement d'avril 3017.",
"armorArmoireLunarArmorText": "Armure lunaire apaisante",
- "armorArmoireLunarArmorNotes": "La lumière de la lune vous rendra fort et perspicace. Augmente la Force de <%= str %> et l'Intelligence de <%= int %>. Armoire enchantée : ensemble lunaire apaisant (objet 2 sur 3).",
+ "armorArmoireLunarArmorNotes": "La lumière de la lune vous rendra fort et perspicace. Augmente la force de <%= str %> et l'intelligence de <%= int %>. Armoire enchantée : ensemble lunaire apaisant (objet 2 sur 3).",
"armorArmoireGladiatorArmorText": "Armure de gladiateur",
- "armorArmoireGladiatorArmorNotes": "Pour être un gladiateur, vous devez non seulement être rusé... mais fort. Augmente la Perception de <%= per %> et la Force de <%= str %>. Armoire enchantée : ensemble du gladiateur (objet 2 sur 3).",
+ "armorArmoireGladiatorArmorNotes": "Pour être un gladiateur, vous devez non seulement être rusé... mais fort. Augmente la perception de <%= per %> et la force de <%= str %>. Armoire enchantée : ensemble du gladiateur (objet 2 sur 3).",
"armorArmoireRancherRobesText": "Tenue d'éleveur",
- "armorArmoireRancherRobesNotes": "Maîtrisez vos montures et rassemblez vos familiers en portant cette tenue d'éleveur magique ! Augmente la Force de <%= str %>, la Perception de <%= per %> et l'Intelligence de <%= int %>. Armoire enchantée : ensemble de l'éleveur (objet 2 sur 3).",
+ "armorArmoireRancherRobesNotes": "Maîtrisez vos montures et rassemblez vos familiers en portant cette tenue d'éleveur magique ! Augmente la force de <%= str %>, la perception de <%= per %> et l'intelligence de <%= int %>. Armoire enchantée : ensemble de l'éleveur (objet 2 sur 3).",
"armorArmoireGoldenTogaText": "Toge dorée",
- "armorArmoireGoldenTogaNotes": "Cette toge scintillante n'est portée que par les véritables héros. Augmente la Force et la Constitution par <%= attrs %> chacune. Armoire enchantée : ensemble de la toge dorée (objet 1 sur 3).",
+ "armorArmoireGoldenTogaNotes": "Cette toge scintillante n'est portée que par les véritables héros. Augmente la force et la constitution par <%= attrs %> chacune. Armoire enchantée : ensemble de la toge dorée (objet 1 sur 3).",
"armorArmoireHornedIronArmorText": "Armure en fer cornue",
- "armorArmoireHornedIronArmorNotes": "Férocement forgée dans le fer, cette armure cornue est presque impossible à briser. Augmente la Constitution de <%= con %> et la Perception de <%= per %>. Armoire enchantée : ensemble des cornes de fer (objet 2 sur 3).",
+ "armorArmoireHornedIronArmorNotes": "Férocement forgée dans le fer, cette armure cornue est presque impossible à briser. Augmente la constitution de <%= con %> et la perception de <%= per %>. Armoire enchantée : ensemble des cornes de fer (objet 2 sur 3).",
"armorArmoirePlagueDoctorOvercoatText": "Pardessus de médecin de la peste",
- "armorArmoirePlagueDoctorOvercoatNotes": "Un authentique pardessus porté par les médecins qui ont combattu la peste de Procrastination ! Augmente l'Intelligence de <%= int %>, la Force de <%= str %> et la Constitution de <%= con %>. Armoire enchantée : ensemble du médecin de la peste (objet 3 sur 3).",
+ "armorArmoirePlagueDoctorOvercoatNotes": "Un authentique pardessus porté par les médecins qui ont combattu la peste de Procrastination ! Augmente l'intelligence de <%= int %>, la force de <%= str %> et la constitution de <%= con %>. Armoire enchantée : ensemble du médecin de la peste (objet 3 sur 3).",
"armorArmoireShepherdRobesText": "Tunique de berger",
- "armorArmoireShepherdRobesNotes": "Le tissu est léger et aéré, parfait pour une chaude journée passée à rassembler des griffons dans le désert. Augmente la Force et la Perception de <%= attrs %> chacune. Armoire enchantée : ensemble du berger (objet 2 sur 3).",
+ "armorArmoireShepherdRobesNotes": "Le tissu est léger et aéré, parfait pour une chaude journée passée à rassembler des griffons dans le désert. Augmente la force et la perception de <%= attrs %> chacune. Armoire enchantée : ensemble du berger (objet 2 sur 3).",
"armorArmoireRoyalRobesText": "Tunique royale",
- "armorArmoireRoyalRobesNotes": "Merveilleux souverain, régnez du matin au soir ! Augmente la Constitution, l'Intelligence et la Perception de <%= attrs %> chacune. Armoire enchantée : ensemble royal (objet 3 sur 3).",
+ "armorArmoireRoyalRobesNotes": "Merveilleux souverain, régnez du matin au soir ! Augmente la constitution, l'intelligence et la perception de <%= attrs %> chacune. Armoire enchantée : ensemble royal (objet 3 sur 3).",
"armorArmoireCrystalCrescentRobesText": "Tunique du croissant de cristal",
- "armorArmoireCrystalCrescentRobesNotes": "Cette tunique magique illumine la nuit. Augmente la Constitution et la Perception de <%= attrs %> chacune. Armoire enchantée : ensemble du croissant de lune (objet 2 sur 3).",
+ "armorArmoireCrystalCrescentRobesNotes": "Cette tunique magique illumine la nuit. Augmente la constitution et la perception de <%= attrs %> chacune. Armoire enchantée : ensemble du croissant de lune (objet 2 sur 3).",
"armorArmoireDragonTamerArmorText": "Armure de dresseur de dragon",
- "armorArmoireDragonTamerArmorNotes": "Les flammes ne peuvent pénétrer cette robuste armure. Augmente la Constitution de <%= con %>. Armoire enchantée : ensemble du dresseur de dragon (objet 3 sur 3).",
+ "armorArmoireDragonTamerArmorNotes": "Les flammes ne peuvent pénétrer cette robuste armure. Augmente la constitution de <%= con %>. Armoire enchantée : ensemble du dresseur de dragon (objet 3 sur 3).",
"armorArmoireBarristerRobesText": "Tunique d'avocat",
- "armorArmoireBarristerRobesNotes": "Très solennelle et majestueuse. Augmente la Constitution de <%= con %>. Armoire enchantée : ensemble de l'avocat (objet 2 sur 3).",
+ "armorArmoireBarristerRobesNotes": "Très solennelle et majestueuse. Augmente la constitution de <%= con %>. Armoire enchantée : ensemble de l'avocat (objet 2 sur 3).",
"armorArmoireJesterCostumeText": "Costume de bouffon",
- "armorArmoireJesterCostumeNotes": "Tralala ! Malgré l'apparence de ce costume, vous n'êtes pas un bouffon. Augmente l'Intelligence de <%= int %>. Armoire enchantée : ensemble du bouffon (Objet 2 sur 3).",
+ "armorArmoireJesterCostumeNotes": "Tralala ! Malgré l'apparence de ce costume, vous n'êtes pas un bouffon. Augmente l'intelligence de <%= int %>. Armoire enchantée : ensemble du bouffon (Objet 2 sur 3).",
"armorArmoireMinerOverallsText": "Salopette de mineur",
- "armorArmoireMinerOverallsNotes": "Elle semble peut-être usée, mais elle contient un enchantement qui repousse la poussière. Augmente la Constitution de <%= con %>. Armoire enchantée : ensemble du mineur (objet 2 sur 3).",
+ "armorArmoireMinerOverallsNotes": "Elle semble peut-être usée, mais elle contient un enchantement qui repousse la poussière. Augmente la constitution de <%= con %>. Armoire enchantée : ensemble du mineur (objet 2 sur 3).",
"armorArmoireBasicArcherArmorText": "Armure d'archer de base",
- "armorArmoireBasicArcherArmorNotes": "Cette veste de camouflage vous permet de vous faufiler incognito dans les forêts. Augmente la Perception de <%= per %>. Armoire enchantée : ensemble de l'archer de base (objet 2 sur 3).",
+ "armorArmoireBasicArcherArmorNotes": "Cette veste de camouflage vous permet de vous faufiler incognito dans les forêts. Augmente la perception de <%= per %>. Armoire enchantée : ensemble de l'archer de base (objet 2 sur 3).",
"armorArmoireGraduateRobeText": "Toge des diplômés",
- "armorArmoireGraduateRobeNotes": "Félicitations ! Cette lourde toge porte toutes les connaissances que vous avez acquises. Augmente l'Intelligence de <%= int %>. Armoire enchantée : ensemble des diplômés (objet 2 sur 3).",
+ "armorArmoireGraduateRobeNotes": "Félicitations ! Cette lourde toge porte toutes les connaissances que vous avez acquises. Augmente l'intelligence de <%= int %>. Armoire enchantée : ensemble des diplômés (objet 2 sur 3).",
"armorArmoireStripedSwimsuitText": "Maillot de bain rayé",
- "armorArmoireStripedSwimsuitNotes": "Qu'est ce que qui pourrait être plus amusant que de combattre les monstres marins sur la plage ? Augmente la Constitution de <%= con %>. Armoire enchantée : ensemble du bord de mer (objet 2 sur 3).",
+ "armorArmoireStripedSwimsuitNotes": "Qu'est ce que qui pourrait être plus amusant que de combattre les monstres marins sur la plage ? Augmente la constitution de <%= con %>. Armoire enchantée : ensemble du bord de mer (objet 2 sur 3).",
"armorArmoireCannoneerRagsText": "Guenilles de canonnier",
- "armorArmoireCannoneerRagsNotes": "Ces guenilles sont plus résistantes qu'elles en ont l'air. Augmentent la Constitution de <%= con %>. Armoire enchantée : ensemble du canonnier (objet 2 sur 3).",
+ "armorArmoireCannoneerRagsNotes": "Ces guenilles sont plus résistantes qu'elles en ont l'air. Augmentent la constitution de <%= con %>. Armoire enchantée : ensemble du canonnier (objet 2 sur 3).",
"armorArmoireFalconerArmorText": "Armure de fauconnerie",
- "armorArmoireFalconerArmorNotes": "Protégez-vous des attaques des serres avec cette robuste armure ! Augmente la Constitution de <%= con %>. Armoire enchantée : ensemble de fauconnerie (objet 1 sur 3).",
+ "armorArmoireFalconerArmorNotes": "Protégez-vous des attaques des serres avec cette robuste armure ! Augmente la constitution de <%= con %>. Armoire enchantée : ensemble de fauconnerie (objet 1 sur 3).",
"armorArmoireVermilionArcherArmorText": "Armure de l'archer vermillon",
- "armorArmoireVermilionArcherArmorNotes": "Cette armure est faite d'un métal rouge enchanté spécialement pour une protection maximale, une restriction minimale et un maximum d'allure ! Augmente la Perception de <%= per %>. Armoire enchantée : ensemble de l'archer vermillon (objet 2 sur 3).",
+ "armorArmoireVermilionArcherArmorNotes": "Cette armure est faite d'un métal rouge enchanté spécialement pour une protection maximale, une restriction minimale et un maximum d'allure ! Augmente la perception de <%= per %>. Armoire enchantée : ensemble de l'archer vermillon (objet 2 sur 3).",
"armorArmoireOgreArmorText": "Armure d'ogre",
- "armorArmoireOgreArmorNotes": "Cette armure imite la peau résistante d'un ogre mais est doublée de laine pour le confort des humains ! Augmente la Constitution de <%= con %>. Armoire enchantée : costume d'ogre (objet 3 sur 3).",
+ "armorArmoireOgreArmorNotes": "Cette armure imite la peau résistante d'un ogre mais est doublée de laine pour le confort des humains ! Augmente la constitution de <%= con %>. Armoire enchantée : costume d'ogre (objet 3 sur 3).",
"armorArmoireIronBlueArcherArmorText": "Armure bleue de l'archer d'acier",
- "armorArmoireIronBlueArcherArmorNotes": "Cette armure va vous protéger des flèches sur le champ de bataille ! Augmente la Force de <%= str %>. Armoire enchantée : ensemble de l'archer d'acier (objet 2 sur 3).",
+ "armorArmoireIronBlueArcherArmorNotes": "Cette armure va vous protéger des flèches sur le champ de bataille ! Augmente la force de <%= str %>. Armoire enchantée : ensemble de l'archer d'acier (objet 2 sur 3).",
"armorArmoireRedPartyDressText": "Robe de soirée rouge",
- "armorArmoireRedPartyDressNotes": "Vous voilà fort, tenace, brillant... et tellement à la mode ! Augmente la Force, la Constitution et l'Intelligence de <%= attrs %> chacune. Armoire enchantée : ensemble du serre-tête rouge (objet 2 sur 2).",
+ "armorArmoireRedPartyDressNotes": "Vous voilà fort, tenace, brillant... et tellement à la mode ! Augmente la force, la constitution et l'intelligence de <%= attrs %> chacune. Armoire enchantée : ensemble du serre-tête rouge (objet 2 sur 2).",
"armorArmoireWoodElfArmorText": "Armure d'elfe des bois",
- "armorArmoireWoodElfArmorNotes": "Cette armure d'écorce et de feuilles fera un camouflage adapté à la vie en forêt. Augmente la Perception de <%= per %>. Armoire enchantée : ensemble de l'elfe des bois (objet 2 sur 3).",
+ "armorArmoireWoodElfArmorNotes": "Cette armure d'écorce et de feuilles fera un camouflage adapté à la vie en forêt. Augmente la perception de <%= per %>. Armoire enchantée : ensemble de l'elfe des bois (objet 2 sur 3).",
"armorArmoireRamFleeceRobesText": "Robes en peau de bélier",
- "armorArmoireRamFleeceRobesNotes": "Cette tunique vous garde au chaud même sous le plus terrible des blizzards. Augmente la Constitution de <%= con %> et la Force de <%= str %>. Armoire enchantée : ensemble du barbare criophore (objet 2 sur 3).",
+ "armorArmoireRamFleeceRobesNotes": "Cette tunique vous garde au chaud même sous le plus terrible des blizzards. Augmente la constitution de <%= con %> et la force de <%= str %>. Armoire enchantée : ensemble du barbare criophore (objet 2 sur 3).",
"armorArmoireGownOfHeartsText": "Toge de cœur",
- "armorArmoireGownOfHeartsNotes": "Cette toge est pleine d'ornements, et en plus, elle vous donnera du baume au cœur. Augmente la Constitution de <%= con %>. Armoire enchantée : ensemble de la reine de cœur (objet 2 sur 3).",
+ "armorArmoireGownOfHeartsNotes": "Cette toge est pleine d'ornements, et en plus, elle vous donnera du baume au cœur. Augmente la constitution de <%= con %>. Armoire enchantée : ensemble de la reine de cœur (objet 2 sur 3).",
"armorArmoireMushroomDruidArmorText": "Armure druidique mycologique",
- "armorArmoireMushroomDruidArmorNotes": "Cette armure de bois ancien, recouverte de petits champignons, vous aidera à entendre les murmures de la faune et de la flore forestière. Augmente la Constitution de <%= con %> et la Perception de <%= per %>. Armoire enchantée : ensemble du druide mycologique (objet 2 sur 3).",
+ "armorArmoireMushroomDruidArmorNotes": "Cette armure de bois ancien, recouverte de petits champignons, vous aidera à entendre les murmures de la faune et de la flore forestière. Augmente la constitution de <%= con %> et la perception de <%= per %>. Armoire enchantée : ensemble du druide mycologique (objet 2 sur 3).",
"armorArmoireGreenFestivalYukataText": "Yukata vert de festivalier",
- "armorArmoireGreenFestivalYukataNotes": "Ce kimono léger vous gardera au frais en toute occasion festive. Augmente la Constitution et la Perception de <%= attrs %> chacune. Armoire enchantée : ensemble du festivalier (objet 1 sur 3).",
+ "armorArmoireGreenFestivalYukataNotes": "Ce kimono léger vous gardera au frais en toute occasion festive. Augmente la constitution et la perception de <%= attrs %> chacune. Armoire enchantée : ensemble du festivalier (objet 1 sur 3).",
"armorArmoireMerchantTunicText": "Tunique de marchand",
- "armorArmoireMerchantTunicNotes": "Les larges manches de cette tunique vous permettent de dissimuler les pièces que vous avez gagnées ! Augmente la Perception de <%= per %>. Armoire enchantée : ensemble du marchand (objet 2 sur 3).",
+ "armorArmoireMerchantTunicNotes": "Les larges manches de cette tunique vous permettent de dissimuler les pièces que vous avez gagnées ! Augmente la perception de <%= per %>. Armoire enchantée : ensemble du marchand (objet 2 sur 3).",
"armorArmoireVikingTunicText": "Tunique viking",
- "armorArmoireVikingTunicNotes": "Cette chaude tunique de laine inclut une cape pour un confort supérieur, et ce même au cœur des bourrasques en pleine mer. Augmente la Constitution de <%= con %> et la Force de <%= str %>. Armoire enchantée : ensemble du viking (objet 1 sur 3).",
+ "armorArmoireVikingTunicNotes": "Cette chaude tunique de laine inclut une cape pour un confort supérieur, et ce même au cœur des bourrasques en pleine mer. Augmente la constitution de <%= con %> et la force de <%= str %>. Armoire enchantée : ensemble du viking (objet 1 sur 3).",
"armorArmoireSwanDancerTutuText": "Tutu de danseur du cygne",
- "armorArmoireSwanDancerTutuNotes": "Une pirouette dans ce superbe tutu à plumes, et vous pourriez bien vous envoler haut dans les airs ! Augmente l'Intelligence et la Force de <%= attrs %> chacune. Armoire enchantée : ensemble du danseur du cygne (objet 2 sur 3).",
+ "armorArmoireSwanDancerTutuNotes": "Une pirouette dans ce superbe tutu à plumes, et vous pourriez bien vous envoler haut dans les airs ! Augmente l'intelligence et la force de <%= attrs %> chacune. Armoire enchantée : ensemble du danseur du cygne (objet 2 sur 3).",
"armorArmoireAntiProcrastinationArmorText": "Armure anti-procrastination",
- "armorArmoireAntiProcrastinationArmorNotes": "Imprégnée d'anciens sortilèges de productivité, cette armure d'acier vous octroiera un surplus de force pour affronter vos tâches. Augmente la Force de <%= str %>. Armoire enchantée : ensemble anti-procrastination (objet 2 sur 3).",
+ "armorArmoireAntiProcrastinationArmorNotes": "Imprégnée d'anciens sortilèges de productivité, cette armure d'acier vous octroiera un surplus de force pour affronter vos tâches. Augmente la force de <%= str %>. Armoire enchantée : ensemble anti-procrastination (objet 2 sur 3).",
"armorArmoireYellowPartyDressText": "Robe de soirée jaune",
- "armorArmoireYellowPartyDressNotes": "Vous voilà perspicace, fort, brillant... et tellement à la mode ! Augmente la Perception, la Force et l'Intelligence de <%= attrs %> chacune. Armoire enchantée : ensemble du serre-tête jaune (objet 2 sur 2).",
+ "armorArmoireYellowPartyDressNotes": "Vous voilà perspicace, fort, brillant... et tellement à la mode ! Augmente la perception, la force et l'intelligence de <%= attrs %> chacune. Armoire enchantée : ensemble du serre-tête jaune (objet 2 sur 2).",
"armorArmoireFarrierOutfitText": "Tenue de maréchal-ferrant",
- "armorArmoireFarrierOutfitNotes": "Ces vêtements de travail résistants peuvent tenir tête à l'étable la plus désordonnée. Augmente l'Intelligence, la Constitution et la Perception de <%= attrs %>chacune. Armoire enchantée : ensemble du maréchal-ferrant (objet 2 sur 3).",
+ "armorArmoireFarrierOutfitNotes": "Ces vêtements de travail résistants peuvent tenir tête à l'étable la plus désordonnée. Augmente l'intelligence, la constitution et la perception de <%= attrs %> chacune. Armoire enchantée : ensemble du maréchal-ferrant (objet 2 sur 3).",
"armorArmoireCandlestickMakerOutfitText": "Habits de cirier",
- "armorArmoireCandlestickMakerOutfitNotes": "Cet ensemble de vêtements résistants vous protègera de la cire brûlante que vous pourriez renverser en pratiquant votre art ! Augmente la Constitution de <%= con %>. Armoire enchantée : ensemble du cirier (objet 1 sur 3).",
+ "armorArmoireCandlestickMakerOutfitNotes": "Cet ensemble de vêtements résistants vous protégera de la cire brûlante que vous pourriez renverser en pratiquant votre art ! Augmente la constitution de <%= con %>. Armoire enchantée : ensemble du cirier (objet 1 sur 3).",
"armorArmoireWovenRobesText": "Tunique tissée",
- "armorArmoireWovenRobesNotes": "Exhibez fièrement votre travail de tissage en portant cette tunique bariolée ! Augmente la Constitution de <%= con %> et l'Intelligence de <%= int %>. Armoire enchantée : ensemble du tisserand (objet 1 sur 3).",
+ "armorArmoireWovenRobesNotes": "Exhibez fièrement votre travail de tissage en portant cette tunique bariolée ! Augmente la constitution de <%= con %> et l'intelligence de <%= int %>. Armoire enchantée : ensemble du tisserand (objet 1 sur 3).",
"armorArmoireLamplightersGreatcoatText": "Pardessus d'allumeur de réverbères",
- "armorArmoireLamplightersGreatcoatNotes": "Cet épais manteau de laine peut résister aux plus rudes des nuits hivernales ! Augmente la Perception de <%= per %>. Armoire enchantée : ensemble de l'éclaireur (objet 2 sur 4).",
+ "armorArmoireLamplightersGreatcoatNotes": "Cet épais manteau de laine peut résister aux plus rudes des nuits hivernales ! Augmente la perception de <%= per %>. Armoire enchantée : ensemble de l'éclaireur (objet 2 sur 4).",
"armorArmoireCoachDriverLiveryText": "Livrée de cocher",
- "armorArmoireCoachDriverLiveryNotes": "Ce lourd manteau vous protégera des intempéries pendant que vous conduisez. De plus, il est plutôt élégant ! Augmente la Force de <%= str %>. Armoire enchantée : ensemble du cocher (objet 1 sur 3).",
+ "armorArmoireCoachDriverLiveryNotes": "Ce lourd manteau vous protégera des intempéries pendant que vous conduisez. De plus, il est plutôt élégant ! Augmente la force de <%= str %>. Armoire enchantée : ensemble du cocher (objet 1 sur 3).",
"armorArmoireRobeOfDiamondsText": "Robe de carreau",
- "armorArmoireRobeOfDiamondsNotes": "Non seulement ces tuniques royales vous donnent un air noble, mais elle vous permettent de voir la noblesse chez les autres. Augmente la Perception de <%= per %>. Armoire enchantée : ensemble du roi de carreau (objet 1 sur 4).",
+ "armorArmoireRobeOfDiamondsNotes": "Non seulement ces tuniques royales vous donnent un air noble, mais elle vous permettent de voir la noblesse chez les autres. Augmente la perception de <%= per %>. Armoire enchantée : ensemble du roi de carreau (objet 1 sur 4).",
"armorArmoireFlutteryFrockText": "Robe papillonnante",
- "armorArmoireFlutteryFrockNotes": "Une robe légère et vaporeuse avec un large jupon que les papillons risquent de prendre pour une fleur géante. Augmente la Constitution, la Perception et la Force de <%= attrs %> chacune. Armoire enchantée : ensemble papillonnant (objet 1 sur 4).",
+ "armorArmoireFlutteryFrockNotes": "Une robe légère et vaporeuse avec un large jupon que les papillons risquent de prendre pour une fleur géante. Augmente la constitution, la perception et la force de <%= attrs %> chacune. Armoire enchantée : ensemble papillonnant (objet 1 sur 4).",
"armorArmoireCobblersCoverallsText": "Combinaison de cordonnier",
"armorArmoireCobblersCoverallsNotes": "Cette combinaison solide a plein de poches pour les outils, les morceaux de cuir et les autres objets utiles ! Augmente la perception et la force de <%= attrs %> chacune. Armoire enchantée : ensemble du cordonnier (objet 1 sur 3).",
"armorArmoireGlassblowersCoverallsText": "Combinaison de souffleur de verre",
- "armorArmoireGlassblowersCoverallsNotes": "Cette combinaison vous protègera quand vous fabriquerez des chef-d’œuvres avec du verre en fusion. Augmente la Constitution de <%= con %>. Armoire enchantée : ensemble du souffleur de verre (objet 2 sur 4).",
+ "armorArmoireGlassblowersCoverallsNotes": "Cette combinaison vous protégera quand vous fabriquerez des chef-d’œuvres avec du verre en fusion. Augmente la constitution de <%= con %>. Armoire enchantée : ensemble du souffleur de verre (objet 2 sur 4).",
"armorArmoireBluePartyDressText": "Robe de soirée bleue",
- "armorArmoireBluePartyDressNotes": "Vous voilà perspicace, résistant, élégant... et tellement à la mode ! Augmente la Perception, la Force et la Constitution de <%= attrs %> chacune. Armoire enchantée : ensemble du serre-tête bleu (objet 2 sur 2).",
+ "armorArmoireBluePartyDressNotes": "Vous voilà perspicace, résistant, élégant... et tellement à la mode ! Augmente la perception, la force et la constitution de <%= attrs %> chacune. Armoire enchantée : ensemble du serre-tête bleu (objet 2 sur 2).",
"armorArmoirePiraticalPrincessGownText": "Peignoir de princesse pirate",
"armorArmoirePiraticalPrincessGownNotes": "Ce vêtement luxueux a de nombreuses poches pour cacher des armes et du butin ! Augmente la perception de <%= per %>. Armoire enchantée : Ensemble de la princesse pirate (Objet 2 de 4).",
"armorArmoireJeweledArcherArmorText": "Armure en joyaux",
- "armorArmoireJeweledArcherArmorNotes": "Cette armure soigneusement décorée vous protégera des projectiles ou des Quotidiennes rouges oubliées ! Augmente la constitution de <%= con %>. Armoire enchantée : Ensemble de l'Archer aux joyaux (Objet 2 de 3).",
+ "armorArmoireJeweledArcherArmorNotes": "Cette armure soigneusement décorée vous protégera des projectiles ou des quotidiennes rouges oubliées ! Augmente la constitution de <%= con %>. Armoire enchantée : Ensemble de l'Archer aux joyaux (Objet 2 de 3).",
"armorArmoireCoverallsOfBookbindingText": "Combinaison de reliure",
"armorArmoireCoverallsOfBookbindingNotes": "Tout ce dont vous avez besoin dans une combinaison, avec des poches pour chaque chose. Une paire de lunettes, de la monnaie, un anneau en or... Augmente la constitution de <%= con %> et la perception de <%= per %>. Armoire enchantée : Ensemble du relieur (Objet 2 de 4).",
"armorArmoireRobeOfSpadesText": "Tunique de Pique",
- "armorArmoireRobeOfSpadesNotes": "Cette tunique luxuriante contient des poches dissimulées pour y ranger des trésors ou des armes - c'est vous qui voyez ! Augmente la Force de <%= str %>. Armoire enchantée : Set As de Pique (objet 2 sur 3).",
+ "armorArmoireRobeOfSpadesNotes": "Cette tunique luxuriante contient des poches dissimulées pour y ranger des trésors ou des armes - c'est vous qui voyez ! Augmente la force de <%= str %>. Armoire enchantée : Set As de Pique (objet 2 sur 3).",
"armorArmoireSoftBlueSuitText": "Doux costume bleu",
"armorArmoireSoftBlueSuitNotes": "Le bleu est une couleur apaisante. À tel point que certains revêtent même cette douce tenue pour dormir... zZz. Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Armoire enchantée: Ensemble de vêtements de détente bleus (Objet 2 de 3).",
"armorArmoireSoftGreenSuitText": "Doux costume vert",
@@ -821,77 +821,77 @@
"headBase0Text": "Pas de couvre-chef",
"headBase0Notes": "Pas de couvre-chef.",
"headWarrior1Text": "Heaume de cuir",
- "headWarrior1Notes": "Un bonnet fait de solides peaux tannées. Augmente la Force de <%= str %>.",
+ "headWarrior1Notes": "Un bonnet fait de solides peaux tannées. Augmente la force de <%= str %>.",
"headWarrior2Text": "Coiffe de mailles",
- "headWarrior2Notes": "Un capuchon en anneaux de métal entrecroisés. Augmente la Force de <%= str %>.",
+ "headWarrior2Notes": "Un capuchon en anneaux de métal entrecroisés. Augmente la force de <%= str %>.",
"headWarrior3Text": "Heaume de plaques",
- "headWarrior3Notes": "Épais casque d'acier, résistant à n'importe quel coup. Augmente la Force de <%= str %>.",
+ "headWarrior3Notes": "Épais casque d'acier, résistant à n'importe quel coup. Augmente la force de <%= str %>.",
"headWarrior4Text": "Heaume rouge",
- "headWarrior4Notes": "Il est orné de rubis pour le pouvoir, et brille lorsque son porteur est énervé. Augmente la Force de <%= str %>.",
+ "headWarrior4Notes": "Il est orné de rubis pour le pouvoir, et brille lorsque son porteur est énervé. Augmente la force de <%= str %>.",
"headWarrior5Text": "Heaume d'or",
- "headWarrior5Notes": "Une couronne royale assortie à son armure étincelante. Augmente la Force de <%= str %>.",
+ "headWarrior5Notes": "Une couronne royale assortie à son armure étincelante. Augmente la force de <%= str %>.",
"headRogue1Text": "Capuchon de cuir",
- "headRogue1Notes": "Capuchon protecteur de base. Augmente la Perception de <%= per %>.",
+ "headRogue1Notes": "Capuchon protecteur de base. Augmente la perception de <%= per %>.",
"headRogue2Text": "Capuchon de cuir noir",
- "headRogue2Notes": "Utile à la fois pour se défendre et se cacher. Augmente la Perception de <%= per %>.",
+ "headRogue2Notes": "Utile à la fois pour se défendre et se cacher. Augmente la perception de <%= per %>.",
"headRogue3Text": "Cagoule de camouflage",
- "headRogue3Notes": "Un peu rêche mais ne gêne pas l'audition. Augmente la Perception de <%= per %>.",
+ "headRogue3Notes": "Un peu rêche mais ne gêne pas l'audition. Augmente la perception de <%= per %>.",
"headRogue4Text": "Capuchon de pénombre",
- "headRogue4Notes": "Confère une parfaite vision dans le noir. Augmente la Perception de <%= per %>.",
+ "headRogue4Notes": "Confère une parfaite vision dans le noir. Augmente la perception de <%= per %>.",
"headRogue5Text": "Capuchon d'ombre",
- "headRogue5Notes": "Dissimule même les pensées à ceux qui voudraient les lire. Augmente la Perception de <%= per %>.",
+ "headRogue5Notes": "Dissimule même les pensées à ceux qui voudraient les lire. Augmente la perception de <%= per %>.",
"headWizard1Text": "Chapeau de magicien",
- "headWizard1Notes": "Simple, confortable, et à la mode. Augmente la Perception de <%= per %>.",
+ "headWizard1Notes": "Simple, confortable, et à la mode. Augmente la perception de <%= per %>.",
"headWizard2Text": "Chapeau conique",
- "headWizard2Notes": "Le couvre-chef traditionnel des sorciers ambulants. Augmente la Perception de <%= per %>.",
+ "headWizard2Notes": "Le couvre-chef traditionnel des sorciers ambulants. Augmente la perception de <%= per %>.",
"headWizard3Text": "Chapeau d'astrologue",
- "headWizard3Notes": "Orné des anneaux de Saturne. Augmente la Perception de <%= per %>.",
+ "headWizard3Notes": "Orné des anneaux de Saturne. Augmente la perception de <%= per %>.",
"headWizard4Text": "Chapeau d'archimage",
- "headWizard4Notes": "Concentre l'esprit pour les incantations les plus intenses. Augmente la Perception de <%= per %>.",
+ "headWizard4Notes": "Concentre l'esprit pour les incantations les plus intenses. Augmente la perception de <%= per %>.",
"headWizard5Text": "Chapeau de mage royal",
- "headWizard5Notes": "Affiche l'autorité sur le destin, la météo, et les mages moins importants. Augmente la Perception de <%= per %>.",
+ "headWizard5Notes": "Affiche l'autorité sur le destin, la météo, et les mages moins importants. Augmente la perception de <%= per %>.",
"headHealer1Text": "Diadème de quartz",
- "headHealer1Notes": "Couvre-chef orné de joyaux, pour rester concentré sur la tâche à venir. Augmente l'Intelligence de <%= int %>.",
+ "headHealer1Notes": "Couvre-chef orné de joyaux, pour rester concentré sur la tâche à venir. Augmente l'intelligence de <%= int %>.",
"headHealer2Text": "Diadème d'améthyste",
- "headHealer2Notes": "Des goûts de luxe pour une profession modeste. Augmente l'Intelligence de <%= int %>.",
+ "headHealer2Notes": "Des goûts de luxe pour une profession modeste. Augmente l'intelligence de <%= int %>.",
"headHealer3Text": "Diadème de saphir",
- "headHealer3Notes": "Brille pour montrer à ceux qui souffrent que le salut est à portée de main. Augmente l'Intelligence de <%= int %>.",
+ "headHealer3Notes": "Brille pour montrer à ceux qui souffrent que le salut est à portée de main. Augmente l'intelligence de <%= int %>.",
"headHealer4Text": "Diadème d’émeraude",
- "headHealer4Notes": "Émet une aura de vie et de croissance. Augmente l'Intelligence de <%= int %>.",
+ "headHealer4Notes": "Émet une aura de vie et de croissance. Augmente l'intelligence de <%= int %>.",
"headHealer5Text": "Diadème royal",
- "headHealer5Notes": "Pour un roi, une reine, ou un faiseur de miracles. Augmente l'Intelligence de <%= int %>.",
+ "headHealer5Notes": "Pour un roi, une reine, ou un faiseur de miracles. Augmente l'intelligence de <%= int %>.",
"headSpecial0Text": "Heaume de l'ombre",
- "headSpecial0Notes": "Le sang et la cendre, la lave et l'obsidienne donnent à ce heaume sa prestance et son pouvoir. Augmente l'Intelligence de <%= int %>.",
+ "headSpecial0Notes": "Le sang et la cendre, la lave et l'obsidienne donnent à ce heaume sa prestance et son pouvoir. Augmente l'intelligence de <%= int %>.",
"headSpecial1Text": "Heaume de cristal",
"headSpecial1Notes": "La couronne préférée de ceux qui règnent par l'exemple. Augmente tous les attributs de <%= attrs %>.",
"headSpecial2Text": "Heaume sans nom",
- "headSpecial2Notes": "Un hommage à ceux qui ont donné de leur personne sans jamais rien demander en retour. Augmente l'Intelligence et la Force de <%= attrs %> chacune.",
+ "headSpecial2Notes": "Un hommage à ceux qui ont donné de leur personne sans jamais rien demander en retour. Augmente l'intelligence et la force de <%= attrs %> chacune.",
"headSpecialTakeThisText": "Heaume Take This",
"headSpecialTakeThisNotes": "Ce heaume a été obtenu en participant à un défi sponsorisé créé par Take This. Félicitations ! Augmente tous les attributs de <%= attrs %>.",
"headSpecialFireCoralCircletText": "Diadème de corail de feu",
- "headSpecialFireCoralCircletNotes": "Ce diadème créé par les plus grands alchimistes d'Habitica vous permet de respirer sous l'eau et de plonger pour trouver des trésors ! Augmente la Perception de <%= per %>.",
+ "headSpecialFireCoralCircletNotes": "Ce diadème créé par les plus grands alchimistes d'Habitica vous permet de respirer sous l'eau et de plonger pour trouver des trésors ! Augmente la perception de <%= per %>.",
"headSpecialPyromancersTurbanText": "Turban de pyromancienne",
- "headSpecialPyromancersTurbanNotes": "Ce turban magique aidera votre cerveau, même dans la fumée la plus épaisse ! Et en plus, il est très confortable ! Augmente la Force de <%= str %>.",
+ "headSpecialPyromancersTurbanNotes": "Ce turban magique aidera votre cerveau, même dans la fumée la plus épaisse ! Et en plus, il est très confortable ! Augmente la force de <%= str %>.",
"headSpecialBardHatText": "Béret de barde",
- "headSpecialBardHatNotes": "Coincez une plume dans votre béret et appelez cela de la \"productivité\" ! Augmente l'Intelligence de <%= int %>.",
+ "headSpecialBardHatNotes": "Coincez une plume dans votre béret et appelez cela de la \"productivité\" ! Augmente l'intelligence de <%= int %>.",
"headSpecialLunarWarriorHelmText": "Casque de guerrier lunaire",
- "headSpecialLunarWarriorHelmNotes": "La puissance de la lune vous renforcera au combat ! Augmente la Force et l'Intelligence de <%= attrs %> chacune.",
+ "headSpecialLunarWarriorHelmNotes": "La puissance de la lune vous renforcera au combat ! Augmente la force et l'intelligence de <%= attrs %> chacune.",
"headSpecialMammothRiderHelmText": "Heaume de chevaucheur de mammouths",
- "headSpecialMammothRiderHelmNotes": "Ne vous laissez pas abuser par son aspect vaporeux, ce couvre-chef vous dotera de vifs pouvoirs de perception ! Augmente la Perception de <%= per %>.",
+ "headSpecialMammothRiderHelmNotes": "Ne vous laissez pas abuser par son aspect vaporeux, ce couvre-chef vous dotera de vifs pouvoirs de perception ! Augmente la perception de <%= per %>.",
"headSpecialPageHelmText": "Heaume de page",
- "headSpecialPageHelmNotes": "Une cotte de mailles : pour le côté stylé ET pratique. Augmente la Perception de <%= per %>.",
+ "headSpecialPageHelmNotes": "Une cotte de mailles : pour le côté stylé ET pratique. Augmente la perception de <%= per %>.",
"headSpecialRoguishRainbowMessengerHoodText": "Capuche du malicieux messager arc-en-ciel",
- "headSpecialRoguishRainbowMessengerHoodNotes": "Cette capuche émet une aura colorée qui vous protégera des plus sales temps. Augmente la Constitution de <%= con %>.",
+ "headSpecialRoguishRainbowMessengerHoodNotes": "Cette capuche émet une aura colorée qui vous protégera des plus sales temps. Augmente la constitution de <%= con %>.",
"headSpecialClandestineCowlText": "Capuche clandestine",
- "headSpecialClandestineCowlNotes": "Faites attention à bien dissimuler votre visage lorsque vous chipez à vos tâches de l'or et du butin ! Augmente la Perception de <%= per %>.",
+ "headSpecialClandestineCowlNotes": "Faites attention à bien dissimuler votre visage lorsque vous chipez à vos tâches de l'or et du butin ! Augmente la perception de <%= per %>.",
"headSpecialSnowSovereignCrownText": "Couronne hivernale de souverain",
- "headSpecialSnowSovereignCrownNotes": "Les joyaux de cette couronne scintillent comme des flocons de neige fraîche. Augmente la Constitution de <%= con %>.",
- "headSpecialSpikedHelmText": "Heaume à piques",
- "headSpecialSpikedHelmNotes": "Vous serez bien à l'abri des quotidiennes errantes et des mauvaises habitudes grâce à ce heaume très pratique (et joli). Augmente la Force de <%= str %>.",
+ "headSpecialSnowSovereignCrownNotes": "Les joyaux de cette couronne scintillent comme des flocons de neige fraîche. Augmente la constitution de <%= con %>.",
+ "headSpecialSpikedHelmText": "Casque à pointes",
+ "headSpecialSpikedHelmNotes": "Vous serez bien à l'abri des quotidiennes errantes et des mauvaises habitudes grâce à ce heaume très pratique (et joli). Augmente la force de <%= str %>.",
"headSpecialDandyHatText": "Chapeau de dandy",
- "headSpecialDandyHatNotes": "Quel beau chapeau ! Flânez avec et vous aurez une sacrée allure. Augmente la Constitution de <%= con %>.",
+ "headSpecialDandyHatNotes": "Quel beau chapeau ! Flânez avec et vous aurez une sacrée allure. Augmente la constitution de <%= con %>.",
"headSpecialKabutoText": "Kabuto de samouraï",
- "headSpecialKabutoNotes": "Ce heaume est beau et fonctionnel ! Vos ennemis seront distraits, trop occupés à l'admirer. Augmente l'Intelligence de <%= int %>.",
+ "headSpecialKabutoNotes": "Ce heaume est beau et fonctionnel ! Vos ennemis seront distraits, trop occupés à l'admirer. Augmente l'intelligence de <%= int %>.",
"headSpecialNamingDay2017Text": "Heaume de griffon pourpre royal",
"headSpecialNamingDay2017Notes": "Bonne fête de l'appellation ! Revêtez ce heaume terrible et plumeux pour célébrer Habitica. N'apporte aucun bonus.",
"headSpecialTurkeyHelmBaseText": "Coiffe de dindon",
@@ -901,105 +901,105 @@
"headSpecialNyeText": "Chapeau pointu absurde",
"headSpecialNyeNotes": "Vous avez reçu un chapeau pointu absurde ! Portez-le avec fierté en célébrant le Nouvel an ! N'apporte aucun bonus.",
"headSpecialYetiText": "Heaume du dresseur de yéti",
- "headSpecialYetiNotes": "Un chapeau adorablement terrifiant. Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2013-2014.",
+ "headSpecialYetiNotes": "Un chapeau adorablement terrifiant. Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2013-2014.",
"headSpecialSkiText": "Casque de ski-sassin",
- "headSpecialSkiNotes": "Garde secrète l'identité de son porteur... et son visage bien au chaud. Augmente la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2013-2014.",
+ "headSpecialSkiNotes": "Garde secrète l'identité de son porteur... et son visage bien au chaud. Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2013-2014.",
"headSpecialCandycaneText": "Chapeau en sucre d'orge",
- "headSpecialCandycaneNotes": "Ce chapeau est le plus délicieux du monde. Il est aussi connu pour apparaître et disparaître mystérieusement. Augmente la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2013-2014.",
+ "headSpecialCandycaneNotes": "Ce chapeau est le plus délicieux du monde. Il est aussi connu pour apparaître et disparaître mystérieusement. Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2013-2014.",
"headSpecialSnowflakeText": "Couronne flocon-de-neige",
- "headSpecialSnowflakeNotes": "Le porteur de cette couronne n'a jamais froid. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2013-2014.",
+ "headSpecialSnowflakeNotes": "Le porteur de cette couronne n'a jamais froid. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2013-2014.",
"headSpecialSpringRogueText": "Masque de chaton furtif",
- "headSpecialSpringRogueNotes": "Personne ne devinera JAMAIS que vous êtes un chat cambrioleur ! Augmente la Perception de <%= per %>. Équipement en édition limitée du printemps 2014.",
+ "headSpecialSpringRogueNotes": "Personne ne devinera JAMAIS que vous êtes un chat cambrioleur ! Augmente la perception de <%= per %>. Équipement en édition limitée du printemps 2014.",
"headSpecialSpringWarriorText": "Casque aux trèfles d'acier",
- "headSpecialSpringWarriorNotes": "Tissé de trèfles des champs, ce casque peut résister même au plus puissant des coups. Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2014.",
+ "headSpecialSpringWarriorNotes": "Tissé de trèfles des champs, ce casque peut résister même au plus puissant des coups. Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2014.",
"headSpecialSpringMageText": "Chapeau en fromage à trous",
- "headSpecialSpringMageNotes": "Ce chapeau renferme une puissante magie ! Essayez de ne pas le grignoter. Augmente la Perception de <%= per %>. Équipement en édition limitée du printemps 2014.",
+ "headSpecialSpringMageNotes": "Ce chapeau renferme une puissante magie ! Essayez de ne pas le grignoter. Augmente la perception de <%= per %>. Équipement en édition limitée du printemps 2014.",
"headSpecialSpringHealerText": "Couronne de l'amitié",
- "headSpecialSpringHealerNotes": "Cette couronne symbolise la loyauté et la dévotion envers ses compagnons. Le chien est le meilleur ami de l'aventurier, après tout ! Augmente l'Intelligence de <%= int %>. Équipement en édition limitée du printemps 2014.",
+ "headSpecialSpringHealerNotes": "Cette couronne symbolise la loyauté et la dévotion envers ses compagnons. Le chien est le meilleur ami de l'aventurier, après tout ! Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2014.",
"headSpecialSummerRogueText": "Bicorne de pirate",
- "headSpecialSummerRogueNotes": "Seuls les pirates les plus productifs peuvent porter cet excellent couvre-chef. Augmente la Perception de <%= per %>. Équipement en édition limitée de l’été 2014.",
+ "headSpecialSummerRogueNotes": "Seuls les pirates les plus productifs peuvent porter cet excellent couvre-chef. Augmente la perception de <%= per %>. Équipement en édition limitée de l’été 2014.",
"headSpecialSummerWarriorText": "Bandana de bretteur",
- "headSpecialSummerWarriorNotes": "Ce tissu doux et salé amplifie la force de son porteur. Augmente la Force de <%= str %>. Équipement en édition limitée de l’été 2014.",
+ "headSpecialSummerWarriorNotes": "Ce tissu doux et salé amplifie la force de son porteur. Augmente la force de <%= str %>. Équipement en édition limitée de l’été 2014.",
"headSpecialSummerMageText": "Chapeau enrubanné de varech",
- "headSpecialSummerMageNotes": "Quoi de plus magique qu'un chapeau enveloppé dans les algues ? Augmente la Perception de <%= per %>. Équipement en édition limitée de l’été 2014.",
+ "headSpecialSummerMageNotes": "Quoi de plus magique qu'un chapeau enveloppé dans les algues ? Augmente la perception de <%= per %>. Équipement en édition limitée de l’été 2014.",
"headSpecialSummerHealerText": "Couronne de corail",
- "headSpecialSummerHealerNotes": "Permet à son porteur de régénérer les récifs endommagés. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l’été 2014.",
+ "headSpecialSummerHealerNotes": "Permet à son porteur de régénérer les récifs endommagés. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l’été 2014.",
"headSpecialFallRogueText": "Capuche rouge sang",
- "headSpecialFallRogueNotes": "L'identité d'un chasseur de vampire doit toujours demeurer secrète. Augmente la Perception de <%= per %>. Équipement en édition limitée de l'automne 2014.",
+ "headSpecialFallRogueNotes": "L'identité d'un chasseur de vampire doit toujours demeurer secrète. Augmente la perception de <%= per %>. Équipement en édition limitée de l'automne 2014.",
"headSpecialFallWarriorText": "Scalp monstrueux de science",
- "headSpecialFallWarriorNotes": "Greffez-vous ce heaume ! Il n'a que TRÈS PEU servi ! Augmente la Force de <%= str %>. Équipement en édition limitée de l'automne 2014.",
+ "headSpecialFallWarriorNotes": "Greffez-vous ce heaume ! Il n'a que TRÈS PEU servi ! Augmente la force de <%= str %>. Équipement en édition limitée de l'automne 2014.",
"headSpecialFallMageText": "Chapeau à pointe",
- "headSpecialFallMageNotes": "La magie imprègne chaque fil de ce chapeau. Augmente la Perception de <%= per %>. Équipement en édition limitée de l'automne 2014.",
+ "headSpecialFallMageNotes": "La magie imprègne chaque fil de ce chapeau. Augmente la perception de <%= per %>. Équipement en édition limitée de l'automne 2014.",
"headSpecialFallHealerText": "Bandages pour tête",
- "headSpecialFallHealerNotes": "Hautement hygiénique tout en restant à la mode. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'automne 2014.",
+ "headSpecialFallHealerNotes": "Hautement hygiénique tout en restant à la mode. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'automne 2014.",
"headSpecialNye2014Text": "Chapeau pointu rigolo",
"headSpecialNye2014Notes": "Vous avez reçu un chapeau pointu rigolo ! Portez-le avec fierté en célébrant le Nouvel an ! N'apporte aucun bonus.",
"headSpecialWinter2015RogueText": "Masque de guivre-givre",
- "headSpecialWinter2015RogueNotes": "Vous êtes vraiment, sérieusement, absolument, une authentique guivre-givre. Vous n'êtes nullement un imposteur qui infiltre leurs rangs dans l'espoir de soutirer quelque trésor gisant dans leurs galeries de glace. Roaar ! Augmente la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2014-2015.",
+ "headSpecialWinter2015RogueNotes": "Vous êtes vraiment, sérieusement, absolument, une authentique guivre-givre. Vous n'êtes nullement un imposteur qui infiltre leurs rangs dans l'espoir de soutirer quelque trésor gisant dans leurs galeries de glace. Graou ! Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2014-2015.",
"headSpecialWinter2015WarriorText": "Casque en pain d’épice",
- "headSpecialWinter2015WarriorNotes": "Réfléchissez, réfléchissez, réfléchissez, aussi fort que vous le pouvez. Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2014-2015.",
+ "headSpecialWinter2015WarriorNotes": "Réfléchissez, réfléchissez, réfléchissez, aussi fort que vous le pouvez. Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2014-2015.",
"headSpecialWinter2015MageText": "Chapeau d'aurore",
- "headSpecialWinter2015MageNotes": "Le tissu de ce chapeau change de texture et brille quand son porteur étudie. Augmente la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2014-2015.",
+ "headSpecialWinter2015MageNotes": "Le tissu de ce chapeau change de texture et brille quand son porteur étudie. Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2014-2015.",
"headSpecialWinter2015HealerText": "Cache-oreilles douillet",
- "headSpecialWinter2015HealerNotes": "Ce cache-oreilles bien chaud vous tiendra à l'écart des bruits distrayants comme des frissons. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2014-2015.",
+ "headSpecialWinter2015HealerNotes": "Ce cache-oreilles bien chaud vous tiendra à l'écart des bruits distrayants comme des frissons. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2014-2015.",
"headSpecialSpring2015RogueText": "Casque pare-feu",
- "headSpecialSpring2015RogueNotes": "Du feu ? HA ! Vous couinez férocement face au feu ! Augmente la Perception de <%= per %>. Équipement en édition limitée du printemps 2015.",
+ "headSpecialSpring2015RogueNotes": "Du feu ? HA ! Vous couinez férocement face au feu ! Augmente la perception de <%= per %>. Équipement en édition limitée du printemps 2015.",
"headSpecialSpring2015WarriorText": "Casque de mise en garde",
- "headSpecialSpring2015WarriorNotes": "Prenez garde au heaume ! Seul un chien féroce peut le porter. Arrêtez de rire. Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2015.",
+ "headSpecialSpring2015WarriorNotes": "Prenez garde au heaume ! Seul un chien féroce peut le porter. Arrêtez de rire. Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2015.",
"headSpecialSpring2015MageText": "Chapeau de mage",
- "headSpecialSpring2015MageNotes": "Qu'est-ce qui est venu d'abord, le lapin ou le chapeau ? Augmente la Perception de <%= per %>. Équipement en édition limitée du printemps 2015.",
+ "headSpecialSpring2015MageNotes": "Qu'est-ce qui est venu d'abord, le lapin ou le chapeau ? Augmente la perception de <%= per %>. Équipement en édition limitée du printemps 2015.",
"headSpecialSpring2015HealerText": "Couronne réconfortante",
- "headSpecialSpring2015HealerNotes": "La perle au centre de cette couronne calme et conforte les personnes qui l'entourent. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée du printemps 2015.",
+ "headSpecialSpring2015HealerNotes": "La perle au centre de cette couronne calme et conforte les personnes qui l'entourent. Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2015.",
"headSpecialSummer2015RogueText": "Chapeau de renégat",
- "headSpecialSummer2015RogueNotes": "Ce chapeau de pirate est tombé par-dessus bord et a été décoré avec des fragments de corail de feu. Augmente la Perception de <%= per %>. Équipement en édition limitée de l'été 2015.",
+ "headSpecialSummer2015RogueNotes": "Ce chapeau de pirate est tombé par-dessus bord et a été décoré avec des fragments de corail de feu. Augmente la perception de <%= per %>. Équipement en édition limitée de l'été 2015.",
"headSpecialSummer2015WarriorText": "Heaume océanique incrusté de joyaux",
- "headSpecialSummer2015WarriorNotes": "Forgé dans du métal du fond des océans par les artisans de Dilatoire, ce heaume est beau et résistant. Augmente la Force de <%= str %>. Équipement en édition limitée de l’été 2015.",
+ "headSpecialSummer2015WarriorNotes": "Forgé dans du métal du fond des océans par les artisans de Dilatoire, ce heaume est beau et résistant. Augmente la force de <%= str %>. Équipement en édition limitée de l’été 2015.",
"headSpecialSummer2015MageText": "Foulard de devin",
- "headSpecialSummer2015MageNotes": "Un pouvoir caché brille dans les fils de ce foulard. Augmente la Perception de <%= per %>. Équipement en édition limitée de l’été 2015.",
+ "headSpecialSummer2015MageNotes": "Un pouvoir caché brille dans les fils de ce foulard. Augmente la perception de <%= per %>. Équipement en édition limitée de l’été 2015.",
"headSpecialSummer2015HealerText": "Bonnet de matelot",
- "headSpecialSummer2015HealerNotes": "Avec votre bonnet de matelot résolument vissé sur la tête, vous pouvez naviguer même sur les mers déchaînées ! Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l’été 2015.",
+ "headSpecialSummer2015HealerNotes": "Avec votre bonnet de matelot résolument vissé sur la tête, vous pouvez naviguer même sur les mers déchaînées ! Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l’été 2015.",
"headSpecialFall2015RogueText": "Ailes de bat-aille",
- "headSpecialFall2015RogueNotes": "Trouvez vos ennemis par écholocation avec ce heaume puissant ! Augmente la Perception de <%= per %>. Équipement en édition limitée de l'automne 2015.",
+ "headSpecialFall2015RogueNotes": "Trouvez vos ennemis par écholocation avec ce heaume puissant ! Augmente la perception de <%= per %>. Équipement en édition limitée de l'automne 2015.",
"headSpecialFall2015WarriorText": "Chapeau d'épouvantail",
- "headSpecialFall2015WarriorNotes": "Tout le monde voudrait ce chapeau -- si seulement ils avaient un cerveau! Augmente la Force de <%= str %>. Équipement en édition limitée de l'automne 2015.",
+ "headSpecialFall2015WarriorNotes": "Tout le monde voudrait ce chapeau -- si seulement ils avaient un cerveau! Augmente la force de <%= str %>. Équipement en édition limitée de l'automne 2015.",
"headSpecialFall2015MageText": "Chapeau rapiécé",
- "headSpecialFall2015MageNotes": "Chaque couture dans ce chapeau augmente sa puissance. Augmente la Perception de <%= per %>. Équipement en édition limitée de l'automne 2015.",
+ "headSpecialFall2015MageNotes": "Chaque couture dans ce chapeau augmente sa puissance. Augmente la perception de <%= per %>. Équipement en édition limitée de l'automne 2015.",
"headSpecialFall2015HealerText": "Chapeau de grenouille",
- "headSpecialFall2015HealerNotes": "C'est un chapeau extrêmement sérieux, digne seulement de l'un des faiseurs de potions les plus avancés. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'automne 2015.",
+ "headSpecialFall2015HealerNotes": "C'est un chapeau extrêmement sérieux, digne seulement de l'un des faiseurs de potions les plus avancés. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'automne 2015.",
"headSpecialNye2015Text": "Chapeau pointu ridicule",
"headSpecialNye2015Notes": "Vous avez reçu un chapeau pointu ridicule ! Portez-le avec fierté en célébrant le Nouvel an ! N'apporte aucun bonus.",
"headSpecialWinter2016RogueText": "Heaume-cacao",
- "headSpecialWinter2016RogueNotes": "Le foulard protecteur de ce confortable heaume s'enlève uniquement pour siroter des boissons chaudes en hiver. Augmente la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2015-2016.",
+ "headSpecialWinter2016RogueNotes": "Le foulard protecteur de ce confortable heaume s'enlève uniquement pour siroter des boissons chaudes en hiver. Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2015-2016.",
"headSpecialWinter2016WarriorText": "Bonnet de bonhomme de neige",
- "headSpecialWinter2016WarriorNotes": "Brr ! Ce majestueux heaume est vraiment puissant... Jusqu'à ce qu'il fonde. Augmente la Force de <%= str %>. Équipement en édition limitée de l'hiver 2015-2016.",
+ "headSpecialWinter2016WarriorNotes": "Brr ! Ce majestueux heaume est vraiment puissant... Jusqu'à ce qu'il fonde. Augmente la force de <%= str %>. Équipement en édition limitée de l'hiver 2015-2016.",
"headSpecialWinter2016MageText": "Capuche de snowboardeur",
- "headSpecialWinter2016MageNotes": "Protège vos yeux de la neige pendant que vous jetez vos sort. Augmente la Perception de <%= per %>. Équipement en édition limitée de l'hiver 2015-2016.",
+ "headSpecialWinter2016MageNotes": "Protège vos yeux de la neige pendant que vous jetez vos sort. Augmente la perception de <%= per %>. Équipement en édition limitée de l'hiver 2015-2016.",
"headSpecialWinter2016HealerText": "Heaume d'ailes de fées",
- "headSpecialWinter2016HealerNotes": "Cesailesbattentsivitequ'ellesrendentflou ! Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2015-2016.",
+ "headSpecialWinter2016HealerNotes": "Cesailesbattentsivitequ'ellesrendentflou ! Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'hiver 2015-2016.",
"headSpecialSpring2016RogueText": "Masque de bon toutou",
- "headSpecialSpring2016RogueNotes": "Oh ! Quel mignon petit chiot ! Viens ici et laisse-moi te caresser la tête... Hé ! Où est passé tout mon or ? Augmente la Perception de <%= per %>. Équipement en édition limitée du printemps 2016.",
+ "headSpecialSpring2016RogueNotes": "Oh ! Quel mignon petit chiot ! Viens ici et laisse-moi te caresser la tête... Hé ! Où est passé tout mon or ? Augmente la perception de <%= per %>. Équipement en édition limitée du printemps 2016.",
"headSpecialSpring2016WarriorText": "Heaume des gardes-souris",
- "headSpecialSpring2016WarriorNotes": "Plus jamais vous ne prendrez de coups sur la tête ! Qu'ils essaient ! Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2016.",
+ "headSpecialSpring2016WarriorNotes": "Plus jamais vous ne prendrez de coups sur la tête ! Qu'ils essaient ! Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2016.",
"headSpecialSpring2016MageText": "Chapeau de grand matou",
- "headSpecialSpring2016MageNotes": "Vêtement pour vous élever au-dessus du simple mage lambda. Augmente la Perception de <%= per %>. Équipement en édition limitée du printemps 2016.",
+ "headSpecialSpring2016MageNotes": "Vêtement pour vous élever au-dessus du simple mage lambda. Augmente la perception de <%= per %>. Équipement en édition limitée du printemps 2016.",
"headSpecialSpring2016HealerText": "Diadème fleuri",
- "headSpecialSpring2016HealerNotes": "Cela étincelle du potentiel d'une nouvelle vie prête à éclore. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée du printemps 2016.",
+ "headSpecialSpring2016HealerNotes": "Cela étincelle du potentiel d'une nouvelle vie prête à éclore. Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2016.",
"headSpecialSummer2016RogueText": "Heaume d'anguille",
- "headSpecialSummer2016RogueNotes": "Jetez un coup d’œil depuis les crevasses rocheuses pendant que vous portez ce casque furtif. Augmente la Perception de <%= per %>. Équipement en édition limitée de l’été 2016.",
+ "headSpecialSummer2016RogueNotes": "Jetez un coup d’œil depuis les crevasses rocheuses pendant que vous portez ce casque furtif. Augmente la perception de <%= per %>. Équipement en édition limitée de l’été 2016.",
"headSpecialSummer2016WarriorText": "Heaume de requin",
- "headSpecialSummer2016WarriorNotes": "Croquez les tâches difficiles avec ce heaume redoutable ! Augmente la Force de <%= str %>. Équipement en édition limitée de l’été 2016.",
+ "headSpecialSummer2016WarriorNotes": "Croquez les tâches difficiles avec ce heaume redoutable ! Augmente la force de <%= str %>. Équipement en édition limitée de l’été 2016.",
"headSpecialSummer2016MageText": "Chapeau-évent",
- "headSpecialSummer2016MageNotes": "De l'eau magique jaillit constamment de ce chapeau. Augmente la Perception de <%= per %>. Équipement en édition limitée de l’été 2016.",
+ "headSpecialSummer2016MageNotes": "De l'eau magique jaillit constamment de ce chapeau. Augmente la perception de <%= per %>. Équipement en édition limitée de l’été 2016.",
"headSpecialSummer2016HealerText": "Heaume d'hippocampe",
- "headSpecialSummer2016HealerNotes": "Ce casque indique que son porteur a été entraîné par les hippocampes guérisseurs magiques de Dilatoire. Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l’été 2016.",
+ "headSpecialSummer2016HealerNotes": "Ce casque indique que son porteur a été entraîné par les hippocampes guérisseurs magiques de Dilatoire. Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l’été 2016.",
"headSpecialFall2016RogueText": "Heaume de veuve-noire",
- "headSpecialFall2016RogueNotes": "Les pattes sur ce heaume tremblent constamment. Augmente la Perception de <%=per %>. Équipement en édition limitée de l'automne 2016.",
+ "headSpecialFall2016RogueNotes": "Les pattes sur ce heaume tremblent constamment. Augmente la perception de <%=per %>. Équipement en édition limitée de l'automne 2016.",
"headSpecialFall2016WarriorText": "Heaume en écorce noueuse",
- "headSpecialFall2016WarriorNotes": "Ce heaume détrempé par les marécages est couvert de morceaux de tourbe. Augmente la Force de <%=str %>. Équipement en édition limitée de l'automne 2016.",
+ "headSpecialFall2016WarriorNotes": "Ce heaume détrempé par les marécages est couvert de morceaux de tourbe. Augmente la force de <%=str %>. Équipement en édition limitée de l'automne 2016.",
"headSpecialFall2016MageText": "Capuche de malice",
- "headSpecialFall2016MageNotes": "Dissimulez vos complots sous cette capuche sombre. Augmente la Perception de <%=per %>. Équipement en édition limitée de l'automne 2016.",
+ "headSpecialFall2016MageNotes": "Dissimulez vos complots sous cette capuche sombre. Augmente la perception de <%=per %>. Équipement en édition limitée de l'automne 2016.",
"headSpecialFall2016HealerText": "Couronne de méduse",
- "headSpecialFall2016HealerNotes": "Malheur à toute personne qui osera vous regarder dans les yeux... Augmente l'Intelligence de <%= int %>. Équipement en édition limitée de l'automne 2016.",
+ "headSpecialFall2016HealerNotes": "Malheur à toute personne qui osera vous regarder dans les yeux... Augmente l'intelligence de <%= int %>. Équipement en édition limitée de l'automne 2016.",
"headSpecialNye2016Text": "Chapeau pointu fantasque",
"headSpecialNye2016Notes": "Vous avez reçu un chapeau pointu fantasque ! Portez-le avec fierté en célébrant le Nouvel an ! N'apporte aucun bonus.",
"headSpecialWinter2017RogueText": "Heaume givré",
@@ -1749,9 +1749,9 @@
"eyewearArmoireGoofyGlassesNotes": "Parfaites pour passer incognito ou juste faire ricaner vos compagnons d'aventure. Augmente la Perception de <%= per %>. Armoire enchantée : objet indépendant.",
"twoHandedItem": "Objet à deux mains.",
"weaponArmoireChefsSpoonText": "Cuillère de chef",
- "weaponArmoireChefsSpoonNotes": "Dressez-la alors que vous poussez votre cri de guerre : \"CUILLEEEEERE !!\" Augmente l'intelligence de <%= int %>. Armoire enchantée: Ensemble du chef (Objet 3 de 4).",
+ "weaponArmoireChefsSpoonNotes": "Dressez-la alors que vous poussez votre cri de guerre : \"CUILLEEEEERE !!\" Augmente l'intelligence de <%= int %>. Armoire enchantée: ensemble du chef (Objet 3 de 4).",
"weaponArmoireVernalTaperText": "Cône vernal",
- "weaponArmoireVernalTaperNotes": "Les jours s'allongent, mais cette bougie vous aidera à trouver votre chemin avant le levé du soleil. Augmente la constitution de <%= con %>. Armoire enchantée : Ensemble des vêtements de printemps (Objet 3 de 3).",
+ "weaponArmoireVernalTaperNotes": "Les jours s'allongent, mais cette bougie vous aidera à trouver votre chemin avant le levé du soleil. Augmente la constitution de <%= con %>. Armoire enchantée : ensemble des vêtements de printemps (Objet 3 de 3).",
"armorArmoireChefsJacketText": "Tablier de chef",
"armorArmoireChefsJacketNotes": "Cette épaisse veste en coton est à double boutonnage pour vous protéger des éclaboussures (et commodément réversible...). Augmente l'intelligence de <%= int %>. Armoire enchantée : Ensemble du chef (objet 2 de 4).",
"armorArmoireVernalVestmentText": "Vêtement de printemps",
@@ -1769,7 +1769,7 @@
"weaponSpecialSpring2019RogueText": "Éclair",
"weaponSpecialSpring2019RogueNotes": "Ces armes renferment le pouvoir du ciel et de la pluie. Il est recommandé de ne pas les utiliser en étant plongé dans l'eau. Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2019.",
"weaponSpecialSpring2019WarriorText": "Épée tronc",
- "weaponSpecialSpring2019WarriorNotes": "Les mauvaises habitudes tremblent devant cette lame verdoyante. Augmente la Force de <%= str %>. Équipement en édition limitée du printemps 2019.",
+ "weaponSpecialSpring2019WarriorNotes": "Les mauvaises habitudes tremblent devant cette lame verdoyante. Augmente la force de <%= str %>. Équipement en édition limitée du printemps 2019.",
"weaponSpecialSpring2019MageText": "Bâton d'ambre",
"weaponSpecialSpring2019MageNotes": "Un moustique est emprisonné dans la résine au sommet de ce bâton ! Peut ou non contenir de l'ADN de dinosaure. Augmente l'intelligence de <%= int %> et la perception de <%= per %>. Équipement en édition limitée du printemps 2019.",
"weaponSpecialSpring2019HealerText": "Chant du printemps",
@@ -1787,13 +1787,13 @@
"weaponArmoireSlingshotText": "Fronde",
"weaponArmoireSlingshotNotes": "Visez vos quotidiennes rouges ! Augmente la force de <%= str %>. Armoire enchantée : objet indépendant.",
"weaponArmoireNephriteBowText": "Arc de néphrite",
- "weaponArmoireNephriteBowNotes": "Cet arc tire des flèches spéciales à la pointe de jade, qui feront tomber même vos mauvaises habitudes les plus coriaces ! Augmente l'intelligence de <%= int => et la force de <%= str %>. Armoire enchantée : Ensemble de l'archère de néphrite (objet 1 de 3).",
+ "weaponArmoireNephriteBowNotes": "Cet arc tire des flèches spéciales à la pointe de jade, qui feront tomber même vos mauvaises habitudes les plus coriaces ! Augmente l'intelligence de <%= int %> et la force de <%= str %>. Armoire enchantée : Ensemble de l'archère de néphrite (objet 1 de 3).",
"weaponArmoireBambooCaneText": "Cane en bambou",
- "weaponArmoireBambooCaneNotes": "Parfait pour vous accompagner dans une promenade ou pour danser le Charleston. Augmente l'intelligence, la perception et la constitution de <%= attrs %> chacune. Armoire enchantée : Ensemble de plaisancier (objet 3 de 3).",
+ "weaponArmoireBambooCaneNotes": "Parfait pour vous accompagner dans une promenade ou pour danser le Charleston. Augmente l'intelligence, la perception et la constitution de <%= attrs %> chacune. Armoire enchantée : ensemble de plaisancier (objet 3 de 3).",
"weaponArmoireAstronomersTelescopeText": "Télescope d'astronome",
- "weaponArmoireAstronomersTelescopeNotes": "Un instrument qui vous permettra d'observer l'ancienne danse des étoiles. Augmente la perception de <%= per %>. Armoire enchantée : Ensemble de mage astronome (objet 3 de 3).",
+ "weaponArmoireAstronomersTelescopeNotes": "Un instrument qui vous permettra d'observer l'ancienne danse des étoiles. Augmente la perception de <%= per %>. Armoire enchantée : ensemble de mage astronome (objet 3 de 3).",
"weaponArmoireMagnifyingGlassText": "Loupe",
- "weaponArmoireMagnifyingGlassNotes": "Aha ! Un indice ! Examinez-le avec attention avec cette précieuse loupe. Augmente la perception de <%= per %>. Armoire enchantée : Ensemble de détective (objet 3 de 4).",
+ "weaponArmoireMagnifyingGlassNotes": "Aha ! Un indice ! Examinez-le avec attention avec cette précieuse loupe. Augmente la perception de <%= per %>. Armoire enchantée : ensemble de détective (objet 3 de 4).",
"armorSpecialSummer2019RogueText": "Queue de requin marteau",
"armorSpecialSummer2019RogueNotes": "Cette queue sinueuse est parfaite pour faire des virages serrés lors des échappées aquatiques aventureuses. Augmente la perception de <%= per %>. Équipement en édition limitée de l'été 2019.",
"armorSpecialSummer2019WarriorText": "Armure carapace",
@@ -1810,7 +1810,7 @@
"armorSpecialSpring2019MageNotes": "Ces robes recueillent l'énergie de la résine magique incrustée dans les fibres de l'ancienne écorce qui en composent le tissu. Augmente l'intelligence de <%= int %>. Équipement en édition limitée du printemps 2019.",
"armorSpecialSpring2019HealerText": "Costume de Robin",
"armorSpecialSpring2019HealerNotes": "Vos plumes brillantes feront savoir à tout le monde que le froid et l'obscurité de l'hiver sont passés. Augmente la constitution de <%= con %>. Équipement en édition limitée du printemps 2019.",
- "armorMystery201903Text": "Armure de Sel-ébration",
+ "armorMystery201903Text": "Armure de sel-ébration",
"armorMystery201903Notes": "Les gens se demandent où vous avez eu cette mer-veilleuse tenue ! Ne confère aucun bonus. Équipement d'abonnement de mars 2019.",
"armorMystery201904Text": "Tenue opalescente",
"armorMystery201904Notes": "Ce vêtement brillant a des opales cousues dans le plastron pour vous donner des pouvoirs arcaniques et un look fabuleux. Ne confère aucun bonus. Équipement d'abonnement d'avril 2019.",
@@ -1897,14 +1897,14 @@
"eyewearMystery201907Text": "Jolies lunettes de soleil",
"eyewearMystery201907Notes": "Ayez l'air impressionnant tout en protégeant vos yeux des rayons UV nocifs ! Ne confère aucun bonus. Équipement d'abonnement de juillet 2019.",
"armorMystery201908Text": "Costume de la faune crapahuteuse",
- "armorMystery201908Notes": "Ces jambes servent à danser ! Et c'est ce qu'elles vont faire . Ne confère aucun bonus. Équipement d'abonnement d'Août 2019.",
+ "armorMystery201908Notes": "Ces jambes servent à danser ! Et c'est ce qu'elles vont faire . Ne confère aucun bonus. Équipement d'abonnement d'août 2019.",
"headAccessoryMystery201908Text": "Cornes de la faune crapahuteuse",
"headAccessoryMystery201908Notes": "Un vent à décorner les boucs n'a aucune chance face à ces cornes ! Ne confère aucun bonus. Équipement d'abonnement d'août 2019.",
"shieldArmoirePolishedPocketwatchNotes": "Vous avez le temps. Et il vous va très bien. Augmente l'intelligence de <%= int %>. Armoire enchantée : Objet indépendant.",
"shieldArmoirePolishedPocketwatchText": "Montre de poche polie",
- "weaponArmoireResplendentRapierNotes": "Démontrez votre talent d'escrimeur avec cette arme finement pointue. Augmente la perception de <%= per %>. Armoire enchantée : Objet indépendant.",
+ "weaponArmoireResplendentRapierNotes": "Démontrez votre talent d'escrimeur avec cette arme finement pointue. Augmente la perception de <%= per %>. Armoire enchantée : objet indépendant.",
"weaponArmoireResplendentRapierText": "Rapière resplendissante",
- "weaponArmoireFloridFanNotes": "Cet éventail mignon en soie se replie quand vous ne l'utilisez pas. Augmente la constitution de <% con %>. Armoire enchantée : Objet indépendant.",
+ "weaponArmoireFloridFanNotes": "Cet éventail mignon en soie se replie quand vous ne l'utilisez pas. Augmente la constitution de <% con %>. Armoire enchantée : objet indépendant.",
"weaponArmoireFloridFanText": "Éventail fleuri",
"eyewearSpecialFall2019HealerNotes": "Endurcissez-vous contre les plus grands ennemis avec ce masque impénétrable. Ne confère aucun bonus. Équipement en édition limitée de l'automne 2019.",
"eyewearSpecialFall2019HealerText": "Visage sombre",
@@ -1941,5 +1941,23 @@
"weaponSpecialFall2019WarriorNotes": "Préparez-vous à déchirer vos ennemis avec les serres d'un corbeau ! Augmente la force de <%= str %>. Équipement en édition limitée de l'automne 2019.",
"weaponSpecialFall2019WarriorText": "Trident serre",
"weaponSpecialFall2019RogueNotes": "Que vous dirigiez un orchestre ou que vous chantiez une aria, cet équipement vous laisse les mains libres pour toutes sortes de gestes dramatiques ! Augmente la force de <%= str %>. Équipement en édition limitée de l'automne 2019.",
- "weaponSpecialFall2019RogueText": "Podium"
+ "weaponSpecialFall2019RogueText": "Podium",
+ "eyewearSpecialKS2019Notes": "Chauve comme ... hmm, les griffons n'ont pas de visière. Cela vous rappellera de ... Oh, mais de qui se moque-t-on ? Ça a juste l'air cool ! Ne confère aucun bonus.",
+ "eyewearSpecialKS2019Text": "Visière mythique du griffon",
+ "shieldArmoireMasteredShadowNotes": "Vos pouvoirs ont amené ces ombres dansantes à vos côté pour réaliser vos moindres souhaits. Augmente la perception et la constitution de <%= attrs %> chacune. Armoire enchantée : Ensemble du maître des ombres (objet 4 de 4).",
+ "shieldArmoireMasteredShadowText": "Ombre maîtrisée",
+ "shieldSpecialKS2019Notes": "Étincelant comme la coquille d'un œuf de griffon, ce magnifique bouclier vous montre comment vous tenir prêt à aider lorsque votre propre fardeau est léger. Augmente la perception de <% per %>.",
+ "shieldSpecialKS2019Text": "Bouclier mythique du griffon",
+ "headArmoireShadowMastersHoodNotes": "Cette capuche vous donne le pouvoir de voir à travers l'obscurité la plus dense. Vous pourriez quand même avoir besoin de collyre de temps en temps. Augmente la perception et la constitution de <%= attrs %> chacun. Armoire enchantée : Ensemble du maître des ombres (objet 2 de 4).",
+ "headArmoireShadowMastersHoodText": "Capuche du maître des ombres",
+ "headSpecialKS2019Notes": "Orné de la ressemblance et du plumage d'un griffon, ce casque glorieux symbolise la façon dont vos compétences et votre soutien sont un exemple pour les autres. Augmente l'intelligence de <%= int %>.",
+ "headSpecialKS2019Text": "Casque mythique du griffon",
+ "armorArmoireShadowMastersRobeNotes": "Le tissu de cette robe fluide est tissé des ombres les plus obscures dans les grottes les plus profondes d'Habitica. Augmente la constitution de <%= con %>. Armoire enchantée : Ensemble du maître des ombres (objet 1 de 4).",
+ "armorArmoireShadowMastersRobeText": "Robe du maître des ombres",
+ "armorSpecialKS2019Notes": "Brillant de l'intérieur comme le cœur noble d'un griffon, cette armure resplendissante vous encourage à ressentir la fierté de vos accomplissements. Augmente la constitution de <%= con %>.",
+ "armorSpecialKS2019Text": "Armure mythique du griffon",
+ "weaponArmoireShadowMastersMaceNotes": "Les créatures des ombres obéiront vos moindres demandes lorsque vous brandirez cette masse luminescente. Augmente la perception de <%= per %>. Armoire enchantée : ensemble du maître des ombres (objet 3 de 4).",
+ "weaponArmoireShadowMastersMaceText": "Masse du maître des ombres",
+ "weaponSpecialKS2019Notes": "Courbé comme le bec et les serres d'un griffon, cette hallebarde ornementée vous rappelle votre force lorsqu'une tâche semble insurmontable. Augmente la force de <%= str %>.",
+ "weaponSpecialKS2019Text": "Glaive mythique du griffon"
}
diff --git a/website/common/locales/fr/generic.json b/website/common/locales/fr/generic.json
index b407e9a81d..c2c77a5272 100644
--- a/website/common/locales/fr/generic.json
+++ b/website/common/locales/fr/generic.json
@@ -68,7 +68,7 @@
"and": "et",
"loginSuccess": "Connexion réussie !",
"youSure": "Confirmez-vous ?",
- "submit": "Poster",
+ "submit": "Valider",
"close": "Fermer",
"saveAndClose": "Enregistrer & Fermer",
"saveAndConfirm": "Sauvegarder & confirmer",
diff --git a/website/common/locales/fr/groups.json b/website/common/locales/fr/groups.json
index 12f4b84081..1b63415f90 100644
--- a/website/common/locales/fr/groups.json
+++ b/website/common/locales/fr/groups.json
@@ -147,7 +147,7 @@
"pm-reply": "Répondre",
"inbox": "Boîte de réception",
"messageRequired": "Un message est requis.",
- "toUserIDRequired": "Un ID d'utilisateur est requis",
+ "toUserIDRequired": "Un identifiant est requis",
"gemAmountRequired": "Un nombre de gemmes est requis",
"notAuthorizedToSendMessageToThisUser": "Vous ne pouvez pas envoyer de message à ce membre, car il ou elle a décidé de bloquer les messages.",
"privateMessageGiftGemsMessage": "Bonjour <%= receiverName %>, <%= senderName %> vous a envoyé <%= gemAmount %> gemmes !",
@@ -168,7 +168,7 @@
"needsTextPlaceholder": "Écrivez votre message ici.",
"copyMessageAsToDo": "Copier le message comme A Faire",
"copyAsTodo": "Copier comme tâche à faire",
- "messageAddedAsToDo": "Message copié comme A Faire.",
+ "messageAddedAsToDo": "Message copié comme tâche à faire.",
"messageWroteIn": "<%= user %> a écrit dans <%= group %>",
"msgPreviewHeading": "Aperçu du message",
"leaderOnlyChallenges": "Seul le responsable du groupe peut créer des défis",
@@ -180,7 +180,7 @@
"inviteMembersHowTo": "Invitez des personnes en utilisant une adresse mail valide ou un ID d'Utilisateur à 36 chiffres. Si l'adresse courriel n'est liée à aucun compte existant, nous inviterons son propriétaire à rejoindre Habitica.",
"inviteFriendsNow": "Inviter des amis maintenant",
"inviteFriendsLater": "Inviter des amis plus tard",
- "inviteAlertInfo": "Si vous avez des amis qui utilisent déjà Habitica, invitez-les avec leur ID d'utilisateur ici.",
+ "inviteAlertInfo": "Si vous avez des amis qui utilisent déjà Habitica, invitez-les avec leur identifiant ici.",
"inviteExistUser": "Inviter des membres existants",
"byColon": "Invité par :",
"inviteNewUsers": "Inviter de nouveaux membres",
@@ -483,5 +483,6 @@
"pmReported": "Merci d'avoir signalé ce message.",
"suggestedGroup": "Suggérer parce que vous venez d'arriver sur Habitica.",
"taskClaimed": "<%= userName %> a revendiqué la tâche <%= taskText %>.",
- "youHaveBeenAssignedTask": "<%= managerName %> vous a assigné la tâche <%= taskText %>."
+ "youHaveBeenAssignedTask": "<%= managerName %> vous a assigné la tâche <%= taskText %>.",
+ "groupActivityNotificationTitle": "<%= user %> a écrit dans <%= group %>"
}
diff --git a/website/common/locales/fr/npc.json b/website/common/locales/fr/npc.json
index 5073ad466f..f9081494d5 100644
--- a/website/common/locales/fr/npc.json
+++ b/website/common/locales/fr/npc.json
@@ -21,7 +21,7 @@
"sleepDescription": "Besoin d'une pause ? Prenez une chambre à l'auberge de Daniel pour mettre en veille les aspects d'Habitica les plus complexes :",
"sleepBullet1": "Les quotidiennes non validées ne feront plus de dommages",
"sleepBullet2": "Les combos ne seront pas interrompus et leur couleur n'évoluera plus",
- "sleepBullet3": "Les boss ne vous infligeront pas de dégâts pour vos quotidiennes manquées",
+ "sleepBullet3": "Les boss ne vous infligeront pas de dégâts pour vos propres quotidiennes manquées",
"sleepBullet4": "Les dommages aux boss et la collecte des objets de quête resteront en instance jusqu'à la sortie de la taverne",
"pauseDailies": "Désactiver les dégâts",
"unpauseDailies": "Activer les dégâts",
diff --git a/website/common/locales/fr/pets.json b/website/common/locales/fr/pets.json
index ff5f5ff765..026be8c601 100644
--- a/website/common/locales/fr/pets.json
+++ b/website/common/locales/fr/pets.json
@@ -144,5 +144,6 @@
"notEnoughMounts": "Vous n'avez pas collecté assez de montures",
"notEnoughPetsMounts": "Vous n'avez pas collecté assez de familiers et de montures",
"wackyPets": "Familiers farfelus",
- "filterByWacky": "Farfelus"
+ "filterByWacky": "Farfelus",
+ "gryphatrice": "Griffatrice"
}
diff --git a/website/common/locales/fr/quests.json b/website/common/locales/fr/quests.json
index cbcf0866a9..f7011b43e1 100644
--- a/website/common/locales/fr/quests.json
+++ b/website/common/locales/fr/quests.json
@@ -136,5 +136,6 @@
"chatItemQuestFinish": "Tout les objets ont été trouvés ! L'équipe reçoit sa récompense.",
"chatQuestAborted": "<%= username %> a interrompu la quête <%= questName %>.",
"chatQuestCancelled": "<%= username %> a annulé la quête en équipe <%= questName %>.",
- "tavernBossTired": "<%= bossName %> essaye de lancer <%= rageName %> mais est trop fatigué pour ça."
+ "tavernBossTired": "<%= bossName %> essaye de lancer <%= rageName %> mais est trop fatigué pour ça.",
+ "questInvitationNotificationInfo": "Vous avez reçu une invitation à une quête"
}
diff --git a/website/common/locales/fr/settings.json b/website/common/locales/fr/settings.json
index 2192fc1de7..1e69056485 100644
--- a/website/common/locales/fr/settings.json
+++ b/website/common/locales/fr/settings.json
@@ -119,8 +119,8 @@
"giftedSubscriptionInfo": "<%= name %> vous a offert un abonnement de <%= months %> mois",
"giftedSubscriptionFull": "Bonjour <%= username %>, <%= sender %> vous a envoyé <%= monthCount %> mois d'abonnement !",
"giftedSubscriptionWinterPromo": "Bonjour <%= username %>, vous avez reçu <%= monthCount %> mois de d'abonnement en cadeau dans le cadre de notre promotion de vacances !",
- "invitedParty": "Invitation dans une équipe",
- "invitedGuild": "Invitation dans une guilde",
+ "invitedParty": "Vous avez reçu une invitation dans une équipe",
+ "invitedGuild": "Vous avez reçu une invitation dans une guilde",
"importantAnnouncements": "Rappels de connexion pour terminer des tâches et recevoir des récompenses",
"weeklyRecaps": "Résumés de l'activité de votre compte durant la semaine passée (N.B. : ceci est actuellement désactivé suite à des problèmes de performance, mais nous espérons pouvoir rétablir bientôt l'envoi des courriels !)",
"onboarding": "Aide à la configuration de votre compte Habitica",
@@ -203,6 +203,12 @@
"goToSettings": "Voir les paramètres",
"usernameVerifiedConfirmation": "Votre nom d'utilisateur, <%= username %>, est confirmé !",
"usernameNotVerified": "Veuillez confirmer votre nom d'utilisateur.",
- "changeUsernameDisclaimer": "Nous allons effectuer une transition des noms de connexion à des noms d'utilisateur publics très bientôt. Ce nom d'utilisateur sera utilisé pour les invitations, les @mentions dans les discussion, et les messages.",
- "verifyUsernameVeteranPet": "Un de ces Familiers Vétéran t'attendra quand tu auras validé !"
+ "changeUsernameDisclaimer": "Ce nom d'utilisateur sera utilisé pour les invitations, les @mentions dans les discussion, et les messages.",
+ "verifyUsernameVeteranPet": "Un de ces Familiers Vétéran t'attendra quand tu auras validé !",
+ "subscriptionReminders": "Rappels d'abonnements",
+ "newPMNotificationTitle": "Nouveau message de <%= name %>",
+ "onlyPrivateSpaces": "Seulement sur les espaces privés",
+ "everywhere": "Partout",
+ "suggestMyUsername": "Suggérer mon identifiant",
+ "mentioning": "Mentions"
}
diff --git a/website/common/locales/fr/tasks.json b/website/common/locales/fr/tasks.json
index eaed751de9..7ce5c487af 100644
--- a/website/common/locales/fr/tasks.json
+++ b/website/common/locales/fr/tasks.json
@@ -1,10 +1,10 @@
{
"clearCompleted": "Supprimer les tâches accomplies",
"clearCompletedDescription": "Les tâches complétées sont supprimées après 30 jours pour les personnes n'ayant pas d'abonnement, et 90 jours pour les personnes bénéficiant d'un abonnement.",
- "clearCompletedConfirm": "Voulez-vous vraiment effacer vos tâches À faire complétées ?",
- "sureDeleteCompletedTodos": "Voulez-vous vraiment effacer vos tâches À faire complétées ?",
+ "clearCompletedConfirm": "Voulez-vous vraiment effacer vos tâches à faire complétées ?",
+ "sureDeleteCompletedTodos": "Voulez-vous vraiment effacer vos tâches à faire complétées ?",
"lotOfToDos": "Vos 30 tâches à faire terminées les plus récentes sont montrées ici. Vous pouvez consulter les tâches plus anciennes depuis Données > Outil d'affichage des données ou Données > Exporter les données > Données utilisateur.",
- "deleteToDosExplanation": "Si vous cliquez sur le bouton ci-dessous, toutes vos tâches À Faire complétées et archivées seront supprimées définitivement, à l'exception des tâches de défis actifs et des offres de groupe. Exportez-les d'abord si vous souhaitez en garder une trace.",
+ "deleteToDosExplanation": "Si vous cliquez sur le bouton ci-dessous, toutes vos tâches à faire complétées et archivées seront supprimées définitivement, à l'exception des tâches de défis actifs et des offres de groupe. Exportez-les d'abord si vous souhaitez en garder une trace.",
"addMultipleTip": "Astuce : Pour ajouter plusieurs <%= taskType %>, séparez-les par un retour à la ligne (Shift+Entrée) puis tapez sur la touche “Entrée.”",
"addsingle": "Ajout unitaire",
"addATask": "Ajouter une <%= type %>",
@@ -26,7 +26,7 @@
"save": "Enregistrer",
"addChecklist": "Ajouter une liste de vérification",
"checklist": "Liste de vérification",
- "checklistText": "Divisez vos tâches ! Les listes de vérification augmentent le gain d'expérience et d'or pour les tâches À Faire, et réduisent les dommages infligés par les Quotidiennes.",
+ "checklistText": "Divisez vos tâches ! Les listes de vérification augmentent le gain d'expérience et d'or pour les tâches à faire, et réduisent les dommages infligés par les quotidiennes.",
"newChecklistItem": "Nouvelle liste de vérification",
"expandChecklist": "Développer la liste de vérification",
"collapseChecklist": "Réduire la liste de vérification",
@@ -69,9 +69,9 @@
"restoreStreak": "Rétablir le combo",
"resetStreak": "Réinitialiser le combo",
"todo": "À faire",
- "todos": "À Faire",
- "newTodo": "Nouvelle tâche À faire",
- "newTodoBulk": "Nouvelles tâches À Faire (une par ligne)",
+ "todos": "À faire",
+ "newTodo": "Nouvelle tâche à faire",
+ "newTodoBulk": "Nouvelles tâches à faire (une par ligne)",
"todosDesc": "Les tâches à faire sont validées une seule fois. Ajoutez des listes de vérification pour augmenter leur valeur.",
"dueDate": "Date butoir",
"remaining": "Actives",
@@ -95,7 +95,7 @@
"price": "Prix",
"tags": "Étiquettes",
"editTags": "Modifier",
- "newTag": "Ajouter une étiquette",
+ "newTag": "Nouvelle étiquette",
"clearTags": "Nettoyer",
"hideTags": "Masquer",
"showTags": "Afficher",
@@ -126,23 +126,23 @@
"taskToTop": "Au sommet",
"taskToBottom": "Tout en bas",
"emptyTask": "Indiquez d'abord le titre de la tâche.",
- "dailiesRestingInInn": "Vous vous reposez à l'auberge ! Vos Quotidiennes ne vous infligeront aucun dégât cette nuit, mais elles seront réinitialisées chaque jour. Si vous participez à une quête, vous n'infligerez aucun dégât / ne récolterez aucun objet, jusqu'à ce que vous quittiez l'auberge... mais un boss peut quand même vous blesser si quelqu'un parmi vos camarades oublie une de ses Quotidiennes.",
+ "dailiesRestingInInn": "Vous vous reposez à l'auberge ! Vos quotidiennes ne vous infligeront aucun dégât cette nuit, mais elles seront réinitialisées chaque jour. Si vous participez à une quête, vous n'infligerez aucun dégât / ne récolterez aucun objet, jusqu'à ce que vous quittiez l'auberge... mais un boss peut quand même vous blesser si quelqu'un parmi vos camarades oublie une de ses quotidiennes.",
"habitHelp1": "Les bonnes habitudes sont les choses que vous faites souvent. Elles octroient de l'or et de l'expérience à chaque fois que vous cliquez sur le <%= plusIcon %>.",
"habitHelp2": "Les mauvaises habitudes sont les choses que vous voulez éviter de faire. Elles retirent de la santé à chaque fois que vous cliquez sur le <%= minusIcon %>.",
"habitHelp3": "Vous pouvez vous inspirer de ces exemples d'habitudes !",
"newbieGuild": "Plus de questions ? Posez-les dans la <%= linkStart %>guilde d'aide de Habitica<%= linkEnd %> !",
- "dailyHelp1": "Les Quotidiennes se répètent <%= emphasisStart %>chaque jour<%= emphasisEnd %> où elles sont actives. Cliquez sur le <%= pencilIcon %> pour changer les jours d'activation de vos Quotidiennes.",
- "dailyHelp2": "Si vous n'accomplissez pas vos tâches Quotidiennes, vous perdez de la Santé lors du Cron (votre passage d'un jour à l'autre).",
- "dailyHelp3": "Les tâches Quotidiennes deviennent <%= emphasisStart %>plus rouges<%= emphasisEnd %> lorsque vous les ratez, et <%= emphasisStart %>plus bleues<%= emphasisEnd %> lorsque vous les accomplissez. Plus une tâche Quotidienne est rouge, plus elle vous récompensera ... ou vous infligera des dégâts.",
+ "dailyHelp1": "Les Quotidiennes se répètent <%= emphasisStart %>chaque jour<%= emphasisEnd %> où elles sont actives. Cliquez sur le <%= pencilIcon %> pour changer les jours d'activation de vos quotidiennes.",
+ "dailyHelp2": "Si vous n'accomplissez pas vos tâches quotidiennes, vous perdez de la santé lors du Cron (votre passage d'un jour à l'autre).",
+ "dailyHelp3": "Les tâches quotidiennes deviennent <%= emphasisStart %>plus rouges<%= emphasisEnd %> lorsque vous les ratez, et <%= emphasisStart %>plus bleues<%= emphasisEnd %> lorsque vous les accomplissez. Plus une tâche quotidienne est rouge, plus elle vous récompensera ... ou vous infligera des dégâts.",
"dailyHelp4": "Pour changer votre Cron, c'est-à-dire le moment du passage d'un jour à l'autre, allez sur <%= linkStart %> Paramètres > Site<%= linkEnd %> > Heure personnalisée de début de journée.",
- "dailyHelp5": "Vous pouvez vous inspirer de ces exemples de Quotidiennes !",
- "toDoHelp1": "Les tâches À Faire sont jaunes par défaut, et rougissent (en prenant de la valeur) au fil du temps que vous mettez à les accomplir.",
- "toDoHelp2": "Les tâches À Faire ne vous blessent jamais ! Elles octroient seulement de l'or et de l'expérience.",
- "toDoHelp3": "En fractionnant votre tâche À Faire en une liste faite de plus petits éléments, vous la rendrez moins effrayante et augmenterez vos points !",
- "toDoHelp4": "Vous pouvez vous inspirer de ces exemples de tâches À Faire !",
+ "dailyHelp5": "Vous pouvez vous inspirer de ces exemples de quotidiennes !",
+ "toDoHelp1": "Les tâches à faire sont jaunes par défaut, et rougissent (en prenant de la valeur) au fil du temps que vous mettez à les accomplir.",
+ "toDoHelp2": "Les tâches à faire ne vous blessent jamais ! Elles octroient seulement de l'or et de l'expérience.",
+ "toDoHelp3": "En fractionnant votre tâche à faire en une liste faite de plus petits éléments, vous la rendrez moins effrayante et augmenterez vos points !",
+ "toDoHelp4": "Vous pouvez vous inspirer de ces exemples de tâches à faire !",
"rewardHelp1": "L'équipement que vous achetez pour votre avatar est entreposé dans <%= linkStart %>Inventaire > Équipement<%= linkEnd %>.",
"rewardHelp2": "L’équipement affecte vos attributs (<%= linkStart %>Utilisateur > Caractéristiques<%= linkEnd %>).",
- "rewardHelp3": "De l'équipement spécial apparaitra ici pendant les Évènements Mondiaux.",
+ "rewardHelp3": "De l'équipement spécial apparaîtra ici pendant les évènements Mondiaux.",
"rewardHelp4": "N'hésitez pas à créer des récompenses personnalisées ! Regardez quelques exemples ici.",
"clickForHelp": "Cliquez pour obtenir de l'aide",
"taskAliasAlreadyUsed": "Le nom de cette tâche est déjà utilisé pour une autre tâche.",
@@ -157,7 +157,7 @@
"tagNotFound": "Aucune étiquette n'a été trouvée pour l'ID fourni.",
"tagIdRequired": "\"tagId\" doit être un UUID valide correspondant à une étiquette appartenant à l'utilisateur.",
"positionRequired": "\"position\" est requis et doit être un nombre.",
- "cantMoveCompletedTodo": "Impossible de déplacer une tâche À Faire complétée.",
+ "cantMoveCompletedTodo": "Impossible de déplacer une tâche à faire complétée.",
"directionUpDown": "\"direction\" est requis et doit être 'up' ou 'down'.",
"alreadyTagged": "La tâche est déjà étiquetée avec l'étiquette utilisée.",
"strengthExample": "Relatif aux exercices et activités physiques",
diff --git a/website/common/locales/hr/subscriber.json b/website/common/locales/hr/subscriber.json
index 5b274e6c0e..89ef22e1ae 100755
--- a/website/common/locales/hr/subscriber.json
+++ b/website/common/locales/hr/subscriber.json
@@ -4,7 +4,7 @@
"subDescription": "Kupuj Dragulje zlatnicima, dobij tajne artikle svaki mjesec, zadrži svoju povijest napretka, udvostručni svoj dnevni limit poklona, podrži razvojne programere. Klikni za više informacija.",
"sendGems": "Pošalji Dragulje",
"buyGemsGold": "Kupi Dragulje Zlatnicima",
- "buyGemsGoldText": "Trgovac Aleksandar će ti prodati Dragulje po cijeni od 20 Zlatnika po Dragulju. Njegova mjesečna pošiljka je ograničena na 25 Dragulja po mjesecu, ali za svaka 3 uzastopna mjeseca tvoje pretplate, ovaj limit će se povećavati za 5 Dragulja, sve dok ne dostigne maksimum od 50 Dragulja po mjesecu! ",
+ "buyGemsGoldText": "Trgovac Aleksandar će ti prodati Dragulje po cijeni od 20 Zlatnika po Dragulju. Njegova mjesečna pošiljka je ograničena na 25 Dragulja po mjesecu, ali za svaka 3 uzastopna mjeseca tvoje pretplate, ovaj limit će se povećavati za 5 Dragulja, sve dok ne dostigne maksimum od 50 Dragulja po mjesecu!",
"mustSubscribeToPurchaseGems": "Trebaš se pretplatiti za kupovinu dragulja bodovima Zlatnika",
"reachedGoldToGemCap": "Dostigao/la si limit konverzije Zlatnika u Dragulje od <%= convCap %> za ovaj mjesec. On postoji da bi se spriječila zloupotreba ili gomilanje. Limit se resetira unutar prva tri dana svakog mjeseca.",
"reachedGoldToGemCapQuantity": "Količina od <%= quantity %> koju si tražio/la prelazi limit konverzije Zlatnika=>Dragulje od <%= convCap %> za ovaj mjesec. Ovo imamo kako bismo spriječili zloupotrebu / gomilanje. Limit se resetira unutar prva tri dana svakog mjeseca.",
@@ -53,7 +53,7 @@
"hostingTypeText": "Zajedničko udomljavanje web sadržaja znači da tvoja organizacija koristi istu bazu podataka kao i prava Habitica iako ti nemaš interakciju s Habiticom. Posvećeno udomljavanje znači da dobiješ vlastitu bazu podataka i server. Možeš odabrati želiš li da ti Habitica udomi server/bazu podataka ili je mi pak možemo instalirati na tvoje vlastite servere.",
"dedicated": "Posvećeno",
"customDomain": "Prilagođena domena",
- "customDomainText": "Po tvom izboru ti možemo dati vlastitu domenu za instalaciju. ",
+ "customDomainText": "Po tvom izboru ti možemo dati vlastitu domenu za instalaciju.",
"maxPlayers": "Maksimalno sudionika",
"maxPlayersText": "Maksimalni broj igrača u tvojoj privatnoj organizaciji.",
"unlimited": "Neograničeno",
@@ -176,7 +176,7 @@
"missingReceipt": "Nedostaje potvrda o plaćanju.",
"cannotDeleteActiveAccount": "Imaš aktivnu pretplatu. Otkaži svoj plan prije brisanja računa.",
"paymentNotSuccessful": "Plaćanje nije uspješno provedeno",
- "planNotActive": "Plan nije još aktiviran (uslijed greške s PayPalom). Započet će na datum <%= nextBillingDate %>, nakon čega možeš otkazati ili zadržati sve svoje pogodnosti.",
+ "planNotActive": "Plan nije još aktiviran (uslijed greške s PayPalom). Započet će na datum <%= nextBillingDate %>, nakon čega možeš otkazati ili zadržati sve svoje pogodnosti",
"notAllowedHourglass": "Ljubimca/Jahaću životinju nije moguće kupiti Mističnim pješčanim satom.",
"readCard": "<%= cardType %> je očitan/a",
"cardTypeRequired": "Potrebna je vrsta kartice",
@@ -214,4 +214,4 @@
"gemsPurchaseNote": "Pretplatnici mogu na Tržnici kupovati dragulje u zamjenu za zlatnike! Za laki pristup ovoj opciji, možeš zakačiti dragulj na svoj stupac Nagrada.",
"gemsRemaining": "dragulja preostalo",
"notEnoughGemsToBuy": "Nisi u mogućnosti kupiti tu količinu dragulja"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/ja/character.json b/website/common/locales/ja/character.json
index 642acdfc6c..96461bf872 100644
--- a/website/common/locales/ja/character.json
+++ b/website/common/locales/ja/character.json
@@ -211,8 +211,8 @@
"style": "髪型",
"facialhair": "顔",
"photo": "写真",
- "info": "Info",
- "joined": "開始日",
+ "info": "情報",
+ "joined": "参加",
"totalLogins": "合計チェックイン回数",
"latestCheckin": "最新チェックイン",
"editProfile": "プロフィールを編集",
@@ -224,5 +224,9 @@
"mainHand": "利き手",
"offHand": "反対の手",
"statPoints": "ステータスポイント",
- "pts": "ポイント"
+ "pts": "ポイント",
+ "purchaseForGold": "<%= cost %> ゴールドで購入しますか?",
+ "chatCastSpellParty": "<%= username %> がパーティーに<%= spell %> をかけました。",
+ "chatCastSpellUser": "<%= username %> が<%= target %>に<%= spell %>をかけました。",
+ "purchasePetItemConfirm": "この購入は、<%= itemText %>ペットを全てかえすために必要なアイテム数より多いようです。よろしいですか?"
}
diff --git a/website/common/locales/ja/content.json b/website/common/locales/ja/content.json
index ad7a18910a..de60fb64f6 100644
--- a/website/common/locales/ja/content.json
+++ b/website/common/locales/ja/content.json
@@ -212,7 +212,7 @@
"hatchingPotionFrost": "霜の",
"hatchingPotionIcySnow": "冷たい雪の",
"hatchingPotionNotes": "これをたまごにかけると、<%= potText(locale) %> ペットが生まれます。",
- "premiumPotionAddlNotes": "クエスト ペットのたまごには使えません。",
+ "premiumPotionAddlNotes": "クエスト ペットのたまごには使えません。<%= date(locale) %>まで購入できます。",
"foodMeat": "肉",
"foodMeatThe": "肉",
"foodMeatA": "肉",
@@ -344,7 +344,12 @@
"questEggDolphinMountText": "イルカ",
"questEggDolphinAdjective": "陽気な",
"hatchingPotionSunshine": "陽光の",
- "hatchingPotionBronze": "ブロンズの",
+ "hatchingPotionBronze": "銅の",
"hatchingPotionWatery": "水の",
- "hatchingPotionSilver": "シルバーの"
+ "hatchingPotionSilver": "銀の",
+ "hatchingPotionShadow": "暗闇の",
+ "premiumPotionUnlimitedNotes": "クエスト ペットのたまごには使えません。",
+ "questEggRobotAdjective": "未来的な",
+ "questEggRobotMountText": "ロボット",
+ "questEggRobotText": "ロボット"
}
diff --git a/website/common/locales/ja/faq.json b/website/common/locales/ja/faq.json
index ea6ad20e2c..d328e5558f 100644
--- a/website/common/locales/ja/faq.json
+++ b/website/common/locales/ja/faq.json
@@ -1,6 +1,6 @@
{
"frequentlyAskedQuestions": "よくある質問",
- "faqQuestion0": "わからないことがあって困っています。どこで全体像を確認できますか?",
+ "faqQuestion0": "よく分からなくて戸惑っています。全体の流れを教えてもらえますか?",
"iosFaqAnswer0": "まず、あなたの毎日の生活の中でやりたいタスクを設定します。そして実生活でそのタスクを完了したらチェックを入れます。すると、ゴールドと経験値を手に入ります。ゴールドでアバターの装備やお好みの「ごほうび」といったアイテムを買えます。経験値によってアバターがレベルアップし、新しいペット、スキルやクエストといった新しい機能をアンロックしていきます! アバターはメニュー >アバターのカスタマイズで設定できます。\n\nいくつかの基本操作 : 右上の (+) をクリックすると、新しいタスクの作成。すでにあるタスクをタップすると編集、左にスワイプすると削除できます。左上でタスクにタグをつけることで並べ替えができます。丸いチェックリストをクリックすることで、表示をたたんだり展開したりできます。",
"androidFaqAnswer0": "まず、あなたの毎日の生活の中でやりたいタスクを設定します。そして実生活でそのタスクを完了し、チェックを入れると、ゴールドと経験値が得られます。ゴールドでアバターの装備やお好みの「ごほうび」といったアイテムを買います。アバターは経験値によってレベルアップし、新しいペット、スキルやクエストといった新しい機能をアンロックしていきます! アバターは、メニュー > 所持品 > アバター でカスタマイズできます。\n\n基本操作 : 右下すみの (+) をクリックすると、新しいタスクの作成。作成済みのタスクをタップすると編集、左にスワイプすると削除。タスクにタグをつけると、右上すみで並べ替えができます。丸いチェックリストをクリックすることで、表示をたたんだり展開したりできます。",
"webFaqAnswer0": "まず、あなたの毎日の生活の中でやりたいタスクを設定します。そして実生活でそのタスクを完了したらチェックを入れます。すると、ゴールドと経験値が手に入ります。ゴールドでアバターの装備やお好みの「ごほうび」といったアイテムを買えます。経験値によってアバターがレベルアップし、新しいペット、スキルやクエストといった新しい機能をアンロックしていきます! 詳しくは [ヘルプ -> 新ユーザーのためのツアー](https://habitica.com/static/overview) を読んでください。",
diff --git a/website/common/locales/ja/front.json b/website/common/locales/ja/front.json
index 8ed49a517d..e73eb3a691 100644
--- a/website/common/locales/ja/front.json
+++ b/website/common/locales/ja/front.json
@@ -127,8 +127,8 @@
"mobileAndroid": "Android",
"mobileIOS": "iOS",
"motivate": "自分自身やチームのやる気を引き上げましょう!",
- "motivate1": "どんなことにでもとりくむやる気を引き上げましょう。",
- "motivate2": "整理される。やる気になる。ゴールドを得る。",
+ "motivate1": "どんなことにでも取り組めるよう自分自身をやる気にさせましょう。",
+ "motivate2": "頭を整理しましょう、やる気を出しましょう、ゴールドを手に入れましょう。",
"oldNews": "ニュース",
"newsArchive": "Wikiaに保存されたこれまでのお知らせ(多言語版)",
"passConfirm": "新しいパスワードを確認する",
diff --git a/website/common/locales/ja/generic.json b/website/common/locales/ja/generic.json
index 2064e8d173..82878f0541 100644
--- a/website/common/locales/ja/generic.json
+++ b/website/common/locales/ja/generic.json
@@ -293,5 +293,6 @@
"contactForm": "モデレーターチームに連絡する",
"options": "オプション",
"demo": "デモ",
- "loadEarlierMessages": "以前のメッセージを読み込む"
+ "loadEarlierMessages": "以前のメッセージを読み込む",
+ "finish": "終了"
}
diff --git a/website/common/locales/ja/groups.json b/website/common/locales/ja/groups.json
index 3043372803..263adb882a 100644
--- a/website/common/locales/ja/groups.json
+++ b/website/common/locales/ja/groups.json
@@ -412,7 +412,7 @@
"createParty": "パーティーを作る",
"inviteMembersNow": "すぐにメンバーを招待したいですか?",
"playInPartyTitle": "パーティーに入ってHabiticaをプレーしましょう!",
- "playInPartyDescription": "仲間たちと一緒に、または各自で、素晴らしいクエストに挑戦しましょう。モンスターと戦ったり、チャレンジを作ったり…… そして、パーティーを通じてあなた自身を責任ある状態にし続けてみましょう。",
+ "playInPartyDescription": "仲間たちと一緒に、または一人で、素晴らしいクエストに挑戦しましょう。モンスターと戦ったり、チャレンジを作ったり…… そして、パーティーを通じてあなた自身を責任ある状態にし続けてみましょう。",
"startYourOwnPartyTitle": "自分のパーティーを作る",
"startYourOwnPartyDescription": "一人でモンスターと戦うか、好きなだけたくさんの友達を招待して戦おう!",
"wantToJoinPartyTitle": "パーティーに参加したいですか?",
diff --git a/website/common/locales/ja/npc.json b/website/common/locales/ja/npc.json
index 477e4ece34..a25a3476ef 100644
--- a/website/common/locales/ja/npc.json
+++ b/website/common/locales/ja/npc.json
@@ -21,7 +21,7 @@
"sleepDescription": "休息が必要ですか? ダニエルのロッジにチェックインして、Habiticaにおける手ごわいゲーム要素を停止させましょう。",
"sleepBullet1": "やり逃した日課によるダメージを受けません",
"sleepBullet2": "タスクの連続実行回数は失われず、タスクの色も変化しません",
- "sleepBullet3": "ボスはあなたの逃した日課によるダメージを発生させません",
+ "sleepBullet3": "ボスはあなた自身が逃した日課によるダメージを与えません",
"sleepBullet4": "あなたがボスに与えたダメージと、アイテム集めのクエストアイテムは、チェックアウトするまで保留されます",
"pauseDailies": "日課を休む",
"unpauseDailies": "日課を休むのをやめる",
@@ -91,7 +91,7 @@
"unlocked": "アイテムがアンロックされました",
"alreadyUnlocked": "全てのセットがすでにアンロックされています。",
"alreadyUnlockedPart": "全てのセットのうち一部がすでにアンロックされています。",
- "invalidQuantity": "購入する個数を数字で入れてください。",
+ "invalidQuantity": "購入する個数は正の整数で入力してください。",
"USD": "(米ドル)",
"newStuff": "Baileyの新着情報",
"newBaileyUpdate": "Baileyから新しいお知らせがあります!",
@@ -168,5 +168,6 @@
"welcome5": "それではアバターをカスタマイズしてタスクを設定しましょう…",
"imReady": "Habitica をはじめる",
"limitedOffer": "<%= date %>まで購入可能",
- "paymentAutoRenew": "この寄付会員はキャンセルするまで自動更新されます。もしこの寄付会員をキャンセルする必要があるときは、設定からキャンセルできます。"
+ "paymentAutoRenew": "この寄付会員はキャンセルするまで自動更新されます。もしこの寄付会員をキャンセルする必要があるときは、設定からキャンセルできます。",
+ "paymentCanceledDisputes": "キャンセルの承認のメールをあなたに送りました。もしそのメールが見つからない場合は、今後の請求についての論争を防ぐために、私たちにご連絡をお願いいたします。"
}
diff --git a/website/common/locales/ja/pets.json b/website/common/locales/ja/pets.json
index e7cd48403d..e9b21cafe9 100644
--- a/website/common/locales/ja/pets.json
+++ b/website/common/locales/ja/pets.json
@@ -144,5 +144,6 @@
"notEnoughMounts": "まだ十分な数の乗騎を集めていません",
"notEnoughPetsMounts": "まだ十分な数のペットと乗騎を集めていません",
"wackyPets": "へんてこなペット",
- "filterByWacky": "へんてこ"
+ "filterByWacky": "へんてこ",
+ "gryphatrice": "グリファトリス"
}
diff --git a/website/common/locales/ja/questscontent.json b/website/common/locales/ja/questscontent.json
index fbe7ac0efc..5372c7f1e7 100644
--- a/website/common/locales/ja/questscontent.json
+++ b/website/common/locales/ja/questscontent.json
@@ -36,7 +36,7 @@
"questRatUnlockText": "市場でネズミのたまごを買えるようになります",
"questOctopusText": "オクトゥルフの呼び声",
"questOctopusNotes": "@Urse、野心あふれる目をした若いライターが、海岸の神秘的な洞窟を探検するのを手助けしてほしいと頼みに来ました。夕暮れの潮だまりの中に、鍾乳石や石筍の巨大な門が立っています。門に近づくと、底にむかって暗い渦が回転しはじめました。畏敬の念を感じてじっと見つめていると、渦の中からイカのようなドラゴンが浮かび上がってきました。「ベタベタした星のたまごたちが目を覚ました」@Urse は狂ったようにうなりました。「何億兆年もの末に、偉大なるオクトゥルフは再び自由になり、喜びに飢えているのだ!」",
- "questOctopusCompletion": "最後の一撃で、巨大生物はやってきた渦に滑りこんで逃げていきました。@Urse は勝利に喜んでいるのか、怪物が去ってしまったことを悲しんでいるのか、表現のしようがありません。押し黙ったまま、彼は潮溜まりのそば、黄金のコインで作った巣の中に 3 つのぬるぬるした巨大なたまごを見つけ、指さしました。「多分、ただのタコのたまごでしょう。」あなたはこわごわ言いました。家に帰ると @Urse は必死に旅行記の執筆にとりくみましたが、あなたは、偉大なるオクトフル(Octothulu)の声を聞くのはこれで終わりではないと疑っていたのです。",
+ "questOctopusCompletion": "最後の一撃で、巨大生物はやってきた渦に滑りこんで逃げていきました。@Urse は勝利に喜んでいるのか、怪物が去ってしまったことを悲しんでいるのか、表現のしようがありません。押し黙ったまま、彼は潮溜まりのそば、黄金のコインで作った巣の中に 3 つのぬるぬるした巨大なたまごを見つけ、指さしました。「多分、ただのタコのたまごでしょう。」あなたはこわごわ言いました。家に帰ると @Urse は必死に旅行記の執筆にとりくみましたが、あなたは、偉大なるオクトゥルフの声を聞くのはこれで終わりではないと疑っていたのです。",
"questOctopusBoss": "オクトゥルフ",
"questOctopusDropOctopusEgg": "タコ ( たまご )",
"questOctopusUnlockText": "市場でタコのたまごを買えるようになります",
@@ -101,7 +101,7 @@
"questGoldenknight1DropGoldenknight2Quest": "黄金騎士・第 2 部:金の騎士 ( 巻物 )",
"questGoldenknight2Text": "黄金騎士・第 2 部:金の騎士",
"questGoldenknight2Notes": "数十件にわたる Habitica の住人の証言で武装して、あなたはついに黄金騎士の前に立ちふさがりました。\n\nあなたは、彼女に Habitica の住人の苦情を一つ一つ読み上げました。「そして、@Pfeffernusse がいうには、いつもあなたが『上から目線』で…」\n\n彼女はあなたを黙らせるように手を上げると、バカにしたように笑います。「お願い。この人たちはただ私の成功をうらやんでるだけなの。文句なんかいってないで、私みたいに必死で働くべきよ! あなたには私の力を見せてあげるわ。私みたいにマジメにとりくまないあなたには、けっして得られないような力をね!」\n\n彼女はモーニングスターを振りあげ、あなたに攻撃を加えようとしています!",
- "questGoldenknight2Boss": "金の騎士",
+ "questGoldenknight2Boss": "黄金騎士",
"questGoldenknight2Completion": "黄金騎士は狼狽してモーニングスターを下ろしました。\n「軽率に感情を爆発させてしまったこと謝るわ。」\n\n彼女は言います。\n「本当は、知らず知らずのうちに他人を傷つけてきたんだと気づいて苦しかったの。そして、自分を守るために激しく非難してしまった… でも、もしかしたらまだ彼らに謝罪できるかしら?」",
"questGoldenknight2DropGoldenknight3Quest": "黄金騎士・第 3 部:鉄の騎士 ( 巻物 )",
"questGoldenknight3Text": "黄金騎士・第 3 部:鉄の騎士",
@@ -109,7 +109,7 @@
"questGoldenknight3Completion": "気持ちのいい金属音と共に、鉄の騎士は膝から崩れ落ちました。\n\n「お前は、本当に強いな。」と、息を切らします。\n「今日の私は、謙虚な気持ちになっておるよ。」\n\n黄金騎士が近づいてきて告げました。\n「ありがとう。私たち親子は、あなたに出会ったことで、少しは謙虚な心を手に入れたと信じてるわ。父と話して、私たちへの苦情について説いておきます。きっと私たちは他の Habitica の人々へも謝罪をはじめるべきでしょうね。」\n\n彼女はしばらく考え込んだのち、あなたへ振り返ります。\n「これはお礼の気持ちよ。このモーニングスターは、あなたが持っていてほしいの。もうあなたのものよ。」",
"questGoldenknight3Boss": "鉄の騎士",
"questGoldenknight3DropHoney": "はちみつ ( えさ )",
- "questGoldenknight3DropGoldenPotion": "金のたまごがえしの薬",
+ "questGoldenknight3DropGoldenPotion": "黄金のたまごがえしの薬",
"questGoldenknight3DropWeapon": "ムステインのマイルストーンマッシュモーニングスター(利き手と反対の手に装備する武器)",
"questGroupEarnable": "獲得可能なクエスト",
"questBasilistText": "バシ・リスト",
@@ -284,7 +284,7 @@
"questFrogUnlockText": "市場でカエルのたまごを買えるようになります",
"questSnakeText": "気晴らしの大蛇",
"questSnakeNotes": "気晴らしの砂丘で生き抜くには強靭な意志が必要です。不毛な砂漠は到底生産的な場所ではなく、揺らぐ砂丘は多くの旅人を迷わせてきました。時に砂漠は現地民すら戦慄させます。砂は移動し、そして村全体をひっくり返してしまうのです。住人たちは、巨大な蛇の姿の怪物が砂の下に潜んでおり、怪物を見つけ出し止めてくれる人のための報酬を皆で出資し溜めているのだといいます。高名な蛇使い@EmeraldOxと@PainterProphetは、その怪物を呼び出す手伝いをするのに同意してくれました。あなたは気晴らしの大蛇を止めることができるでしょうか?",
- "questSnakeCompletion": "魔術師たちの援助を得て、あなたは気晴らしの大蛇を退けることに成功しました。砂の民を助けることが出来て嬉しい半面、あなたは退けた敵に少し哀れみを感じてしまいます。あなたが景色をじっと見つめていると、@LordDarklyが歩み寄ってきました。「ありがとう!これは僅かだが、我々の感謝の気持ちだ」彼はあなたにいくらかのお金と…蛇の卵を手渡しました!あなたはきっと、あの雄大な獣の姿をふたたび見ることができるでしょう。",
+ "questSnakeCompletion": "魔術師たちの援助を得て、あなたは気晴らしの大蛇を退けることに成功しました。砂の民を助けることが出来て嬉しい半面、あなたは退けた敵に少し哀れみを感じてしまいます。あなたが景色をじっと見つめていると、@LordDarklyが歩み寄ってきました。「ありがとう!これは僅かだが、我々の感謝の気持ちだ」彼はあなたにいくらかのお金と…蛇の卵を手渡しました!あなたはきっと、あの雄大な生物の姿をふたたび見ることができるでしょう。",
"questSnakeBoss": "気晴らしの大蛇",
"questSnakeDropSnakeEgg": "ヘビ(たまご)",
"questSnakeUnlockText": "市場でヘビのたまごを買えるようになります",
@@ -423,13 +423,13 @@
"questSlothCompletion": "やりました! ねむケモノを倒すと、エメラルドは砕け散りました。「呪いから解放してくれてありがとう」ナマケモノは言いました。「これでやっとよく眠れる…重たい背中の宝石もなくなったし。感謝のしるしにこのたまごを受け取ってよ。あとエメラルドもね」あなたにたまごを3つ渡すと、ナマケモノはもっと温かい地方を目指して去っていくのでした。",
"questSlothBoss": "ねむケモノ",
"questSlothDropSlothEgg": "ナマケモノ(たまご)",
- "questSlothUnlockText": "市場でのナマケモノのたまご購入をアンロック",
+ "questSlothUnlockText": "市場でナマケモノのたまごを買えるようになります",
"questTriceratopsText": "トリケラ・ステップス",
"questTriceratopsNotes": "頂上に雪を戴くオダヤカニ火山はいつもハイキングや観光客で賑わっています。旅行者の一人@plumillaが人々に向かって叫びました。「見て見て! 地面を魔法で光らせてみたよ! これならみんなでアウトドア日課用のゲームができるね!」本当に、地面に赤く光る文様が渦巻いています。このエリアに住む有史以前のペットたちすら珍しがって遊びにやってきました。
@McCoylyは腕組みします。「つまり、日課の完了を怠ったことが、私たちの生産性安定装置の崩壊を招いたのだろうと仮定しているよ。あれは正常に稼働するのに整合性を必要とするタイムトラベルにおいて、必要不可欠なパーツなんだ。達成する力こそ、時間と空間を移動するために必要だ! これ以上は説明している時間がない、@Revよ。君は37年後にそのことを発見するだろう、というか君の協力者である謎のタイムトラベラーズが教えてくれる。さしあたり、私たちのタイムマシーンを修理するのを手伝ってくれるかい?」",
+ "questRobotText": "奇怪で機械な驚異!",
+ "questRobotCompletion": "@Revとアカウンタビリティ・バディが最後のボルトを適切な位置に設置すると、タイムマシーンはブンブンと再び動きはじめました。@FolleMenteと@McCoylyは飛び乗ります。「助けてくれてありがとう! 私たちは未来でまた出会うだろう! ちなみに、これらは君の新しい発明品の役に立つはずだよ!」そうしてタイムトラベラーたちは姿を消してしまいましたが、古い生産性安定装置の残骸の中に、3つの時計仕掛けのたまごを残していきました。おそらくこれらは、アカウンタビリティ・バディの新たな生産ラインの極めて重要な構成要素となるでしょう!"
}
diff --git a/website/common/locales/ja/settings.json b/website/common/locales/ja/settings.json
index d60c105a8c..adddce9b0c 100644
--- a/website/common/locales/ja/settings.json
+++ b/website/common/locales/ja/settings.json
@@ -106,7 +106,7 @@
"usernameOrEmail": "ユーザー名またはメールアドレス",
"email": "メール",
"registerWithSocial": "<%= network %> で登録",
- "registeredWithSocial": "<%= network %> で登録しました。",
+ "registeredWithSocial": "<%= network %> で登録しました",
"loginNameDescription": "これは Habitica でのログインに使用するものです。変更するには、下のフォームを利用してください。アバター上や、チャットメッセージで表示される「表示名」を変更するには、ユーザーアイコン > プロフィールへ進み、「編集」ボタンをクリックしてください。",
"emailNotifications": "メール通知",
"wonChallenge": "あなたはチャレンジに成功しました!",
@@ -129,7 +129,7 @@
"invitedQuest": "クエストへ招待されました",
"kickedGroup": "グループから追い出されました",
"remindersToLogin": "Habitica へのチェックインを通知する",
- "subscribeUsing": "寄付の送金方法 : ",
+ "subscribeUsing": "寄付の送金方法",
"unsubscribedSuccessfully": "購読を中止しました!",
"unsubscribedTextUsers": "Habitica からのメールをすべて停止しました。設定 > 通知受け取りたいメールだけを有効にすることができます(要ログイン)。",
"unsubscribedTextOthers": "Habitica からの他のメールは発信されません。",
@@ -148,7 +148,7 @@
"promoCode": "プロモコード",
"promoCodeApplied": "プロモコードが適用されました! 所持品を確認してください",
"promoPlaceholder": "プロモコードを入力してください",
- "displayInviteToPartyWhenPartyIs1": "パーティーのメンバーが1人の場合、「パーティに招待する」ボタンを表示する",
+ "displayInviteToPartyWhenPartyIs1": "パーティーのメンバーが1人の場合、「パーティに招待する」ボタンを表示する。",
"saveCustomDayStart": "日付更新の時間を保存する",
"registration": "登録",
"addLocalAuth": "メールアドレスとログインパスワードを追加する",
@@ -170,7 +170,7 @@
"regIdRequired": "RegId が必要",
"invalidPushClient": "無効なクライアントです。Habitica の公式クライアントのみがプッシュ通知を受信できます。",
"pushDeviceAdded": "プッシュ先携帯端末が追加されました",
- "pushDeviceAlreadyAdded": "ユーザーにはすでに プッシュ先の携帯端末があります。",
+ "pushDeviceAlreadyAdded": "ユーザーにはすでに プッシュ先の携帯端末があります",
"pushDeviceNotFound": "この id に対応したユーザーは、プッシュ対応端末を持っていません。",
"pushDeviceRemoved": "プッシュ先携帯端末を解除しました。",
"buyGemsGoldCap": "購入可能数が <%= amount %> 個になりました",
@@ -179,9 +179,9 @@
"purchasedPlanId": "<%= months %>カ月ごとに<%= price %>米ドルずつ (<%= plan %>)",
"purchasedPlanExtraMonths": "あなたは <%= months %> カ月分の寄付(有料利用)延長クレジットをもっています。",
"consecutiveSubscription": "継続的な寄付",
- "consecutiveMonths": "継続月数 : ",
- "gemCapExtra": "追加のジェム購入権 : ",
- "mysticHourglasses": "神秘の砂時計 : ",
+ "consecutiveMonths": "継続月数 :",
+ "gemCapExtra": "追加のジェム購入権 :",
+ "mysticHourglasses": "神秘の砂時計 :",
"mysticHourglassesTooltip": "神秘の砂時計",
"paypal": "PayPal",
"amazonPayments": "Amazon ペイメント",
@@ -204,5 +204,7 @@
"usernameVerifiedConfirmation": "あなたのユーザー名、<%= username %>、は承認されました!",
"usernameNotVerified": "あなたのユーザー名を承認してください。",
"changeUsernameDisclaimer": "私たちはもうすぐログイン名を、固有の、公開のユーザー名に移行します。このユーザー名は、招待、チャットでの@返信、メッセージのやりとりなどで使用されます。",
- "verifyUsernameVeteranPet": "あなたが承認を終えたあとには、百戦練磨のペットのうち1匹があなたを待っていることでしょう!"
+ "verifyUsernameVeteranPet": "あなたが承認を終えたあとには、百戦練磨のペットのうち1匹があなたを待っていることでしょう!",
+ "subscriptionReminders": "寄付についての通知",
+ "newPMNotificationTitle": "<%= name %>からの新しいメッセージ"
}
diff --git a/website/common/locales/ko/achievements.json b/website/common/locales/ko/achievements.json
index bfbe00bda5..c772277b3b 100755
--- a/website/common/locales/ko/achievements.json
+++ b/website/common/locales/ko/achievements.json
@@ -1,9 +1,9 @@
{
- "achievement": "기본 업적",
- "share": "공유하기",
- "onwards": "Onwards!",
- "levelup": "실생활의 목표들을 달성함으로써 레벨 %ld이 되었어요!",
- "reachedLevel": "레벨<%= level %>에 도달했습니다.",
- "achievementLostMasterclasser": "퀘스트 완료자: 마스터클래서 시리즈",
- "achievementLostMasterclasserText": "마스터클래서 퀘스트에서 16개의 모든 퀘스트를 완료하고 잃어버린 마스터클래서의 신비를 풀어냈습니다!"
+ "achievement": "업적",
+ "share": "공유하기",
+ "onwards": "Onwards!",
+ "levelup": "실생활의 목표들을 달성함으로써 레벨 %ld이 되었어요!",
+ "reachedLevel": "레벨<%= level %>에 도달했습니다.",
+ "achievementLostMasterclasser": "퀘스트 완료자: 마스터클래서 시리즈",
+ "achievementLostMasterclasserText": "마스터클래서 퀘스트에서 16개의 모든 퀘스트를 완료하고 잃어버린 마스터클래서의 신비를 풀어냈습니다!"
}
diff --git a/website/common/locales/ko/subscriber.json b/website/common/locales/ko/subscriber.json
index 4839e3112c..ae7cb22db9 100755
--- a/website/common/locales/ko/subscriber.json
+++ b/website/common/locales/ko/subscriber.json
@@ -13,16 +13,16 @@
"doubleDrops": "Daily drop caps doubled",
"doubleDropsText": "마구간을 더욱 빨리 채우세요!",
"mysteryItem": "매월마다 새로운 특권층인 아이템들",
- "mysteryItemText": "매달 당신의 아바타를 위한 독특한 꾸미기 아이템을 받으실 겁니다! 그리고 3달마다 연속 후원해 주시는 분들께, 신비한 시간 여행자가 전통적인 (혹인 미래지향적인) 꾸미기 아이템을 얻을 수 있게 해드립니다!",
+ "mysteryItemText": "매달 당신의 아바타를 위한 독특한 꾸미기 아이템을 받으실 겁니다! 그리고 3달마다 연속 후원해 주시는 분들께, 신비한 시간 여행자가 전통적인 (혹인 미래지향적인) 꾸미기 아이템을 얻을 수 있게 해드립니다.",
"supportDevs": "개발자들을 지원하세요",
- "supportDevsText": "구독은 Habitica가 번성하고 새 기능을 개발하는 것에 대해 투자받는데 도움이 됩니다. 당신의 너그러움에 감사드립니다.",
+ "supportDevsText": "구독은 Habitica가 번성하고 새 기능을 개발하는 것에 대해 투자받는데 도움이 됩니다. 당신의 너그러움에 감사드립니다!",
"exclusiveJackalopePet": "Exclusive pet",
"exclusiveJackalopePetText": "Get the Royal Purple Jackalope pet, available only to subscribers!",
"giftSubscription": "정기 후원을 다른 분에게 선물하고 싶으세요?",
"giftSubscriptionText1": "사람들의 프로필을 열어보세요! 파티 상단에 있는 아바타를 클릭하거나 채팅에서 이름을 클릭하여 볼 수 있습니다.",
"giftSubscriptionText2": "Click on the gift icon in the top right of their profile.",
"giftSubscriptionText3": "\"정기 후원\"을 선택하고 당신의 결제 정보를 입력하세요.",
- "giftSubscriptionText4": " Habitica를 지원해 주셔서 고맙습니다!",
+ "giftSubscriptionText4": "Habitica를 지원해 주셔서 고맙습니다!",
"monthUSD": "USD / 월",
"organization": "단체",
"groupPlans": "Group Plans",
@@ -55,7 +55,7 @@
"customDomain": "사용자 지정 도메인",
"customDomainText": "저희는 당신의 도메인에 설치할 수 있도록 선택적으로 제공해 드립니다.",
"maxPlayers": "최대 참가자",
- "maxPlayersText": "당신의 개별 단체에 가입할 수 있는 최대 참가자",
+ "maxPlayersText": "당신의 개별 단체에 가입할 수 있는 최대 참가자.",
"unlimited": "무제한",
"priSupport": "Priority Support On Tickets & Hosting",
"priSupportText": "First to be provided for with support.",
@@ -91,8 +91,8 @@
"timeTravelersAlreadyOwned": "축하합니다! 시간여행자가 현재 제공하는 모든 것을 얻으셨습니다. 사이트를 지원해주셔서 고맙습니다!",
"mysticHourglassPopover": "신비로운 모래시계는 당신이 월간 미스터리 아이템 세트나 과거의 월드 보스 보상과 같은 시간 한정 아이템을 구매할 수 있도록 해줍니다!",
"mysterySetNotFound": "미스터리 세트를 찾을 수 없거나, 이미 보유하고 있습니다.",
- "mysteryItemIsEmpty": "미스터리 아이템이 없습니다.",
- "mysteryItemOpened": "미스터리 아이템이 열렸습니다",
+ "mysteryItemIsEmpty": "미스터리 아이템이 없습니다",
+ "mysteryItemOpened": "미스터리 아이템이 열렸습니다.",
"mysterySet201402": "날개달린 메신저 세트",
"mysterySet201403": "숲 산책가 세트",
"mysterySet201404": "황혼의 나비 세트",
@@ -159,7 +159,7 @@
"mysterySetwondercon": "Wondercon",
"subUpdateCard": "카드 업데이트",
"subUpdateTitle": "업데이트",
- "subUpdateDescription": "지불할 카드를 갱신하세요",
+ "subUpdateDescription": "지불할 카드를 갱신하세요.",
"notEnoughHourglasses": "신비로운 모래시계가 부족합니다.",
"hourglassBuyEquipSetConfirm": "신비로운 모래시계 1개로 이 아이템의 풀세트를 사시겠습니까?",
"hourglassBuyItemConfirm": "신비로운 모래시계 1개로 이 아이템을 사시겠습니까?",
@@ -175,12 +175,12 @@
"missingSubscriptionCode": "Missing subscription code. Possible values: basic_earned, basic_3mo, basic_6mo, google_6mo, basic_12mo.",
"missingReceipt": "Missing Receipt.",
"cannotDeleteActiveAccount": "정기 후원을 하고 계십니다. 계정을 삭제하기 전 해당 계획을 취소하세요.",
- "paymentNotSuccessful": "결제를 완료하지 못했습니다.",
+ "paymentNotSuccessful": "결제를 완료하지 못했습니다",
"planNotActive": "The plan hasn't activated yet (due to a PayPal bug). It will begin <%= nextBillingDate %>, after which you can cancel to retain your full benefits",
"notAllowedHourglass": "신비로운 모래시계로는 펫이나 탑승펫을 구매할 수 없습니다.",
- "readCard": "<%= cardType %> 는 읽었습니다.",
+ "readCard": "<%= cardType %> 는 읽었습니다",
"cardTypeRequired": "카드 타입이 필요합니다",
- "cardTypeNotAllowed": "카드 타입을 알 수 없습니다",
+ "cardTypeNotAllowed": "카드 타입을 알 수 없습니다.",
"invalidCoupon": "유효하지 않은 쿠폰 코드입니다.",
"couponUsed": "쿠폰 코드가 이미 사용되었습니다.",
"couponCodeRequired": "쿠폰 코드가 필요합니다.",
@@ -214,4 +214,4 @@
"gemsPurchaseNote": "Subscribers can buy gems for gold in the Market! For easy access, you can also pin the gem to your Rewards column.",
"gemsRemaining": "gems remaining",
"notEnoughGemsToBuy": "You are unable to buy that amount of gems"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/lt/settings.json b/website/common/locales/lt/settings.json
index 2013682a72..35d1c74e3a 100755
--- a/website/common/locales/lt/settings.json
+++ b/website/common/locales/lt/settings.json
@@ -10,7 +10,7 @@
"newTaskEditPop": "Pažymėjus šį nustatymą, naujos užduotys bus iškarto atidarytos, kur jūs galėsi pakeist detales kaip užrašus ir žymes.",
"dailyDueDefaultView": "Pagal nutylėjimą Dienos stulpelyje pasirinkti 'Likusios' kortelę",
"dailyDueDefaultViewPop": "Pažymėjus šį nustatymą, atsidarius užduočių puslapį, Dienos užduočių stulpely visada pradžioje bus atidaroma 'Likusios' kortelė",
- "reverseChatOrder": "Rodyti pokalbių žinutes atvirkštine tvarka.",
+ "reverseChatOrder": "Rodyti pokalbių žinutes atvirkštine tvarka",
"startAdvCollapsed": "Advanced Settings in tasks start collapsed",
"startAdvCollapsedPop": "With this option set, Advanced Settings will be hidden when you first open a task for editing.",
"dontShowAgain": "Daugiu nerodyti",
@@ -84,7 +84,7 @@
"resetDo": "Pirmyn, perkurk mano prfofilį!",
"resetComplete": "Perkūrimas baigtas!",
"fixValues": "Pataisyti Reikšmes",
- "fixValuesText1": "Jei susidūrei su puslapio klaida ar pats netyčia suklydai, kas neigiamai paveikė tavo veikėją (žala kurios neturėjai gauti, auksas kurio gavai per daug ir pan.), gali pats(i) čia tai pataisyti. Taip, tai leidžia sukčiauti, taigi naudokis šita funkcija protingai arba pats sugadinsi savo įgūdžių skatinimą.",
+ "fixValuesText1": "Jei susidūrei su puslapio klaida ar pats netyčia suklydai, kas neigiamai paveikė tavo veikėją (žala kurios neturėjai gauti, auksas kurio gavai per daug ir pan.), gali pats(i) čia tai pataisyti. Taip, tai leidžia sukčiauti, taigi naudokis šita funkcija protingai arba pats sugadinsi savo įgūdžių skatinimą!",
"fixValuesText2": "Note that you cannot restore Streaks on individual tasks here. To do that, edit the Daily and go to Advanced Settings, where you will find a Restore Streak field.",
"disabledWinterEvent": "Neveikia per 4 Žiemos Pasakų švėntės dalį (nes atlygius galima pirkti už auksą).",
"fix21Streaks": "21 Dienos Serijos",
@@ -92,7 +92,7 @@
"deleteDo": "Taip, trinti mano profilį!",
"enterNumber": "Prašome įvesti skaičių nuo 0 iki 24",
"fillAll": "Prašome užpildyti visus laukelius",
- "invalidPasswordResetCode": "Pateiktas slaptažodžio keitimo kodas neteisingas arba nebegalioja. ",
+ "invalidPasswordResetCode": "Pateiktas slaptažodžio keitimo kodas neteisingas arba nebegalioja.",
"passwordChangeSuccess": "Tavo slaptažodis sėkmingai pakeistas į tą, kurį ką tik pasirinkai. Dabar gali juo naudotis prisijungimui prie savo paskyros.",
"passwordSuccess": "Slaptažodis pakeistas",
"usernameSuccess": "Username successfully changed",
@@ -181,7 +181,7 @@
"consecutiveSubscription": "Nuosekli Prenumerata",
"consecutiveMonths": "Nuoseklūs Mėnesiai:",
"gemCapExtra": "Papildomas Brangakmenių Limitas:",
- "mysticHourglasses": "Paslaptingi Smėlio Laikrodžiai",
+ "mysticHourglasses": "Paslaptingi Smėlio Laikrodžiai:",
"mysticHourglassesTooltip": "Mystic Hourglasses",
"paypal": "PayPal",
"amazonPayments": "Amazon Payments",
@@ -205,4 +205,4 @@
"usernameNotVerified": "Please confirm your username.",
"changeUsernameDisclaimer": "We will be transitioning login names to unique, public usernames soon. This username will be used for invitations, @mentions in chat, and messaging.",
"verifyUsernameVeteranPet": "One of these Veteran Pets will be waiting for you after you've finished confirming!"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/lt/subscriber.json b/website/common/locales/lt/subscriber.json
index b3b29e2a88..e7f4c0df6d 100755
--- a/website/common/locales/lt/subscriber.json
+++ b/website/common/locales/lt/subscriber.json
@@ -64,7 +64,7 @@
"gameFeatures": "Žaidimo savybės",
"gold2Gem": "Brangakmeniai perkami už auksą",
"gold2GemText": "Nariai galės nusipirkti Brangakmenius už auksą, kas reiškia, kad nariam nereiks nieko pirkt už tikrus pinigus.",
- "infiniteGem": "Vadovas gauna begalybę Brangakmenių.",
+ "infiniteGem": "Vadovas gauna begalybę Brangakmenių",
"infiniteGemText": "Organizacijos varovai gaus tiek brangakmenių kiek tik jiems jų reik, kuriuos galima naudot kurt gildijoms, iššūkių prizams ir pan.",
"notYetPlan": "Planas dar neveikia, bet susisiekite su mumis ir mes jus informuosime apie pakitimus.",
"contactUs": "Susisiek su mumis",
@@ -76,7 +76,7 @@
"subGemPop": "Because you subscribe to Habitica, you can purchase a number of Gems each month using Gold.",
"subGemName": "Prenumeratos Brangakmeniai",
"freeGemsTitle": "Gauk brangakmenių nemokamai",
- "maxBuyGems": "Pasiekei šio mėnesio Brangakmenių pirkimo limitą. Daugiau jų galima bus nusipirkti per pirmas tris kiekvieno mėnesio dienas. Dėkui už prenumeravimą! ",
+ "maxBuyGems": "Pasiekei šio mėnesio Brangakmenių pirkimo limitą. Daugiau jų galima bus nusipirkti per pirmas tris kiekvieno mėnesio dienas. Dėkui už prenumeravimą!",
"buyGemsAllow1": "Gali pirkti",
"buyGemsAllow2": "daugiau brangakmenių šį mėnesį",
"purchaseGemsSeparately": "Pirkti daugiau brangakmenių",
@@ -89,9 +89,9 @@
"timeTravelersPopoverNoSubMobile": "Looks like you’ll need a Mystic Hourglass to open the time portal and summon the Mysterious Time Travelers.",
"timeTravelersPopover": "Your Mystic Hourglass has opened our time portal! Choose what you’d like us to fetch from the past or future.",
"timeTravelersAlreadyOwned": "Sveikiname! Surinkai viską, ką šiuo metu tau gali pasiūlyti Keliautojai Laiku. Dėkui už puslapio paramą!",
- "mysticHourglassPopover": "Paslaptingas Smėlio Laikrodis leidžia tau pirkti kai kuriuos riboto laiko daiktus, tokius kaip mėnesiniai paslaptingi daiktų rinkiniai ir lobius iš pasaulinių pabaisų iš praeities.",
+ "mysticHourglassPopover": "Paslaptingas Smėlio Laikrodis leidžia tau pirkti kai kuriuos riboto laiko daiktus, tokius kaip mėnesiniai paslaptingi daiktų rinkiniai ir lobius iš pasaulinių pabaisų iš praeities!",
"mysterySetNotFound": "Paslaptingas rinkinys nerastas, arba yra jau gautas.",
- "mysteryItemIsEmpty": "Paslaptingų drabužių nėra.",
+ "mysteryItemIsEmpty": "Paslaptingų drabužių nėra",
"mysteryItemOpened": "Paslaptingas drabužis gautas.",
"mysterySet201402": "Sparnuoto Pasiuntinio Rinkinys",
"mysterySet201403": "Miškų Klajoklio rinkinys",
@@ -171,12 +171,12 @@
"hourglassPurchase": "Daiktas nupirktas už Paslaptingą Smėlio Laikrodį!",
"hourglassPurchaseSet": "Daiktų rinkinys nupirktas už Paslaptingą Smėlio Laikrodį!",
"missingUnsubscriptionCode": "Trūksta prenumeratos kodo.",
- "missingSubscription": "Vartotojas neturi aktyvios prenumeratos.",
+ "missingSubscription": "Vartotojas neturi aktyvios prenumeratos",
"missingSubscriptionCode": "Trūksta prenumeratos kodo. Galimos reikšmės: basic_earned, basic_3mo, basic_6mo, google_6mo, basic_12mo.",
"missingReceipt": "Missing Receipt.",
"cannotDeleteActiveAccount": "Turi aktyvią prenumeratą. Atsisakyk mokėjimo plano prieš ištrinant paskyrą.",
"paymentNotSuccessful": "Mokėjimas nebuvo patvirtintas",
- "planNotActive": "Planas dar nebuvo aktyvuotas (dėl PayPal klaidos). Jis prasidės <%= nextBillingDate %>. Po šios datos galėsi jį atšaukti ir vistiek išlaikyti visus jos bonusus.",
+ "planNotActive": "Planas dar nebuvo aktyvuotas (dėl PayPal klaidos). Jis prasidės <%= nextBillingDate %>. Po šios datos galėsi jį atšaukti ir vistiek išlaikyti visus jos bonusus",
"notAllowedHourglass": "Šio augintion negalima nusipirkti už Paslaptingą Smėlio Laikrodį.",
"readCard": "<%= cardType %> buvo nuskaityta",
"cardTypeRequired": "Prašome įvesti kortelės tipą",
@@ -214,4 +214,4 @@
"gemsPurchaseNote": "Subscribers can buy gems for gold in the Market! For easy access, you can also pin the gem to your Rewards column.",
"gemsRemaining": "gems remaining",
"notEnoughGemsToBuy": "You are unable to buy that amount of gems"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/nl/achievements.json b/website/common/locales/nl/achievements.json
index af45151400..a1bc08e4b8 100644
--- a/website/common/locales/nl/achievements.json
+++ b/website/common/locales/nl/achievements.json
@@ -24,5 +24,15 @@
"achievementAridAuthority": "Regenarme Regent",
"achievementDustDevilModalText": "Je hebt alle Woestijn Huisdieren verzameld!",
"achievementDustDevilText": "Heeft alle Woestijn Huisdieren verzameld.",
- "achievementDustDevil": "Stofduivel"
+ "achievementDustDevil": "Stofduivel",
+ "achievementKickstarter2019Text": "Heeft het Speldjes-Kickstarter project van 2019 gesteund",
+ "achievementKickstarter2019": "Speldjes-Kickstarter Steuner",
+ "achievementUndeadUndertakerModalText": "Je hebt alle Zombie Rijdieren getemd!",
+ "achievementUndeadUndertakerText": "Heeft alle Zombie Rijdieren getemd.",
+ "achievementUndeadUndertaker": "Ondode Ondernemer",
+ "achievementMonsterMagusModalText": "Je hebt alle Zombie Huisdieren verzameld!",
+ "achievementMonsterMagusText": "Heeft alle Zombie Huisdieren verzameld.",
+ "achievementMonsterMagus": "Monster Magiër",
+ "achievementPartyOn": "Je gezelschap is gegroeid tot 4 leden!",
+ "achievementPartyUp": "Je bent gaan samenwerken met een gezelschapslid!"
}
diff --git a/website/common/locales/nl/backgrounds.json b/website/common/locales/nl/backgrounds.json
index e68d8dbfba..7f4199734d 100644
--- a/website/common/locales/nl/backgrounds.json
+++ b/website/common/locales/nl/backgrounds.json
@@ -457,5 +457,19 @@
"backgroundUnderwaterVentsNotes": "Neem een diepe duik naar de Ventilatieopeningen onder Water.",
"backgroundUnderwaterVentsText": "Ventilatieopeningen onder Water",
"backgroundSeasideCliffsNotes": "Sta op het strand met boven je de schoonheid van de Kliffen aan Zee.",
- "backgroundSeasideCliffsText": "Kliffen aan Zee"
+ "backgroundSeasideCliffsText": "Kliffen aan Zee",
+ "backgroundMonsterMakersWorkshopNotes": "Experimenteer met ontkrachte wetenschappen in de Werkplaats van een Monstermaker.",
+ "backgroundMonsterMakersWorkshopText": "Werkplaats van de Monstermaker",
+ "backgroundPumpkinCarriageNotes": "Rijd in een betoverde Pompoenkoets voordat de klok middernacht slaat.",
+ "backgroundPumpkinCarriageText": "Pompoepkoets",
+ "backgroundFoggyMoorNotes": "Pas op waar je staat als je een Mistig Veen oversteekt.",
+ "backgroundFoggyMoorText": "Mistig Veen",
+ "backgrounds102019": "SET 65: uitgebracht in oktober 2019",
+ "backgroundInAClassroomNotes": "Zuig de kennis van je mentoren op in een Klaslokaal",
+ "backgroundInAClassroomText": "Klaslokaal",
+ "backgroundInAnAncientTombNotes": "Verken de mysteries van een Eeuwenoude Tombe.",
+ "backgroundInAnAncientTombText": "Eeuwenoude Tombe",
+ "backgroundAutumnFlowerGardenNotes": "Neem de warmte van een Herfstbloementuin in je op.",
+ "backgroundAutumnFlowerGardenText": "Herfstbloementuin",
+ "backgrounds092019": "SET 64: uitgebracht in september 2019"
}
diff --git a/website/common/locales/nl/challenge.json b/website/common/locales/nl/challenge.json
index 69c9228d8e..5f298931a2 100644
--- a/website/common/locales/nl/challenge.json
+++ b/website/common/locales/nl/challenge.json
@@ -42,10 +42,10 @@
"challengeDescr": "Omschrijving",
"prize": "Prijs",
"prizePop": "Als iemand jouw uitdaging 'wint', dan kun je aan de winnaar edelstenen uitreiken. Het maximum aantal dat je kunt schenken is het aantal edelstenen dat jij bezit (plus het aantal gilde-edelstenen, als jij het gilde van deze uitdaging hebt aangemaakt). Let op: deze prijs kan later niet veranderd worden.",
- "prizePopTavern": "Als iemand jouw uitdaging 'wint', dan kun je aan de winnaar edelstenen uitreiken.Max = het aantal edelstenen dat jij bezit Let op: de prijs kan later niet veranderd worden en herberg-uitdagingen worden niet terugbetaald als de uitdaging wordt geannuleerd.",
- "publicChallenges": "Minimaal 1 edelsteen voor openbare uitdagingen (helpt spam voorkomen, echt).",
- "publicChallengesTitle": "Openbare uitdagingen",
- "officialChallenge": "Officiële Habitica-uitdaging",
+ "prizePopTavern": "Als iemand jouw uitdaging 'wint', dan kun je aan de winnaar edelstenen uitreiken.Max = het aantal edelstenen dat jij bezit. Let op: de prijs kan later niet veranderd worden en herberg-uitdagingen worden niet terugbetaald als de uitdaging wordt geannuleerd.",
+ "publicChallenges": "Minimaal 1 Edelsteen voor openbare uitdagingen (helpt spam voorkomen, echt).",
+ "publicChallengesTitle": "Openbare Uitdagingen",
+ "officialChallenge": "Officiële Habitica-Uitdaging",
"by": "door",
"participants": "<%= membercount %> deelnemers",
"join": "Meedoen",
@@ -78,7 +78,7 @@
"noChallengeOwnerPopover": "Deze uitdaging heeft geen eigenaar omdat de eigenaar zijn of haar account heeft verwijderd.",
"challengeMemberNotFound": "Gebruiker niet gevonden onder de deelnemers aan de uitdaging",
"onlyGroupLeaderChal": "Alleen de groepsleider kan uitdagingen creëren",
- "tavChalsMinPrize": "De prijs voor openbare uitdagingen moet tenminste 1 edelsteen zijn.",
+ "tavChalsMinPrize": "De prijs voor Openbare Uitdagingen moet tenminste 1 edelsteen zijn.",
"cantAfford": "Je kunt deze beloning niet betalen. Koop meer edelstenen of verlaag de prijs.",
"challengeIdRequired": "\"challengeId\" moet een valide UUID zijn.",
"winnerIdRequired": "\"winnerId\" moet een valide UUID zijn.",
@@ -88,18 +88,18 @@
"winnerNotFound": "De winnaar met id \"<%= userId %>\" is niet gevonden of maakt geen deel uit van de uitdaging.",
"noCompletedTodosChallenge": "\"includeCompletedTodos\" wordt niet ondersteund bij het ophalen van uitdagingstaken.",
"userTasksNoChallengeId": "Wanneer \"tasksOwner\" \"user\" is, kan \"challengeId\" niet worden gegeven.",
- "onlyChalLeaderEditTasks": "Taken die bij een uitdaging horen kunnen alleen aangepast worden door de leider.",
+ "onlyChalLeaderEditTasks": "Taken die bij een uitdaging horen kunnen alleen worden aangepast door de leider.",
"userAlreadyInChallenge": "Gebruiker doet al mee aan deze uitdaging.",
"cantOnlyUnlinkChalTask": "Alleen afgebroken uitdagingstaken kunnen worden losgekoppeld.",
- "shortNameTooShort": "Labelnaam moet bestaan uit in ieder geval 3 karakters.",
+ "shortNameTooShort": "Labelnaam moet bestaan uit minstens 3 karakters.",
"joinedChallenge": "Doet mee aan een uitdaging",
- "joinedChallengeText": "Deze gebruiker heeft zichzelf op de proef gesteld door mee te doen aan een uitdaging!",
+ "joinedChallengeText": "Deze gebruiker heeft zichzelf op de proef gesteld door mee te doen aan een Uitdaging!",
"myChallenges": "Mijn Uitdagingen",
"findChallenges": "Ontdek Uitdagingen",
"noChallengeTitle": "Je hebt geen Uitdagingen.",
- "challengeDescription1": "Uitdagingen zijn gemeenschappelijke evenementen waarin spelers strijden en prijzen willen door een groep gerelateerde taken te voltooien.",
+ "challengeDescription1": "Uitdagingen zijn gemeenschappelijke evenementen waarin spelers strijden en prijzen winnen door een groep gerelateerde taken te voltooien.",
"challengeDescription2": "Zoek aanbevolen Uitdagingen gebaseerd op je interesses, neus door Habitica’s publieke Uitdagingen of maak je eigen Uitdagingen.",
- "noChallengeMatchFilters": "We konden geen overeenkomstige uitdaging vinden.",
+ "noChallengeMatchFilters": "We konden geen overeenkomstige Uitdagingen vinden.",
"createdBy": "Gecreëerd door",
"joinChallenge": "Doe mee aan Uitdaging",
"leaveChallenge": "Verlaat Uitdaging",
@@ -108,11 +108,11 @@
"challengeDescription": "Beschrijving van de uitdaging",
"selectChallengeWinnersDescription": "Selecteer een winnaar uit de deelnemers aan de Uitdaging",
"awardWinners": "Prijswinnaar",
- "doYouWantedToDeleteChallenge": "Wil je deze uitdaging verwijderen?",
+ "doYouWantedToDeleteChallenge": "Wil je deze Uitdaging verwijderen?",
"deleteChallenge": "Uitdaging verwijderen",
- "challengeNamePlaceholder": "Wat is de naam van je uitdaging?",
+ "challengeNamePlaceholder": "Wat is de naam van je Uitdaging?",
"challengeSummary": "Samenvatting",
- "challengeSummaryPlaceholder": "Geef een korte beschrijving over je gemaakte Uitdaging voor andere Habiticanen. Wat is het hoofddoel van je Uitdaging en waarom zouden anderen moeten deelnemen? \nProbeer slimme sleutelwoorden te gebruiken in de beschrijving zodat andere Habiticanen je Uitdaging makkelijk kunnen vinden als ze erop zoeken.",
+ "challengeSummaryPlaceholder": "Geef een korte beschrijving van je gemaakte Uitdaging voor andere Habiticanen. Wat is het hoofddoel van je Uitdaging en waarom zouden anderen moeten deelnemen? Probeer slimme sleutelwoorden te gebruiken in de beschrijving zodat andere Habiticanen je Uitdaging makkelijk kunnen vinden als ze zoeken!",
"challengeDescriptionPlaceholder": "Gebruik deze sectie om een meer gedetailleerd inzicht te geven in wat deelnemers allemaal moeten weten over jouw Uitdaging.",
"challengeGuild": "Toevoegen aan",
"challengeMinimum": "Minimaal 1 Edelsteen voor openbare Uitdagingen (het helpt spam te voorkomen, echt waar!).",
@@ -120,10 +120,10 @@
"shortName": "Korte Naam",
"shortNamePlaceholder": "Welk kort label kan worden gebruikt om je Uitdaging te kenmerken?",
"updateChallenge": "Uitdaging updaten",
- "haveNoChallenges": "Deze groep heeft geen uitdagingen",
+ "haveNoChallenges": "Deze groep heeft geen Uitdagingen",
"loadMore": "Laad Meer",
"exportChallengeCsv": "Uitdaging exporteren",
- "editingChallenge": "Uitdaging aan het bewerke",
+ "editingChallenge": "Uitdaging aan het bewerken",
"nameRequired": "Naam is vereist",
"tagTooShort": "De labelnaam is te kort",
"summaryRequired": "Samenvatting is vereist",
@@ -134,6 +134,6 @@
"viewProgressOf": "Bekijk vooruitgang van",
"viewProgress": "Bekijk Vooruitgang",
"selectMember": "Lid selecteren",
- "confirmKeepChallengeTasks": "Wil je je Uitdagingstaken behouden?",
+ "confirmKeepChallengeTasks": "Wil je je uitdagingstaken behouden?",
"selectParticipant": "Selecteer een deelnemer"
}
diff --git a/website/common/locales/nl/character.json b/website/common/locales/nl/character.json
index 2bf76d8d2c..be1657ff88 100644
--- a/website/common/locales/nl/character.json
+++ b/website/common/locales/nl/character.json
@@ -7,9 +7,9 @@
"noPhoto": "Deze Habiticaan heeft geen foto toegevoegd.",
"other": "Overige",
"fullName": "Volledige naam",
- "displayName": "Naam weergave",
- "changeDisplayName": "Verander display naam",
- "newDisplayName": "Nieuwe display naam",
+ "displayName": "Naam weergeven",
+ "changeDisplayName": "Verander Getoonde Naam",
+ "newDisplayName": "Nieuwe Getoonde Naam",
"displayPhoto": "Foto",
"displayBlurb": "Blurb",
"displayBlurbPlaceholder": "Stel jezelf voor, alsjeblieft",
@@ -28,8 +28,8 @@
"locked": "vergrendeld",
"shirts": "Shirts",
"shirt": "Shirt",
- "specialShirts": "Speciale shirts",
- "bodyHead": "Kapsel en haarkleur",
+ "specialShirts": "Speciale Shirts",
+ "bodyHead": "Kapsels en Haarkleuren",
"bodySkin": "Huid",
"skin": "Huid",
"color": "Kleur",
@@ -54,35 +54,35 @@
"basicSkins": "Basishuidskleuren",
"rainbowSkins": "Regenbooghuidskleuren",
"pastelSkins": "Pastelhuidskleuren",
- "spookySkins": "Spookachtige huidskleuren",
- "supernaturalSkins": "Bovennatuurlijke huidskleuren",
- "splashySkins": "Spetterende huidskleuren",
- "winterySkins": "Winterige huidskleuren",
+ "spookySkins": "Spookachtige Huidskleuren",
+ "supernaturalSkins": "Bovennatuurlijke Huidskleuren",
+ "splashySkins": "Spetterende Huidskleuren",
+ "winterySkins": "Winterhuidskleuren",
"rainbowColors": "Regenboogkleuren",
- "shimmerColors": "Glanzende haarkleuren",
- "hauntedColors": "Spookachtige haarkleuren",
+ "shimmerColors": "Glanzende Haarkleuren",
+ "hauntedColors": "Spookachtige Haarkleuren",
"winteryColors": "Winterkleuren",
"equipment": "Uitrusting",
"equipmentBonus": "Uitrusting",
"equipmentBonusText": "Door je gevechtsuitrusting geleverde bonuspunten voor je eigenschappen. Zie het Uitrustings-tabblad onder Boedel om je gevechtsuitrusting te selecteren.",
- "classBonusText": "Jouw klasse (Krijger, als je nog geen andere klasse hebt vrijgespeeld of geselecteerd) gebruikt zijn eigen uitrusting effectiever dan de uitrusting van een andere klasse. Uitrustingsstukken die horen bij je huidige klasse geven een 50% bonus bovenop de eigenschapsbonus die het normaal al verleent.",
+ "classBonusText": "Jouw klasse (Krijger, als je nog geen andere klasse hebt vrijgespeeld of geselecteerd) gebruikt zijn eigen uitrusting effectiever dan de uitrusting van een andere klasse. Uitrustingsstukken die horen bij je huidige klasse geven een 50% bonus bovenop de eigenschapsbonus die ze normaal verlenen.",
"classEquipBonus": "Klassebonus",
"battleGear": "Strijduitrusting",
"gear": "Uitrusting",
- "battleGearText": "Dit is de uitrusting die je in de strijd draagt. Het beïnvloedt scores als je met taken bezig bent.",
+ "battleGearText": "Dit is de uitrusting die je in de strijd draagt. Het beïnvloedt je scores als je met taken bezig bent.",
"autoEquipBattleGear": "Automatisch nieuwe uitrusting gebruiken",
"costume": "Kostuum",
"costumeText": "Als een andere uitrusting mooier vindt dan de uitrusting die je gebruikt, vink dan \"Kostuum gebruiken\" aan om een andere uitrusting zichtbaar te maken terwijl je je strijduitrusting eronder draagt.",
"useCostume": "Kostuum gebruiken",
"useCostumeInfo1": "Klik op \"Kostuum gebruiken\" om jouw avatar voorwerpen aan te laten trekken zonder de Eigenschappen, die je van jouw Strijduitrusting krijgt, te veranderen! Hierdoor kun je links de uitrusting met de beste eigenschappen gebruiken, en rechts je avatar aankleden met andere uitrusting.",
"useCostumeInfo2": "Als je op \"Kostuum gebruiken\" klikt, ziet je avatar er vrij simpel uit... maar maak je geen zorgen! Als je aan de linkerkant kijkt, zie je dat je strijduitrusting nog steeds actief is. Nu kun je het interessant maken! Alles wat je aan de rechterkant aanklikt om aan te trekken heeft geen invloed op je eigenschappen, maar kan er wel voor zorgen dat je er fantastisch uitziet. Probeer de verschillende combinaties eens - mix verschillende sets, en zoek je kostuum uit bij je huisdieren, rijdieren en achtergronden.
Heb je nog vragen? Kijk dan eens naar de Kostuumpagina op de wiki. Heb je de perfecte outfit gevonden? Laat hem dan zien in het Carnavals Verkleedgilde of schep erover op in de Herberg!",
- "costumePopoverText": "Selecteer \"Kostuum gebruiken\" om jouw avatar voorwerpen aan te laten trekken zonder de Eigenschappen, die je van jouw Strijduitrusting krijgt, te veranderen! Dit betekent dat je jouw avatar elke uitrusting aan kan trekken, terwijl je alsnog je Strijduitrusting gebruikt.",
- "autoEquipPopoverText": "Selecteer deze optie om een uitrusting automatisch aan te trekken als je hem koopt.",
+ "costumePopoverText": "Selecteer \"Kostuum gebruiken\" om jouw avatar voorwerpen aan te laten trekken zonder de Eigenschappen die je van jouw Strijduitrusting krijgt, te veranderen! Dit betekent dat je jouw avatar elke uitrusting aan kunt trekken, terwijl je alsnog je Strijduitrusting gebruikt.",
+ "autoEquipPopoverText": "Selecteer deze optie om een uitrusting automatisch aan te trekken als je deze koopt.",
"costumeDisabled": "Je hebt je kostuum uitgezet.",
- "gearAchievement": "Je hebt de prestatie \"Hoogst haalbare uitrusting\" behaald door de hoogst haalbare uitrusting voor je klasse aan te schaffen! Je hebt de volgende sets compleet gemaakt:",
+ "gearAchievement": "Je hebt de prestatie \"Hoogst Haalbare Uitrusting\" behaald door de hoogst haalbare uitrusting voor een klasse aan te schaffen! Je hebt de volgende sets compleet gemaakt:",
"gearAchievementNotification": "Je hebt de pretatie \"Hoogst haalbare uitrusting\" behaald door de hoogst haalbare uitrusting aan te schaffen voor een klasse!",
- "moreGearAchievements": "Om meer van de \"Hoogst haalbare uitrusting\"-badges te halen, kun je van klasse veranderen op de Instelling > Website pagina en de uitrusting van je nieuwe klasse kopen!",
- "armoireUnlocked": "Voor meer uitrustingsstukken, kijk in het betoverde kabinet! Klik op het betoverde kabinet onder beloningen en maak kans op speciale uitrustingsstukken! Het kabinet kan je ook willekeurig ervaringspunten of voedsel geven.",
+ "moreGearAchievements": "Om meer van de \"Hoogst haalbare uitrusting\"-badges te halen, kun je van klasse veranderen in het Instellingen > Gebruiker-pagina en de uitrusting van je nieuwe klasse kopen!",
+ "armoireUnlocked": "Voor meer uitrustingsstukken, kijk in het Betoverde Kabinet! Klik op het Betoverde Kabinet onder Beloningen en maak kans op speciale uitrustingsstukken! Het Kabinet kan je ook willekeurig Ervaringspunten of voedsel geven.",
"ultimGearName": "Ultieme uitrusting - <%= ultClass %>",
"ultimGearText": "Heeft de hoogst haalbare wapen- en uitrustingset voor de <%= ultClass %>-klasse behaald.",
"level": "Niveau",
@@ -96,32 +96,32 @@
"mp": "MP",
"xp": "EP",
"health": "Gezondheid",
- "allocateStr": "Punten toegewezen aan kracht:",
- "allocateStrPop": "Wijs een punt toe aan kracht",
- "allocateCon": "Punten toegewezen aan lichaam:",
- "allocateConPop": "Wijs een punt toe aan lichaam",
- "allocatePer": "Punten toegewezen aan perceptie:",
- "allocatePerPop": "Wijs een punt toe aan perceptie",
- "allocateInt": "Punten toegewezen aan intelligentie:",
- "allocateIntPop": "Wijs een punt toe aan intelligentie",
- "noMoreAllocate": "Nu je niveau 100 hebt bereikt verdien je geen nieuwe eigenschapspunten meer. Je kunt doorgaan met het bereiken van logeren niveaus, of een nieuwe avontuur beginnen vanaf niveau 1 door de Bol der Hergeboorte te gebruiken. Deze is dan gratis te verkrijgen op de markt.",
+ "allocateStr": "Punten toegewezen aan Kracht:",
+ "allocateStrPop": "Wijs een Punt toe aan Kracht",
+ "allocateCon": "Punten toegewezen aan Lichaam:",
+ "allocateConPop": "Wijs een punt toe aan Lichaam",
+ "allocatePer": "Punten toegewezen aan Perceptie:",
+ "allocatePerPop": "Wijs een punt toe aan Perceptie",
+ "allocateInt": "Punten toegewezen aan Intelligentie:",
+ "allocateIntPop": "Wijs een punt toe aan Intelligentie",
+ "noMoreAllocate": "Nu je niveau 100 hebt bereikt verdien je geen nieuwe Eigenschapspunten meer. Je kunt doorgaan met het bereiken van hogere niveaus, of een nieuw avontuur beginnen vanaf niveau 1 door de Bol der Hergeboorte te gebruiken. Deze is dan gratis te verkrijgen op de Markt.",
"stats": "Statistieken",
"achievs": "Prestaties",
"strength": "Kracht",
- "strText": "Kracht vergroot de kans op kritieke aanvallen, en zorgt ervoor dat je hieruit meer goud, ervaring en andere voorwerpen krijgt. Het zorgt er ook voor dat je meer schade aanricht aan boss monsters.",
+ "strText": "Kracht vergroot de kans op kritieke aanvallen, en zorgt ervoor dat je hieruit meer Goud, Ervaringspunten en andere voorwerpen krijgt. Het zorgt er ook voor dat je meer schade aanricht aan eindbazen.",
"constitution": "Lichaam",
- "conText": "Lichaam vermindert de schade die je ontvangt van negatieve gewoontes en gemiste dagelijkse taken.",
+ "conText": "Lichaam vermindert de schade die je ontvangt van negatieve Gewoontes en gemiste Dagtaken.",
"perception": "Perceptie",
- "perText": "Perceptie verhoogt hoeveel goud je verdient en, zodra je de markt hebt vrijgespeeld, verhoogt de kans op het vinden van spullen wanneer je taken afstreept.",
+ "perText": "Perceptie verhoogt hoeveel Goud je verdient en, zodra je de Markt hebt vrijgespeeld, verhoogt de kans op het vinden van spullen wanneer je taken afstreept.",
"intelligence": "Intelligentie",
- "intText": "Intelligentie bepaalt hoeveel ervaringspunten je verdient en, zodra je een klasse hebt vrijgespeeld, bepaalt het je maximale mana beschikbaar voor klassespecifieke vaardigheden.",
- "levelBonus": "Niveaugerelateerde bonus",
- "levelBonusText": "Elke eigenschap krijgt een bonus gelijk aan de helft van (jouw niveau min 1).",
- "allocatedPoints": "Toegewezen punten",
+ "intText": "Intelligentie bepaalt hoeveel Ervaringspunten je verdient en, zodra je een Klasse hebt vrijgespeeld, bepaalt het je maximale hoeveelheid Mana voor klassespecifieke vaardigheden.",
+ "levelBonus": "Niveaugerelateerde Bonus",
+ "levelBonusText": "Elke Eigenschap krijgt een bonus gelijk aan de helft van (jouw Niveau min 1).",
+ "allocatedPoints": "Toegewezen Punten",
"allocatedPointsText": "Eigenschapspunten die je hebt verdiend en toegewezen. Wijs punten toe met behulp van de Karakterbouw-kolom.",
"allocated": "Toegewezen",
"buffs": "Versterkingen",
- "buffsText": "Tijdelijke eigenschapsbonussen afkomstig van vaardigheden en prestaties. Deze verdwijnen aan het einde van de dag. Je kunt de vaardigheden die je hebt vrijgespeeld vinden in de Beloningslijst van de Takenpagina.",
+ "buffsText": "Tijdelijke Eigenschapsbonussen afkomstig van vaardigheden en prestaties. Deze verdwijnen aan het einde van de dag. Je kunt de vaardigheden die je hebt vrijgespeeld vinden in de Beloningslijst van je Takenpagina.",
"characterBuild": "Karakterbouw",
"class": "Klasse",
"experience": "Ervaring",
@@ -133,42 +133,42 @@
"mystery": "Verrassingsartikelen",
"changeClass": "Verander van Klasse, Eigenschapspunten terugkrijgen",
"lvl10ChangeClass": "Om van klasse te veranderen moet je ten minste niveau 10 zijn.",
- "changeClassConfirmCost": "Weet je zeker dat je je klasse wil veranderen voor 3 edelstenen?",
+ "changeClassConfirmCost": "Weet je zeker dat je je klasse wil veranderen voor 3 Edelstenen?",
"invalidClass": "Ongeldige klasse. Specificeer \"krijger\", \"dief\", \"magiër\" of \"heler\".",
- "levelPopover": "Elk niveau geeft je één Punt om toe te wijzen aan een Eigenschap van jouw keuze. Je kunt dit handmatig doen of het spel voor jou laten beslissen door gebruik te maken van één van de automatische verdelingsopties.",
- "unallocated": "Nog niet toegewezen eigenschapspunten",
- "haveUnallocated": "Je hebt <%= points %> eigenschapspunt(en) nog niet toegewezen",
- "autoAllocation": "Automatische verdeling",
- "autoAllocationPop": "Wijst punten toe aan Eigenschappen op basis van jouw voorkeuren, wanneer je een niveau omhoog gaat.",
+ "levelPopover": "Elk niveau geeft je één Punt om toe te wijzen aan een Eigenschap naar keuze. Je kunt dit handmatig doen of het spel voor jou laten beslissen door gebruik te maken van één van de automatische verdelingsopties.",
+ "unallocated": "Nog niet toegewezen Eigenschapspunten",
+ "haveUnallocated": "Je hebt <%= points %> Eigenschapspunt(en) nog niet toegewezen",
+ "autoAllocation": "Automatische Verdeling",
+ "autoAllocationPop": "Wijst Punten toe aan Eigenschappen op basis van jouw voorkeuren, wanneer je een niveau omhoog gaat.",
"evenAllocation": "Verdeel Eigenschapspunten gelijkmatig",
- "evenAllocationPop": "Wijst hetzelfde aantal punten toe aan elke eigenschap.",
- "classAllocation": "Verdeel punten op basis van klasse",
- "classAllocationPop": "Wijst meer punten toe aan de Eigenschappen die belangrijk zijn voor jouw klasse.",
- "taskAllocation": "Verdeel punten gebaseerd op taken activiteiten",
- "taskAllocationPop": "Wijst punten toe op basis van de kracht, intelligentie, lichaam en perceptie categorieën die horen bij de taken die je vervuld hebt.",
- "distributePoints": "Verdeel niet toegekende punten",
- "distributePointsPop": "Verdeelt alle nog niet toegekende eigenschapspunten aan de hand van het gekozen toekenningsschema.",
- "warriorText": "Krijgers behalen meer en betere \"voltreffers\", die willekeurig extra goud, ervaringspunten, en kans op vondsten geven voor het afstrepen van een taak. Ook doen ze veel schade aan eindbazen. Speel een Krijger als je je gemotiveerd voelt door onvoorspelbare jackpot-achtige beloningen of als je pijn aan eindbazen wil uitdelen in queesten!",
- "wizardText": "Magiërs leren snel, ze krijgen sneller ervaringspunten en niveaus dan de andere klassen. Je hebben ook veel mana beschikbaar voor speciale vaardigheden. Speel een magiër als je houdt van de tactische aspecten van Habitica of als je erg gemotiveerd wordt door stijging in niveaus en het vrijspelen van nieuwe functionaliteiten!",
- "mageText": "Magiërs leren snel, ze krijgen sneller ervaringspunten en niveaus dan de andere klassen. Je hebben ook veel mana beschikbaar voor speciale vaardigheden. Speel een magiër als je houdt van de tactische aspecten van Habitica of als je erg gemotiveerd wordt door stijging in niveaus en het vrijspelen van nieuwe functionaliteiten!",
- "rogueText": "Dieven houden ervan rijkdom te vergaren, verkrijgen meer goud dan enig ander en zijn bedreven in het vinden van willekeurige voorwerpen. Hun kenmerkende behendigheid laat hen de consequenties ontduiken van het missen van dagelijkse taken. Speel een dief als je veel motivatie vindt in het krijgen van beloningen, het behalen van prestaties en het streven naar buit en badges!",
- "healerText": "Helers zijn ongevoelig voor schade, en kunnen deze bescherming uitstrekken naar anderen. Gemiste dagelijkse taken en slechte gewoontes hebben nauwelijks invloed op hun humeur, en ze hebben manieren om gezondheidspunten te herstellen na een mislukking. Speel een Heler als je het leuk vindt om anderen in je gezelschap te assisteren, of als het idee om de dood voor de gek te houden door hard te werken je inspireert!",
+ "evenAllocationPop": "Wijst hetzelfde aantal Punten toe aan elke Eigenschap.",
+ "classAllocation": "Verdeel Punten op basis van Klasse",
+ "classAllocationPop": "Wijst meer Punten toe aan de Eigenschappen die belangrijk zijn voor jouw Klasse.",
+ "taskAllocation": "Verdeel Punten gebaseerd op voltooide taken",
+ "taskAllocationPop": "Wijst Punten toe op basis van de Kracht-, Intelligentie-, Lichaam- en Perceptie-categorieën die horen bij de taken die je vervuld hebt.",
+ "distributePoints": "Verdeel niet toegekende Punten",
+ "distributePointsPop": "Verdeelt alle nog niet toegekende Eigenschapspunten aan de hand van het gekozen toekenningsschema.",
+ "warriorText": "Krijgers behalen meer en betere \"voltreffers\", die willekeurig extra Goud, Ervaringspunten, en kans op vondsten geven voor het afstrepen van een taak. Ook doen ze veel schade aan eindbazen. Speel een Krijger als je je gemotiveerd voelt door onvoorspelbare jackpot-achtige beloningen of als eindbazen je eindbazen er van langs wil geven in Queesten!",
+ "wizardText": "Magiërs leren snel, ze krijgen sneller Ervaringspunten en Niveaus dan de andere klassen. Je hebben ook veel Mana beschikbaar voor speciale vaardigheden. Speel een Magiër als je houdt van de tactische aspecten van Habitica of als je erg gemotiveerd wordt door stijging in niveaus en het vrijspelen van nieuwe functionaliteiten!",
+ "mageText": "Magiërs leren snel, ze krijgen sneller Ervaringspunten en Niveaus dan de andere klassen. Je hebben ook veel Mana beschikbaar voor speciale vaardigheden. Speel een Magiër als je houdt van de tactische aspecten van Habitica of als je erg gemotiveerd wordt door stijging in niveaus en het vrijspelen van nieuwe functionaliteiten!",
+ "rogueText": "Dieven houden ervan rijkdom te vergaren, verkrijgen meer Goud dan enig ander en zijn bedreven in het vinden van willekeurige voorwerpen. Hun kenmerkende behendigheid laat hen de consequenties ontduiken van het missen van Dagtaken. Speel een dief als je veel motivatie vindt in het krijgen van Beloningen, het halen van Prestaties en het streven naar buit en badges!",
+ "healerText": "Helers zijn ongevoelig voor schade, en kunnen deze bescherming uitstrekken naar anderen. Gemiste Dagtaken en slechte Gewoontes hebben nauwelijks invloed op hen, en ze hebben manieren om Gezondheidspunten te herstellen na een mislukking. Speel een Heler als je het leuk vindt om anderen in je gezelschap te assisteren, of als het idee om de dood voor de gek te houden door hard te werken je inspireert!",
"optOutOfClasses": "Afmelden",
"optOutOfPMs": "Afmelden",
- "chooseClass": "Je klasse kiezen",
+ "chooseClass": "Je Klasse kiezen",
"chooseClassLearnMarkdown": "[Leer meer over Habitica's klassesysteem] (https://habitica.fandom.com/nl/wiki/Klasse_systeem)",
"optOutOfClassesText": "Geen zin om een klasse te kiezen? Wil je later pas kiezen? Meld je af - je speelt dan een krijger zonder speciale vaardigheden. Je kunt later in de wiki over het klassensysteem lezen en op ieder moment de klassen aanzetten in het menu onder Gebruiker -> Statistieken.",
"selectClass": "Selecteer <%= heroClass %>",
"select": "Selecteren",
"stealth": "Heimelijkheid",
- "stealthNewDay": "Wanneer een nieuwe dag begint, ontwijk je de schade van dit aantal gemiste dagelijkse taken.",
- "streaksFrozen": "Series bevroren",
- "streaksFrozenText": "Series van gemiste dagelijkse taken worden niet teruggezet op nul aan het einde van de dag.",
+ "stealthNewDay": "Wanneer een nieuwe dag begint, ontwijk je de schade van dit aantal gemiste Dagtaken.",
+ "streaksFrozen": "Series Bevroren",
+ "streaksFrozenText": "Series van gemiste Dagtaken worden niet teruggezet op nul aan het einde van de dag.",
"respawn": "Herrijs!",
- "youDied": "Je bent doodgegaan!",
- "dieText": "Je hebt een niveau, al je goud, en een willekeurig onderdeel van je uitrusting verloren. Herrijs, Habiteer, en probeer het opnieuw! Bedwing die slechte gewoontes, let erop je dagelijkse taken bij te houden en houd de dood van je af met een gezondheidsdrankje als je wankelt!",
- "sureReset": "Weet je het zeker? Dit zal je karakters klasse en toegewezen Eigenschapspunten resetten (je krijgt ze allemaal terug om opnieuw toe te wijzen) en kost 3 edelstenen.",
- "purchaseFor": "Kopen voor <%= cost %> edelstenen?",
+ "youDied": "Je bent Doodgegaan!",
+ "dieText": "Je hebt een niveau, al je goud en een willekeurig onderdeel van je uitrusting verloren. Herrijs, Habiticaan, en probeer het opnieuw! Bedwing die slechte gewoontes, let erop je Dagtaken bij te houden en houd de dood van je af met een gezondheidsdrankje als je wankelt!",
+ "sureReset": "Weet je het zeker? Dit zal je karakters klasse en toegewezen Eigenschapspunten resetten (je krijgt ze allemaal terug om opnieuw toe te wijzen) en kost 3 Edelstenen.",
+ "purchaseFor": "Kopen voor <%= cost %> Edelstenen?",
"purchaseForHourglasses": "Koop voor <%= cost %> Zandlopers?",
"notEnoughMana": "Niet genoeg mana.",
"invalidTarget": "Je kan daar geen vaardigheid op uitspreken.",
@@ -176,22 +176,22 @@
"youCastTarget": "Je hebt <%= spell %> uitgesproken over <%= target %>.",
"youCastParty": "Je hebt <%= spell %> uitgesproken voor het gezelschap.",
"critBonus": "Voltreffer! Bonus: ",
- "gainedGold": "Je hebt wat goud verdiend",
- "gainedMana": "Je hebt wat mana verdiend",
- "gainedHealth": "Je hebt wat gezondheidspunten verdiend",
- "gainedExperience": "Je hebt wat ervaring verdiend",
- "lostGold": "Je hebt wat goud uitgegeven",
- "lostMana": "Je hebt wat mana gebruikt",
- "lostHealth": "Je hebt wat gezondheidspunten verloren",
- "lostExperience": "Je hebt wat ervaring verloren",
- "displayNameDescription1": "Dit is wat je ziet in de berichten die je plaatst in de herberg, gildes en de groepschat, naast wat er op je avatar wordt weergegeven. Om het te wijzigen klik je op de knop Wijzigen. Als je in plaats daarvan je inlognaam wil veranderen, ga dan naar",
+ "gainedGold": "Je hebt wat Goud verdiend",
+ "gainedMana": "Je hebt wat Mana verdiend",
+ "gainedHealth": "Je hebt wat \\gezondheidspunten verdiend",
+ "gainedExperience": "Je hebt wat Ervaring verdiend",
+ "lostGold": "Je hebt wat Goud uitgegeven",
+ "lostMana": "Je hebt wat Mana gebruikt",
+ "lostHealth": "Je hebt wat Gezondheidspunten verloren",
+ "lostExperience": "Je hebt wat Ervaring verloren",
+ "displayNameDescription1": "Dit is wat je ziet in de berichten die je plaatst in de Herberg, gildes en de groepschat, naast wat er op je avatar wordt weergegeven. Om het te wijzigen klik je op de knop Wijzigen. Als je in plaats daarvan je inlognaam wil veranderen, ga dan naar",
"displayNameDescription2": "Instellingen->Site",
"displayNameDescription3": "en kijk in het registratiegedeelte.",
"unequipBattleGear": "Gevechtsuitrusting uittrekken",
"unequipCostume": "Kostuum uittrekken",
"equip": "Aantrekken",
"unequip": "Uittrekken",
- "unequipPetMountBackground": "Huisdier, rijdier en achtergrond uitschakelen",
+ "unequipPetMountBackground": "Huisdier, Rijdier en Achtergrond uitschakelen",
"animalSkins": "Dierenhuiden",
"chooseClassHeading": "Kies een klasse! Of kies ervoor om later te beslissen.",
"warriorWiki": "Krijger",
@@ -205,16 +205,16 @@
"int": "INT",
"showQuickAllocation": "Toon verdeling Eigenschapspunten",
"hideQuickAllocation": "Verberg verdeling Eigenschapspunten",
- "quickAllocationLevelPopover": "Met ieder niveau verdien je een Punt om toe te wijzen aan een Eigenschap van jouw keuze. Je kunt dit eigenhandig doen of het spel voor je laten bepalen door een van de automatische toewijzingsopties te kiezen in Gebruiker -> Statistieken.",
+ "quickAllocationLevelPopover": "Met ieder niveau verdien je een Punt om toe te wijzen aan een Eigenschap van jouw keuze. Je kunt dit eigenhandig doen of het spel voor je laten bepalen door een van de automatische toewijzingsopties te kiezen in Gebruiker > Statistieken.",
"notEnoughAttrPoints": "Je hebt niet genoeg Eigenschapspunten.",
- "classNotSelected": "Je moet een klasse selecteren voordat je Eigenschapspunten kan toewijzen.",
+ "classNotSelected": "Je moet een Klasse selecteren voordat je Eigenschapspunten kunt toewijzen.",
"style": "Stijl",
"facialhair": "Gezicht",
"photo": "Foto",
"info": "Informatie",
"joined": "Meedoen",
- "totalLogins": "Totaal aantal check-ins",
- "latestCheckin": "Laatste check-in",
+ "totalLogins": "Totaal aantal Check-ins",
+ "latestCheckin": "Laatste Check-in",
"editProfile": "Profiel bewerken",
"challengesWon": "Uitdagingen gewonnen",
"questsCompleted": "Queesten voltooid",
@@ -224,5 +224,9 @@
"mainHand": "Dominante-hand",
"offHand": "Andere hand",
"statPoints": "Eigenschapspunten",
- "pts": "ptn"
+ "pts": "ptn",
+ "chatCastSpellUser": "<%= username %> spreekt <%= spell %> uit op <%= target %>.",
+ "chatCastSpellParty": "<%= username %> spreekt <%= spell %> uit voor het gezelschap.",
+ "purchasePetItemConfirm": "Deze aankoop zou het aantal voorwerpen dat je nodig hebt om alle mogelijke <%= itemText %> huisdieren uit te broeden, overschrijden. Weet je het zeker?",
+ "purchaseForGold": "Kopen voor <%= cost %> Goud?"
}
diff --git a/website/common/locales/nl/communityguidelines.json b/website/common/locales/nl/communityguidelines.json
index 45c292d3eb..0dcaa2a38f 100644
--- a/website/common/locales/nl/communityguidelines.json
+++ b/website/common/locales/nl/communityguidelines.json
@@ -1,6 +1,6 @@
{
- "iAcceptCommunityGuidelines": "Ik stem ermee in me aan de gemeenschapsrichtlijnen te houden",
- "tavernCommunityGuidelinesPlaceholder": "Vriendelijke aanwijzing: Dit is een chat voor alle leeftijden, dus houd inhoud en taal gepast! Raadpleeg de gemeenschapsrichtlijnen in de zijbalk als je vragen hebt.",
+ "iAcceptCommunityGuidelines": "Ik stem ermee in me aan de Gemeenschapsrichtlijnen te houden",
+ "tavernCommunityGuidelinesPlaceholder": "Vriendelijke aanwijzing: dit is een chat voor alle leeftijden, dus houd inhoud en taal gepast! Raadpleeg de Gemeenschapsrichtlijnen in de zijbalk als je vragen hebt.",
"lastUpdated": "Laatste update:",
"commGuideHeadingWelcome": "Welkom in Habitica!",
"commGuidePara001": "Wees gegroet, avonturier! Welkom in Habitica, het land van productiviteit, een gezonde levensstijl en de incidentele op hol geslagen griffioen. We hebben een vrolijke gemeenschap van behulpzame mensen die elkaar ondersteunen op weg naar zelfverbetering. Om erbij te passen heb je alleen een positieve houding, een respectvolle manier en het begrip dat iedereen andere vaardigheden en limieten heeft, inclusief jij! Habiticanen zijn geduldig met elkaar en proberen te helpen indien mogelijk.",
@@ -31,7 +31,7 @@
"commGuidePara023": "Gesprekken neigen te roteren rondom informeel kletsen en productiviteit of levensverbeteringstips. Omdat de herbergchat maar 200 berichten kan onthouden is het geen goede plek voor langere gesprekken over één onderwerp, vooral niet over gevoelige onderwerpen (zoals politiek, religies, depressie, het wel of niet verbieden van de aardmanjacht, enz.). Deze gesprekken moeten in de daarvoor geschikte gildes gevoerd worden of in de Back Corner. Een moderator kan je naar een geschikte Gilde sturen, maar het is uiteindelijk je eigen verantwoordelijkheid voor het vinden en praten in de geschikte plaats.",
"commGuidePara024": "Bespreek geen verslavende middelen in de herberg Veel mensen gebruiken Habitica om van hun slechte gewoontes af te komen. Gesprekken over verslavende of illegale middelen maakt dit wellicht veel moeilijker voor ze! Toon respect voor je mede-Herberggasten en houd hier rekening mee. Hieronder vallen onder andere: roken, alcohol, pornografie, gokken en drugsgebruik en -misbruik.",
"commGuidePara027": "Als een moderator aangeeft dat je het gesprek elders moet gaan houde en er geen relevante Gilde is, kunnen ze suggereren om de 'Back Corner' te gebruiken. De 'Back Corner'-Gilde is een vrije openbare ruimte voor het discusseren van potentieel gevoelige onderwerpen die alleen gebruikt moet worden als een moderator erheen heeft gewezen. Het wordt zorgvuldig gesurveilleerd door het team van moderators. Het is niet de plaats voor algemene discussies of gesprekken, en je zal hier alleen naartoe gewezen worden wanneer het toepasbaar is.",
- "commGuideHeadingPublicGuilds": "Openbare gildes",
+ "commGuideHeadingPublicGuilds": "Openbare Gildes",
"commGuidePara029": "Openbare Gildes lijken op de herberg, behalve dat ze een eigen thema hebben en niet zo gericht zijn op algemene gesprekken. Openbare chat in de Gildes moet op dit thema gericht zijn. Leden van het Wordsmith-Gilde vinden het waarschijnlijk niet leuk als het gesprek opeens over tuinieren gaat in plaats van over schrijven, en een Drakenfokkersgilde is misschien niet geïnteresseerd in het ontcijferen van oeroude runen. Sommige Gildes zijn hier minder streng in dan anderen, maar over het algemeen geldt: houd je aan het onderwerp!",
"commGuidePara031": "Sommige openbare Gildes bespreken gevoelige onderwerpen zoals depressie, religie, politiek, en dergelijke. Dit is prima, zolang de gesprekken in het gilde de algemene voorwaarden of richtlijnen voor openbare ruimtes niet overtreden, en zolang ze over het onderwerp blijven gaan.",
"commGuidePara033": "Openbare Gildes mogen GEEN 18+ materiaal bevatten. Als ze van plan zijn om regelmatig gevoelig materiaal te bespreken, moeten ze dat aangeven in de beschrijving van het gilde. Dit houdt Habitica voor iedereen veilig en comfortabel.",
diff --git a/website/common/locales/nl/content.json b/website/common/locales/nl/content.json
index 1768f71037..2f8f80a107 100644
--- a/website/common/locales/nl/content.json
+++ b/website/common/locales/nl/content.json
@@ -4,76 +4,76 @@
"armoireText": "Betoverd Kabinet",
"armoireNotesFull": "Open het Kabinet om willekeurig speciale Uitrusting, Ervaringspunten of Voedsel te ontvangen! Resterende stukken uitrusting:",
"armoireLastItem": "Je hebt het laatste stuk zeldzame Uitrusting gevonden in het Betoverde Kabinet.",
- "armoireNotesEmpty": "Het Kabinet krijgt in de eerste week van iedere maand nieuwe uitrustingsstukken. Tot die tijd kun je blijven klikken voor Ervaring en Voedsel!",
- "dropEggWolfText": "Wolf",
+ "armoireNotesEmpty": "Het Kabinet krijgt in de eerste week van iedere maand nieuwe Uitrusting. Tot die tijd kun je blijven klikken voor Ervaring en Voedsel!",
+ "dropEggWolfText": "Wolvenwelp",
"dropEggWolfMountText": "Wolf",
"dropEggWolfAdjective": "een loyale",
- "dropEggTigerCubText": "Tijgerwelpje",
+ "dropEggTigerCubText": "Tijgerwelp",
"dropEggTigerCubMountText": "Tijger",
"dropEggTigerCubAdjective": "een woeste",
- "dropEggPandaCubText": "Pandawelpje",
+ "dropEggPandaCubText": "Pandawelp",
"dropEggPandaCubMountText": "Panda",
"dropEggPandaCubAdjective": "een zachtaardige",
- "dropEggLionCubText": "Leeuwenwelpje",
+ "dropEggLionCubText": "Leeuwenwelp",
"dropEggLionCubMountText": "Leeuw",
"dropEggLionCubAdjective": "een koninklijke",
- "dropEggFoxText": "Vos",
+ "dropEggFoxText": "Vossenwelp",
"dropEggFoxMountText": "Vos",
"dropEggFoxAdjective": "een sluwe",
- "dropEggFlyingPigText": "Vliegend Varken",
+ "dropEggFlyingPigText": "Vliegende Big",
"dropEggFlyingPigMountText": "Vliegend Varken",
- "dropEggFlyingPigAdjective": "een wispelturig",
- "dropEggDragonText": "Draak",
+ "dropEggFlyingPigAdjective": "een wispelturige",
+ "dropEggDragonText": "Drakenjong",
"dropEggDragonMountText": "Draak",
- "dropEggDragonAdjective": "een machtige",
- "dropEggCactusText": "Cactus",
+ "dropEggDragonAdjective": "een machtig",
+ "dropEggCactusText": "Cactusstek",
"dropEggCactusMountText": "Cactus",
"dropEggCactusAdjective": "een prikkende",
- "dropEggBearCubText": "Berenwelpje",
+ "dropEggBearCubText": "Berenwelp",
"dropEggBearCubMountText": "Beer",
"dropEggBearCubAdjective": "een dappere",
- "questEggGryphonText": "Griffioen",
+ "questEggGryphonText": "Griffioenkuiken",
"questEggGryphonMountText": "Griffioen",
- "questEggGryphonAdjective": "een trotse",
- "questEggHedgehogText": "Egel",
+ "questEggGryphonAdjective": "een trots(e)",
+ "questEggHedgehogText": "Baby-Egel",
"questEggHedgehogMountText": "Egel",
"questEggHedgehogAdjective": "een stekelige",
- "questEggDeerText": "Hert",
+ "questEggDeerText": "Hertenkalf",
"questEggDeerMountText": "Hert",
"questEggDeerAdjective": "een elegant",
"questEggEggText": "Ei",
"questEggEggMountText": "Eiermand",
- "questEggEggAdjective": "een kleurrijke",
- "questEggRatText": "Rat",
+ "questEggEggAdjective": "een kleurrijk(e)",
+ "questEggRatText": "Rattenjong",
"questEggRatMountText": "Rat",
- "questEggRatAdjective": "een sociale",
- "questEggOctopusText": "Achtarmige Inktvis",
- "questEggOctopusMountText": "Achtarmige Inktvis",
+ "questEggRatAdjective": "een speels(e)",
+ "questEggOctopusText": "Baby-Octopus",
+ "questEggOctopusMountText": "Octopus",
"questEggOctopusAdjective": "een gladde",
- "questEggSeahorseText": "Zeepaardje",
- "questEggSeahorseMountText": "Zeepaardje",
+ "questEggSeahorseText": "Zeepaardjong",
+ "questEggSeahorseMountText": "Zeepaard",
"questEggSeahorseAdjective": "een eersteklas",
- "questEggParrotText": "Papegaai",
+ "questEggParrotText": "Papegaaikuiken",
"questEggParrotMountText": "Papegaai",
- "questEggParrotAdjective": "een veelkleurige",
- "questEggRoosterText": "Haan",
+ "questEggParrotAdjective": "een veelkleurig(e)",
+ "questEggRoosterText": "Kuiken",
"questEggRoosterMountText": "Haan",
- "questEggRoosterAdjective": "een paraderende",
- "questEggSpiderText": "Spin",
+ "questEggRoosterAdjective": "een paraderend(e)",
+ "questEggSpiderText": "Baby-Spin",
"questEggSpiderMountText": "Spin",
"questEggSpiderAdjective": "een kunstzinnige",
- "questEggOwlText": "Uil",
+ "questEggOwlText": "Baby-Uil",
"questEggOwlMountText": "Uil",
"questEggOwlAdjective": "een wijze",
- "questEggPenguinText": "Pinguïn",
+ "questEggPenguinText": "Pinguïnkuiken",
"questEggPenguinMountText": "Pinguïn",
- "questEggPenguinAdjective": "een spitsvondige",
- "questEggTRexText": "Tyrannosaurus",
+ "questEggPenguinAdjective": "een spitsvondig(e)",
+ "questEggTRexText": "Baby-Tyrannosaurus",
"questEggTRexMountText": "Tyrannosaurus",
"questEggTRexAdjective": "een kortarmige",
- "questEggRockText": "Rots",
+ "questEggRockText": "Kiezel",
"questEggRockMountText": "Rots",
- "questEggRockAdjective": "een levende",
+ "questEggRockAdjective": "een levendige",
"questEggBunnyText": "Konijn",
"questEggBunnyMountText": "Konijn",
"questEggBunnyAdjective": "een knuffelig",
diff --git a/website/common/locales/nl/contrib.json b/website/common/locales/nl/contrib.json
index 7a2bfe9076..a2bde9f7ba 100644
--- a/website/common/locales/nl/contrib.json
+++ b/website/common/locales/nl/contrib.json
@@ -1,5 +1,5 @@
{
- "playerTiersDesc": "De gekleurde gebruikersnamen die je in de chat ziet, staan voor de bijdrager's rang van die persoon. Des te hoger de rang, des te meer de persoon aan habitica heeft bijgedragen door kunst, codes, de gemeenschap en meer!",
+ "playerTiersDesc": "De gekleurde gebruikersnamen die je in de chat ziet, staan voor de bijdragersrang van die persoon. Des te hoger de rang, des te meer de persoon aan Habitica heeft bijgedragen door kunst, codes, de gemeenschap en meer!",
"tier1": "Rang 1 (Vriend)",
"tier2": "Rang 2 (Vriend)",
"tier3": "Rang 3 (Elite)",
@@ -11,14 +11,14 @@
"tierStaff": "Personeel (Heroïsch)",
"tierNPC": "NPC",
"friend": "Vriend",
- "friendFirst": "Wanneer je eerste set inzendingen wordt geïmplementeerd, ontvang je de Habitica-bijdragersbadge. In de herbergchat zal je naam trots tonen dat je een bijdrager bent. Als beloning voor je werk ontvang je daarnaast 3 edelstenen.",
- "friendSecond": "Wanneer je tweede set inzendingen wordt geïmplementeerd, wordt het kristallen harnas beschikbaar gesteld voor aankoop in de beloningswinkel. Als beloning voor het voortzetten van je werk ontvang je daarnaast 3 edelstenen.",
+ "friendFirst": "Wanneer je eerste set inzendingen wordt geïmplementeerd, ontvang je de Habitica-bijdragersbadge. In de herbergchat zal je naam trots tonen dat je een bijdrager bent. Als beloning voor je werk ontvang je daarnaast 3 Edelstenen.",
+ "friendSecond": "Wanneer je tweede set inzendingen wordt geïmplementeerd, wordt het Kristallen Harnas beschikbaar gesteld voor aankoop in de Beloningswinkel. Als beloning voor het voortzetten van je werk ontvang je daarnaast 3 Edelstenen.",
"elite": "Elite",
- "eliteThird": "Wanneer je derde set inzendingen wordt geïmplementeerd, wordt de kristallen helm beschikbaar gesteld voor aankoop in de beloningswinkel. Als beloning voor het voortzetten van je werk ontvang je daarnaast 3 edelstenen.",
+ "eliteThird": "Wanneer je derde set inzendingen wordt geïmplementeerd, wordt de Kristallen Helm beschikbaar gesteld voor aankoop in de Beloningswinkel. Als beloning voor het voortzetten van je werk ontvang je daarnaast 3 Edelstenen.",
"eliteFourth": "Wanneer je vierde set inzendingen wordt geïmplementeerd, wordt het kristallen zwaard beschikbaar gesteld voor aankoop in de beloningswinkel. Als een beloning voor het voortzetten van je werk ontvang je daarnaast 4 edelstenen.",
"champion": "Kampioen",
"championFifth": "Wanneer je vijfde set inzendingen wordt geïmplementeerd, wordt het kristallen schild beschikbaar gesteld voor aankoop in de beloningswinkel. Als beloning voor het voortzetten van je werk ontvang je daarnaast 4 edelstenen.",
- "championSixth": "Wanneer je zesde set inzendingen wordt geïmplementeerd ontvang je een Hydra als huisdier. Ook krijg je 4 edelstenen.",
+ "championSixth": "Wanneer je zesde set inzendingen wordt geïmplementeerd ontvang je een Hydra als Huisdier. Ook krijg je 4 Edelstenen.",
"legendary": "Legendarisch",
"legSeventh": "Wanneer je zevende set inzendingen wordt geïmplementeerd, ontvang je 4 edelstenen en word je lid van het geëerde Bijdragersgilde. Je wordt ingewijd in wat zich achter de schermen van Habitica zoal allemaal afspeelt! Voor verdere bijdragen krijg je er geen bijdragersniveaus bij, maar kun je nog steeds edelstenen en titels verdienen.",
"moderator": "Beheerder",
@@ -34,7 +34,7 @@
"contribName": "Bijdrager",
"contribText": "Heeft bijgedragen aan Habitica, zijnde via code, kunst, muziek, schrijfwerk, of andere methodes. Om meer te leren, sluit je aan bij de gilde van Ambitieuze Legendes!",
"readMore": "Lees meer",
- "kickstartName": "Kickstarter-helper - $<%= key %> rang",
+ "kickstartName": "Kickstarter-Backer - $<%= key %> rang",
"kickstartText": "Heeft het Kickstarterproject gesteund",
"helped": "Heeft Habitica helpen groeien",
"helpedText1": "Heeft Habitica geholpen te groeien door het invullen van",
@@ -46,7 +46,7 @@
"hallContributors": "Hal der Bijdragers",
"hallPatrons": "Hal der Weldoeners",
"rewardUser": "Gebruiker belonen",
- "UUID": "Gebruikers ID",
+ "UUID": "Gebruikers-ID",
"loadUser": "Gebruiker laden",
"noAdminAccess": "Je hebt geen beheerderstoegang.",
"userNotFound": "Gebruiker niet gevonden.",
@@ -58,17 +58,17 @@
"admin": "Beheerder",
"notGems": "is in Amerikaanse dollars ($), niet in edelstenen. Dus als dit getal 1 is, betekent het 4 Edelstenen. Gebruik deze optie alleen als je handmatig edelstenen aan gebruikers geeft, niet als je bijdragersrangen toekent. Bijdragersrangen geven automatisch edelstenen.",
"gamemaster": "Spelmeester (medewerker/beheerder)",
- "backerTier": "Ondersteunersniveau",
+ "backerTier": "Backers-Rang",
"balance": "Balans",
"tierPop": "Klik op de niveaulabels voor details.",
"playerTiers": "Spelersrangen",
"tier": "Rang",
- "visitHeroes": "Bezoek de Hal der Helden (bijdragers en helpers)",
+ "visitHeroes": "Bezoek de Hal der Helden (bijdragers en backers)",
"conLearn": "Leer meer over bijdragersbeloningen",
"conLearnHow": "Lees meer over hoe je kunt bijdragen aan Habitica",
"conLearnURL": "https://habitica.fandom.com/nl/wiki/Bijdragen_aan_Habitica",
"conRewardsURL": "http://habitica.fandom.com/wiki/Contributor_Rewards",
- "surveysSingle": "Heeft Habitica geholpen om te groeien, of door een enquête in te vullen of door mee te helpen met een grote speltest. Bedankt!",
+ "surveysSingle": "Heeft Habitica geholpen om te groeien door een enquête in te vullen of door mee te helpen met een grote speltest. Bedankt!",
"surveysMultiple": "Heeft Habitica helpen groeien op <%= count %> momenten, door een enquête in te vullen of door mee te helpen met een grote test. Bedankt!",
"currentSurvey": "Huidige enquête",
"surveyWhen": "De badge zal eind maart worden uitgereikt, wanneer de enquêtes van alle deelnemers zijn verwerkt.",
diff --git a/website/common/locales/nl/death.json b/website/common/locales/nl/death.json
index b0661d7765..8e74b85f84 100644
--- a/website/common/locales/nl/death.json
+++ b/website/common/locales/nl/death.json
@@ -1,17 +1,17 @@
{
- "lostAllHealth": "Je gezondheidspunten zijn op!",
+ "lostAllHealth": "Je Gezondheidspunten zijn op!",
"dontDespair": "Wanhoop niet!",
- "deathPenaltyDetails": "Je hebt een niveau, je goud en een stuk van je uitrusting verloren, maar je kunt het allemaal terug krijgen door hard te werken! Succes! Je zult het fantastisch doen.",
- "refillHealthTryAgain": "Vul je gezondheid aan en probeer het opnieuw",
+ "deathPenaltyDetails": "Je hebt een Niveau, je Goud en een stuk Uitrusting verloren, maar je kunt het allemaal terug krijgen door hard te werken! Succes! Je zult het fantastisch doen.",
+ "refillHealthTryAgain": "Vul je Gezondheid aan en probeer het opnieuw",
"dyingOftenTips": "Gebeurt dit vaker? Hier zijn een paar tips!",
- "losingHealthWarning": "Voorzichtig - je gezondheid gaat achteruit!",
- "losingHealthWarning2": "Laat je gezondheid niet to nul zakken! Als dat gebeurt verlies je een niveau, je goud, en een stuk uitrusting.",
- "toRegainHealth": "Om gezondheid te herstellen:",
- "lowHealthTips1": "Ga een niveau omhoog om volledig te genezen!",
- "lowHealthTips2": "Koop een gezonheidsdrankje van de beloning kolom om 15 gezondheidspunten te herstellen.",
- "losingHealthQuickly": "Snel gezondheid aan het verliezen?",
- "lowHealthTips3": "Onvolledige dagelijkse taken doen je 's nachts pijn, dus wees voorzichtig en voeg in eerste instantie niet te veel toe!",
- "lowHealthTips4": "Als een dagelijkse taak op een bepaalde dag niet gedaan hoeft te worden kun je die dag uitschakelen door op het potlood te klikken.",
+ "losingHealthWarning": "Voorzichtig - Je Gezondheid gaat achteruit!",
+ "losingHealthWarning2": "Laat je Gezondheid niet tot nul zakken! Als dat gebeurt verlies je een Niveau, je Goud, en een stuk uitrusting.",
+ "toRegainHealth": "Om Gezondheid te herstellen:",
+ "lowHealthTips1": "Ga een Niveau omhoog om volledig te genezen!",
+ "lowHealthTips2": "Koop een Gezonheidsdrankje van de Beloningen-kolom om 15 Gezondheidspunten te herstellen.",
+ "losingHealthQuickly": "Snel Gezondheid aan het verliezen?",
+ "lowHealthTips3": "Onvoltooide Dagtaken doen je 's nachts pijn, dus wees voorzichtig en voeg er in eerste instantie niet te veel toe!",
+ "lowHealthTips4": "Als een Dagtaak op een bepaalde dag niet gedaan hoeft te worden, kun je die dag uitschakelen door op het potlood-icoon te klikken.",
"goodLuck": "Veel plezier!",
"cannotRevive": "Je kan niet herrijzen als je niet dood bent"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/nl/defaulttasks.json b/website/common/locales/nl/defaulttasks.json
index 9116f3780a..e74843173c 100644
--- a/website/common/locales/nl/defaulttasks.json
+++ b/website/common/locales/nl/defaulttasks.json
@@ -1,21 +1,21 @@
{
"defaultHabit1Text": "Productief werk (klik op het potlood om aan te passen)",
- "defaultHabit1Notes": "Voorbeelden van goede gewoontes: + Eet wat groente + 15 minutes productief werk",
+ "defaultHabit1Notes": "Voorbeelden van goede Gewoontes: + Eet wat groente + 15 minuten productief werk",
"defaultHabit2Text": "Junkfood eten (klik op het potlood om aan te passen)",
- "defaultHabit2Notes": "Voorbeelden van slechte gewoontes: - Roken - Uitstelgedrag",
+ "defaultHabit2Notes": "Voorbeelden van slechte Gewoontes: - Roken - Uitstelgedrag",
"defaultHabit3Text": "De trap/lift nemen (klik op het potlood om aan te passen)",
- "defaultHabit3Notes": "Voorbeelden van goede en slechte gewoontes: +/- Neem de trap/lift +/- Drink water/frisdrank",
+ "defaultHabit3Notes": "Voorbeelden van goede en slechte Gewoontes: +/- Neem de trap/lift +/- Drink water/frisdrank",
"defaultHabit4Text": "Voeg een taak toe aan Habitica",
- "defaultHabit4Notes": "Een gewoonte, dagelijkse taak of to-do",
- "defaultHabit5Text": "Tik hier om dit in een slechte gewoonte te veranderen die je wilt afleren",
+ "defaultHabit4Notes": "Een Gewoonte, Dagtaak of To-Do",
+ "defaultHabit5Text": "Tik hier om dit in een slechte Gewoonte te veranderen die je wilt afleren",
"defaultHabit5Notes": "Of verwijder van het bewerkscherm",
"defaultDaily1Text": "Gebruik Habitica om je taken bij te houden",
"defaultTodo1Text": "Aanmelden bij Habitica (Streep mij af!)",
- "defaultTodoNotes": "Je kunt deze to-do afmaken, bijwerken of verwijderen.",
+ "defaultTodoNotes": "Je kunt deze To-Do afstrepen, bijwerken of verwijderen.",
"defaultTodo2Text": "Voltooi Justins taakrondleiding",
"defaultTodo2Notes": "Bezoek alle secties van de onderste balk",
"defaultReward1Text": "15 minuten pauze",
- "defaultReward1Notes": "Zelfgekozen beloningen bestaan in vele vormen. Sommige mensen wachten met het kijken van hun favoriete serie totdat ze het goud hebben om er voor te betalen.",
+ "defaultReward1Notes": "Zelfgekozen beloningen bestaan in vele vormen. Sommige mensen wachten met het kijken van hun favoriete serie totdat ze het Goud hebben om er voor te betalen.",
"defaultReward2Text": "Beloon jezelf",
"defaultReward2Notes": "Kijk tv, speel een spel, eet iets lekkers, aan jou de keuze!",
"defaultTag1": "Werk",
@@ -24,5 +24,18 @@
"defaultTag4": "School",
"defaultTag5": "Teams",
"defaultTag6": "Klusjes",
- "defaultTag7": "Creativiteit"
-}
\ No newline at end of file
+ "defaultTag7": "Creativiteit",
+ "healthDailyNotes": "Tik aan om dingen te veranderen!",
+ "healthDailyText": "Flossen",
+ "healthHabit": "Eet gezond/ongezond voedsel",
+ "exerciseTodoNotes": "Tik aan om een checklist toe te voegen!",
+ "exerciseTodoText": "Stel een trainingsschema in",
+ "exerciseDailyNotes": "Tik aan om je schema te kiezen en oefeningen te specificeren!",
+ "exerciseDailyText": "Strekken >> Dagelijkse trainingsroutine",
+ "exerciseHabit": "10 min cardio >> + 10 minuten cardio",
+ "workTodoProjectNotes": "Tik aan om de naam van je huidige project te specificeren + stel een einddatum!",
+ "workTodoProject": "Werkproject >> Voltooi werkproject",
+ "workDailyImportantTaskNotes": "Tik aan om je belangrijkste taak te specificeren",
+ "workDailyImportantTask": "Belangrijkste taak >> Gewerkt aan de belangrijkste taak van vandaag",
+ "workHabitMail": "Verwerk je e-mail"
+}
diff --git a/website/common/locales/nl/gear.json b/website/common/locales/nl/gear.json
index 25b7db54d9..8777075e75 100644
--- a/website/common/locales/nl/gear.json
+++ b/website/common/locales/nl/gear.json
@@ -3,14 +3,14 @@
"equipmentType": "Type",
"klass": "Klasse",
"groupBy": "Groeperen volgens <%= type %>",
- "classBonus": "(Dit voorwerp komt overeen met je klasse, waardoor het een extra 1.5 Stat vermenigvuldiging geeft.)",
+ "classBonus": "(Dit voorwerp hoort bij je klasse, dus krijgt het een 1.5 Stat vermenigvuldiging.)",
"classArmor": "Klasse Pantser",
"featuredset": "Uitgelichte Set <%= name %>",
"mysterySets": "Mysterie Sets",
"gearNotOwned": "Je bezit dit voorwerp niet.",
"noGearItemsOfType": "Je bezit geen van deze.",
- "noGearItemsOfClass": "Je bezit al je klasse uitrustingen al! Er zullen meer worden uitgebracht tijdens Grand Gala's en rondom de zonnewendes en dag- en nachteveningen.",
- "classLockedItem": "Dit voorwerp is alleen beschikbaar voor een specifieke klasse. Vanaf level 10 of hoger kan je veranderen van klasse via Gebruiker icoon > Instellingen > Karakterbouw!",
+ "noGearItemsOfClass": "Je bezit al je klasse-uitrustingen al! Er zullen er meer worden uitgebracht tijdens de Grote Gala's, rondom de zonnewendes en dag- en nachteveningen.",
+ "classLockedItem": "Dit voorwerp is alleen beschikbaar voor een specifieke klasse. Vanaf level 10 of hoger kun je veranderen van klasse via Gebruikers-icoon > Instellingen > Karakterbouw!",
"tierLockedItem": "Dit voorwerp is alleen beschikbaar zodra je alle andere voorwerpen in de reeks hebt aangeschaft. Werk je weg omhoog!",
"sortByType": "Type",
"sortByPrice": "Prijs",
@@ -25,75 +25,75 @@
"weaponWarrior0Text": "Trainingszwaard",
"weaponWarrior0Notes": "Oefenwapen. Verleent geen voordelen.",
"weaponWarrior1Text": "Zwaard",
- "weaponWarrior1Notes": "Normaal soldatenzwaard. Verhoogt kracht met <%= str %>.",
+ "weaponWarrior1Notes": "Normaal soldatenzwaard. Verhoogt Kracht met <%= str %>.",
"weaponWarrior2Text": "Bijl",
"weaponWarrior2Notes": "Dubbelzijdig hakwapen. Verhoogt Kracht met <%= str %>",
"weaponWarrior3Text": "Morgenster",
- "weaponWarrior3Notes": "Zware knuppel met wrede punten. Verhoogt kracht met <%= str %>.",
+ "weaponWarrior3Notes": "Zware knuppel met wrede punten. Verhoogt Kracht met <%= str %>.",
"weaponWarrior4Text": "Saffieren Zwaard",
- "weaponWarrior4Notes": "Zwaard met een snede die bijt als de noorderwind. Verhoogt kracht met <%= str %>.",
+ "weaponWarrior4Notes": "Zwaard met een snede die bijt als de noordenwind. Verhoogt Kracht met <%= str %>.",
"weaponWarrior5Text": "Robijnen Zwaard",
- "weaponWarrior5Notes": "Wapen waarin de gloed van het smeden nooit vervaagt. Verhoogt kracht met <%= str %>.",
+ "weaponWarrior5Notes": "Wapen waarin de gloed van het smeden nooit vervaagt. Verhoogt Kracht met <%= str %>.",
"weaponWarrior6Text": "Gouden Zwaard",
- "weaponWarrior6Notes": "Verdelger van de schepselen der duisternis. Verhoogt kracht met <%= str %>.",
+ "weaponWarrior6Notes": "Verdelger van de schepselen der duisternis. Verhoogt Kracht met <%= str %>.",
"weaponRogue0Text": "Dolk",
"weaponRogue0Notes": "Het basiswapen van de dief. Verleent geen voordelen.",
"weaponRogue1Text": "Kort Zwaard",
- "weaponRogue1Notes": "Licht zwaard dat goed te verbergen is. Verhoogt kracht met <%= str %>.",
+ "weaponRogue1Notes": "Licht zwaard dat goed te verbergen is. Verhoogt Kracht met <%= str %>.",
"weaponRogue2Text": "Kromzwaard",
- "weaponRogue2Notes": "Scherp zwaard om snel een moordslag mee toe te brengen. Verhoogt kracht met <%= str %>.",
- "weaponRogue3Text": "Hakmes",
- "weaponRogue3Notes": "Opvallend wildernismes, zowel survivalgereedschap als een wapen. Verhoogt kracht met <%= str %>.",
+ "weaponRogue2Notes": "Scherp zwaard om snel een dodelijke slag mee toe te brengen. Verhoogt Kracht met <%= str %>.",
+ "weaponRogue3Text": "Kukri",
+ "weaponRogue3Notes": "Opvallend wildernismes, zowel survivalgereedschap als een wapen. Verhoogt Kracht met <%= str %>.",
"weaponRogue4Text": "Nunchucks",
- "weaponRogue4Notes": "Zware wapenstokken die rondgezwaaid worden aan een stuk ketting. Verhoogt kracht met <%= str %>.",
- "weaponRogue5Text": "Ninjatō-do",
- "weaponRogue5Notes": "Zo gestroomlijnd en dodelijk als de ninja zelf. Verhoogt kracht met <%= str %>.",
+ "weaponRogue4Notes": "Zware wapenstokken die rondgezwaaid worden aan een stuk ketting. Verhoogt Kracht met <%= str %>.",
+ "weaponRogue5Text": "Ninjatō-Do",
+ "weaponRogue5Notes": "Zo gestroomlijnd en dodelijk als de ninja zelf. Verhoogt Kracht met <%= str %>.",
"weaponRogue6Text": "Haakzwaard",
- "weaponRogue6Notes": "Complex wapen om tegenstanders te verstrikken en te ontwapenen. Verhoogt kracht met <%= str %>.",
+ "weaponRogue6Notes": "Complex wapen om tegenstanders te verstrikken en te ontwapenen. Verhoogt Kracht met <%= str %>.",
"weaponWizard0Text": "Staf van de Leerling",
"weaponWizard0Notes": "Oefenstaf. Verleent geen voordelen.",
"weaponWizard1Text": "Houten staf",
- "weaponWizard1Notes": "Basiswerktuig uit gesneden hout. Verhoogt intelligentie met <%= int %> en perceptie met <%= per %>.",
- "weaponWizard2Text": "Staf met juwelen",
- "weaponWizard2Notes": "Concentreert kracht door middel van een edelsteen. Verhoogt intelligentie met <%= int %> en perceptie met <%= per %>.",
+ "weaponWizard1Notes": "Basisinstrument uit gesneden hout. Verhoogt Intelligentie met <%= int %> en Perceptie met <%= per %>.",
+ "weaponWizard2Text": "Staf vol Juwelen",
+ "weaponWizard2Notes": "Concentreert kracht door middel van een edelsteen. Verhoogt Intelligentie met <%= int %> en Perceptie met <%= per %>.",
"weaponWizard3Text": "IJzeren Staf",
- "weaponWizard3Notes": "Bedekt met metalen platen om warmte, kou en bliksem te geleiden. Verhoogt intelligentie met <%= int %> en perceptie met <%= per %>.",
+ "weaponWizard3Notes": "Bedekt met metalen platen om warmte, kou en bliksem te geleiden. Verhoogt Intelligentie met <%= int %> en Perceptie met <%= per %>.",
"weaponWizard4Text": "Messing Staf",
- "weaponWizard4Notes": "Heel erg zwaar en net zo krachtig. Verhoogt intelligentie met <%= int %> en perceptie met <%= per %>.",
+ "weaponWizard4Notes": "Heel erg zwaar en net zo krachtig. Verhoogt Intelligentie met <%= int %> en Perceptie met <%= per %>.",
"weaponWizard5Text": "Staf van de Aartsmagiër",
- "weaponWizard5Notes": "Helpt bij het weven van zelfs de meest complexe spreuken. Verhoogt intelligentie met <%= int %> en perceptie met <%= per %>.",
+ "weaponWizard5Notes": "Helpt bij het weven van zelfs de meest complexe spreuken. Verhoogt Intelligentie met <%= int %> en Perceptie met <%= per %>.",
"weaponWizard6Text": "Gouden Staf",
- "weaponWizard6Notes": "Gemaakt van orichalcum, alchemistengoud, machtig en zeldzaam. Verhoogt intelligentie met <%= int %> en perceptie met <%= per %>.",
+ "weaponWizard6Notes": "Gemaakt van orichalcum, het alchemistengoud, machtig en zeldzaam. Verhoogt Intelligentie met <%= int %> en Perceptie met <%= per %>.",
"weaponHealer0Text": "Beginnersstaf",
"weaponHealer0Notes": "Voor helers in opleiding. Verleent geen voordelen.",
- "weaponHealer1Text": "Volgelingenstaf",
- "weaponHealer1Notes": "Vervaardigd tijdens de inwijding van een heler. Verhoogt intelligentie met <%= int %>.",
+ "weaponHealer1Text": "Staf van de Altaardienaar",
+ "weaponHealer1Notes": "Vervaardigd tijdens de inwijding van de heler. Verhoogt Intelligentie met <%= int %>.",
"weaponHealer2Text": "Staf van Kwarts",
- "weaponHealer2Notes": "Bekroond met een edelsteen die genezende eigenschappen heeft. Verhoogt intelligentie met <%= int %>.",
+ "weaponHealer2Notes": "Bekroond met een edelsteen met genezende eigenschappen. Verhoogt Intelligentie met <%= int %>.",
"weaponHealer3Text": "Staf van Amethist",
- "weaponHealer3Notes": "Zuivert gif met een enkele aanraking. Verhoogt intelligentie met <%= int %>.",
+ "weaponHealer3Notes": "Zuivert gif met een enkele aanraking. Verhoogt Intelligentie met <%= int %>.",
"weaponHealer4Text": "Geneesherenstaf",
- "weaponHealer4Notes": "Niet alleen een insigne, maar ook een helerswerktuig. Verhoogt intelligentie met <%= int %>.",
- "weaponHealer5Text": "Koninklijke scepter",
- "weaponHealer5Notes": "Geschikt om de hand van een monarch te sieren, of van de persoon die de rechterhand van de monarch is. Verhoogt intelligentie met <%= int %>.",
+ "weaponHealer4Notes": "Niet alleen een insigne, maar ook een helerswerktuig. Verhoogt Intelligentie met <%= int %>.",
+ "weaponHealer5Text": "Koninklijke Scepter",
+ "weaponHealer5Notes": "Geschikt om de hand van een monarch te sieren, of van de persoon die de rechterhand van de monarch is. Verhoogt Intelligentie met <%= int %>.",
"weaponHealer6Text": "Gouden Scepter",
- "weaponHealer6Notes": "Verzacht de pijn van eenieder die er naar kijkt. Verhoogt intelligentie met <%= int %>.",
+ "weaponHealer6Notes": "Verzacht de pijn van eenieder die er naar kijkt. Verhoogt Intelligentie met <%= int %>.",
"weaponSpecial0Text": "Mes der Duistere Zielen",
- "weaponSpecial0Notes": "Verzwelgt de levenskracht van vijanden om kracht te geven aan zijn venijnige slagen. Verhoogt kracht met <%= str %>.",
+ "weaponSpecial0Notes": "Verzwelgt de levenskracht van vijanden om kracht te geven aan zijn venijnige slagen. Verhoogt Kracht met <%= str %>.",
"weaponSpecial1Text": "Kristallen Zwaard",
"weaponSpecial1Notes": "Haar sprankelende facetten vertellen het verhaal van een held. Verhoogt alle Stats met <%= attrs %>.",
"weaponSpecial2Text": "Stephen Webers Schacht van de Draak",
- "weaponSpecial2Notes": "Voel de kracht van de draak opwellen van binnenuit! Verhoogt kracht en perceptie elk met <%= attrs %>.",
+ "weaponSpecial2Notes": "Voel de kracht van de draak opwellen van binnenuit! Verhoogt Kracht en Perceptie elk met <%= attrs %>.",
"weaponSpecial3Text": "Mustaines Mijlpaalmalende Morgenster",
- "weaponSpecial3Notes": "Meetings, monsters, malaise: makkie! Meppen maar! Verhoogt kracht, intelligentie, en lichaam elk met <%= attrs %>.",
+ "weaponSpecial3Notes": "Meetings, monsters, malaise: makkie! Meppen maar! Verhoogt Kracht, Intelligentie, en Lichaam elk met <%= attrs %>.",
"weaponSpecialCriticalText": "Kritieke Hamer van Fout-Vernietiging",
- "weaponSpecialCriticalNotes": "Deze kampioen heeft een grote GitHub-vijand gedood waaraan vele krijgers ten onder gingen. Uitgerust met de botten van Bug, deelt deze hamer een machtige, kritieke klap uit. Verhoogt kracht en perceptie elk met <%= attrs %>.",
+ "weaponSpecialCriticalNotes": "Deze kampioen heeft een grote GitHub-vijand gedood waaraan vele krijgers ten onder gingen. Uitgerust met de botten van Bug, deelt deze hamer een machtige, kritieke klap uit. Verhoogt Kracht en Perceptie elk met <%= attrs %>.",
"weaponSpecialTakeThisText": "'Take This'-zwaard",
"weaponSpecialTakeThisNotes": "Dit zwaard is verdiend door het meedoen aan een gesponsorde Uitdaging gecreëerd door Take This. Gefeliciteerd! Verhoogt alle Stats met <%= attrs %>.",
"weaponSpecialTridentOfCrashingTidesText": "Drietand van Verpletterend Getij",
- "weaponSpecialTridentOfCrashingTidesNotes": "Geeft je de mogelijkheid om vissen te gebieden en je taken machtige steken toe te brengen. Verhoogt intelligentie met <%= int %>.",
- "weaponSpecialTaskwoodsLanternText": "Takenboslantaarn",
- "weaponSpecialTaskwoodsLanternNotes": "Bij het begin van de tijd gegeven aan de beschermersgeest van de Takenbos Boomgaarden. Deze lantaarn kan het donkerste duister oplichten en krachtige spreuken weven. Verhoogt perceptie en intelligentie elk met <%= attrs %>.",
+ "weaponSpecialTridentOfCrashingTidesNotes": "Geeft je de mogelijkheid om vissen te gebieden en je taken machtige steken toe te brengen. Verhoogt Intelligentie met <%= int %>.",
+ "weaponSpecialTaskwoodsLanternText": "Takenbos-Lantaarn",
+ "weaponSpecialTaskwoodsLanternNotes": "Bij het begin van de tijd gegeven aan de beschermersgeest van de Takenbos-Boomgaarden. Deze lantaarn kan het donkerste duister oplichten en krachtige spreuken weven. Verhoogt Perceptie en Intelligentie elk met <%= attrs %>.",
"weaponSpecialBardInstrumentText": "Bardenluit",
"weaponSpecialBardInstrumentNotes": "Tokkel een vrolijk deuntje op deze magische luit! Verhoogt intelligentie en perceptie elk met <%= attrs %>.",
"weaponSpecialLunarScytheText": "Maanzeis",
diff --git a/website/common/locales/nl/inventory.json b/website/common/locales/nl/inventory.json
index 37f5124ae8..e4babee240 100644
--- a/website/common/locales/nl/inventory.json
+++ b/website/common/locales/nl/inventory.json
@@ -1,8 +1,8 @@
{
- "noItemsAvailableForType": "Je hebt geen <%= type %>.",
- "foodItemType": "Voedsel",
- "eggsItemType": "Eieren",
- "hatchingPotionsItemType": "Uitbroeddrankjes",
- "specialItemType": "Speciale artikelen",
- "lockedItem": "Vergrendeld artikel"
+ "noItemsAvailableForType": "Je hebt geen <%= type %>.",
+ "foodItemType": "Voedsel",
+ "eggsItemType": "Eieren",
+ "hatchingPotionsItemType": "Uitbroeddrank",
+ "specialItemType": "Speciale artikelen",
+ "lockedItem": "Vergrendeld artikel"
}
diff --git a/website/common/locales/nl/loadingscreentips.json b/website/common/locales/nl/loadingscreentips.json
index 226c576c04..e4dfe04d71 100644
--- a/website/common/locales/nl/loadingscreentips.json
+++ b/website/common/locales/nl/loadingscreentips.json
@@ -1,38 +1,38 @@
{
- "tipTitle": "Tip #<%= tipNumber %>",
- "tip1": "Houd je taken overal in de gaten met de Habitica mobiele app. ",
- "tip2": "Klik op de uitrusting voor een preview, of gebruik de uitrusting direct door op de ster in de linkerbovenhoek te klikken!",
- "tip3": "Gebruik emoticons om snel onderscheid te maken tussen je taken.",
- "tip4": "Gebruik het # teken voor de naam van een taak om het heel groot te maken!",
- "tip5": "Het is het beste om versterkende vaardigheden in de ochtend te gebruiken zodat ze langer blijven bestaan.",
- "tip6": "Ga met je muis over de taak en klik op de stipjes om de gevorderde taakinstellingen te beheren, zoals de mogelijkheid om je taak naar de top/ het einde van je lijst te verplaatsen.",
- "tip7": "Sommige achtergronden passen perfect bij elkaar als gezelschapsleden dezelfde achtergrond gebruiken. Voorbeeld: Bergenmeer, Pagodas, Rollende Heuvels.",
- "tip8": "Stuur een persoonlijk bericht naar iemand door te klikken op het envelopje bij zijn of haar naam in de chat!",
- "tip9": "Gebruik filters en de zoekfunctie bij Inventarissen, Winkels, Gilden en Uitdagingen om snel te vinden wat je zoekt.",
- "tip10": "Je kan edelstenen winnen door deel te nemen aan uitdagingen. Dagelijks worden er nieuwe toegevoegd!",
- "tip11": "Meer dan vier gezelschapsleden hebben vergroot verantwoording!",
- "tip12": "Voeg checklists toe aan jouw To-Do's om jouw beloningen te vermenigvuldigen!",
- "tip13": "Klik op \"Labels\" op de takenpagina om onbeheerbare taken zeer beheerbaar te maken!",
- "tip14": "Je kan titels of inspirerende uitspraken zonder (+/-) toevoegen aan je lijst van gewoontes .",
- "tip15": "Voltooi alle Masterclasser Queestes om meer over de geheime leer van Habitica te leren.",
- "tip16": "Klik op de link naar de Data Weergave Tool in de footer voor waardevolle inzichten in jouw vooruitgang.",
- "tip17": "Gebruik de mobiele app’s om herinneringen in te stellen voor je taken.",
- "tip18": "Gewoontes die positief of negatief zijn, \"vervagen\" en worden weer langzaam geel.",
- "tip19": "Stimuleer jouw Intelligentie Statistiek om meer ervaring te verwerven wanneer je een taak voltooid.",
- "tip20": "Verhoog je perceptie-eigenschap om meer vondsten en goud te krijgen.",
- "tip21": "Verhoog je kracht-eigenschap om meer schade toe te brengen aan eindbazen en meer voltreffers te krijgen.",
- "tip22": "Verhoog je lichaam-eigenschap om de schade van onvoltooide dagelijkse taken te minderen.",
- "tip23": "Bereik level 100 om de Bol der Hergeboorte gratis vrij te spelen en start een nieuw avontuur!",
- "tip24": "Heb je een vraag? Raadpleeg het Habitica Help Gilde!",
- "tip25": "De vier seizoengebonden Grote Gala's beginnen dicht bij de zonnewendes en de nachteveningen.",
- "tip26": "Je kan naar een Gezelschap zoeken of Gezelschapsgenoten vinden in de 'Party Wanted' Gilde!",
- "tip27": "Gisteren een dagelijkse taak gedaan, maar vergeten het te controleren? Maak je geen zorgen! Met Registreer Activiteit van Gisteren, heb je de kans om te registreren wat je deed voordat je je nieuwe dag begint.",
- "tip28": "Stel een Handmatig Dagritme in via Gebruikersicon > Instellingen om te controleren wanneer jouw dag opnieuw begint.",
- "tip29": "Voltooi al je Dagelijkse Taken om een Perfecte Dag Versterken te krijgen die jouw Statistieken bevordert!",
- "tip30": "Je kan mensen uitnodigen voor gilden, niet enkel voor groepen. ",
- "tip31": "Bekijk de voorgemaakte lijsten in de \"Library of Tasks and Challenges\" gilde voor voorbeeldtaken.",
- "tip32": "Veel code, kunst and schrijfkunst van Habitica is gemaakt door vrijwillige bijdragers! Neem een kijkje in de Aspiring Legends Gilde voor hulp.",
- "tip33": "Neem een kijkje in de \"Prikbord\" gilde voor nieuws over gilden, uitdagingen en andere door spelers gemaakte evenementen - en kondig die van jou daar aan!",
- "tip34": "Herevalueer jouw taken af en toe om zeker te zijn dat ze actueel zijn!",
- "tip35": "Gebruikers die lid zijn van een Groepsplan krijgen de mogelijkheid taken op te dragen aan andere gebruikers die lid zijn van die groep voor extra taakbeheer en verantwoording."
+ "tipTitle": "Tip #<%= tipNumber %>",
+ "tip1": "Houd je taken overal in de gaten met de Habitica mobiele apps.",
+ "tip2": "Klik op de uitrusting voor een preview, of gebruik de uitrusting direct door op de ster in de linkerbovenhoek te klikken!",
+ "tip3": "Gebruik emoticons om snel onderscheid te maken tussen je taken.",
+ "tip4": "Gebruik het #-teken voor de naam van een taak om deze heel groot te maken!",
+ "tip5": "Het is het beste om versterkende vaardigheden in de ochtend te gebruiken, zodat ze langer blijven bestaan.",
+ "tip6": "Ga met je muis over de taak en klik op de punten om de uitgebreide taakinstellingen te beheren, zoals de mogelijkheid om je taak naar de top/ het einde van je lijst te verplaatsen.",
+ "tip7": "Sommige achtergronden passen perfect bij elkaar als gezelschapsleden dezelfde achtergrond gebruiken. Voorbeeld: Bergenmeer, Pagodas, Rollende Heuvels.",
+ "tip8": "Stuur een persoonlijk bericht naar iemand door te klikken op hun naam en dan op het envelopje bovenin hun profiel!",
+ "tip9": "Gebruik filters en de zoekfunctie bij Inventarissen, Winkels, Gilden en Uitdagingen om snel te vinden wat je zoekt.",
+ "tip10": "Je kunt Edelstenen winnen door deel te nemen aan Uitdagingen. Dagelijks worden er nieuwe toegevoegd!",
+ "tip11": "Meer dan vier Gezelschapsleden hebben vergroot de verantwoordelijkheid!",
+ "tip12": "Voeg checklists toe aan jouw To-Do's om je beloningen te vermenigvuldigen!",
+ "tip13": "Klik op \"Labels\" op de takenpagina om ellenlange takenlijsten beheersbaar te maken!",
+ "tip14": "Je kan titels of inspirerende uitspraken toevoegen aan je lijst van Gewoontes zonder (+/-) .",
+ "tip15": "Voltooi alle Masterclasser Queestes om meer over de geheime leer van Habitica te leren.",
+ "tip16": "Klik op de link naar de Data Display Tool (Gegevens weergeven) in de footer voor waardevolle inzichten in jouw vooruitgang.",
+ "tip17": "Gebruik de mobiele apps om herinneringen in te stellen voor je taken.",
+ "tip18": "Gewoontes die positief of negatief zijn, \"vervagen\" en worden weer langzaam geel.",
+ "tip19": "Stimuleer jouw Intelligentie-Eigenschap om meer ervaring te verwerven wanneer je een taak voltooid.",
+ "tip20": "Verhoog je Perceptie-Eigenschap om meer vondsten en Goud te krijgen.",
+ "tip21": "Verhoog je Kracht-Eigenschap om meer schade toe te brengen aan eindbazen en meer voltreffers te krijgen.",
+ "tip22": "Verhoog je Lichaam-Eigenschap om de schade van onvoltooide Dagtaken te minderen.",
+ "tip23": "Bereik level 100 om de Bol der Hergeboorte gratis vrij te spelen en start een nieuw avontuur!",
+ "tip24": "Heb je een vraag? Raadpleeg het Habitica Help Gilde!",
+ "tip25": "De vier seizoengebonden Grote Gala's beginnen dicht bij de zonnewendes en de nachteveningen.",
+ "tip26": "Je kunt naar een Gezelschap zoeken of Gezelschapsgenoten vinden in de 'Party Wanted' Gilde!",
+ "tip27": "Gisteren een Dagtaak gedaan, maar vergeten het af te vinken? Maak je geen zorgen! Met Registreer Activiteit van Gisteren, heb je de kans om te registreren wat je deed voordat je je nieuwe dag begint.",
+ "tip28": "Stel Aangepaste Dagstart in via Gebruikersicoon > Instellingen om te bepalen wanneer jouw dag opnieuw begint.",
+ "tip29": "Voltooi al je Dagtaken om een Perfecte-Dag Versterking te krijgen die jouw Eigenschappen bevordert!",
+ "tip30": "Je kunt mensen ook uitnodigen voor Gilden, niet alleen voor groepen.",
+ "tip31": "Bekijk de voorgemaakte lijsten in het \"Library of Tasks and Challenges\"-Gilde voor voorbeeldtaken.",
+ "tip32": "Veel code, kunst en schrijfkunst van Habitica is gemaakt door vrijwillige bijdragers! Neem een kijkje in het \"Aspiring Legends\"-Gilde voor hulp.",
+ "tip33": "Neem een kijkje in het \"Prikbord\"-Gilde voor nieuws over Gilden, uitdagingen en andere door spelers gemaakte evenementen - en kondig die van jou daar aan!",
+ "tip34": "Herevalueer jouw taken af en toe om zeker te zijn dat ze actueel zijn!",
+ "tip35": "Gebruikers die lid zijn van een Groepsplan krijgen de mogelijkheid taken op te dragen aan andere gebruikers die lid zijn van die groep voor extra taakbeheer en verantwoordelijkheid."
}
diff --git a/website/common/locales/nl/loginincentives.json b/website/common/locales/nl/loginincentives.json
index 5dc03b3edd..a122715f21 100644
--- a/website/common/locales/nl/loginincentives.json
+++ b/website/common/locales/nl/loginincentives.json
@@ -1,29 +1,29 @@
{
- "unlockedReward": "Je hebt <%= reward %> ontvangen",
- "earnedRewardForDevotion": "Je hebt <%= reward %> verdiend, omdat je vastberaden bent om je leven te verbeteren.",
- "nextRewardUnlocksIn": "Check-ins tot je volgende prijs: <%= numberOfCheckinsLeft %>",
- "awesome": "Super!",
- "totalCount": "<%= count %> totaal aantal",
- "countLeft": "Check-ins tot je volgende beloning: <%= count %>",
- "incentivesDescription": "Als het gaat om gewoontes opbouwen is consistentie noodzakelijk. Elke dag die je incheckt zul je dichter bij een prijs komen.",
- "totalCheckins": "<%= count %> check-ins",
- "checkinEarned": "Je check-in-teller is omhoog gegaan!",
- "unlockedCheckInReward": "Je hebt een check-in-prijs ontgrendeld!",
- "totalCheckinsTitle": "Totaal aantal check-ins",
- "checkinProgressTitle": "Vooruitgang tot volgende",
- "incentiveBackgroundsUnlockedWithCheckins": "Deze achtergronden zullen worden ontgrendeld door dagelijkse check-ins.",
- "checkinReceivedAllRewardsMessage": "Je hebt alle beschikbare check-inprijzen ontvangen! Gefeliciteerd!",
- "oneOfAllPetEggs": "één van elk standaard huisdier-ei",
- "twoOfAllPetEggs": "twee van elk standaard huisdier-ei",
- "threeOfAllPetEggs": "drie van elk standaard huisdier-ei",
- "oneOfAllHatchingPotions": "één van elke standaard uitbroeddrank",
- "threeOfEachFood": "drie van elk standaard huisdiervoedsel",
- "fourOfEachFood": "vier van elk standaard huisdiervoedsel",
- "twoSaddles": "twee zadels",
- "threeSaddles": "drie zadels",
- "incentiveAchievement": "de Koninklijk Loyaal prestatie",
- "royallyLoyal": "Koninklijk Loyaal",
- "royallyLoyalText": "Deze gebruiker heeft meer dan 500 keer ingecheckt en heeft elke check-inprijs verdiend!",
- "checkInRewards": "Check-inprijzen",
- "backloggedCheckInRewards": "Je hebt check-inprijzen ontvangen! Ga naar je boedel en uitrusting om je nieuwe voorwerpen te zien."
+ "unlockedReward": "Je hebt <%= reward %> ontvangen",
+ "earnedRewardForDevotion": "Je hebt <%= reward %> verdiend, omdat je vastberaden bent je leven te verbeteren.",
+ "nextRewardUnlocksIn": "Check-ins tot je volgende prijs: <%= numberOfCheckinsLeft %>",
+ "awesome": "Super!",
+ "totalCount": "<%= count %> totaal aantal",
+ "countLeft": "Check-ins tot je volgende beloning: <%= count %>",
+ "incentivesDescription": "Als het gaat om gewoontes opbouwen is consistentie noodzakelijk. Elke dag die je incheckt zul je dichter bij een prijs komen.",
+ "totalCheckins": "<%= count %> check-ins",
+ "checkinEarned": "Je check-in-teller is omhoog gegaan!",
+ "unlockedCheckInReward": "Je hebt een check-in-prijs ontgrendeld!",
+ "totalCheckinsTitle": "Totaal aantal check-ins",
+ "checkinProgressTitle": "Vooruitgang tot volgende",
+ "incentiveBackgroundsUnlockedWithCheckins": "Deze achtergronden zullen worden ontgrendeld door dagelijkse check-ins.",
+ "checkinReceivedAllRewardsMessage": "Je hebt alle beschikbare check-inprijzen ontvangen! Gefeliciteerd!",
+ "oneOfAllPetEggs": "één van elk standaard Huisdier-Ei",
+ "twoOfAllPetEggs": "twee van elk standaard Huisdier-Ei",
+ "threeOfAllPetEggs": "drie van elk standaard Huisdier-Ei",
+ "oneOfAllHatchingPotions": "één van elke standaard Uitbroeddrank",
+ "threeOfEachFood": "drie van elk standaard Huisdiervoedsel",
+ "fourOfEachFood": "vier van elk standaard Huisdiervoedsel",
+ "twoSaddles": "twee Zadels",
+ "threeSaddles": "drie Zadels",
+ "incentiveAchievement": "de Koninklijk Loyaal prestatie",
+ "royallyLoyal": "Koninklijk Loyaal",
+ "royallyLoyalText": "Deze gebruiker heeft meer dan 500 keer ingecheckt en heeft elke check-in-prijs verdiend!",
+ "checkInRewards": "Check-in-prijzen",
+ "backloggedCheckInRewards": "Je hebt check-in-prijzen ontvangen! Ga naar je Boedel en Uitrusting om je nieuwe voorwerpen te zien."
}
diff --git a/website/common/locales/nl/maintenance.json b/website/common/locales/nl/maintenance.json
index 1ad36f3e01..7d9a2a8378 100644
--- a/website/common/locales/nl/maintenance.json
+++ b/website/common/locales/nl/maintenance.json
@@ -1,34 +1,33 @@
{
- "habiticaBackSoon": "Maak je geen zorgen, Habitica is snel weer terug!",
- "importantMaintenance": "We zijn bezig met belangrijke onderhoud waarvan we schatten dat het tot 10 uur s'nachts Pacifische Tijd (5:00 UTC) zal duren.",
- "maintenance": "Onderhoud",
- "maintenanceMoreInfo": "Wil je meer informatie over het onderhoud? <%= linkStart %>Bekijk onze infopagina<%= linkEnd %>.",
- "noDamageKeepStreaks": "Je zult GEEN schade ontvangen of series verliezen!",
- "thanksForPatience": "Bedankt voor je geduld!",
- "twitterMaintenanceUpdates": "Bekijk voor de meest recente updates onze Twitter, waar we alle statusinformatie plaatsen.",
- "veteranPetAward": "Aan het einde zul je een Veteraan dier ontvangen!",
-
- "maintenanceInfoTitle": "Informatie over het aankomende onderhoud van Habitica",
- "maintenanceInfoWhat": "Wat gebeurt er?",
- "maintenanceInfoWhatText": "Op 21 Mei, zal Habitica uit de lucht zijn wegens onderhoud voor bijna de gehele dag. Je zult geen schade aan ondervinden of schade krijgen in het weekend, zelfs als je niet kan inloggen voor het afvinken van je Dagelijkse taken. We zullen zo hard mogelijk werken om zo snel mogelijk weer in de lucht te zijn en plaatsen updates op ons Twitter account. Aan het einde van het onderhoud, ontvangt iedereen als bedankje voor het geduld een zeldzaam dier!",
- "maintenanceInfoWhy": "Waarom gebeurt dit?",
- "maintenanceInfoWhyText": "De afgelopen maanden hebben wij achter de schermen hard nagedacht over Habitica. We hebben vooral de API herschreven. Hoewel dit op het eerste gezicht niet heel anders lijkt te zijn, is er in werkelijkheid heel veel vernieuwd. Dit geeft ons veel meer flexibiliteit wanneer we in de toekomst andere functies willen toevoegen, en het leidt tot verbeterde prestaties!",
- "maintenanceInfoTechDetails": "Wil je meer details over de technische kant van het proces? Bezoek The Forge, ons dev blog.",
- "maintenanceInfoMore": "Meer informatie",
- "maintenanceInfoAccountChanges": "Wat voor veranderingen zie ik in mijn account nadat de herschrijving voltooid is?",
- "maintenanceInfoAccountChangesText": "In het begin zullen er geen noemenswaardige veranderingen zijn behalve prestatieverbetering voor functies zoals uitdagingen. Als je veranderingen opmerkt die er niet zou moeten zijn, stuur dan een e-mail naar <%= hrefTechAssistanceEmail %> en we zullen het voor je uitzoeken!",
- "maintenanceInfoAddFeatures": "Wat voor functies zal dit Habitica in staat stellen om toe te voegen?",
- "maintenanceInfoAddFeaturesText": "Alles herschrijven zal ons in staat stellen om een verbeterde chat in de gilden te plaatsen, plannen op te stellen voor organisaties en families, additionele productiviteitsfuncties als maandelijkse taken en de mogelijkheid om taken van gisteren af te vinken. Dit zijn allemaal op zichzelf staande functies, dus het kost tijd om ze te bouwen, maar het was onmogelijk om eraan te beginnen voordat alles herschreven is.",
- "maintenanceInfoHowLong": "Hoe lang zal dit onderhoud duren?",
- "maintenanceInfoHowLongText": "We moeten taken en data verhuizen voor alle 1,3 miljoen Habitica gebruikers -- geen makkelijke taak! We verwachten dat het plaats zal vinden tussen 13:00 uur Pacifische tijd (20:00 uur UTC) en 22:00 uur Pacifische tijd (5:00 uur UTC). Wees gerust, we doen er alles aan om het zo snel mogelijk te volbrengen. Je kunt updates volgen op onze Twitter.",
- "maintenanceInfoStatsAffected": "Wat voor effect heeft dit op mijn dagelijkse taken, series, versterkingen en queesten?",
- "maintenanceInfoStatsAffectedText1": "Je zult GEEN enkele schade of verlies van streak krijgen dit weekend, je dag zal normaal resetten. Dagelijkse taken die je afgevinkt hebt zullen weer on-aangevinkt worden, buffs gereset etc. Als je in een verzamelqueeste zit, zul je nog steeds voorwerpen vinden. Als je in een eindbazengevecht zit, zul jij nog steeds schade toebrengen aan de baas maar de baas niet aan jou. (Ook monsters hebben immers een pauze nodig!)",
- "maintenanceInfoStatsAffectedText2": "Na lang nagedacht te hebben, heeft het team geconcludeerd dat dit het eerlijkste was omdat de meeste gebruikers niet in staat waren om hun Dagelijkse taken af te vinken tijdens het onderhoud. Het spijt ons als dit ongemakken heeft veroorzaakt.",
- "maintenanceInfoSeeTasks": "Wat als ik mijn takenlijst moet zien?",
- "maintenanceInfoSeeTasksText": "Als je al weet dat je zaterdag je takenlijst moet bekijken voor jezelf, dan raden wij het je aan om een screenshot te nemen van je takenlijst, vóór het onderhoud, zodat je daarop kunt kijken. ",
- "maintenanceInfoRarePet": "Wat voor zeldzaam dier zal ik ontvangen?",
- "maintenanceInfoRarePetText": "Aan het einde van het onderhoud, ontvangt iedereen als bedankje voor het geduld een Veteraandier! Als je nooit een Veteraandier hebt ontvangen zul je nu een Veteraanwolf krijgen. Als je al een Veteraanwolf hebt zul je een Veteraantijger krijgen. Als je beide al hebt dan zul je een nooit eerder gezien Veteraandier ontvangen. Na het Onderhoud kan het enkele uren duren voordat je het dier kunt zien, maar wees niet ongerust: iedereen krijgt er een.",
- "maintenanceInfoWho": "Wie heeft er gewerkt aan dit enorme project?",
- "maintenanceInfoWhoText": "We zijn blij dat je het vraagt! Het is gelukt door onze fantastische contributor Paglias, met veel hulp van Blade, TheHollidayInn, SabreCat, Victor Pudeyev, TheUnknown en Alys.",
- "maintenanceInfoTesting": "De nieuwe versie is ontelbaar keer getest door een stel geweldige open-source vrijwilligers. Bedankt, we konden dit niet doen zonder jullie!"
+ "habiticaBackSoon": "Maak je geen zorgen, Habitica is snel weer terug!",
+ "importantMaintenance": "We zijn bezig met belangrijk onderhoud waarvan we schatten dat het tot 10 uur s'nachts Pacifische Tijd (5:00 UTC) zal duren.",
+ "maintenance": "Onderhoud",
+ "maintenanceMoreInfo": "Wil je meer informatie over het onderhoud? <%= linkStart %>Bekijk onze infopagina<%= linkEnd %>.",
+ "noDamageKeepStreaks": "Je zult GEEN schade ontvangen of series verliezen!",
+ "thanksForPatience": "Bedankt voor je geduld!",
+ "twitterMaintenanceUpdates": "Bekijk voor de meest recente updates onze Twitter, waar we alle statusinformatie zullen plaatsen.",
+ "veteranPetAward": "Aan het einde zul je een Veteraan-Huisdier ontvangen!",
+ "maintenanceInfoTitle": "Informatie over het Aankomende Onderhoud van Habitica",
+ "maintenanceInfoWhat": "Wat gebeurt er?",
+ "maintenanceInfoWhatText": "Op 21 Mei, zal Habitica uit de lucht zijn wegens onderhoud voor bijna de gehele dag. Je zult geen schade aan ondervinden of schade krijgen in het weekend, zelfs als je niet kan inloggen voor het afvinken van je Dagtaken. We zullen zo hard mogelijk werken om zo snel mogelijk weer in de lucht te zijn en plaatsen updates op onze Twitter-account. Aan het einde van het onderhoud ontvangt iedereen als bedankje voor het geduld een zeldzaam dier!",
+ "maintenanceInfoWhy": "Waarom gebeurt dit?",
+ "maintenanceInfoWhyText": "De afgelopen maanden hebben wij achter de schermen hard nagedacht over Habitica. We hebben vooral de API herschreven. Hoewel dit op het eerste gezicht niet heel anders lijkt te zijn, is er in werkelijkheid heel veel vernieuwd. Dit geeft ons veel meer flexibiliteit wanneer we in de toekomst andere functies willen toevoegen, en het leidt tot verbeterde prestaties!",
+ "maintenanceInfoTechDetails": "Wil je meer details over de technische kant van het proces? Bezoek The Forge, ons dev blog.",
+ "maintenanceInfoMore": "Meer informatie",
+ "maintenanceInfoAccountChanges": "Wat voor veranderingen zie ik in mijn account nadat de herschrijving voltooid is?",
+ "maintenanceInfoAccountChangesText": "In het begin zullen er geen noemenswaardige veranderingen zijn behalve prestatieverbetering voor functies zoals uitdagingen. Als je veranderingen opmerkt die er niet zou moeten zijn, stuur dan een e-mail naar <%= hrefTechAssistanceEmail %> en we zullen het voor je uitzoeken!",
+ "maintenanceInfoAddFeatures": "Wat voor functies zal dit Habitica in staat stellen toe te voegen?",
+ "maintenanceInfoAddFeaturesText": "Alles herschrijven zal ons in staat stellen om een verbeterde chat in de gilden te plaatsen, plannen op te stellen voor organisaties en families, additionele productiviteitsfuncties als maandelijkse taken en de mogelijkheid om taken van gisteren af te vinken. Dit zijn allemaal op zichzelf staande functies, dus het kost tijd om ze te bouwen, maar het was onmogelijk om eraan te beginnen voordat alles herschreven is.",
+ "maintenanceInfoHowLong": "Hoe lang zal dit onderhoud duren?",
+ "maintenanceInfoHowLongText": "We moeten taken en data verhuizen voor alle 1,3 miljoen Habitica gebruikers -- geen makkelijke taak! We verwachten dat het plaats zal vinden tussen 13:00 uur Pacifische tijd (20:00 uur UTC) en 22:00 uur Pacifische tijd (5:00 uur UTC). Wees gerust, we doen er alles aan om het zo snel mogelijk te volbrengen. Je kunt updates volgen op onze Twitter.",
+ "maintenanceInfoStatsAffected": "Wat voor effect heeft dit op mijn Dagtaken, Series, Versterkingen en Queesten?",
+ "maintenanceInfoStatsAffectedText1": "Je zult GEEN enkele schade of verlies van streak krijgen dit weekend, je dag zal normaal resetten. Dagelijkse taken die je afgevinkt hebt zullen weer on-aangevinkt worden, buffs gereset etc. Als je in een verzamelqueeste zit, zul je nog steeds voorwerpen vinden. Als je in een eindbazengevecht zit, zul jij nog steeds schade toebrengen aan de baas maar de baas niet aan jou. (Ook monsters hebben immers een pauze nodig!)",
+ "maintenanceInfoStatsAffectedText2": "Na lang nagedacht te hebben, heeft het team geconcludeerd dat dit het eerlijkste was omdat de meeste gebruikers niet in staat waren om hun Dagelijkse taken af te vinken tijdens het onderhoud. Het spijt ons als dit ongemakken heeft veroorzaakt.",
+ "maintenanceInfoSeeTasks": "Wat als ik mijn takenlijst moet zien?",
+ "maintenanceInfoSeeTasksText": "Als je al weet dat je zaterdag je takenlijst moet bekijken voor jezelf, dan raden wij het je aan om een screenshot te nemen van je takenlijst, vóór het onderhoud, zodat je daarop kunt kijken. ",
+ "maintenanceInfoRarePet": "Wat voor zeldzaam dier zal ik ontvangen?",
+ "maintenanceInfoRarePetText": "Aan het einde van het onderhoud, ontvangt iedereen als bedankje voor het geduld een Veteraandier! Als je nooit een Veteraandier hebt ontvangen zul je nu een Veteraanwolf krijgen. Als je al een Veteraanwolf hebt zul je een Veteraantijger krijgen. Als je beide al hebt dan zul je een nooit eerder gezien Veteraandier ontvangen. Na het Onderhoud kan het enkele uren duren voordat je het dier kunt zien, maar wees niet ongerust: iedereen krijgt er een.",
+ "maintenanceInfoWho": "Wie heeft er gewerkt aan dit enorme project?",
+ "maintenanceInfoWhoText": "We zijn blij dat je het vraagt! Het is gelukt door onze fantastische contributor Paglias, met veel hulp van Blade, TheHollidayInn, SabreCat, Victor Pudeyev, TheUnknown en Alys.",
+ "maintenanceInfoTesting": "De nieuwe versie is ontelbaar keer getest door een stel geweldige open-source vrijwilligers. Bedankt, we konden dit niet doen zonder jullie!"
}
diff --git a/website/common/locales/nl/merch.json b/website/common/locales/nl/merch.json
index 39e5936b03..4b7267b9f1 100644
--- a/website/common/locales/nl/merch.json
+++ b/website/common/locales/nl/merch.json
@@ -1,20 +1,14 @@
{
- "merch" : "Merchandise",
- "merchandiseDescription": "Op zoek naar t-shirts, mokken of stickers om je Habitica-trots te laten zien? Klik hier!",
-
- "merch-teespring-summary" : "Teespring is een platform dat het voor iedereen gemakkelijk maakt om de hoge-kwaliteitsproducten te maken en verkopen waar men van houdt, zonder kosten of risico's.",
- "merch-teespring-goto" : "Haal een Habitica T-shirt",
-
- "merch-teespring-mug-summary" : "Teespring is een platform dat het voor iedereen gemakkelijk maakt om de hoge-kwaliteitsproducten te maken en verkopen waar men van houdt, zonder kosten of risico's.",
- "merch-teespring-mug-goto" : "Haal een Habitica-mok",
-
- "merch-teespring-eu-summary" : "EUROPESE VERSIE : Teespring is een platform dat het voor iedereen gemakkelijk maakt om de hoge-kwaliteitsproducten te maken en verkopen waar men van houdt, zonder kosten of risico's.",
- "merch-teespring-eu-goto" : "Haal een Habitica T-shirt (EU)",
-
- "merch-teespring-mug-eu-summary" : "EUROPESE VERSIE : Teespring is een platform dat het voor iedereen gemakkelijk maakt om de hoge-kwaliteitsproducten te maken en verkopen waar men van houdt, zonder kosten of risico's.",
- "merch-teespring-mug-eu-goto" : "Haal een Habitica-mok (EU)",
-
- "merch-stickermule-summary" : "Plak de trotse Melior waar jij (of iemand anders) een herinnering nodig hebt voor zowel hedendaagse als toekomstige prestaties!",
- "merch-stickermule-goto" : "Haal Habitica stickers"
-
+ "merch": "Merchandise",
+ "merchandiseDescription": "Op zoek naar t-shirts, mokken of stickers om je Habitica-trots te laten zien? Klik hier!",
+ "merch-teespring-summary": "Teespring is een platform dat het voor iedereen gemakkelijk maakt om de hoge-kwaliteitsproducten te maken en verkopen waar men van houdt, zonder kosten of risico's.",
+ "merch-teespring-goto": "Haal een Habitica T-shirt",
+ "merch-teespring-mug-summary": "Teespring is een platform dat het voor iedereen gemakkelijk maakt om de hoge-kwaliteitsproducten te maken en verkopen waar men van houdt, zonder kosten of risico's.",
+ "merch-teespring-mug-goto": "Haal een Habitica-Mok",
+ "merch-teespring-eu-summary": "EUROPESE VERSIE : Teespring is een platform dat het voor iedereen gemakkelijk maakt om de hoge-kwaliteitsproducten te maken en verkopen waar men van houdt, zonder kosten of risico's.",
+ "merch-teespring-eu-goto": "Haal een Habitica T-shirt (EU)",
+ "merch-teespring-mug-eu-summary": "EUROPESE VERSIE : Teespring is een platform dat het voor iedereen gemakkelijk maakt om de hoge-kwaliteitsproducten te maken en verkopen waar men van houdt, zonder kosten of risico's.",
+ "merch-teespring-mug-eu-goto": "Haal een Habitica-mok (EU)",
+ "merch-stickermule-summary": "Plak de trotse Melior waar jij (of iemand anders) een herinnering nodig hebt aan hedendaagse of toekomstige prestaties!",
+ "merch-stickermule-goto": "Haal Habitica stickers"
}
diff --git a/website/common/locales/nl/npc.json b/website/common/locales/nl/npc.json
index 9ebd01fec3..d92d9a076f 100644
--- a/website/common/locales/nl/npc.json
+++ b/website/common/locales/nl/npc.json
@@ -1,31 +1,31 @@
{
"npc": "NPC",
"npcAchievementName": "<%= key %> NPC",
- "npcAchievementText": "Heeft het Kickstarter project op het hoogste niveau gesteund!",
+ "npcAchievementText": "Heeft het Kickstarter-project op het hoogste niveau gesteund!",
"welcomeTo": "Welkom bij",
"welcomeBack": "Welkom terug!",
"justin": "Justin",
- "justinIntroMessage1": "Hello there! You must be new here. My name is Justin, and I'll be your guide in Habitica.",
+ "justinIntroMessage1": "Hello! Je bent vast nieuw hier. Mijn naam is Justin en ik zal je gids zijn in Habitica.",
"justinIntroMessage2": "Om te beginnen moet je een avatar aanmaken.",
"justinIntroMessage3": "Geweldig! Waar zou je aan willen werken tijdens deze reis?",
- "justinIntroMessageUsername": "Before we begin, let’s figure out what to call you. Below you’ll find a display name and username I’ve generated for you. After you’ve picked a display name and username, we’ll get started by creating an avatar!",
- "justinIntroMessageAppearance": "So how would you like to look? Don’t worry, you can change this later.",
- "introTour": "Hier zijn we dan! Ik heb enkele Taken voor je ingevuld gebaseerd op je interesses, je kan dus meteen aan de slag. Klik op een Taak om deze te bewerken of voeg een nieuwe Taak toe die in je routine past!",
+ "justinIntroMessageUsername": "Voordat we beginnen, hoe moeten we je noemen? Hier onder vindt je een zichtbare naam en een gebruikersnaam die ik voor je heb gegenereerd. Als je deze namen hebt uitgekozen, zullen we beginnen door een avatar aan te maken.",
+ "justinIntroMessageAppearance": "Hoe wil je er uit zien? Maak je geen zorgen, je kunt dit later nog aanpassen.",
+ "introTour": "Hier zijn we dan! Ik heb enkele Taken voor je ingevuld gebaseerd op je interesses, je kunt dus meteen aan de slag. Klik op een Taak om deze te bewerken of voeg nieuwe Taken toe die in je routine passen!",
"prev": "Vorige",
"next": "Volgende",
"randomize": "Randomiseren",
"mattBoch": "Matt Boch",
- "mattShall": "Zal ik je je ros brengen, <%= name %>? Als je een huisdier genoeg voedsel hebt gevoerd om het in een rijdier te veranderen, zal het hier verschijnen. Klik op een rijdier om het te zadelen!",
+ "mattShall": "Zal ik je je ros brengen, <%= name %>? Als je een Huisdier genoeg voedsel hebt gevoerd om het in een Rijdier te veranderen, zal het hier verschijnen. Klik op een rijdier om het te zadelen!",
"mattBochText1": "Welkom in de Stal! Ik ben Matt, de Dierenmeester. Na niveau 3 kun je huisdieren laten uitkomen door middel van eieren en toverdranken. Als je een dier laat uitkomen in de markt, zal het hier verschijnen! Klik op de afbeelding van een huisdier om het aan je avatar toe te voegen! Voeder je huisdieren met het voedsel dat je vindt na niveau 3, zodat ze uitgroeien tot krachtige rijdieren.",
"welcomeToTavern": "Welkom bij de Herberg!",
- "sleepDescription": "Heb je een pauze nodig? Neem een kijkje in Daniel's café om enkele van de moeilijkere spel mechanismen te pauzeren:",
- "sleepBullet1": "Gemiste dagelijkse taken zullen je niet beschadigen",
+ "sleepDescription": "Heb je een pauze nodig? Neem een kijkje in Daniel's Herberg om enkele van de moeilijkere spelmechanismen te pauzeren:",
+ "sleepBullet1": "Gemiste Dagtaken zullen je niet beschadigen",
"sleepBullet2": "Taken zullen geen aantal opeenvolgingen verliezen of zullen geen kleur verliezen",
"sleepBullet3": "Bazen zullen geen schade aanbrengen voor je gemiste dagelijke taken",
"sleepBullet4": "Your boss damage or collection Quest items will stay pending until check-out",
"pauseDailies": "Pauzeer schade",
"unpauseDailies": "Schade hervatten",
- "staffAndModerators": "Staf en moderators",
+ "staffAndModerators": "Staf en Moderators",
"communityGuidelinesIntro": "Habitica probeerd om een verwelkomende omgeving te maken voor gebruikers van alle leeftijden, achtergronden, zeker in openbare ruimten zoals de Taverne. Als je een vraag hebt, raadpleeg dan alsjeblieft onze Maatschapij Richtlijnen.",
"acceptCommunityGuidelines": "Ik stem ermee in om me aan de gemeenschapsrichtlijnen te houden",
"daniel": "Daniël",
@@ -33,29 +33,29 @@
"danielText2": "Wees gewaarschuwd: Als je meedoet aan een queeste met een eindbaas, zal de eindbaas je nog steeds pijn doen voor de gemiste dagelijkse taken van je groepsgenoten, tenzij ze ook in de herberg verblijven! Je zult zelf ook geen schade toebrengen aan de eindbaas (of voorwerpen krijgen) totdat je de Herberg verlaat.",
"danielTextBroken": "Welkom in de herberg... Denk ik... Als je rust nodig hebt, zal ik je onderbrengen in de herberg... Zolang je ingecheckt bent, zullen je dagelijkse taken je geen pijn doen aan het eind van de dag... Je kunt ze nog wel afvinken... Als je daar de energie voor hebt...",
"danielText2Broken": "Oh... Als je meedoet aan een queeste met een eindbaas, zal de eindbaas je nog steeds pijn doen voor de gemiste dagelijkse taken van je groepsgenoten... Je zult zelf ook geen schade toebrengen aan de eindbaas (of voorwerpen vinden) totdat je de Herberg verlaat...",
- "worldBossEvent": "Wereldbaasevenement",
- "worldBossDescription": "Wereldbaasbeschrijving",
+ "worldBossEvent": "Wereldbaas-Evenement",
+ "worldBossDescription": "Wereldbaas-Beschrijving",
"alexander": "Alexander de Koopman",
- "welcomeMarket": "Welkom op de markt! Koop zeldzame eieren en drankjes! Verkoop je overschot! Gebruik nuttige diensten! Kom langs en bekijk zelf wat we voor je hebben.",
- "welcomeMarketMobile": "Welkom op de Markt! Koop moelijk-te-vinden eieren en dranken! Kom kijken wat we te bieden hebben.",
+ "welcomeMarket": "Welkom op de Markt! Koop zeldzame eieren en drankjes! Verkoop je overschotten! Gebruik nuttige diensten! Kom langs en bekijk zelf wat we voor je hebben.",
+ "welcomeMarketMobile": "Welkom op de Markt! Koop moelijk-te-vinden eieren en uitbroeddranken! Kom kijken wat we te bieden hebben.",
"displayItemForGold": "Wil je een <%= itemType %> verkopen?",
"displayEggForGold": "Wil je een <%= itemType %> Ei verkopen?",
- "displayPotionForGold": "Wil je een <%= itemType %> Toverdrank verkopen?",
+ "displayPotionForGold": "Wil je een <%= itemType %> Uitbroeddrank verkopen?",
"sellForGold": "Verkopen voor <%= gold %> Goud",
"howManyToSell": "Hoeveel wil je verkopen?",
"yourBalance": "Je balans",
"sell": "Verkopen",
"buyNow": "Koop nu",
- "sortByNumber": "Nummer",
- "featuredItems": "Uitgelichte items!",
+ "sortByNumber": "Aantal",
+ "featuredItems": "Uitgelichte voorwerpen!",
"hideLocked": "Verberg vergrendelde",
- "hidePinned": "Vastgepinde verbergen",
+ "hidePinned": "Verberg vastgezette",
"hideMissing": "Verberg missende",
- "amountExperience": "<%= amount %> ervaring",
- "amountGold": "<%= amount %> goud",
- "namedHatchingPotion": "<%= type %> uitbroeddrank",
- "buyGems": "Koop edelstenen",
- "purchaseGems": "Koop edelstenen",
+ "amountExperience": "<%= amount %> Ervaring",
+ "amountGold": "<%= amount %> Goud",
+ "namedHatchingPotion": "<%= type %> Uitbroeddrank",
+ "buyGems": "Koop Edelstenen",
+ "purchaseGems": "Koop Edelstenen",
"items": "Voorwerpen",
"AZ": "A-Z",
"sort": "Sorteren",
@@ -65,19 +65,19 @@
"quantity": "Hoeveelheid",
"cost": "Kosten",
"shops": "Winkels",
- "custom": "Aangepast",
+ "custom": "Aangepaste",
"wishlist": "Wensenlijst",
"wrongItemType": "Het voorwerptype \"<%= type %>\" is niet geldig.",
"wrongItemPath": "Het voorwerppad \"<%= path %>\" is niet geldig.",
"unpinnedItem": "Je hebt <%= item %> losgemaakt! Het zal niet langer in je beloningskolom verschijnen.",
- "cannotUnpinArmoirPotion": "Het gezondheidsdrankje en het Betoverd kabinet kunnen niet losgemaakt worden.",
+ "cannotUnpinArmoirPotion": "Het Gezondheidsdrankje en het Betoverd Kabinet kunnen niet losgemaakt worden.",
"purchasedItem": "Je hebt <%= itemName %> gekocht",
"ian": "Ian",
"ianText": "Welkom in de Queestenwinkel! Hier kun je queesten inzetten om samen met je vrienden monsters te verslaan. Neem een kijkje aan de rechterkant om te bekijken welke prachtige queesten te koop zijn!",
"ianTextMobile": "Kan ik je interesse opwekken in enkele van onze queeste rollen? Activeer ze om monsters te bevechten met je gezelschap!",
"ianBrokenText": "Welkom in de Queestenwinkel... Hier kun je queeste-perkamentrollen gebruiken om samen met je vrienden monsters te verslaan... Neem een kijkje aan de rechterkant om te bekijken welke prachtige queesten er te koop zijn...",
- "featuredQuests": "Uitgelichte queesten!",
- "cannotBuyItem": "Je kan dit voorwerp niet kopen.",
+ "featuredQuests": "Uitgelichte Queesten!",
+ "cannotBuyItem": "Je kunt dit voorwerp niet kopen.",
"mustPurchaseToSet": "Moet <%= val %> kopen om het op <%= key %> te zetten.",
"typeRequired": "Type is vereist",
"positiveAmountRequired": "Positieve hoeveelheid is vereist",
@@ -97,32 +97,32 @@
"newBaileyUpdate": "Nieuwe update van Bailey!",
"tellMeLater": "Een andere keer lezen",
"dismissAlert": "Boodschap verbergen",
- "donateText1": "Voegt 20 edelstenen toe aan je account. Edelstenen kunnen worden gebruikt om speciale digitale objecten te kopen, zoals shirts en kapsels.",
+ "donateText1": "Voegt 20 Edelstenen toe aan je account. Edelstenen kunnen worden gebruikt om speciale digitale objecten te kopen, zoals shirts en kapsels.",
"donateText2": "Steun Habitica",
"donateText3": "Habitica is een open-sourceproject dat afhankelijk is van onze gebruikers voor ondersteuning. Het geld dat jij uitgeeft aan edelstenen helpt ons om de servers te laten lopen, een kleine stafgroep medewerkers te onderhouden, nieuwe functies te ontwikkelen en onze vrijwillige programmeurs te prikkelen. Bedankt voor je gulheid!",
- "donationDesc": "20 edelstenen, donatie aan Habitica",
+ "donationDesc": "20 Edelstenen, donatie aan Habitica",
"payWithCard": "Betaal met creditcard",
"payNote": "Opmerking: PayPal doet er soms lang over om een betaling te verwerken. We raden je aan te betalen met een creditcard.",
"card": "CreditCard (met Stripe)",
"amazonInstructions": "Klik op de knop om te betalen via de Amazon Betaaldienst",
"paymentMethods": "Koop met",
- "paymentSuccessful": "Your payment was successful!",
- "paymentYouReceived": "You received:",
- "paymentYouSentGems": "You sent <%= name %>:",
- "paymentYouSentSubscription": "You sent <%= name %> a <%= months %>-months Habitica subscription.",
+ "paymentSuccessful": "Je betaling van succesvol!",
+ "paymentYouReceived": "Je ontving:",
+ "paymentYouSentGems": "Je verzond <%= name %>:",
+ "paymentYouSentSubscription": "Je verzond <%= name %> een <%= months %> maanden durend Habitica-abonnement.",
"paymentSubBilling": "Your subscription will be billed $<%= amount %> every <%= months %> months.",
"success": "Success!",
- "classGear": "Klassespecifieke uitrusting",
- "classGearText": "Gefeliciteerd met je gekozen klasse! Ik heb je nieuwe standaard wapen in je boedel gestopt. Neem hieronder een kijkje om het te dragen!",
+ "classGear": "Klassespecifieke Uitrusting",
+ "classGearText": "Gefeliciteerd met je gekozen klasse! Ik heb je nieuwe standaardwapen in je boedel gestopt. Neem hieronder een kijkje om het te dragen!",
"classStats": "These are your class's Stats; they affect the game-play. Each time you level up, you get one Point to allocate to a particular Stat. Hover over each Stat for more information.",
"autoAllocate": "Automatische verdeling",
"autoAllocateText": "If 'Automatic Allocation' is selected, your avatar gains Stats automatically based on your tasks' Stats, which you can find in TASK > Edit > Advanced Settings > Stat Allocation. Eg, if you hit the gym often, and your 'Gym' Daily is set to 'Strength', you'll gain Strength automatically.",
"spells": "Vaardigheden",
"spellsText": "Je kunt nu klassegerelateerde vaardigheden ontgrendelen. De eerste ontdek je in niveau 11. Je mana wordt met 10 punten per dag gevuld, plus 1 punt per vervulde Taak.",
"skillsTitle": "Vaardigheden",
- "toDo": "To-do",
+ "toDo": "To-Do",
"moreClass": "Voor meer informatie over het klassesysteem, zie: Wikia.",
- "tourWelcome": "Welkom in Habitica! Dit is jouw To-do-lijst. Vink een taak af om verder te gaan!",
+ "tourWelcome": "Welkom in Habitica! Dit is jouw To-Do-lijst. Vink een taak af om verder te gaan!",
"tourExp": "Goed gedaan! Door het afvinken van een taak krijg je ervaring en goud!",
"tourDailies": "Deze kolom in voor dagelijkse taken. Om door te gaan kun je een taak toevoegen die je elke dag zou moeten doen. Voorbeelden van dagelijkse taken: je bed opmaken, flossen, je werk e-mail checken",
"tourCron": "Schitterend! Je dagelijkse taken zullen elke dag gereset worden.",
diff --git a/website/common/locales/nl/overview.json b/website/common/locales/nl/overview.json
index e0fc563be3..cb97add5d6 100644
--- a/website/common/locales/nl/overview.json
+++ b/website/common/locales/nl/overview.json
@@ -1,10 +1,10 @@
{
"needTips": "Tips nodig om van start te gaan? Hier is een korte speluitleg!",
"step1": "Stap 1: Voer taken in",
- "webStep1Text": "Habitica is niets zonder doelen in het echte leven, dus voeg enkele taken toe. Je kunt later nog meer taken toevoegen zodra je er meer bedenkt!
\n* **[Taken](https://habitica.fandom.com/nl/wiki/To-do's) opstellen:**\n\nVoeg taken die je eenmalig of zelden doet één voor één toe aan de Takenkolom. Je kunt op het potlood klikken om ze te bewerken en om afvinklijsten, een einddatum en meer toe te voegen!
\n* **[Dagelijkse taken](https://habitica.fandom.com/nl/wiki/Dagelijkse_taken) opstellen:**\n\nVoeg activiteiten die je dagelijks of op een bepaalde dag van de week moet doen toe aan de Dagelijkse taken kolom. Klik op het potloodicoon van de taak om te kiezen op welke dag(en) van de week de taak moet worden gedaan. Je kunt de taak ook zo aanpassen dat deze zichzelf herhaalt om de zoveel dagen, bijvoorbeeld om de drie dagen.
\n* **[Gewoonten](https://habitica.fandom.com/nl/wiki/Gewoontes) opstellen:**\n\nVoeg gewoonten die je wilt ontwikkelen toe in de Gewoontenkolom. Je kan de gewoonte aanpassen en er een enkel goede gewoonte of een enkel slechte gewoonte van maken.
\n* **[Beloningen](https://habitica.fandom.com/nl/wiki/Beloningen) opstellen:**\n\nNaast de beloningen die je in het spel worden aangeboden, kun je activiteiten of lekkernijen die je als motivatie wilt gebruiken in de Beloningenkolom toevoegen. Het is belangrijk om jezelf een pauze te gunnen!
Als je inspiratie nodig hebt om taken toe te voegen, neem dan kijkje op de wikipagina's over [Voorbeelden van gewoonten](https://habitica.fandom.com/nl/wiki/Voorbeeldgewoontes), [Voorbeelden van dagelijkse taken](https://habitica.fandom.com/nl/wiki/Voorbeelden_van_dagelijkse_taken), [Voorbeelden van Taken](https://habitica.fandom.com/nl/wiki/Voorbeeld_To-do's) en [Voorbeelden van aangepaste beloningen](https://habitica.fandom.com/nl/wiki/Voorbeelden_van_aangepaste_beloningen).",
- "step2": "Stap 2: krijg punten door dingen te doen in het echte leven",
- "webStep2Text": "Begin nu met het tackelen van je doelen op de lijst! Als je taken voltooit en ze afstreept in Habitica krijg je [ervaringspunten](https://habitica.fandom.com/nl/wiki/Ervaringspunten), die je helpen om niveaus omhoog te gaan, en [goud](https://habitica.fandom.com/nl/wiki/Goud), waarmee je beloningen kunt kopen. Als je terugvalt in slechte gewoontes of dagelijkse taken mist, zul je [levenspunten](https://habitica.fandom.com/nl/wiki/Levenspunten) verliezen. Op deze manier zijn de ervaringsbalk en gezondheidsbalk een leuke indicator van je vooruitgang ten opzichte van je doelen. Je zult zien dat je echte leven verbetert naarmate je personage in het spel vooruit gaat.",
- "step3": "Stap 3: bewerk en verken Habitica",
+ "webStep1Text": "Habitica is niets zonder doelen in het echte leven, dus voeg enkele taken toe. Je kunt later nog meer taken toevoegen zodra je er meer bedenkt!
\n* **[Taken](https://habitica.fandom.com/nl/wiki/To-do's) opstellen:**\n\nVoeg taken die je eenmalig of zelden doet één voor één toe aan de Taken-kolom. Je kunt op het potlood klikken om ze te bewerken en om afvinklijsten, een einddatum en meer toe te voegen!
\n* **[Dagelijkse taken](https://habitica.fandom.com/nl/wiki/Dagelijkse_taken) opstellen:**\n\nVoeg activiteiten die je dagelijks of op een bepaalde dag van de week moet doen toe aan de Dagtaken-kolom. Klik op het potloodicoon van de taak om te kiezen op welke dag(en) van de week de taak moet worden gedaan. Je kunt de taak ook zo aanpassen dat deze zichzelf herhaalt om de zoveel dagen, bijvoorbeeld om de drie dagen.
\n* **[Gewoonten](https://habitica.fandom.com/nl/wiki/Gewoontes) opstellen:**\n\nVoeg gewoonten die je wilt ontwikkelen toe in de Gewoontenkolom. Je kan de gewoonte aanpassen en er een enkel goede gewoonte of een enkel slechte gewoonte van maken.
\n* **[Beloningen](https://habitica.fandom.com/nl/wiki/Beloningen) opstellen:**\n\nNaast de beloningen die je in het spel worden aangeboden, kun je activiteiten of lekkernijen die je als motivatie wilt gebruiken in de Beloningenkolom toevoegen. Het is belangrijk om jezelf een pauze te gunnen!
Als je inspiratie nodig hebt om taken toe te voegen, neem dan kijkje op de wikipagina's over [Voorbeelden van gewoonten](https://habitica.fandom.com/nl/wiki/Voorbeeldgewoontes), [Voorbeelden van dagelijkse taken](https://habitica.fandom.com/nl/wiki/Voorbeelden_van_dagelijkse_taken), [Voorbeelden van Taken](https://habitica.fandom.com/nl/wiki/Voorbeeld_To-do's) en [Voorbeelden van aangepaste beloningen](https://habitica.fandom.com/nl/wiki/Voorbeelden_van_aangepaste_beloningen).",
+ "step2": "Stap 2: Verdien punten door dingen te doen in het echte leven",
+ "webStep2Text": "Begin nu met het tackelen van de doelen op je lijst! Als je taken voltooit en ze afstreept in Habitica krijg je [Ervaringspunten](https://habitica.fandom.com/nl/wiki/Ervaringspunten), die je helpen om niveaus omhoog te gaan, en [Goud](https://habitica.fandom.com/nl/wiki/Goud), waarmee je beloningen kunt kopen. Als je terugvalt in slechte gewoontes of dagelijkse taken mist, zul je [Levenspunten](https://habitica.fandom.com/nl/wiki/Levenspunten) verliezen. Op deze manier zijn de ervaringsbalk en gezondheidsbalk een leuke indicator van je vooruitgang ten opzichte van je doelen. Je zult zien dat je echte leven verbetert naarmate je personage in het spel vooruit gaat.",
+ "step3": "Stap 3: Bewerk en verken Habitica",
"webStep3Text": "Zodra je wat meer vertrouwd bent met de basis, kun je nog meer uit Habitica halen met deze vernuftige functies: \n * Organiseer je taken met [labels](http://habitica.fandom.com/wiki/Tags) (wijzig de taak om labels toe te voegen).\n * Pas je [avatar] aan (http://habitica.fandom.com/wiki/Avatar) door te klikken op het gebruikersicoon in de hoek rechtsboven. \n * Koop je [Uitrusting](http://habitica.fandom.com/wiki/Equipment) in de Beloningensectie of in de [Winkels](<%= shopUrl %>), en verander het via [Boedel> Uitrusting](<%= equipUrl %>).\n * Bouw een band op met andere gebruikers in de [Herberg](http://habitica.fandom.com/wiki/Tavern).\n * Vanaf niveau 3, broedt [Huisdieren] uit (http://habitica.fandom.com/wiki/Pets) door [Eieren] (http://habitica.fandom.com/wiki/Eggs) en [Uitbroeddrankjes](http://habitica.fandom.com/wiki/Hatching_Potions) te verzamelen. [Voed](http://habitica.fandom.com/wiki/Food) ze om ze te laten uitgroeien tot [Rijdieren](http://habitica.fandom.com/wiki/Mounts).\n * Op niveau 10: Kies een specifieke [Klasse](http://habitica.fandom.com/wiki/Class_System) en gebruik de klassespecifieke [vaardigheden](http://habitica.fandom.com/wiki/Skills) (levels 11 to 14).\n * Vorm een gezelschap met je vrienden (door te klikken op [Gezelschap](<%= partyUrl %>) in de navigatiebalk) en zo verantwoording af te leggen en om Queesterollen te verdienen.\n * Versla Monsters en verzamel voorwerpen op [queesten](http://habitica.fandom.com/wiki/Quests) (Je ontvangt een Queeste op niveau 15).",
- "overviewQuestions": "Heb je vragen? Check de [FAQ](<%= faqUrl %>)! Als dat je vraag niet beantwoordt, dan kun je hulp zoeken bij het [Habitica Help guild](<%= helpGuildUrl %>).\n\n Veel succes met je taken!"
+ "overviewQuestions": "Heb je vragen? Bekijk de [FAQ](<%= faqUrl %>)! Als dat je vraag niet beantwoordt, dan kun je hulp zoeken bij het [Habitica Help guild](<%= helpGuildUrl %>).\n\n Veel succes met je taken!"
}
diff --git a/website/common/locales/nl/pets.json b/website/common/locales/nl/pets.json
index 0b8cf6b47e..9d0d9e2561 100644
--- a/website/common/locales/nl/pets.json
+++ b/website/common/locales/nl/pets.json
@@ -1,18 +1,18 @@
{
"stable": "Stal",
"pets": "Huisdieren",
- "activePet": "Actief huisdier",
- "noActivePet": "Geen actief huisdier",
+ "activePet": "Actief Huisdier",
+ "noActivePet": "Geen actief Huisdier",
"petsFound": "Huisdieren gevonden",
- "magicPets": "Huisdieren van een magische uitbroeddrank",
- "rarePets": "Zeldzame huisdieren",
+ "magicPets": "Huisdieren van een magische Uitbroeddrank",
+ "rarePets": "Zeldzame Huisdieren",
"questPets": "Huisdieren van queesten",
"mounts": "Rijdieren",
- "activeMount": "Actief rijdier",
- "noActiveMount": "Geen actief rijdier",
+ "activeMount": "Actief Rijdier",
+ "noActiveMount": "Geen actief Rijdier",
"mountsTamed": "Rijdieren getemd",
"questMounts": "Rijdieren van queesten",
- "magicMounts": "Rijdieren van een magische uitbroeddrank",
+ "magicMounts": "Rijdieren van een magische Uitbroeddrank",
"rareMounts": "Zeldzame rijdieren",
"etherealLion": "Etherische Leeuw",
"veteranWolf": "Veteranenwolf",
diff --git a/website/common/locales/nl/rebirth.json b/website/common/locales/nl/rebirth.json
index 8ee1183176..974ee3fd65 100644
--- a/website/common/locales/nl/rebirth.json
+++ b/website/common/locales/nl/rebirth.json
@@ -1,29 +1,30 @@
{
- "rebirthNew": "Hergeboorte: nieuw avontuur beschikbaar!",
- "rebirthUnlock": "Je hebt Hergeboorte vrijgespeeld! Dit speciale marktvoorwerp stelt je in staat om een nieuw spel te beginnen vanaf niveau 1 terwijl je je taken, prestaties, dieren, en meer behoudt. Gebruik het om nieuw leven in Habitica te blazen als je voelt dat je alles al bereikt hebt, of om nieuwe spelonderdelen te beleven met de frisse blik van een beginnend personage!",
- "rebirthBegin": "Hergeboorte: begin een nieuw avontuur",
- "rebirthStartOver": "Hergeboorte start je personage opnieuw vanaf niveau 1.",
- "rebirthAdvList1": "Je krijgt je volle gezondheid terug.",
- "rebirthAdvList2": "Je hebt geen ervaring of goud.",
- "rebirthAdvList3": "Je gewoontes, dagelijkse taken en to-do's zijn teruggezet op geel en je series zijn gereset, met uitzondering van uitdagingstaken.",
+ "rebirthNew": "Hergeboorte: Nieuw Avontuur Beschikbaar!",
+ "rebirthUnlock": "Je hebt Hergeboorte vrijgespeeld! Dit speciale marktvoorwerp stelt je in staat om een nieuw spel te beginnen vanaf Niveau 1 terwijl je je taken, prestaties, dieren, en meer behoudt. Gebruik het om nieuw leven in Habitica te blazen als je voelt dat je alles al bereikt hebt of om nieuwe spelonderdelen te beleven met de frisse blik van een beginnend personage!",
+ "rebirthBegin": "Hergeboorte: Begin een Nieuw Avontuur",
+ "rebirthStartOver": "Hergeboorte start je personage opnieuw vanaf Niveau 1.",
+ "rebirthAdvList1": "Je krijgt je volle Gezondheid terug.",
+ "rebirthAdvList2": "Je hebt geen Ervaring of Goud.",
+ "rebirthAdvList3": "Je Gewoontes, Dagtaken en To-Do's zijn teruggezet op geel en je series zijn gereset, met uitzondering van uitdagingstaken.",
"rebirthAdvList4": "Je hebt de startklasse van Krijger tot je een nieuwe klasse verwerft.",
"rebirthInherit": "Je nieuwe personage erft een paar dingen van zijn voorganger:",
"rebirthInList1": "Taken, geschiedenis, uitrusting en instellingen blijven behouden.",
- "rebirthInList2": "Uitdagings-, gilde- en groepslidmaatschappen blijven behouden.",
- "rebirthInList3": "Je behoudt je edelstenen, helpersniveaus en bijdragersrang.",
- "rebirthInList4": "Voorwerpen die je verkregen hebt met edelstenen of uit willekeurige vondsten (zoals huis- en rijdieren) blijven behouden.",
- "rebirthEarnAchievement": "Je kunt ook een prestatie verdienen voor het beginnen van een nieuw avontuur!",
+ "rebirthInList2": "Uitdagings-, Gilde- en Groepslidmaatschappen blijven behouden.",
+ "rebirthInList3": "Je behoudt je Edelstenen, backer-niveaus en bijdragersrangen.",
+ "rebirthInList4": "Voorwerpen die je verkregen hebt met Edelstenen of uit willekeurige vondsten (zoals huis- en rijdieren) blijven behouden.",
+ "rebirthEarnAchievement": "Je verdient ook een Prestatie voor het beginnen van een nieuw avontuur!",
"beReborn": "Herboren worden",
- "rebirthAchievement": "Je bent een nieuw avontuur begonnen! Dit is hergeboorte <%= number %> voor jou en het hoogste niveau dat je behaald hebt is <%= level %>. Begin je volgende nieuwe avontuur als je een nog hoger niveau hebt bereikt om deze prestatie nog een keer te behalen!",
- "rebirthAchievement100": "Je bent een nieuw avontuur begonnen! Dit is hergeboorte <%= number %> voor je en het hoogste niveau dat je hebt bereikt is 100 of hoger. Om deze prestatie te stapelen, begin dan je nieuwe avontuur wanneer je op zijn minst level 100 hebt bereikt!",
- "rebirthBegan": "Is een nieuw avontuur begonnen",
- "rebirthText": "Is <%= rebirths %> nieuwe avonturen begonnen",
- "rebirthOrb": "Heeft een Bol der Hergeboorte gebruikt om opnieuw te beginnen na het bereiken van niveau <%= level %>.",
- "rebirthOrb100": "Heeft een Bol der Hergeboorte gebruikt om opnieuw te beginnen na het bereiken van niveau 100 of hoger.",
+ "rebirthAchievement": "Je bent een nieuw avontuur begonnen! Dit is Hergeboorte <%= number %> voor jou en het hoogste Niveau dat je behaald hebt is <%= level %>. Begin je volgende nieuwe avontuur als je een nog hoger niveau hebt bereikt om deze Prestatie nog een keer te behalen!",
+ "rebirthAchievement100": "Je bent een nieuw avontuur begonnen! Dit is Hergeboorte <%= number %> voor je en het hoogste Niveau dat je hebt bereikt is 100 of hoger. Om deze prestatie nog een keer te behalen, begin dan je nieuwe avontuur wanneer je op zijn minst Niveau 100 hebt bereikt!",
+ "rebirthBegan": "Is een Nieuw Avontuur begonnen",
+ "rebirthText": "Is <%= rebirths %> Nieuwe Avonturen begonnen",
+ "rebirthOrb": "Heeft een Bol der Hergeboorte gebruikt om opnieuw te beginnen na het bereiken van Niveau <%= level %>.",
+ "rebirthOrb100": "Heeft een Bol der Hergeboorte gebruikt om opnieuw te beginnen na het bereiken van Niveau 100 of hoger.",
"rebirthOrbNoLevel": "Heeft een Bol der Hergeboorte gebruikt om opnieuw te beginnen.",
- "rebirthPop": "Herstart je personage direct als een niveau 1 Krijger zonder je prestaties, verzamelobjecten en uitrusting te verliezen. Je taken en hun geschiedenis zal hetzelfde blijven maar worden gereset naar geel. Je series worden verwijderd behalve bij taken van uitdagingen. Je Goud, ervaring, Mana en de effecten van al je vaardigheden gaan verloren. Dit alles gaat direct in werking. Voor meer informatie zie de pagina van de Bol der Hergeboorte.",
+ "rebirthPop": "Herstart je personage direct als een Niveau 1 Krijger zonder je prestaties, verzamelobjecten en uitrusting te verliezen. Je taken en hun geschiedenis zal hetzelfde blijven maar ze worden gereset naar geel. Je series worden verwijderd behalve bij taken van uitdagingen. Je Goud, Ervaring, Mana en de effecten van al je Vaardigheden gaan verloren. Dit alles gaat direct in werking. Voor meer informatie zie de pagina van de Bol der Hergeboorte.",
"rebirthName": "Bol der Hergeboorte",
- "reborn": "Herboren, maximale niveau <%= reLevel %>",
+ "reborn": "Herboren, maximale Niveau <%= reLevel %>",
"confirmReborn": "Weet je het zeker?",
- "rebirthComplete": "Je bent herboren!"
-}
\ No newline at end of file
+ "rebirthComplete": "Je bent herboren!",
+ "nextFreeRebirth": "<%= days %> dagen tot GRATIS Bol der Hergeboorte"
+}
diff --git a/website/common/locales/nl/spells.json b/website/common/locales/nl/spells.json
index 4460b67beb..417f6b959f 100644
--- a/website/common/locales/nl/spells.json
+++ b/website/common/locales/nl/spells.json
@@ -2,47 +2,47 @@
"spellWizardFireballText": "Uiteenspatting van Vlammen",
"spellWizardFireballNotes": "Je roept EP op en brengt verschroeiende schade toe aan Eindbazen! (Gebaseerd op: INT)",
"spellWizardMPHealText": "Golf van Ether",
- "spellWizardMPHealNotes": "Je offert Mana op om de rest van je gezelschap, behalve Magiërs, MP te geven! (Gebaseerd op: INT)",
+ "spellWizardMPHealNotes": "Je offert Mana op om de rest van je Gezelschap, behalve Magiërs, MP te geven! (Gebaseerd op: INT)",
"spellWizardEarthText": "Aardbeving",
- "spellWizardEarthNotes": "Je mentale aura doet de grond trillen en verhoogt de Intelligentie van je gezelschap! (Gebaseerd op oorspronkelijke Intelligentie zonder bonussen.)",
+ "spellWizardEarthNotes": "Je mentale macht doet de grond trillen en verhoogt de Intelligentie van je Gezelschap! (Gebaseerd op: oorspronkelijke INT)",
"spellWizardFrostText": "IJskoude Vorst",
- "spellWizardFrostNotes": "Met één spreuk worden al je series bevroren, zodat deze morgen niet naar nul gereset worden! ",
- "spellWizardFrostAlreadyCast": "Je hebt deze spreuk vandaag al gebruikt. Je series zijn bevroren, het is niet nodig om hem nog eens te gebruiken.",
+ "spellWizardFrostNotes": "Met één spreuk worden al je series bevroren, zodat deze morgen niet naar nul teruggezet worden! ",
+ "spellWizardFrostAlreadyCast": " Je hebt deze spreuk vandaag al gebruikt. Je series zijn bevroren, het is niet nodig om hem nog eens te gebruiken.",
"spellWarriorSmashText": "Wrede Slag",
- "spellWarriorSmashNotes": "Je maakt een taak blauwer/minder rood en deelt extra schade toe aan eindbazen! (Gebaseerd op Kracht.)",
+ "spellWarriorSmashNotes": "Je maakt een taak blauwer/minder rood en deelt extra schade toe aan Eindbazen! (Gebaseerd op KRA.)",
"spellWarriorDefensiveStanceText": "Defensieve Houding",
- "spellWarriorDefensiveStanceNotes": "Je gaat op je hurken zitten en je Lichaam wordt sterker! (Gebaseerd op oorspronkelijke LIC zonder bonussen)",
+ "spellWarriorDefensiveStanceNotes": "Je gaat op je hurken zitten en je Lichaam wordt sterker! (Gebaseerd op: oorspronkelijke LIC)",
"spellWarriorValorousPresenceText": "Bemoedigende Aanwezigheid",
- "spellWarriorValorousPresenceNotes": "Je lef versterkt de Kracht van je gehele gezelschap! (Gebaseerd op oorspronkelijke Kracht zonder bonussen.)",
+ "spellWarriorValorousPresenceNotes": "Je lef versterkt de Kracht van je gehele Gezelschap! (Gebaseerd op: oorspronkelijke KRA.)",
"spellWarriorIntimidateText": "Intimiderende Blik",
- "spellWarriorIntimidateNotes": "Je scherpe staar versterkt het Lichaam van je gehele gezelschap! (Gebaseerd op oorspronkelijke LIC zonder bonussen.)",
+ "spellWarriorIntimidateNotes": "Je scherpe staar versterkt het Lichaam van je gehele gezelschap! (Gebaseerd op: oorspronkelijke LIC)",
"spellRoguePickPocketText": "Zakkenroller",
- "spellRoguePickPocketNotes": "Je berooft een taak en vindt goud! (Gebaseerd op Perceptie.)",
+ "spellRoguePickPocketNotes": "Je berooft een taak en vindt Goud! (Gebaseerd op PER)",
"spellRogueBackStabText": "Ruggesteek",
- "spellRogueBackStabNotes": "Je verraadt een naïeve taak en ontvangt goud en ervaringspunten. (Gebaseerd op Kracht.)",
+ "spellRogueBackStabNotes": "Je verraadt een naïeve taak en ontvangt Goud en EP! (Gebaseerd op KRA)",
"spellRogueToolsOfTradeText": "Dievenkneepjes",
- "spellRogueToolsOfTradeNotes": "Je listige talenten versterken de Perceptie van je gehele gezelschap! (Gebaseerd op oorspronkelijke Perceptie zonder bonussen.)",
+ "spellRogueToolsOfTradeNotes": "Je listige talenten versterken de Perceptie van je gehele Gezelschap! (Gebaseerd op: oorspronkelijke PER)",
"spellRogueStealthText": "Heimelijkheid",
- "spellRogueStealthNotes": "Met elke spreuk zullen een aantel van je onafgemaakte Dagelijkse Taken je deze nacht niet kunnen vinden en hun roodheid en series zullen niet veranderen. (Gebaseerd op Perceptie.)",
- "spellRogueStealthDaliesAvoided": "<%= originalText %> Aantal dagelijkse taken vermeden: <%= number %>.",
- "spellRogueStealthMaxedOut": "Je hebt al je dagelijkse taken al vermeden; het is niet nodig deze spreuk nogmaals te gebruiken. ",
+ "spellRogueStealthNotes": "Met elke spreuk zullen een aantel van je onafgemaakte Dagtaken je deze nacht niet kunnen vinden. Hun series en kleur zullen niet veranderen. (Gebaseerd op: PER)",
+ "spellRogueStealthDaliesAvoided": "<%= originalText %> Aantal Dagtaken vermeden: <%= number %>.",
+ "spellRogueStealthMaxedOut": " Je hebt al je Dagtaken al vermeden; het is niet nodig deze spreuk nogmaals te gebruiken.",
"spellHealerHealText": "Helend Licht",
- "spellHealerHealNotes": "Glanzend licht herstelt je wonden! (Gebaseerd op Lichaam en Intelligentie.)",
+ "spellHealerHealNotes": "Glanzend licht herstelt je wonden! (Gebaseerd op LIC en INT)",
"spellHealerBrightnessText": "Schroeiende Helderheid",
- "spellHealerBrightnessNotes": "Een straal van licht maakt al je taken blauwer en minder rood! (Gebaseerd op: INT)",
+ "spellHealerBrightnessNotes": "Een straal van licht maakt al je taken blauwer/minder rood! (Gebaseerd op: INT)",
"spellHealerProtectAuraText": "Beschermende Aura",
- "spellHealerProtectAuraNotes": "Je beschermt je gezelschap door hun Lichaam te verhogen. (Gebaseerd op oorspronkelijke LIC zonder bonussen)",
+ "spellHealerProtectAuraNotes": "Je beschermt je Gezelschap door hun Lichaam te verhogen! (Gebaseerd op: oorspronkelijke LIC)",
"spellHealerHealAllText": "Zegening",
- "spellHealerHealAllNotes": "Je verzachtende spreuk herstelt de wonden van je gehele gezelschap! (Gebaseerd op Lichaam en Intelligentie.)",
+ "spellHealerHealAllNotes": "Je verzachtende spreuk herstelt de wonden van je gehele Gezelschap! (Gebaseerd op LIC en INT)",
"spellSpecialSnowballAuraText": "Sneeuwbal",
"spellSpecialSnowballAuraNotes": "Verander je vrienden in een sneeuwpop!",
"spellSpecialSaltText": "Zout",
"spellSpecialSaltNotes": "Draai de spreuk terug die je in een sneeuwpop veranderde.",
"spellSpecialSpookySparklesText": "Spookachtige Glitters",
"spellSpecialSpookySparklesNotes": "Verander je vriend in een doorzichtige maat!",
- "spellSpecialOpaquePotionText": "Ondoorzichtig toverdrankje",
+ "spellSpecialOpaquePotionText": "Ondoorzichtig Toverdrankje",
"spellSpecialOpaquePotionNotes": "Draai de spreuk terug die je transparant maakte.",
- "spellSpecialShinySeedText": "Glanzend zaadje",
+ "spellSpecialShinySeedText": "Glanzend Zaadje",
"spellSpecialShinySeedNotes": "Verander een vriend in een blij bloemetje!",
"spellSpecialPetalFreePotionText": "Ontbladeringsdrankje",
"spellSpecialPetalFreePotionNotes": "Draai de spreuk terug die je in een bloem veranderde.",
@@ -55,5 +55,5 @@
"challengeTasksNoCast": "Het uitspreken van een vaardigheid op uitdagingstaken is niet toegestaan.",
"groupTasksNoCast": "Je mag geen vaardigheden gebruiken op groepstaken.",
"spellNotOwned": "Je bezit deze vaardigheid niet.",
- "spellLevelTooHigh": "Je moet niveau <%= level %> zijn om deze vaardigheid te gebruiken."
-}
\ No newline at end of file
+ "spellLevelTooHigh": "Je moet Niveau <%= level %> zijn om deze vaardigheid te gebruiken."
+}
diff --git a/website/common/locales/nl/tasks.json b/website/common/locales/nl/tasks.json
index 6918d0326c..9201eec911 100644
--- a/website/common/locales/nl/tasks.json
+++ b/website/common/locales/nl/tasks.json
@@ -1,8 +1,8 @@
{
"clearCompleted": "Voltooide taken verwijderen",
- "clearCompletedDescription": "Voltooide taken worden na 30 dagen verwijderd zonder abonnement, met een abonnement worden ze na 90 dagen verwijderd.",
- "clearCompletedConfirm": "Weet je zeker dat je je voldooide taken wilt verwijderen?",
- "sureDeleteCompletedTodos": "Weet je zeker dat je je voltooide to-do's wilt verwijderen?",
+ "clearCompletedDescription": "Voltooide To-Do's worden na 30 dagen voor niet-abonnees, voor abonnees worden ze na 90 dagen verwijderd.",
+ "clearCompletedConfirm": "Weet je zeker dat je je voldooide To-Do's wilt verwijderen?",
+ "sureDeleteCompletedTodos": "Weet je zeker dat je je voltooide To-Do's wilt verwijderen?",
"lotOfToDos": "Je meest recente 30 voltooide To-do's worden hier getoond. Je kan oudere voltooide To-do's zien via Gegevens > Gegevens weergeven of Gegevens > Gegevens exporteren > Gebruikersgegevens.",
"deleteToDosExplanation": "Met de onderstaande knop worden al je voltooide To-do's en gearchiveerde To-do's voorgoed verwijderd, behalve de To-do's van actieve uitdagingen en groepsplannen. Exporteer ze eerst als je ze wil bewaren.",
"addMultipleTip": "Tip: Om meerdere <%= taskType %> toe te voegen, kun je ze scheiden met een 'line break' (Shift + Enter), druk daarna op 'Enter'",
diff --git a/website/common/locales/no/settings.json b/website/common/locales/no/settings.json
index 1b5cd4b73b..18f23f6e5a 100755
--- a/website/common/locales/no/settings.json
+++ b/website/common/locales/no/settings.json
@@ -3,12 +3,12 @@
"language": "Språk",
"americanEnglishGovern": "Om det er ulikheter i oversettelsene, er det Amerikansk Engelsk som gjelder.",
"helpWithTranslation": "Vil du hjelpe til med å oversette Habitica? Bra! Besøk dette Trello kortet.",
- "showHeaderPop": "Vis Avatar, Helse/Erfaringsindikatorer og Klan",
+ "showHeaderPop": "Vis Avatar, Helse/Erfaringsindikatorer og Klan.",
"stickyHeader": "Header sitter fast",
"stickyHeaderPop": "Fester header til toppen av skjermen. Umerket vil den scrolles ut av skjermbildet.",
"newTaskEdit": "Åpne nye oppgaver i redigeringsmodus",
"newTaskEditPop": "Med dette valget vil nye oppgaver umiddelbart åpnes for at du skal kunne legge til detaljer som notater og merkelapper.",
- "dailyDueDefaultView": "Lag \"må gjøres\" fanen standard.",
+ "dailyDueDefaultView": "Lag \"må gjøres\" fanen standard",
"dailyDueDefaultViewPop": "Med denne valget sett, vil de Daglige oppgavene dine bli standard sett til 'må gjøres' isteden for 'alle'",
"reverseChatOrder": "Vis meldingene i motsatt rekkefølge",
"startAdvCollapsed": "Advanced Settings in tasks start collapsed",
@@ -17,17 +17,17 @@
"suppressLevelUpModal": "Ikke vis pop-up vinduet når jeg når et nytt nivå",
"suppressHatchPetModal": "Ikke vis pop-up vinduet når jeg klekker et nytt kjæledyr",
"suppressRaisePetModal": "Ikke vis pop-up vinduet når jeg har oppfostret et kjæledyr til et ridedyr",
- "suppressStreakModal": "Ikke vis pop-up vinduet når jeg mottar et ",
+ "suppressStreakModal": "Ikke vis pop-up vinduet når jeg mottar et",
"showTour": "Vis Omvisning",
- "restartTour": "Start introduksjonsturen fra da du først ble medlem av Habitica",
+ "restartTour": "Start introduksjonsturen fra da du først ble medlem av Habitica.",
"showBailey": "Vis Bailey",
- "showBaileyPop": "Få Utroper Bailey frem så du kan se gamle nyheter på nytt",
+ "showBaileyPop": "Få Utroper Bailey frem så du kan se gamle nyheter på nytt.",
"fixVal": "Reparer karakterverdier",
"fixValPop": "Endre verdier som helse, nivå og gull manuelt.",
"invalidLevel": "Ugyldig verdi: Nivå må være 1 eller høyere.",
"enableClass": "Slå på klassesystem",
"enableClassPop": "Du valgte vekk klassesystemet i utgangsspunktet, vil du delta nå?",
- "classTourPop": "Vis omvisningen for bruk av klassesystem",
+ "classTourPop": "Vis omvisningen for bruk av klassesystem.",
"resetAccount": "Nullstill konto",
"resetAccPop": "Start på nytt, fjern alle nivåer, gull, utstyr, logg og oppgaver.",
"deleteAccount": "Slett konto",
@@ -37,10 +37,10 @@
"dataExport": "Data-eksport",
"saveData": "Her er noen valg for å lagre dine data.",
"habitHistory": "Vane-logg",
- "exportHistory": "Eksporter logg",
+ "exportHistory": "Eksporter logg:",
"csv": "(CSV)",
"userData": "Brukerdata",
- "exportUserData": "Eksporter brukerdata",
+ "exportUserData": "Eksporter brukerdata:",
"export": "Eksporter",
"xml": "(XML)",
"json": "(JSON)",
@@ -89,7 +89,7 @@
"disabledWinterEvent": "Deaktivert under Winter Wonderland pt.4 (siden belønningene kan kjøpes for gull).",
"fix21Streaks": "21-dagers gjennomføringskjede",
"discardChanges": "Fjern endringer",
- "deleteDo": "Gjør det, slett kontoen min.",
+ "deleteDo": "Gjør det, slett kontoen min!",
"enterNumber": "Angi et nummer mellom 0 og 24",
"fillAll": "Vennligst fyll ut alle feltene",
"invalidPasswordResetCode": "Den angitte tilbakestillingskoden for ditt passord er ugyldig eller utløpt.",
@@ -130,10 +130,10 @@
"kickedGroup": "Kastet ut fra gruppe",
"remindersToLogin": "Påminnelse om å sjekke Habitica",
"subscribeUsing": "Abonner med",
- "unsubscribedSuccessfully": "Ditt abonnement er fjernet! ",
+ "unsubscribedSuccessfully": "Ditt abonnement er fjernet!",
"unsubscribedTextUsers": "You have successfully unsubscribed from all Habitica emails. You can enable only the emails you want to receive from Settings > > Notifications (requires login).",
"unsubscribedTextOthers": "Du vil ikke få noe annen epost fra Habitica.",
- "unsubscribeAllEmails": "Kryss av for å fjerne ditt abonnement på epost fra Habitica.",
+ "unsubscribeAllEmails": "Kryss av for å fjerne ditt abonnement på epost fra Habitica",
"unsubscribeAllEmailsText": "Ved å krysse av i denne boksen, vedkjenner jeg at ved å fjerne abonnementet på epost, vil ikke Habitica lengre ha muligheten til å varsle meg via epost om viktige endringer gjort på siden eller min konto.",
"unsubscribeAllPush": "Huk av for å fjerne ditt abonnement på alle push notifikasjoner",
"correctlyUnsubscribedEmailType": "Abonnementet for \"<%= emailType %>\"-epostene er fjernet.",
@@ -205,4 +205,4 @@
"usernameNotVerified": "Please confirm your username.",
"changeUsernameDisclaimer": "We will be transitioning login names to unique, public usernames soon. This username will be used for invitations, @mentions in chat, and messaging.",
"verifyUsernameVeteranPet": "One of these Veteran Pets will be waiting for you after you've finished confirming!"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/no/subscriber.json b/website/common/locales/no/subscriber.json
index 2afa132a66..27614bbda8 100755
--- a/website/common/locales/no/subscriber.json
+++ b/website/common/locales/no/subscriber.json
@@ -26,10 +26,10 @@
"monthUSD": "USD / Måned",
"organization": "Organisasjon",
"groupPlans": "Gruppeplaner",
- "indivPlan1": "For individer er Habitica gratis å spille. Selv for små interessegrupper er det gratis (eller billig).",
+ "indivPlan1": "For individer er Habitica gratis å spille. Selv for små interessegrupper er det gratis (eller billig)",
"indivPlan2": "kan bli brukt for å motivere deltager til atferdsmodifikasjon. Tenk skrivegrupper, kunst utfordringer, og mer.",
"groupText1": "Men noen gruppeledere vil ha mer kontroll, personvern, sikkerhet og støtte. Eksempler av slike grupper er familier, helse og velvære grupper, ansatte grupper, og mer. Disse planer gir privat bruk av Habitica for din grupper eller organisasjon, sikkert og uavhengig av",
- "groupText2": "Se nedenfor for flere plan fordeler, og kontakt oss for mer informasjon.",
+ "groupText2": "Se nedenfor for flere plan fordeler, og kontakt oss for mer informasjon!",
"planFamily": "Familie (Kommer snart)",
"planGroup": "Gruppe (Kommer snart)",
"dedicatedHost": "Dedikert hosting",
@@ -38,7 +38,7 @@
"subscribe": "Abonner",
"subscribed": "Abonnerer",
"nowSubscribed": "You are now subscribed to Habitica!",
- "manageSub": "Klikk for å håndtere abonnementer.",
+ "manageSub": "Klikk for å håndtere abonnementer",
"cancelSub": "Avbestill abonnement",
"cancelSubInfoGoogle": "Vennligst gå til \"Konto\" > \"Abonnenter\" > delen av Google Play Store appen for å avslutte ditt abonnement eller for å se ditt abonnements avslutnings dato hvis du allerede har avsluttet det. Denne siden kan ikke vise deg om du har avsluttet ditt abonnement eller ikke.",
"cancelSubInfoApple": "Please follow Apple's official instructions to cancel your subscription or to see your subscription's termination date if you have already cancelled it. This screen is not able to show you whether your subscription has been cancelled.",
@@ -70,7 +70,7 @@
"contactUs": "Kontakt oss",
"checkout": "Kasse",
"sureCancelSub": "Er du sikker på at du vil stoppe abonnementet ditt?",
- "subCanceled": "Abonnement blir inaktiv på ",
+ "subCanceled": "Abonnement blir inaktiv på",
"buyGemsGoldTitle": "Tilgang til å kjøpe Juveler med Gull",
"becomeSubscriber": "Bli abonnent",
"subGemPop": "Because you subscribe to Habitica, you can purchase a number of Gems each month using Gold.",
@@ -89,7 +89,7 @@
"timeTravelersPopoverNoSubMobile": "Looks like you’ll need a Mystic Hourglass to open the time portal and summon the Mysterious Time Travelers.",
"timeTravelersPopover": "Your Mystic Hourglass has opened our time portal! Choose what you’d like us to fetch from the past or future.",
"timeTravelersAlreadyOwned": "Gratulerer! Du eier allerede alt det de mystiske tidsreiserne for øyeblikket har å tilby. Takk for at du støtter Habitica!",
- "mysticHourglassPopover": "Du kan kjøpe utvalgte, tidsbegrensede gjenstander med de Mystiske Timeglassene, slik som de månedlige settene med mystiske gjenstander fra fortiden, og belønninger fra tidligere verdensmonstre.",
+ "mysticHourglassPopover": "Du kan kjøpe utvalgte, tidsbegrensede gjenstander med de Mystiske Timeglassene, slik som de månedlige settene med mystiske gjenstander fra fortiden, og belønninger fra tidligere verdensmonstre!",
"mysterySetNotFound": "Mysterium settet er ikke funnet, eller allerede eid.",
"mysteryItemIsEmpty": "Mysteriums objekter er tomme",
"mysteryItemOpened": "Mysteriums objekt åpnet.",
@@ -165,7 +165,7 @@
"hourglassBuyItemConfirm": "Kjøp denne gjenstanden for 1 Mystisk Timeglass?",
"petsAlreadyOwned": "Kjæledyr er allerede eid.",
"mountsAlreadyOwned": "Ridedyret er allerede eid.",
- "typeNotAllowedHourglass": "Objekttype er ikke støttet for betaling med Mystisk Timeglass. Tillate typer: <%= allowedTypes %> ",
+ "typeNotAllowedHourglass": "Objekttype er ikke støttet for betaling med Mystisk Timeglass. Tillate typer: <%= allowedTypes %>",
"petsNotAllowedHourglass": "Kjæledyret kan ikke kjøpes med mystiske timeglass.",
"mountsNotAllowedHourglass": "Ridedyret kan ikke kjøpes med mystiske timeglass.",
"hourglassPurchase": "Du har kjøpt en gjenstand med et mystisk timeglass!",
@@ -180,7 +180,7 @@
"notAllowedHourglass": "Kjæledyr/ridedyr er ikke tilgjengelig ved betaling ved Mystisk Timeglass.",
"readCard": "<%= cardType %> har blitt belastet",
"cardTypeRequired": "Korttype behøves",
- "cardTypeNotAllowed": "Ukjent korttype",
+ "cardTypeNotAllowed": "Ukjent korttype.",
"invalidCoupon": "Ugyldig kupongkode.",
"couponUsed": "Kupongkode har allerede blitt brukt.",
"couponCodeRequired": "Kupongkoden behøves.",
@@ -214,4 +214,4 @@
"gemsPurchaseNote": "Subscribers can buy gems for gold in the Market! For easy access, you can also pin the gem to your Rewards column.",
"gemsRemaining": "gems remaining",
"notEnoughGemsToBuy": "You are unable to buy that amount of gems"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/no/tasks.json b/website/common/locales/no/tasks.json
index fb2f21e6a9..1ca249618f 100755
--- a/website/common/locales/no/tasks.json
+++ b/website/common/locales/no/tasks.json
@@ -1,34 +1,34 @@
{
"clearCompleted": "Fjern fullførte",
- "clearCompletedDescription": "Completed To-Dos are deleted after 30 days for non-subscribers and 90 days for subscribers.",
- "clearCompletedConfirm": "Er du sikker på at du vil slette dine fullførte oppgaver?",
- "sureDeleteCompletedTodos": "Er du sikker på at du vil slette dine fullførte oppgaver?",
- "lotOfToDos": "Dine 30 nyeste ferdige Gjøremål vises her. Du kan se eldre ferdige Gjøremål i Data > Datavisningsverktøy eller Data > Eksporter data > Brukerdata.",
- "deleteToDosExplanation": "Hvis du trykker på knappen under vil alle dine ferdige gjøremål og lagrede gjøremål bli permanent slettet, med unntak av gjøremål fra aktive utfordringer og gruppeplaner. Eksporter dem først hvis du vil beholde gjøremålene.",
- "addMultipleTip": "Tip: To add multiple <%= taskType %>, separate each one using a line break (Shift + Enter) and then press \"Enter.\"",
- "addsingle": "Legg til Enkel",
- "addATask": "Add a <%= type %>",
- "editATask": "Edit a <%= type %>",
- "createTask": "Create <%= type %>",
- "addTaskToUser": "Add Task",
- "scheduled": "Scheduled",
- "theseAreYourTasks": "These are your <%= taskType %>",
+ "clearCompletedDescription": "Fulltørte To-Dos blir slettet etter 30 dager for brukere uten abonnement og 90 dager for abonnenter.",
+ "clearCompletedConfirm": "Er du sikker på at du vil slette de fullførte oppgavene dine?",
+ "sureDeleteCompletedTodos": "Er du sikker på at du vil slette de fullførte oppgavene dine?",
+ "lotOfToDos": "Her finner du de 30 sist gjennomførte oppgavene dine. Du kan se eldre gjennomførte oppgaver i Data > Datavisningsverktøy eller Data > Eksporter data > Brukerdata.",
+ "deleteToDosExplanation": "Hvis du trykker på knappen under vil alle gjennomførte og lagrede oppgaver bli permanent slettet, med unntak av oppgaver fra aktive utfordringer og gruppeplaner. Eksporter dem hvis du vil beholde oppgavene.",
+ "addMultipleTip": "Tips: For å legge til flere <%= taskType %>, kan du skille dem ved å bruke linjeskift (Shift + Enter) og trykke \"Enter.\"",
+ "addsingle": "Legg til en og en",
+ "addATask": "Legg til en <%= type %>",
+ "editATask": "Endre en <%= type %>",
+ "createTask": "Lag <%= type %>",
+ "addTaskToUser": "Legg til oppgave",
+ "scheduled": "Planlagt",
+ "theseAreYourTasks": "Dette er dine <%= taskType %>",
"habit": "Vane",
"habits": "Vaner",
"newHabit": "Ny vane",
"newHabitBulk": "Nye vaner (en per linje)",
- "habitsDesc": "Habits don't have a rigid schedule. You can check them off multiple times per day.",
- "positive": "Positive",
- "negative": "Negative",
+ "habitsDesc": "Vaner følger ikke et fast tidsskjema. Du kan gjøre dem flere ganger daglig.",
+ "positive": "Positiv",
+ "negative": "Negativ",
"yellowred": "Svak",
"greenblue": "Sterk",
"edit": "Endre",
"save": "Lagre",
"addChecklist": "Legg til sjekkliste",
"checklist": "Sjekkliste",
- "checklistText": "Del en oppgave i mindre deler! Sjekklister øker mengden Erfaring og Gull som tjenes fra et Gjøremål, og reduserer skaden påført av en Daglig.",
- "newChecklistItem": "New checklist item",
- "expandChecklist": "Expand Checklist",
+ "checklistText": "Del en oppgave i mindre deler! Sjekklister gir mer erfaring og gull , og reduserer skaden påført av en Daglig.",
+ "newChecklistItem": "Nytt punkt",
+ "expandChecklist": "Utvid sjekkliste",
"collapseChecklist": "Collapse Checklist",
"text": "Tittel",
"extraNotes": "Ekstra notater",
@@ -210,4 +210,4 @@
"searchTasks": "Search titles and descriptions...",
"sessionOutdated": "Your session is outdated. Please refresh or sync.",
"errorTemporaryItem": "This item is temporary and cannot be pinned."
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/pl/achievements.json b/website/common/locales/pl/achievements.json
index c68d13c434..943028941e 100644
--- a/website/common/locales/pl/achievements.json
+++ b/website/common/locales/pl/achievements.json
@@ -1,9 +1,11 @@
{
- "achievement": "Osiągnięcie",
- "share": "Udostępnij",
- "onwards": "Naprzód!",
- "levelup": "Realizując życiowe cele, osiągnąłeś wyższy poziom i jesteś teraz w pełni wyleczony!",
- "reachedLevel": "Osiągnąłeś poziom <%= level %>",
- "achievementLostMasterclasser": "Realizator misji: Mistrzowie Klas",
- "achievementLostMasterclasserText": "Wykonałeś wszystkie szesnaście misji w cyklu Mistrzów Klas i rozwiązałeś zagadkę Zaginionego Mistrza!"
+ "achievement": "Osiągnięcie",
+ "share": "Udostępnij",
+ "onwards": "Naprzód!",
+ "levelup": "Realizując życiowe cele, osiągnąłeś wyższy poziom i jesteś teraz w pełni wyleczony!",
+ "reachedLevel": "Osiągnąłeś poziom <%= level %>",
+ "achievementLostMasterclasser": "Realizator misji: Mistrzowie Klas",
+ "achievementLostMasterclasserText": "Wykonano wszystkie szesnaście misji w cyklu Mistrzów Klas i rozwiązano zagadkę Zaginionego Mistrza!",
+ "achievementAridAuthorityModalText": "Oswoiłeś wszystkie Pustynne Wierzchowce!",
+ "achievementLostMasterclasserModalText": "Wykonałeś wszystkie szesnaście misji z serii Mistrzowie Klas i rozwiązałeś zagadkę Zaginionego Mistrza!"
}
diff --git a/website/common/locales/pl/backgrounds.json b/website/common/locales/pl/backgrounds.json
index 6ae5d68047..dbff16a6c8 100644
--- a/website/common/locales/pl/backgrounds.json
+++ b/website/common/locales/pl/backgrounds.json
@@ -422,5 +422,54 @@
"backgroundFieldWithColoredEggsText": "Pole kolorowych jaj",
"backgroundFieldWithColoredEggsNotes": "Zapoluj na wiosenny skarb na polu kolorowych jaj.",
"backgroundFlowerMarketText": "Kwiatowy rynek",
- "backgroundFlowerMarketNotes": "Znajdź idealne kolory na bukiet na kwiatowym rynku."
+ "backgroundFlowerMarketNotes": "Znajdź idealne kolory na bukiet na kwiatowym rynku.",
+ "backgroundSeasideCliffsNotes": "Stań na plaży z pięknymi, nadmorskimi klifami powyżej.",
+ "backgroundSeasideCliffsText": "Nadmorskie klify",
+ "backgroundSchoolOfFishNotes": "Popływaj pośród ławicy ryb.",
+ "backgroundSchoolOfFishText": "Ławica ryb",
+ "backgrounds062019": "Zestaw 61: Wydany w czerwcu 2019",
+ "backgroundRainbowMeadowNotes": "Znajdź garnek ze złotem, w miejscu, gdzie kończy się tęcza na łące.",
+ "backgroundRainbowMeadowText": "Tęczowa Łąka",
+ "backgroundParkWithStatueNotes": "Podążaj ścieżką kwiatową przez park z rzeźbą.",
+ "backgroundParkWithStatueText": "Park z Pomnikiem",
+ "backgroundDojoNotes": "Naucz się nowych technik w sali treningowej Dojo.",
+ "backgroundDojoText": "Dojo",
+ "backgrounds052019": "Zestaw 60: Wydany w maju 2019",
+ "backgroundBlossomingDesertNotes": "Zostań naocznym świadkiem rzadkiego, niesamowitego rozkwitu na Kwitnącej Pustyni.",
+ "backgroundBlossomingDesertText": "Kwitnąca pustynia",
+ "backgroundHalflingsHouseNotes": "Odwiedź urzekający dom hobbita.",
+ "backgroundHalflingsHouseText": "Dom hobbita",
+ "backgroundBirchForestNotes": "Figle w spokojnym, brzozowym lesie.",
+ "backgroundBirchForestText": "Brzozowy las",
+ "backgrounds042019": "Zestaw 59: Wydany w kwietniu 2019",
+ "backgroundMonsterMakersWorkshopNotes": "Eksperymentuj z podejrzanymi doświadczeniami w potwornej pracowni twórcy.",
+ "backgroundMonsterMakersWorkshopText": "Potworna pracownia twórcy",
+ "backgroundPumpkinCarriageNotes": "Przejażdżka w zaczarowanym powozie dyniowym, zanim zegar pokaże północ.",
+ "backgroundPumpkinCarriageText": "Dyniowy Powóz",
+ "backgroundFoggyMoorNotes": "Patrz pod nogi pokonując mgliste torfowiska.",
+ "backgroundFoggyMoorText": "Mgliste torfowiska",
+ "backgrounds102019": "ZESTAW 65: Wydany w październiku 2019",
+ "backgroundInAClassroomNotes": "Przyswajaj w klasie wiedzę od swojego nauczyciela.",
+ "backgroundInAClassroomText": "Klasa",
+ "backgroundInAnAncientTombNotes": "Poznaj tajemnice starożytnego grobowca.",
+ "backgroundInAnAncientTombText": "Starożytny grobowiec",
+ "backgroundAutumnFlowerGardenNotes": "Przenieś się w ciepło jesiennego ogrodu z kwiatami.",
+ "backgroundAutumnFlowerGardenText": "Jesienny ogród kwiatowy",
+ "backgrounds092019": "ZESTAW 64: Wydany we Wrześniu 2019",
+ "backgroundTreehouseNotes": "Spędzaj czas w nadrzewnej kryjówce, tylko dla siebie, we własnym domku na drzewie.",
+ "backgroundTreehouseText": "Domek na drzewie",
+ "backgroundGiantDandelionsNotes": "Przechadzki wśród gigantycznych dmuchawców.",
+ "backgroundGiantDandelionsText": "Gigantyczne dmuchawce",
+ "backgroundAmidAncientRuinsNotes": "Stań z szacunkiem dla tajemniczej przeszłości pośród starożytnych ruin.",
+ "backgroundAmidAncientRuinsText": "Wśród starożytnych ruin",
+ "backgrounds082019": "ZESTAW 63: Wydany w sierpniu 2019",
+ "backgroundAmongGiantAnemonesNotes": "Eksploruj podwodne życie wkoło raf, wśród gigantycznych anemonów chroniących rafy przed drapieżnikami.",
+ "backgroundAmongGiantAnemonesText": "Pośród gigantycznych anemonów",
+ "backgroundFlyingOverTropicalIslandsNotes": "Niech widok zapiera Ci dech w piersiach podczas lotu nad tropikalną wyspą.",
+ "backgroundFlyingOverTropicalIslandsText": "Przelot nad tropikalną wyspą",
+ "backgroundLakeWithFloatingLanternsNotes": "Widok gwiazd w atmosferze festiwalu nad jeziorem z pływającymi latarniami.",
+ "backgroundLakeWithFloatingLanternsText": "Jezioro z pływającymi latarniami",
+ "backgrounds072019": "ZESTAW 62: Lipiec 2019",
+ "backgroundUnderwaterVentsNotes": "Zanurkuj głęboko, głęboko w dół, aż do podwodnych głębin.",
+ "backgroundUnderwaterVentsText": "Podwodne głębiny"
}
diff --git a/website/common/locales/pl/content.json b/website/common/locales/pl/content.json
index 1e3311897e..450cf3de9b 100644
--- a/website/common/locales/pl/content.json
+++ b/website/common/locales/pl/content.json
@@ -212,7 +212,7 @@
"hatchingPotionFrost": "Mroźny",
"hatchingPotionIcySnow": "Lodowaty Śnieg",
"hatchingPotionNotes": "Wylej eliksir na jajko, a wykluje się z niego <%= potText(locale) %>.",
- "premiumPotionAddlNotes": "Nie nadaje się do użytku na jajach otrzymanych za misje.",
+ "premiumPotionAddlNotes": "Nie nadaje się do użytku na jajach otrzymanych za misje. Dostępny w sprzedaży do <%= date(locale) %>.",
"foodMeat": "Mięso",
"foodMeatThe": "Mięso",
"foodMeatA": "Mięso",
@@ -349,5 +349,7 @@
"hatchingPotionSilver": "Srebrny",
"questEggRobotAdjective": "futurystyczny",
"questEggRobotMountText": "Robot",
- "questEggRobotText": "Robot"
+ "questEggRobotText": "Robot",
+ "hatchingPotionShadow": "Cienisty",
+ "premiumPotionUnlimitedNotes": "Nie nadaje się do użytku na jajach."
}
diff --git a/website/common/locales/pl/defaulttasks.json b/website/common/locales/pl/defaulttasks.json
index fe5ad92f0d..95ad079a61 100644
--- a/website/common/locales/pl/defaulttasks.json
+++ b/website/common/locales/pl/defaulttasks.json
@@ -1,16 +1,16 @@
{
- "defaultHabit1Text": "Produktywna praca (kliknij ołówek aby edytować)",
+ "defaultHabit1Text": "Produktywna praca (kliknij ołówek, aby edytować)",
"defaultHabit1Notes": "Przykładowe dobre nawyki: + Zjedz warzywo + 15 minut produktywnej pracy",
- "defaultHabit2Text": "Jedz śmieciowe jedzenie (kliknij ołówek aby edytować)",
+ "defaultHabit2Text": "Jedzenie śmieciowego jedzenia (kliknij ołówek aby edytować)",
"defaultHabit2Notes": "Przykładowe złe Nawyki: - Palenie - Odkładanie na później",
"defaultHabit3Text": "Wybierz schody/windę (kliknij ołówek aby edytować)",
"defaultHabit3Notes": "Przykładowe dobre i złe Nawyki: +/- Użyj schodów/windy ; +/- Wypij wodę/napój gazowany",
"defaultHabit4Text": "Dodaj zadanie do Habitiki",
"defaultHabit4Notes": "Nawyk, Codzienne lub Do-Zrobienia",
- "defaultHabit5Text": "Kliknij tutaj aby zrobić z tego zły nawyk, z którym chcesz skończyć",
+ "defaultHabit5Text": "Kliknij tutaj, aby zrobić z tego zły nawyk, z którym chcesz skończyć",
"defaultHabit5Notes": "Lub usuń z ekranu edycji",
"defaultDaily1Text": "Użyj Habitiki, aby kontrolować swoje zadania",
- "defaultTodo1Text": "Dołączyć do Habitica (Odhacz mnie!)",
+ "defaultTodo1Text": "Dołączyć do Habitiki (Odhacz mnie!)",
"defaultTodoNotes": "Możesz wypełnić to zadanie Do-Zrobienia, zedytować je lub usunąć.",
"defaultTodo2Text": "Skończ przewodnik Justina o zadaniach",
"defaultTodo2Notes": "Odwiedź wszystkie sekcje na dolnym pasku",
@@ -24,5 +24,11 @@
"defaultTag4": "Szkoła",
"defaultTag5": "Zespoły",
"defaultTag6": "Prace domowe",
- "defaultTag7": "Twórczość"
-}
\ No newline at end of file
+ "defaultTag7": "Twórczość",
+ "choresDailyText": "Umyj naczynia",
+ "choresHabit": "10 minut sprzątania",
+ "selfCareHabit": "Zrób sobie krótką przerwę",
+ "schoolDailyText": "Skończ zadania domowe",
+ "exerciseDailyText": "Rozciąganie>>Codzienne ćwiczenia",
+ "workHabitMail": "Sprawdź e-mail"
+}
diff --git a/website/common/locales/pl/generic.json b/website/common/locales/pl/generic.json
index c04363d93f..26bb2a3fbc 100644
--- a/website/common/locales/pl/generic.json
+++ b/website/common/locales/pl/generic.json
@@ -293,5 +293,6 @@
"contactForm": "Skontaktuj się z Drużyną Moderatorów",
"options": "Opcje",
"loadEarlierMessages": "Wczytaj Wcześniejsze Wiadomości",
- "demo": "Demo"
+ "demo": "Demo",
+ "finish": "Zakończ"
}
diff --git a/website/common/locales/pl/groups.json b/website/common/locales/pl/groups.json
index b6028cdfd6..1dbce0f6fd 100644
--- a/website/common/locales/pl/groups.json
+++ b/website/common/locales/pl/groups.json
@@ -250,19 +250,19 @@
"onlyGroupLeaderCanEditTasks": "Nie masz uprawnień do zarządzania zadaniami!",
"onlyGroupTasksCanBeAssigned": "Można przypisywać wyłącznie zadania grupowe",
"assignedTo": "Przyznany do",
- "assignedToUser": "Przyznany do <%= userName %>",
- "assignedToMembers": "Przyznano do <%= userCount %> użytkowników",
- "assignedToYouAndMembers": "Przyznany do ciebie i <%= userCount %> użytkowników",
+ "assignedToUser": "Przyznany do <%= userName %>",
+ "assignedToMembers": "Przyznano do <%= userCount %> użytkowników",
+ "assignedToYouAndMembers": "Przyznany do ciebie i <%= userCount %> użytkowników",
"youAreAssigned": "Zostałeś/aś przyznany/a do tego zadania",
"taskIsUnassigned": "To zadanie nie jest przypisane",
"confirmClaim": "Czy jesteś pewny, że chcesz sobie rościć to zadanie?",
"confirmUnClaim": "Czy jesteś pewien, że chcesz odpuścić roszczenia do tego zadania?",
"confirmApproval": "Czy na pewno chcesz zatwierdzić to zadanie?",
"confirmNeedsWork": "Czy jesteś pewny, że chcesz oznaczyć to zadanie jako wymagające pracy?",
- "userRequestsApproval": "<%= userName %> prosi o zatwierdzenie",
- "userCountRequestsApproval": "<%= userCount %> members request approval",
+ "userRequestsApproval": "<%= userName %> prosi o zatwierdzenie",
+ "userCountRequestsApproval": "<%= userCount %> użytkowników prosi o zatwierdzenie",
"youAreRequestingApproval": "Prosisz o zatwierdzenie",
- "chatPrivilegesRevoked": "Nie możesz tego zrobić, ponieważ twoje czatowe przywileje zostały wycofane.",
+ "chatPrivilegesRevoked": "Nie możesz tego zrobić, ponieważ twoje czatowe przywileje zostały usunięte. Aby uzyskać wyjaśnienia lub zapytać o możliwość przywrócenia uprawnień, napisz e-mail do Menedżera Społeczności na adres admin@habitica.com, ewentualnie poproś rodzica lub opiekuna, aby zrobił to za Ciebie. W treści zgłoszenia należy podać nazwę użytkownika (@TwojaNazwa) . Jeśli moderator przekazał Ci informację, że zakaz czatowania ma charakter tymczasowy, wtedy nie ma potrzeby wysyłania e-mail.",
"cannotCreatePublicGuildWhenMuted": "Nie możesz stworzyć publicznej gildii ponieważ twoje czatowe przywileje zostały wycofane.",
"cannotInviteWhenMuted": "Nie możesz zaprosić nikogo do gildii lub drużyny ponieważ twoje czatowe przywileje zostały wycofane.",
"newChatMessagePlainNotification": "Nowa wiadomość w <%= groupName %> od <%= authorName %>. Kliknij tu by otworzyć stronę czatu!",
@@ -277,10 +277,10 @@
"confirmRemoveTag": "Czy na pewno chcesz usunąć \"<%= tag %>\"?",
"groupHomeTitle": "Strona Główna",
"assignTask": "Przydziel zadanie",
- "claim": "Zgłoś się",
+ "claim": "Przejmij zadanie",
"removeClaim": "Usuń roszczenie",
- "onlyGroupLeaderCanManageSubscription": "Tylko przywódca grupy może zarządzać subskrypcjami grupy.",
- "yourTaskHasBeenApproved": "Twoje zadanie <%= taskText %> zostało zatwierdzone.",
+ "onlyGroupLeaderCanManageSubscription": "Tylko przywódca grupy może zarządzać subskrypcjami grupy",
+ "yourTaskHasBeenApproved": "Twoje zadanie <%= taskText %> zostało zatwierdzone.",
"taskNeedsWork": "<%= managerName %> oznaczył <%= taskText %> jako potrzebujące dodatkowej pracy.",
"userHasRequestedTaskApproval": "<%= user %> chce zatwierdzenia <%= taskName %>",
"approve": "Zatwierdź",
@@ -332,21 +332,21 @@
"claimedBy": "\n\nZgłoszone przez: <%= claimingUsers %>",
"cantDeleteAssignedGroupTasks": "Nie możesz usunąć zadań grupy, które są przypisane do ciebie.",
"confirmGuildPlanCreation": "Stworzyć tę grupę?",
- "groupPlanUpgraded": "<%= groupName %> was upgraded to a Group Plan!",
- "groupPlanCreated": "<%= groupName %> was created!",
+ "groupPlanUpgraded": "<%= groupName %> przekształcono w Plan Grupowy!",
+ "groupPlanCreated": "Utworzono <%= groupName %>!",
"onlyGroupLeaderCanInviteToGroupPlan": "Tylko przywódca grupy może zapraszać użytkowników do grupy z abonamentem.",
"paymentDetails": "Szczegóły płatności",
"aboutToJoinCancelledGroupPlan": "Zamierzasz dołączyć do grupy z anulowanym planem. NIE będziesz mógł otrzymać darmowego abonamentu.",
- "cannotChangeLeaderWithActiveGroupPlan": "Nie możesz zmienić lidera grupy, dopóki posiada ona aktywny plan",
+ "cannotChangeLeaderWithActiveGroupPlan": "Nie możesz zmienić lidera grupy, dopóki posiada ona aktywny plan.",
"leaderCannotLeaveGroupWithActiveGroup": "Lider nie może opuścić grupy, dopóki posiada ona aktywny plan",
"youHaveGroupPlan": "Otrzymujesz darmowy abonament, ponieważ jesteś członkiem grupy posiadającej swój Plan Grupowy. Zostanie on zakończony, kiedy nie będziesz już przynależał do grupy posiadającej Plan Grupowy. Wszystkie miesiące dodatkowego abonamentu, które posiadasz zostaną zużyte po zakończeniu Planu Grupowego.",
"cancelGroupSub": "Anuluj plan grupowy",
- "confirmCancelGroupPlan": "Czy jesteś pewien, że chcesz anulować Plan Grupowy i pozbawić wszystkich członków płynących z niego korzyści, łącznie z ich darmowym abonamentem ?",
+ "confirmCancelGroupPlan": "Czy jesteś pewien, że chcesz anulować swój Plan Grupowy? Wszyscy członkowie Grupy utracą subskrypcje i korzyści.",
"canceledGroupPlan": "Anulowano plan grupowy",
"groupPlanCanceled": "Plan grupowy stanie się nieaktywny",
"purchasedGroupPlanPlanExtraMonths": "Posiadasz <%= months %> miesięcy dodatkowego abonamentu grupowego.",
- "addManager": "Assign Manager",
- "removeManager2": "Unassign Manager",
+ "addManager": "Przypisz Menedżera",
+ "removeManager2": "Odwołaj Menedżera",
"userMustBeMember": "Użytkownik musi być managerem",
"userIsNotManager": "Użytkownik nie jest managerem",
"canOnlyApproveTaskOnce": "To zadanie zostało już zatwierdzone.",
@@ -356,20 +356,20 @@
"badAmountOfGemsToPurchase": "Wartość musi wynosić przynajmniej 1.",
"groupPolicyCannotGetGems": "Zasady grupy, do której przynależysz uniemożliwiają jej członkom otrzymywanie klejnotów.",
"viewParty": "Pokaż Drużynę",
- "newGuildPlaceholder": "Wprowadź nazwę gildii",
+ "newGuildPlaceholder": "Wprowadź nazwę gildii.",
"guildMembers": "Członkowie gildii",
"guildBank": "Bank gildii",
- "chatPlaceholder": "Tutaj wpisz swoją wiadomość do członków Gildii.",
- "partyChatPlaceholder": "Tutaj wpisz swoją wiadomość do członków Drużyny.",
+ "chatPlaceholder": "Tutaj wpisz swoją wiadomość do członków Gildii",
+ "partyChatPlaceholder": "Tutaj wpisz swoją wiadomość do członków Drużyny",
"fetchRecentMessages": "Pobierz ostatnie wiadomości",
"like": "Lubię to",
"liked": "Lubisz to",
"joinGuild": "Dołącz do Gildii",
"inviteToGuild": "Zaproś do Gildii",
- "inviteToParty": "Invite to Party",
- "inviteEmailUsername": "Invite via Email or Username",
- "inviteEmailUsernameInfo": "Invite users via a valid email or username. If an email isn't registered yet, we'll invite them to join.",
- "emailOrUsernameInvite": "Email address or username",
+ "inviteToParty": "Zaproś do Drużyny",
+ "inviteEmailUsername": "Zaproś przez e-mail lub nazwę użytkownika",
+ "inviteEmailUsernameInfo": "Zaproś użytkowników poprzez poprawny e-mail lub nazwę użytkownika. Jeśli e-mail nie jest jeszcze zarejestrowany, zaprosimy ich do przyłączenia.",
+ "emailOrUsernameInvite": "Adres e-mail lub nazwa użytkownika",
"messageGuildLeader": "Napisz wiadomość do przywódcy gildii",
"donateGems": "Podaruj klejnoty",
"updateGuild": "Zaktualizuj Gildię",
@@ -388,7 +388,7 @@
"bronzeTier": "Ranga Brązowa",
"privacySettings": "Ustawienia prywatności",
"onlyLeaderCreatesChallenges": "Tylko Przywódca może tworzyć Wyzwania",
- "onlyLeaderCreatesChallengesDetail": "With this option selected, ordinary group members cannot create Challenges for the group.",
+ "onlyLeaderCreatesChallengesDetail": "Przy zaznaczeniu tej opcji, zwykli członkowie grupy nie będą mogli tworzyć wyzwań dla grupy.",
"privateGuild": "Prywatna Gildia",
"charactersRemaining": "<%= characters %> znaków pozostało",
"guildSummary": "Podsumowanie",
@@ -398,15 +398,15 @@
"markdownFormattingHelp": "[Pomoc na temat formatowania Markdown](http://habitica.fandom.com/wiki/Markdown_Cheat_Sheet)",
"partyDescriptionPlaceholder": "Tutaj jest opis Twojej Drużyny. On definiuje to co robimy w tej Drużynie. Jeśli chcesz się dowiedzieć się więcej na temat tego co się robi w tej Drużynie to przeczytaj opis. Dajesz i nie przestajesz.",
"guildGemCostInfo": "Koszt w Klejnotach promuje tworzenie wysokiej jakości Gildii i zostaje przeniesione do banku Gidli.",
- "noGuildsTitle": "Nie jesteś członkiem żadnej Gildii",
+ "noGuildsTitle": "Nie jesteś członkiem żadnej Gildii.",
"noGuildsParagraph1": "Gildie są grupami społecznymi stworzonymi przez innych graczy, które mogą zaofiarować Ci wsparcie, odpowiedzialność i zachęcającą rozmowę.",
"noGuildsParagraph2": "Naciśnij zakładkę Odkryj Gildie by zobaczyć Gildie polecane na podstawie zainteresowań, przeglądnąć publiczne Gildie Habitiki albo stworzyć własną Gildie.",
- "noGuildsMatchFilters": "We couldn't find any matching Guilds.",
+ "noGuildsMatchFilters": "Nie możemy znaleźć żadnej, pasującej Gildii.",
"privateDescription": "Prywatna Gildia nie będzie się wyświetlać w katalogu Gildii Habitiki. Nowy członkowie mogą dołączyć tylko poprzez zaproszenie.",
"removeInvite": "Usuń Zaproszenie",
"removeMember": "Usuń Członka",
"sendMessage": "Wyślij wiadomość",
- "promoteToLeader": "Transfer Ownership",
+ "promoteToLeader": "Przekaż prawa właściciela",
"inviteFriendsParty": "Zaproszenie przyjaciela do Twojej Drużyny otrzymasz ekskluzywny zwój misji by razem walczyć z Bazy-Listą!",
"upgradeParty": "Ulepsz Drużynę",
"createParty": "Stwórz Drużynę",
@@ -416,7 +416,7 @@
"startYourOwnPartyTitle": "Utwórz swoją własną drużynę",
"startYourOwnPartyDescription": "Walcz z potworami samemu albo zaproś tylu swoich przyjaciół ile chcesz!",
"wantToJoinPartyTitle": "Chcesz dołączyć do drużyny?",
- "wantToJoinPartyDescription": "Give your username to a friend who already has a Party, or head to the Party Wanted Guild to meet potential comrades!",
+ "wantToJoinPartyDescription": "Podaj swoją nazwę użytkownika przyjacielowi, który ma już Drużynę lub udaj się do Gildii Poszukiwaczy Drużyn aby poznać nowych przyjaciół!",
"copy": "Kopiuj",
"inviteToPartyOrQuest": "Zaproś Drużynę do Misji",
"inviteInformation": "Naciśnięcie \"Zaproś\" wyśle zaproszenie do członków Twojej Drużyny. Misja rozpocznie się kiedy wszyscy członkowie ją zaakceptują albo odrzucą.",
@@ -425,7 +425,7 @@
"upgrade": "Ulepsz",
"selectPartyMember": "Wybierz Członka Drużyny",
"areYouSureDeleteMessage": "Czy jesteś pewny, że chcesz usunąć tą wiadomość?",
- "reverseChat": "Odwróć Chat.",
+ "reverseChat": "Odwróć Chat",
"invites": "Zaproszenia",
"details": "Szczegóły",
"participantDesc": "Misja się rozpocznie kiedy wszyscy członkowie albo ją zaakceptują albo odrzucą. Tylko ci którzy nacisnęli \"Zaakceptuj\" będą mogli uczestniczyć w misji i otrzymać nagrody.",
@@ -477,8 +477,12 @@
"whatIsGroupManagerDesc": "Zarządca Grupy jest użytkownikiem, który nie ma dostępu do szczegółów płatności, ale może tworzyć, przydzielać i akceptować wspólne Zadania dla członków Grupy. Awansuj Zarządców z listy członków Grupy.",
"goToTaskBoard": "Idź do Tablicy Zadań",
"sharedCompletion": "Warunkowe zakończenie",
- "recurringCompletion": "None - Group task does not complete",
- "singleCompletion": "Single - Completes when any assigned user finishes",
- "allAssignedCompletion": "All - Completes when all assigned users finish",
- "pmReported": "Dziękujemy za zaraportowanie tej wiadomości."
+ "recurringCompletion": "Nikt - Zadanie grupowe nie zostało zrealizowane",
+ "singleCompletion": "Niektórzy - Ustawiane, gdy ktoś z przypisanych użytkowników zrealizuje zadanie",
+ "allAssignedCompletion": "Wszyscy - Ustawiane, gdy wszyscy przypisani użytkownicy zakończą zadanie",
+ "pmReported": "Dziękujemy za zaraportowanie tej wiadomości.",
+ "groupActivityNotificationTitle": "<%= user %> napisał w <%= group %>",
+ "suggestedGroup": "Sugerowane, ponieważ jesteś nowicjuszem w Habitica.",
+ "taskClaimed": "<%= userName %> przejął zadanie <%= taskText %>.",
+ "youHaveBeenAssignedTask": "<%= managerName %> przyznał(a) Ci zadanie <%= taskText %>."
}
diff --git a/website/common/locales/pl/limited.json b/website/common/locales/pl/limited.json
index cd800dbcec..40444bfc91 100644
--- a/website/common/locales/pl/limited.json
+++ b/website/common/locales/pl/limited.json
@@ -160,6 +160,12 @@
"summer2019WaterLilyMageSet": "Lilia Wodna (Mag)",
"summer2019ConchHealerSet": "Muszla (Medyk)",
"summer2019HammerheadRogueSet": "Rekin Młot (Łotrzyk)",
- "eventAvailabilityReturning": "Możliwość zakupu do <%= availableDate(locale) %>. Ten eliksir został wprowadzony w <%= previousDate(locale) %>.",
- "june2018": "Czerwiec 2018"
+ "eventAvailabilityReturning": "Możliwość zakupu do <%= availableDate(locale) %>. Ten eliksir był ostatnio dostępny w dniu <%= previousDate(locale) %>.",
+ "june2018": "Czerwiec 2018",
+ "september2018": "Wrzesień 2018",
+ "september2017": "Wrzesień 2017",
+ "fall2019RavenSet": "Kruk (Wojownik)",
+ "fall2019LichSet": "Nieumarły (Medyk)",
+ "fall2019CyclopsSet": "Cyklop (Mag)",
+ "fall2019OperaticSpecterSet": "Upiór w operze (Łotrzyk)"
}
diff --git a/website/common/locales/pl/npc.json b/website/common/locales/pl/npc.json
index ac6b04c631..e6b38bbd9a 100644
--- a/website/common/locales/pl/npc.json
+++ b/website/common/locales/pl/npc.json
@@ -21,7 +21,7 @@
"sleepDescription": "Potrzebujesz przerwy? Odwiedź Gospodę Daniela by zatrzymać bardziej skomplikowane elementy Habitiki:",
"sleepBullet1": "Pominięte Codziennie nie zadadzą Ci obrażeń",
"sleepBullet2": "Zadania nie stracą serii ani nie osłabią się w kolorze",
- "sleepBullet3": "Bossowie nie zadadzą ci obrażeń za ominięte Codziennie",
+ "sleepBullet3": "Bossowie nie zadadzą ci obrażeń za ominięte, własne Codziennie",
"sleepBullet4": "Twoje obrażenia dla bossa albo zebranie przedmiotów zostaną jako oczekujące do końca dnia",
"pauseDailies": "Wstrzymaj obrażenia",
"unpauseDailies": "Wznów otrzymywanie obrażeń",
diff --git a/website/common/locales/pl/pets.json b/website/common/locales/pl/pets.json
index 9c7cd75062..190af44e4c 100644
--- a/website/common/locales/pl/pets.json
+++ b/website/common/locales/pl/pets.json
@@ -144,5 +144,6 @@
"notEnoughMounts": "Nie zabrałeś/aś wystarczająco wierzchowców",
"notEnoughPetsMounts": "Nie zebrałeś/aś wystarczająco chowańców i wierzchowców",
"wackyPets": "Zwariowane chowańce",
- "filterByWacky": "Zwariowane"
+ "filterByWacky": "Zwariowane",
+ "gryphatrice": "Bazyligryfek"
}
diff --git a/website/common/locales/pl/quests.json b/website/common/locales/pl/quests.json
index 8c94fbc93a..3896977b6f 100644
--- a/website/common/locales/pl/quests.json
+++ b/website/common/locales/pl/quests.json
@@ -71,8 +71,8 @@
"scrollsText1": "Do wykonania misji potrzebna jest drużyna. Jeśli chcesz je wykonywać w pojedynkę,",
"scrollsText2": "stwórz pustą drużynę",
"scrollsPre": "Jeszcze nie odblokowałeś tej misji!",
- "alreadyEarnedQuestLevel": "Już zdobyłeś tę misję dzięki osiągnięciu poziomu <%= level %>. ",
- "alreadyEarnedQuestReward": "Już zdobyłeś tę misję dzięki ukończeniu <%= priorQuest %>. ",
+ "alreadyEarnedQuestLevel": "Już zdobyłeś(-aś) tą misję dzięki osiągnięciu poziomu <%= level %>. ",
+ "alreadyEarnedQuestReward": "Już zdobyłeś(-aś) tą misję dzięki ukończeniu <%= priorQuest %>. ",
"completedQuests": "Zakończył następujące misje",
"mustComplete": "Musisz najpierw ukończyć <%= quest %>.",
"mustLevel": "Musisz mieć co najmniej poziom <%= level %>, by rozpocząć tą misję.",
@@ -136,5 +136,6 @@
"chatItemQuestFinish": "Wszystkie przedmioty zostały znalezione! Drużyna otrzymuje swoje nagrody.",
"chatQuestAborted": "<%= username %> przerywa drużynową misję <%= questName %>.",
"chatQuestCancelled": "<%= username %> anuluje drużynową misję <%= questName %>.",
- "tavernBossTired": "<%= bossName %> próbuje wyzwolić <%= rageName %> ale zmęczenie na to nie pozwala."
+ "tavernBossTired": "<%= bossName %> próbuje wyzwolić <%= rageName %> ale zmęczenie na to nie pozwala.",
+ "questInvitationNotificationInfo": "Zostałeś(-aś) zaproszony(-a) do przyłączenia się do misji"
}
diff --git a/website/common/locales/pl/questscontent.json b/website/common/locales/pl/questscontent.json
index fd4d3faae2..a83fdb1e55 100644
--- a/website/common/locales/pl/questscontent.json
+++ b/website/common/locales/pl/questscontent.json
@@ -311,7 +311,7 @@
"questSnailCompletion": "Dosięgasz uderzeniem skorupy wielkiego ślimaka i rozbijasz ją na pół. Uwolniona z niego, fala wody zmywa szlam, a orzeźwieni Habiticanie radują się w koło. \"Patrzcie!\" woła @Misceo. \"Tam, w resztkach błota leży niewielka grupa ślimaczych jaj.\"",
"questSnailBoss": "Ślimak ze Ślęczącego Ścieku",
"questSnailDropSnailEgg": "Ślimak (jajo)",
- "questSnailUnlockText": "Odblokowuje zakup jaj ślimaka na targu",
+ "questSnailUnlockText": "Odblokowuje dostęp do kupna jaj ślimaka na Targu",
"questBewilderText": "Be-Wilder",
"questBewilderNotes": "Przyjęcie zaczyna się jak każde inne.
Przystawki są wyśmienite muzyka gra i nawet można przyzwyczaić się do tańczących słoni. Habitanie śmieją się i zaciągają zapachem kwiatów, szczęśliwi że mają chwilę wytchnienia od swoich najbardziej wymagających zadań, a Prima Aprilis uwija się wśród nich, ochoczo prezentując triki i robiąc żarty.
Kiedy na wieży zegarowej w Mistiflying wybija północ, Prima Aprilis wchodzi na scenę by wygłosić przemowę.
“Przyjaciele! Wrogowie! Znajomi! Nadstawcie uszy.” Tłum chichocze gdy zwierzęce uszy wyrastają im na głowach.
“Jak już wiecie,” kontynuuje Aprilis, “moje dziwaczne iluzje zwykle utrzymują się jeden dzień. Lecz mam zaszczyt ogłosić że odkryłem coś co zagwarantuje wieczną zabawę, bez potrzeby zmagania się z ciężarem odpowiedzialności. Uroczy Habitanie, poznajcie mojego magicznego przyjaciela... Be-Wilder'a!”
Lemoness zbladła, upuszczając przekąski. “Czekajcie! Nie wierz--”
Nagle obłoki mgły, gęste i połyskujące, zaczynają wypełniać pomieszczenie, wirując dookoła Prima Aprilis'a, scalają się w puchowe pióra. Gawiedź zamiera gdy potwór rozwija swoje migoczące iluzją skrzydła. Wydaje przy tym straszny szyderczy śmiech.
“Och, musiały minąć całe wieki by Habitanie stali się wystarczająco głupi by mnie przyzwać. Jakie to cudowne uczucie móc w końcu posiadać ciało.”
Bzycząc w opresji, magiczne pszczoły Mistiflying uciekają z dryfującego miasta, w chmurach. Jeden po drugim, wiosenne kwiaty zamykają swoje kwiatostany.
“Moi drodzy przyjaciele, czemu się boicie?” wykrakał Be-Wilder, trzepocząc skrzydłami. “Nie będziecie musieli już płacić za swoje nagrody. Dam wam wszystko czego pragniecie!”
Deszcz monet sypie się z nieba, uderzając w ziemię z ogromną siłą, a mieszkańcy krzyczą i w popłochu szukają schronienia. “To jakiś żart?” Baconsaur krzyczy gdy złoto roztrzaskuje dachówki.
PainterProphet uskakuje przed piorunem uderzającym tuż nad jego głową. Mgła przesłania słońce. “Nie! Nie tym razem, nie wierzę w to!”
Szybko, Habitanie, nie pozwólcie Bossowi Światowemu odciągnąć nas od naszych celów! Skupcie się na zadaniach do ukończenia abyśmy mogli ocalić nie tylko Mistiflying -- ale i nasze życia.",
"questBewilderCompletion": "Be-Wilder POKONANY!
Udało nam się! Be-Wilder wydaje z siebie lamentujący płacz i wznosi się w powietrze, rozrzucając pióra, które deszczem opadają na ziemie. Powoli i stopniowo przeistacza się w chmurę iskrzącej mgiełki. Gdy tylko słońce zaczyna przedzierać swoje pierwsze promyki przez mgłę, Be-Wilder wyparowuje, ujawniając się kaszlące, przeszczęśliwe ludzkie formy Bailey'a, Matt'a, Alex'a.... i Prima Aprilis'a we własnej osobie.
Mistiflying jest uratowane!
Prima Aprilis czuje wstyd i wygląda na zakłopotanego. “Oh, hm,” mówi. “Być może troszeczkę…. przesadziłem.”
Tłum wydaje ciche pomruki. Przemokłe kwiaty znów rozkwitają przy ścieżkach. Gdzieś w oddali dach zawala się ze spektakularnym hukiem.
“Ee, tak” wybąkuje Prima Aprilis. “To jest. Chciałem powiedzieć, że bardzo przepraszam.” Zatacza się na bok. “Doszedłem do wniosku że nie można ciągle się bawić. Nie zaszkodzi czasmi się skupić na zadaniach. Może popracuję nad lepszymi dowcipami na przyszły rok.”
Redphoenix kaszle znacząco.
“Oczywiście zaraz po tym jak zabiorę się za wiosenne porządki w mieście!” mówi Prima Aprilis. “Nie bójcie się, doprowadzę Habit City do całkowitego porządku. Nikt nie jest lepszy ode mnie we władaniu mopem dwuręcznym.”
Rozradowany wędrowny zespół zaczyna grać piosenki.
Nie minie wiele zanim Habit City powróci do normalnego stanu. Teraz, gdy Be-Wilder wyparował, magiczne pszczoły Mistiflying wracają do pracy. Miasto znów zakwitnie i popłynie jeszcze raz.
Gdy Habitanie ściskają magiczne pszczoły, Prima Aprilisowi zapaliła się lampka nad głową. “Oho, mam pomysł! Chcielibyście zachować niektóre z tych kędzierzawych pszczół - Chowańców i Wierzchowców? Ten prezent doskonale symbolizuje równowagę pomiędzy ciężką pracą a słodką nagrodą. Chyba staje się zbyt nudny i alegoryczny?” Puszcza oko. “Poza tym one nie mają żądeł!”",
@@ -397,7 +397,7 @@
"questFerretCompletion": "Pokonałeś oszustkę o delikatnym futrze i @UncommonCriminal oddaje ludziom z tłumu ich pieniądze. Zostaje nawet odrobina złota dla ciebie. Dodatkowo, wygląda na to, że Niegodziwa Fretka podczas pośpiesznej ucieczki upuściła jakieś jajka!",
"questFerretBoss": "Niegodziwa Fretka",
"questFerretDropFerretEgg": "Fretka (jajo)",
- "questFerretUnlockText": "Odblokowuje dostęp do kupna jaj fretki na targu",
+ "questFerretUnlockText": "Odblokowuje dostęp do kupna jaj fretki na Targu",
"questDustBunniesText": "Dzikie Kurzowe Króliki",
"questDustBunniesNotes": "It's been a while since you've done any dusting in here, but you're not too worried—a little dust never hurt anyone, right? It's not until you stick your hand into one of the dustiest corners and feel something bite that you remember @InspectorCaracal's warning: leaving harmless dust sit too long causes it to turn into vicious dust bunnies! You'd better defeat them before they cover all of Habitica in fine particles of dirt!",
"questDustBunniesCompletion": "Kurzowe króliki zmieniły się w chmurę... no cóż, kurzu. Kiedy opada, rozglądasz się dookoła. Zapomniałeś już jak ładnie wygląda to miejsce, kiedy jest czyste. Zauważasz mały stos złota tam, gdzie dotąd był kurz. Hmm, a tak się zastanawiałeś, gdzie on się podział!",
@@ -638,7 +638,7 @@
"questSilverText": "Srebrny Przepis",
"questSilverCollectSilverIngots": "Srebrne Sztabki",
"questSilverDropSilverPotion": "Srebrny Eliksir Wyklucia",
- "questSilverUnlockText": "Odblokowuje możliwość zakupu w sklepie Srebrnych eliksirów wyklucia",
+ "questSilverUnlockText": "Odblokowuje możliwość zakupu Srebrnych eliksirów wyklucia na Targu",
"questDolphinText": "Delfin Zwątpienia",
"questDolphinBoss": "Delfin Zwątpienia"
}
diff --git a/website/common/locales/pl/settings.json b/website/common/locales/pl/settings.json
index 8ba92e1d16..2c840cb90a 100644
--- a/website/common/locales/pl/settings.json
+++ b/website/common/locales/pl/settings.json
@@ -119,8 +119,8 @@
"giftedSubscriptionInfo": "<%= name %> podarował Ci <%= months %> miesięczną subskrypcję",
"giftedSubscriptionFull": "Hej <%= username %>, <%= sender %> podarował Ci <%= monthCount %> miesięcy subskrypcji!",
"giftedSubscriptionWinterPromo": "Cześć <%= username %>, otrzymałeś <%= monthCount %> miesięcy subskrybcji w ramach naszej promocji świątecznego rozdawania prezentów!",
- "invitedParty": "Zaproszony do Drużyny",
- "invitedGuild": "Zaproszony do Gildii",
+ "invitedParty": "Zostałeś(-aś) zaproszony(-a) do Drużyny",
+ "invitedGuild": "Zostałeś(-aś) zaproszony(-a) do Gildii",
"importantAnnouncements": "Przypomnienia o meldowaniu, aby wykonywać zadania i otrzymywać nagrody",
"weeklyRecaps": "Podsumowanie aktywności na koncie w ostatnim tygodniu (Uwaga: z powodów wydajnościowych ta opcja jest aktualnie wyłączona, ale mamy nadzieję przywrócić ją do działania już niedługo!)",
"onboarding": "Wskazówki dot. zakładania konta Habitiki",
@@ -203,6 +203,12 @@
"goToSettings": "Przejdź do ustawień",
"usernameVerifiedConfirmation": "Twoja nazwa użytkownika, <%= username %>, została potwierdzona!",
"usernameNotVerified": "Prosimy potwierdzić swoją nazwę użytkownika.",
- "changeUsernameDisclaimer": "Wkrótce będziemy zmieniać nazwy logowania na unikalne, publiczne nazwy użytkowników. Nowe nazwy użytkowników będą używane do: zaproszeń, wywoływania innych osób na czacie poprzez @nazwę oraz w korespondencji.",
- "verifyUsernameVeteranPet": "Jedno zwierzątko z oddziału Weteranów będzie czekało na ciebie po potwierdzeniu!"
+ "changeUsernameDisclaimer": "Nowe nazwy użytkowników będą używane do: zaproszeń, wywoływania innych osób na czacie poprzez @nazwę oraz w korespondencji.",
+ "verifyUsernameVeteranPet": "Jedno zwierzątko z oddziału Weteranów będzie czekało na ciebie po potwierdzeniu!",
+ "subscriptionReminders": "Przypomnienia o subskrypcji",
+ "newPMNotificationTitle": "Nowa wiadomość od <%= name %>",
+ "onlyPrivateSpaces": "Tylko w przestrzeniach prywatnych",
+ "everywhere": "Gdziekolwiek",
+ "suggestMyUsername": "Podpowiedz nazwę użytkownika",
+ "mentioning": "Wspomnienia"
}
diff --git a/website/common/locales/pl/spells.json b/website/common/locales/pl/spells.json
index 1d9531f060..d42459e3a2 100644
--- a/website/common/locales/pl/spells.json
+++ b/website/common/locales/pl/spells.json
@@ -38,9 +38,9 @@
"spellSpecialSnowballAuraNotes": "Zmień członka drużyny w mroźnego bałwana!",
"spellSpecialSaltText": "Sól",
"spellSpecialSaltNotes": "Cofnij zaklęcie, które zmieniło cię w bałwana.",
- "spellSpecialSpookySparklesText": "Straszne iskierki",
+ "spellSpecialSpookySparklesText": "Upiorne iskierki",
"spellSpecialSpookySparklesNotes": "Zamień swojego przyjaciela w przeźroczystego towarzysza!",
- "spellSpecialOpaquePotionText": "Nieprzejrzysty eliksir",
+ "spellSpecialOpaquePotionText": "Eliksir nieprzejrzystości",
"spellSpecialOpaquePotionNotes": "Cofnij zaklęcie, które uczyniło Cię niewidzialnym.",
"spellSpecialShinySeedText": "Lśniące nasiono",
"spellSpecialShinySeedNotes": "Zamień przyjaciela w radosnego kwiatka!",
diff --git a/website/common/locales/pl/subscriber.json b/website/common/locales/pl/subscriber.json
index 395171e6cd..a9254a06ae 100644
--- a/website/common/locales/pl/subscriber.json
+++ b/website/common/locales/pl/subscriber.json
@@ -224,5 +224,6 @@
"mysterySet201904": "Zestaw Luksusowych Opali",
"mysterySet201905": "Zestaw Oślepiającego Smoka",
"subCanceledTitle": "Subskrypcja anulowana",
- "mysterySet201908": "Zestaw Wyluzowanego Fauna"
+ "mysterySet201908": "Zestaw Wyluzowanego Fauna",
+ "mysterySet201909": "Zestaw wesołego orzeszka"
}
diff --git a/website/common/locales/pt_BR/achievements.json b/website/common/locales/pt_BR/achievements.json
index d387702924..129ffbfe9e 100644
--- a/website/common/locales/pt_BR/achievements.json
+++ b/website/common/locales/pt_BR/achievements.json
@@ -24,5 +24,15 @@
"achievementAridAuthority": "Autoridade Árida",
"achievementDustDevilModalText": "Você coletou todos os Mascotes do tipo Deserto!",
"achievementDustDevilText": "Coletou todos os Mascotes do tipo Deserto.",
- "achievementDustDevil": "Diabo da Poeira"
+ "achievementDustDevil": "Diabo da Poeira",
+ "achievementKickstarter2019Text": "Apoiou o Projeto dos Broches no Kickstarter de 2019",
+ "achievementKickstarter2019": "Apoiador dos Broches Kickstarter",
+ "achievementUndeadUndertakerModalText": "Você domesticou todas as Montarias Zumbis!",
+ "achievementUndeadUndertakerText": "Domesticou todas as Montarias Zumbis.",
+ "achievementUndeadUndertaker": "Agente Morto-vivo",
+ "achievementMonsterMagusModalText": "Você coletou todos os Mascotes Zumbis!",
+ "achievementMonsterMagusText": "Coletou todos os Mascotes Zumbis.",
+ "achievementMonsterMagus": "Mago(a) Monstruoso(a)",
+ "achievementPartyOn": "Seu grupo cresceu para 4 membros!",
+ "achievementPartyUp": "Você se juntou a um membro do grupo!"
}
diff --git a/website/common/locales/pt_BR/backgrounds.json b/website/common/locales/pt_BR/backgrounds.json
index b58e9f7117..b2ead1466f 100644
--- a/website/common/locales/pt_BR/backgrounds.json
+++ b/website/common/locales/pt_BR/backgrounds.json
@@ -464,5 +464,12 @@
"backgroundLakeWithFloatingLanternsText": "Lago com as Lanternas Flutuantes",
"backgrounds072019": "Conjunto 62: Lançado em Julho de 2019",
"backgroundUnderwaterVentsNotes": "Mergulhe bem fundo, abaixo das Aberturas Subaquáticas.",
- "backgroundUnderwaterVentsText": "Aberturas Subaquáticas"
+ "backgroundUnderwaterVentsText": "Aberturas Subaquáticas",
+ "backgroundMonsterMakersWorkshopNotes": "Experimente ciências desacreditadas em uma Oficina de Criadores de Monstros.",
+ "backgroundMonsterMakersWorkshopText": "Oficina do Criador de Monstros",
+ "backgroundPumpkinCarriageNotes": "Ande em uma Carruagem de Abóbora encantada antes que o relógio aconteça à meia-noite.",
+ "backgroundPumpkinCarriageText": "Carruagem de Abóbora",
+ "backgroundFoggyMoorNotes": "Fique atento com sua travessia em uma Charneca Nevoenta.",
+ "backgroundFoggyMoorText": "Charneca Nevoenta",
+ "backgrounds102019": "Conjunto 65: Lançado em Outubro de 2019"
}
diff --git a/website/common/locales/pt_BR/content.json b/website/common/locales/pt_BR/content.json
index 503f149287..fb8b9f004a 100644
--- a/website/common/locales/pt_BR/content.json
+++ b/website/common/locales/pt_BR/content.json
@@ -350,5 +350,6 @@
"questEggDolphinText": "Golfinho",
"questEggRobotText": "Robô",
"questEggDolphinMountText": "Golfinho",
- "hatchingPotionShadow": "Sombra"
+ "hatchingPotionShadow": "Sombra",
+ "premiumPotionUnlimitedNotes": "Não utilizável em ovos de mascotes adquiridos em missões."
}
diff --git a/website/common/locales/pt_BR/gear.json b/website/common/locales/pt_BR/gear.json
index 933366a4b8..45a5721795 100644
--- a/website/common/locales/pt_BR/gear.json
+++ b/website/common/locales/pt_BR/gear.json
@@ -1874,5 +1874,90 @@
"armorSpecialKS2019Notes": "Brilhando por dentro como o coração nobre de um grifo, essa armadura resplandecente te encoraja a se orgulhar de suas realizações. Aumenta a Constituição em <%= con %>.",
"armorSpecialKS2019Text": "Armadura do Grifo Mítico",
"weaponSpecialKS2019Notes": "Curvo como o bico e as garras de um grifo, este cabo ornamentado o lembra da sua força quando a tarefa à frente parecer assustadora. Aumenta a Força em <%= str %>.",
- "weaponSpecialKS2019Text": "Gládio do Grifo Mítico"
+ "weaponSpecialKS2019Text": "Gládio do Grifo Mítico",
+ "headAccessoryMystery201908Text": "Chifres do Fauno Descomprometido",
+ "headAccessoryMystery201906Notes": "Diz a lenda que esses ouvidos finos ajudam a escutar os chamados e canções de todos os habitantes das profundezas. Não confere benefícios. Item de Assinante em Junho de 2019.",
+ "headAccessoryMystery201906Text": "Orelhas de Koi",
+ "headAccessoryMystery201905Notes": "Esses chifres são afiados e brilhantes. Não confere benefícios. Item de Assinante em Maio de 2019.",
+ "headAccessoryMystery201905Text": "Chifres de Dragão Deslumbrantes",
+ "backMystery201905Notes": "Voe para reinos incalculáveis com essas asas iridescentes. Não confere benefícios. Item de Assinante em Maio de 2019.",
+ "backMystery201905Text": "Asas Deslumbrantes do Dragão",
+ "shieldArmoireMasteredShadowNotes": "Seus poderes trouxeram essas sombras para o seu lado para cumprir suas ordens. Aumentam a Percepção e Constituição em <%= attrs %>, cada. Armário Encantado: Conjunto do(a) Mestre(a) das Sombras (Item 4 de 4).",
+ "shieldArmoireMasteredShadowText": "Sombra Dominada",
+ "shieldArmoirePolishedPocketwatchNotes": "Você tem tempo. E isso deixa seu visual muito charmoso. Aumenta a Inteligência em <%= int %>. Armário Encantado: Item Independente.",
+ "shieldArmoirePolishedPocketwatchText": "Relógio de Bolso Polido",
+ "shieldArmoireTrustyUmbrellaNotes": "Os mistérios costumam ser acompanhados por intempéries, portanto esteja preparado! Aumenta a Inteligência em <%= int %>. Armário Encantado:Conjunto do Detetive (Item 4 de 4).",
+ "shieldArmoireTrustyUmbrellaText": "Guarda-chuva Fiel",
+ "shieldSpecialFall2019HealerNotes": "Aproveite o lado sombrio das artes do curandeiro com este Grimório! Aumenta a Constituição em <%= con %>. Equipamento de Edição Limitada do Outono de 2019.",
+ "shieldSpecialFall2019HealerText": "Grimório Grotesco",
+ "shieldSpecialFall2019WarriorNotes": "O brilho escuro da pena de um corvo se tornou sólido, este escudo irá frustrar todos os ataques. Aumenta a Constituição em <%= con %>. Equipamento de Edição Limitada do Outono de 2019.",
+ "shieldSpecialFall2019WarriorText": "Escudo do Corvo das trevas",
+ "shieldSpecialSummer2019MageNotes": "Suando ao sol do verão? Não! Realizando uma conjuração elementar simples para encher o lago de lírios. Aumenta a Percepção em <%= per %>. Equipamento de Edição Limitada do Verão de 2019.",
+ "shieldSpecialSummer2019MageText": "Gotas de Água pura",
+ "shieldSpecialSummer2019HealerNotes": "Informe àqueles que precisam de ajuda que você está chegando com o som alto desta trombeta de concha. Equipamento de Edição Limitada do Verão de 2019. Aumenta a Constituição em 9. ",
+ "shieldSpecialSummer2019HealerText": "Trombeta de Concha",
+ "shieldSpecialSummer2019WarriorText": "Escudo de Meia Concha",
+ "shieldSpecialKS2019Notes": "Brilhando como a casca de um ovo de grifo, este magnífico escudo mostra como estar pronto para ajudar quando seus próprios encargos são leves. Aumenta a Percepção em <%= per %>.",
+ "shieldSpecialKS2019Text": "Escudo do Grifo Mítico",
+ "headArmoireShadowMastersHoodNotes": "Este capuz lhe concede o poder de ver até as mais profundas trevas. Ocasionalmente, podem ser necessários colírios apesar disso. Aumenta Percepção e Constituição em <%= attrs %>, cada. Armário Encantado: Conjunto do(a) Mestre(a) das Sombras (Item 2 de 4).",
+ "headArmoireShadowMastersHoodText": "Capuz do(a) Mestre(a) das Sombras",
+ "headArmoireDeerstalkerCapNotes": "Este chapéu é perfeito para excursões rurais, mas também é um equipamento aceitável para a solução de mistérios! Aumenta Inteligência em <%= int %>. Armário Encantado: Conjunto do Detetive (Item 1 de 4).",
+ "headArmoireDeerstalkerCapText": "Chapéu de Detetive",
+ "headArmoireBoaterHatNotes": "Este chapéu de palha é realmente incrível! Aumenta a Força, Constituição e Percepção em <%= attrs %>, cada. Armário Encantado: Conjunto do Barqueiro (Item 2 de 3).",
+ "headArmoireAstronomersHatNotes": "Um chapéu perfeito para observação celestial ou um _brunch_ chique de um mago. Armário Encantado: Conjunto do(a) Mago(a) Astrônomo(a) (Item 2 de 3).",
+ "headArmoireAstronomersHatText": "Chapéu do Astrônomo",
+ "headArmoireBoaterHatText": "Chapéu do Barqueiro",
+ "headArmoireNephriteHelmNotes": "A pluma de jade esculpida no topo deste elmo é encantada para aprimorar seu objetivo. Aumenta a Percepção em <%= per %> e a Inteligência em <%= int %>. Armário Encantado: Conjunto do Arqueiro de Nefrita (Item 2 de 3).",
+ "headArmoireNephriteHelmText": "Elmo de Nefrita",
+ "headMystery201907Notes": "Nada diz \"Estou relaxando aqui!\" tão bem como um boné para trás. Não confere nenhum benefício. Item de Assinante em Julho de 2019.",
+ "headMystery201907Text": "Chapéu para trás",
+ "headMystery201909Notes": "Toda bolota precisa de um chapéu! Ou...Cúpula, se você quiser ser técnico sobre isso. Não confere benefícios. Item de Assinante em Setembro de 2019.",
+ "headMystery201909Text": "Chapéu de Bolota Afável",
+ "headMystery201904Notes": "As opalas deste anel brilham em todas as cores do arco-íris, dando-lhe uma variedade de propriedades mágicas. Não confere benefícios. Item de Assinante em Abril de 2019.",
+ "headMystery201904Text": "Anel de Opala Luxuriante",
+ "headSpecialFall2019HealerNotes": "Vista esta mitra sombria para aproveitar os poderes do temível Lich. Aumenta a Inteligência em <%= int %>. Equipamento de Edição Limitada do Outono de 2019.",
+ "headSpecialFall2019HealerText": "Mitra Sombria",
+ "armorArmoireShadowMastersRobeNotes": "O tecido deste manto esvoaçante é feito a partir das sombras mais escuras das cavernas mais profundas de Habitica. Aumenta a Constituição em <%= con %>. Armário Encantado: Conjunto do(a) Mestre das Sombras (Item 1 de 4).",
+ "armorArmoireShadowMastersRobeText": "Vestes do(a) Mestre das Sombras",
+ "weaponArmoireShadowMastersMaceText": "Maça do(a) Mestre das Sombras",
+ "weaponArmoireShadowMastersMaceNotes": "Criaturas das trevas obedecerão a todos os seus comandos quando você acenar com esta maça brilhante. Aumenta a Percepção em <%= per %>. Armário Encantado: Conjunto do(a) Mestre das Sombras (Item 3 de 4).",
+ "headSpecialFall2019MageNotes": "Seu único olho ameaçador inibe a percepção de profundidade, mas esse é um preço pequeno a pagar pela maneira como aprimora seu foco em um ponto único e intenso. Aumenta a Percepção em <%= per %>. Equipamento de Edição Limitada do Outono de 2019.",
+ "headSpecialFall2019MageText": "Máscara do Ciclope",
+ "headSpecialFall2019WarriorNotes": "As órbitas escuras deste capacete craniano assustarão os mais valentes de seus inimigos. Aumenta a Força em <%= str %>. Equipamento de Edição Limitada do Outono de 2019.",
+ "headSpecialFall2019WarriorText": "Capacete de Caveira Obsidiana",
+ "headSpecialFall2019RogueNotes": "Você encontrou esse chapéu em um leilão de roupas possivelmente amaldiçoadas ou no sótão de um avô excêntrico? Qualquer que seja sua origem, sua idade e seu desgaste, te dar um ar de mistério. Aumenta a percepção em <%= per %>. Equipamento de Edição Limitada do Outono de 2019.",
+ "headSpecialFall2019RogueText": "Chapéu de Ópera Antiquado",
+ "headSpecialSummer2019HealerNotes": "A estrutura espiralada dessa concha o ajudará a ouvir qualquer pedido de ajuda nos sete mares. Aumenta a Inteligência em <%= int %>. Equipamento de Edição Limitada do Verão de 2019.",
+ "headSpecialSummer2019HealerText": "Coroa de Concha",
+ "headSpecialSummer2019MageNotes": "Ao contrário do que acredita o senso comum, sua cabeça não é um lugar apropriado para os sapos empoleirar-se. Aumenta a percepção em <%= per %>. Equipamento de Edição Limitada do Verão de 2019.",
+ "headSpecialSummer2019MageText": "Chapéu de Lírio",
+ "headSpecialSummer2019WarriorNotes": "Isso não permitirá que você abaixe a cabeça entre os ombros, mas o protegerá se você bater no fundo de um barco. Aumenta a Força em <%= str %>. Equipamento de Edição Limitada do Verão de 2019.",
+ "headSpecialKS2019Notes": "Ornamentado com a aparência da plumagem de um grifo, este glorioso elmo simboliza a maneira como suas habilidades e comportamento são um exemplo para os outros. Aumenta a Inteligência em <%= int %>.",
+ "headSpecialKS2019Text": "Elmo do Grifo Mítico",
+ "armorArmoireAstronomersRobeNotes": "A seda e a luz das estrelas transformaram um tecido que não é apenas mágico, mas muito respirável. Aumenta a Percepção e a Constituição em <%= attrs %> cada. Armário Encantado: Conjunto de Mago Astrônomo (Item 1 de 3).",
+ "armorArmoireBoatingJacketNotes": "Seja em um iate chique ou em um calhambeque, você será o miado do gato nesta jaqueta e gravata. Aumenta a Força, Inteligência e Percepção em <%= attrs %> cada. Armário Encantado: Conjunto de Barco (Item 1 de 3).",
+ "headAccessoryMystery201908Notes": "Se vestir estes chifres na cabeça, você está com sorte! Não confere benefícios. Item de Assinante em Agosto de 2019.",
+ "eyewearSpecialFall2019HealerNotes": "Fortaleça-se contra os inimigos mais difíceis com esta máscara inescrutável. Equipamento de Edição Limitada do Outono de 2019.",
+ "eyewearMystery201907Notes": "Fique incrível enquanto protege seus olhos dos raios UV prejudiciais! Não confere benefícios. Item de Assinante em Julho de 2019.",
+ "eyewearSpecialFall2019HealerText": "Viseira Sombria",
+ "shieldSpecialSummer2019WarriorNotes": "Encarapace-se atrás deste forte escudo redondo, gravado com a estampa do seu réptil favorito. Aumenta a cada em <%=com %>. Equipamento de Edição Limitada de Verão de 2019.",
+ "eyewearMystery201907Text": "Doces Óculos de Sol",
+ "eyewearSpecialFall2019RogueNotes": "Você pensaria que uma máscara completa protegeria melhor sua identidade, mas as pessoas tendem a ficar muito impressionadas com seu design rígido para notar qualquer recurso de identificação que possa ser revelado. Equipamento de Edição Limitada do Outono de 2019.",
+ "eyewearSpecialFall2019RogueText": "Meia-Máscara de Osso Branco",
+ "eyewearSpecialKS2019Notes": "Forte como um grifo... hmm, os grifos não têm viseiras. Isso lembra que você... oh, estamos brincando, parece legal! Não confere benefícios.",
+ "eyewearSpecialKS2019Text": "Viseira do Grifo Mítico",
+ "eyewearSpecialYellowHalfMoonNotes": "Óculos com armação amarela e lentes crescentes. Não confere benefícios.",
+ "eyewearSpecialYellowHalfMoonText": "Óculos Meia-lua Amarelos",
+ "eyewearSpecialWhiteHalfMoonNotes": "Óculos com armação branca e lentes crescentes. Não confere benefícios.",
+ "eyewearSpecialWhiteHalfMoonText": "Óculos Meia-lua Brancos",
+ "eyewearSpecialRedHalfMoonNotes": "Óculos com armação vermelha e lentes crescentes. Não confere benefícios.",
+ "eyewearSpecialRedHalfMoonText": "Óculos Meia-lua Vermelhos",
+ "eyewearSpecialPinkHalfMoonNotes": "Óculos com armação rosa e lentes crescentes. Não confere benefícios.",
+ "eyewearSpecialPinkHalfMoonText": "Óculos Meia-lua Rosas",
+ "eyewearSpecialGreenHalfMoonNotes": "Óculos com armação verde e lentes crescentes. Não confere benefícios.",
+ "eyewearSpecialGreenHalfMoonText": "Óculos Meia-lua Verdes",
+ "eyewearSpecialBlueHalfMoonNotes": "Óculos com armação azul e lentes crescentes. Não confere benefícios.",
+ "eyewearSpecialBlueHalfMoonText": "Óculos de Meia-lua Azuis",
+ "eyewearSpecialBlackHalfMoonNotes": "Óculos com armação preta e lentes crescentes. Não confere nenhum benefício.",
+ "eyewearSpecialBlackHalfMoonText": "Óculos pretos de meia-lua"
}
diff --git a/website/common/locales/pt_BR/groups.json b/website/common/locales/pt_BR/groups.json
index 02db838871..2872a1c009 100644
--- a/website/common/locales/pt_BR/groups.json
+++ b/website/common/locales/pt_BR/groups.json
@@ -483,5 +483,6 @@
"pmReported": "Obrigado por denunciar esta mensagem.",
"youHaveBeenAssignedTask": "<%= managerName %> atribuiu a você a tarefa <%= taskText %>.",
"suggestedGroup": "Sugerido porque você é novo no Habitica.",
- "taskClaimed": "<%= userName %> reivindicou a tarefa <%= taskText %>."
+ "taskClaimed": "<%= userName %> reivindicou a tarefa <%= taskText %>.",
+ "groupActivityNotificationTitle": "<%= user %> postou em <%= group %>"
}
diff --git a/website/common/locales/pt_BR/npc.json b/website/common/locales/pt_BR/npc.json
index 1312d01e9a..21dbd0f70d 100644
--- a/website/common/locales/pt_BR/npc.json
+++ b/website/common/locales/pt_BR/npc.json
@@ -21,7 +21,7 @@
"sleepDescription": "Precisa de um descanso? Faça uma visita à Pousada do Daniel e pare algumas das mecânicas de jogo mais difíceis do Habitica:",
"sleepBullet1": "Diárias não feitas não lhe causarão dano",
"sleepBullet2": "As Tarefas não vão perder seus combos ou decair de cor",
- "sleepBullet3": "Os Chefões não causarão dano pelas Diárias não feitas",
+ "sleepBullet3": "Os Chefões não causam danos pelas suas Diárias não concluídas",
"sleepBullet4": "Seu dano no Chefão ou itens de Missão de coleta ficarão acumulados até o fim do dia",
"pauseDailies": "Pausar Danos",
"unpauseDailies": "Reativar Danos",
diff --git a/website/common/locales/pt_BR/pets.json b/website/common/locales/pt_BR/pets.json
index 5f5f589c4f..77cfe2afe6 100644
--- a/website/common/locales/pt_BR/pets.json
+++ b/website/common/locales/pt_BR/pets.json
@@ -144,5 +144,6 @@
"notEnoughMounts": "Você AINDA não coletou montarias suficientes",
"notEnoughPetsMounts": "Você AINDA não coletou mascotes e montarias suficientes",
"wackyPets": "Mascotes Malucos",
- "filterByWacky": "Maluco"
+ "filterByWacky": "Maluco",
+ "gryphatrice": "Grifoatrice"
}
diff --git a/website/common/locales/pt_BR/quests.json b/website/common/locales/pt_BR/quests.json
index 360359ca0f..2bcc731611 100644
--- a/website/common/locales/pt_BR/quests.json
+++ b/website/common/locales/pt_BR/quests.json
@@ -136,5 +136,6 @@
"chatItemQuestFinish": "Todos os itens foram encontrados! Todos os membros do Grupo que participaram desta missão receberam suas recompensas.",
"chatFindItems": "<%= username %> encontrou <%= items %>.",
"chatBossDefeated": "Você derrotou o(a) <%= bossName %>! Todos os membros do Grupo que participaram desta missão receberam recompensas por esta vitória.",
- "chatBossDamage": "<%= username %> atacaou <%= bossName %> e causou <%= userDamage %> de dano. <%= bossName %> atacou o Grupo e causou <%= bossDamage %> de dano."
+ "chatBossDamage": "<%= username %> atacaou <%= bossName %> e causou <%= userDamage %> de dano. <%= bossName %> atacou o Grupo e causou <%= bossDamage %> de dano.",
+ "questInvitationNotificationInfo": "Você foi convidado(a) parar participar de uma missão"
}
diff --git a/website/common/locales/pt_BR/settings.json b/website/common/locales/pt_BR/settings.json
index 4c95e93fd4..6ef838e563 100644
--- a/website/common/locales/pt_BR/settings.json
+++ b/website/common/locales/pt_BR/settings.json
@@ -119,8 +119,8 @@
"giftedSubscriptionInfo": "<%= name %> presentou você com <%= months %> meses de assinatura",
"giftedSubscriptionFull": "Olá <%= username %>, <%= sender %> te envou <%= monthCount %> meses de assinatura!",
"giftedSubscriptionWinterPromo": "Olá, <%= username %>, você recebeu <%= monthCount %> meses de assinatura como parte de nossa promoção de presentes de Natal!",
- "invitedParty": "Te convidaram para um Grupo",
- "invitedGuild": "Te convidaram para uma Guilda",
+ "invitedParty": "Você foi convidado(a) para um Grupo",
+ "invitedGuild": "Você foi convidado(a) para uma Guilda",
"importantAnnouncements": "Lembretes de fazer check-in para completar tarefas e receber recompensas",
"weeklyRecaps": "Resumos de atividades da sua conta na semana passada (Nota: Atualmente está desativado devido a problemas de desempenho, mas esperamos ter isto funcionando e enviando e-mails novamente em breve!)",
"onboarding": "Orientações em como preparar sua conta no Habitica",
@@ -203,7 +203,12 @@
"goToSettings": "Ir para Configurações",
"usernameVerifiedConfirmation": "Seu nome de usuário, <%= username %>, foi confirmado!",
"usernameNotVerified": "Por favor, confirme seu nome de usuário.",
- "changeUsernameDisclaimer": "Faremos a transição dos nomes de login para nomes de usuários públicos exclusivos em breve. Este nome de usuário será usado para convites, @menções em bate-papo e mensagens.",
+ "changeUsernameDisclaimer": "Este nome de usuário será usado para convites, @menções em bate-papo e mensagens.",
"verifyUsernameVeteranPet": "Um desses Mascotes Veteranos estará esperando por você assim que estiver terminado de confirmar!",
- "subscriptionReminders": "Lembretes de inscrições"
+ "subscriptionReminders": "Lembretes de inscrições",
+ "newPMNotificationTitle": "Nova Mensagem de <%= name %>",
+ "onlyPrivateSpaces": "Apenas em espaços privados",
+ "everywhere": "Em toda parte",
+ "suggestMyUsername": "Sugerir meu nome de usuário",
+ "mentioning": "Menção"
}
diff --git a/website/common/locales/ru/achievements.json b/website/common/locales/ru/achievements.json
index b1542b327f..616b89b168 100644
--- a/website/common/locales/ru/achievements.json
+++ b/website/common/locales/ru/achievements.json
@@ -24,5 +24,13 @@
"achievementDustDevilText": "Собраны все пустынные питомцы.",
"achievementDustDevil": "Песчаный вихрь",
"achievementAridAuthorityModalText": "Вы собрали всех пустынных скакунов!",
- "achievementAridAuthorityText": "Собраны все пустынные скакуны."
+ "achievementAridAuthorityText": "Собраны все пустынные скакуны.",
+ "achievementKickstarter2019": "Сторонник проекта на Kickstarter",
+ "achievementKickstarter2019Text": "Поддержал проект на Kickstarter в 2019 году",
+ "achievementUndeadUndertakerModalText": "Вы собрали всех зомби-скакунов!",
+ "achievementUndeadUndertakerText": "Собраны все зомби-скакуны.",
+ "achievementUndeadUndertaker": "Гробовщик",
+ "achievementMonsterMagusModalText": "Вы собрали всех зомби-питомцев!",
+ "achievementMonsterMagusText": "Собраны все зомби-питомцы.",
+ "achievementMonsterMagus": "Некромант"
}
diff --git a/website/common/locales/ru/backgrounds.json b/website/common/locales/ru/backgrounds.json
index e602099729..97803b8709 100644
--- a/website/common/locales/ru/backgrounds.json
+++ b/website/common/locales/ru/backgrounds.json
@@ -464,5 +464,12 @@
"backgroundInAnAncientTombNotes": "Бросьте вызов тайнам древней гробницы.",
"backgroundInAnAncientTombText": "Древняя гробница",
"backgroundAutumnFlowerGardenNotes": "Окунитесь в тепло осеннего цветочного сада.",
- "backgroundAutumnFlowerGardenText": "Осенний цветочный сад"
+ "backgroundAutumnFlowerGardenText": "Осенний цветочный сад",
+ "backgroundMonsterMakersWorkshopNotes": "Поэкспериментируйте с сомнительными науками в мастерской монстров.",
+ "backgroundMonsterMakersWorkshopText": "Мастерская монстров",
+ "backgroundPumpkinCarriageNotes": "Прокатитесь в заколдованной карете из тыквы, пока часы не пробили полночь.",
+ "backgroundPumpkinCarriageText": "Карета из тыквы",
+ "backgroundFoggyMoorNotes": "Смотрите под ноги, гуляя по туманной местности.",
+ "backgroundFoggyMoorText": "Туманная местность",
+ "backgrounds102019": "Набор 65: Выпущен в октябре 2019"
}
diff --git a/website/common/locales/ru/defaulttasks.json b/website/common/locales/ru/defaulttasks.json
index dccc69f4c6..65ff6bb7e9 100644
--- a/website/common/locales/ru/defaulttasks.json
+++ b/website/common/locales/ru/defaulttasks.json
@@ -30,5 +30,8 @@
"selfCareDailyText": "5 минут спокойного дыхания",
"healthTodoNotes": "Нажмите, чтобы добавить списки!",
"exerciseTodoNotes": "Нажмите, чтобы добавить список!",
- "exerciseTodoText": "Установить расписание тренировок"
+ "exerciseTodoText": "Установить расписание тренировок",
+ "workHabitMail": "Проверить почту",
+ "workTodoProject": "Рабочий проект >> Завершить рабочий проект",
+ "workDailyImportantTaskNotes": "Нажмите, чтобы указать наиболее важную задачу"
}
diff --git a/website/common/locales/ru/gear.json b/website/common/locales/ru/gear.json
index b303bdab96..809f229bf5 100644
--- a/website/common/locales/ru/gear.json
+++ b/website/common/locales/ru/gear.json
@@ -895,7 +895,7 @@
"headSpecialNamingDay2017Text": "Шлем королевского пурпурного грифона",
"headSpecialNamingDay2017Notes": "С днём наречения! Носите этот суровый шлем с перьями, празднуя новое имя Habitica. Бонусов не даёт.",
"headSpecialTurkeyHelmBaseText": "Шлем индейки",
- "headSpecialTurkeyHelmBaseNotes": "Ваш костюм на день благодарения будет закончен с этим шлемом с клювом.",
+ "headSpecialTurkeyHelmBaseNotes": "Ваш костюм на день благодарения будет выглядеть законченным, если вы наденете этот шлем с клювом! Бонусов не дает.",
"headSpecialTurkeyHelmGildedText": "Позолоченный индюшачий шлем",
"headSpecialTurkeyHelmGildedNotes": "Кулдык-кулдык! Драгоценности! Бонусов не дает.",
"headSpecialNyeText": "Абсурдная праздничная шляпа",
@@ -1910,15 +1910,54 @@
"headMystery201909Text": "Шляпа учтивого желудя",
"headMystery201909Notes": "Каждому желудю нужна шляпа! Э-э, плюска, если быть точным. Бонусов не дает. Подарок подписчикам сентября 2019.",
"armorMystery201909Notes": "Прочный внешний вид оберегает вас, но лучше остерегаться белок... Бонусов не дает. Подарок подписчикам сентября 2019.",
- "armorSpecialFall2019WarriorNotes": "Эти пернатые одеяния дают способность к полету, позволяя вам парить над любыми битвами. Увеличивает телосложение на <%= con %>. Ограниченный выпуск осени 2019.",
+ "armorSpecialFall2019WarriorNotes": "Эти пернатые одеяния дают способность к полету, позволяя вам парить над любыми битвами. Увеличивает телосложение на <%= con %>. Ограниченный выпуск осени 2019.",
"armorSpecialFall2019WarriorText": "Крылья ночи",
- "armorSpecialFall2019RogueNotes": "Этот наряд поставляется в комплекте с белыми перчатками и идеально подходит для размышлений в вашей личной ложе над сценой или для потрясающих прогулок по парадным лестницам. Увеличивает восприятие на <%= per %>. Ограниченный выпуск осени 2019.",
+ "armorSpecialFall2019RogueNotes": "Этот наряд поставляется в комплекте с белыми перчатками и идеально подходит для размышлений в вашей личной ложе над сценой или для потрясающих прогулок по парадным лестницам. Увеличивает восприятие на <%= per %>. Ограниченный выпуск осени 2019.",
"armorSpecialFall2019RogueText": "Оперный жакет с пелериной",
- "weaponSpecialFall2019HealerText": "",
+ "weaponSpecialFall2019HealerText": "Ужасающая филактерия",
"weaponSpecialFall2019MageNotes": "Будь то ковка молний, возведение укреплений или просто вселение ужаса в сердца смертных, этот посох дает силу гигантов творить чудеса. Увеличивает интеллект на <%= int %> и восприятие на <%= per %>. Ограниченный выпуск осени 2019.",
"weaponSpecialFall2019MageText": "Одноглазый посох",
"weaponSpecialFall2019WarriorNotes": "Приготовьтесь разорвать своих врагов когтями ворона! Увеличивает силу на <%= str %>. Ограниченный выпуск осени 2019.",
"weaponSpecialFall2019WarriorText": "Когтистый трезубец",
"weaponSpecialFall2019RogueNotes": "Если вы управляете оркестром или поете арию, то эта полезная вещь освобождает ваши руки для драматических жестов! Увеличивает силу на <%= str %>. Ограниченный выпуск осени 2019.",
- "weaponSpecialFall2019RogueText": "Пюпитр"
+ "weaponSpecialFall2019RogueText": "Пюпитр",
+ "eyewearSpecialFall2019HealerNotes": "Сразитесь с самыми сильными противниками с помощью этой непроницаемой маски. Бонусов не дает. Ограниченный выпуск осени 2019.",
+ "eyewearSpecialFall2019HealerText": "Темная личина",
+ "eyewearSpecialFall2019RogueNotes": "Вы могли бы подумать, что цельная маска лучше скрыла бы вашу личность, однако, люди, как правило, слишком восхищены ее строгим дизайном, чтобы заметить кого-то за ней. Бонусов не дает. Ограниченный выпуск осени 2019.",
+ "eyewearSpecialFall2019RogueText": "Белая костяная полумаска",
+ "eyewearSpecialKS2019Notes": "Дерзкая, как маска грифона... хм, у грифонов нет масок. Это напоминает вам... стоп, кого мы обманываем, она просто круто выглядит! Бонусов не дает.",
+ "eyewearSpecialKS2019Text": "Маска мифического грифона",
+ "shieldArmoireMasteredShadowNotes": "Ваша мощь склонила эти кружащиеся тени на вашу сторону, чтобы выполнять ваши приказы. Увеличивает восприятие и телосложение на <%= attrs %>. Зачарованный сундук: Набор Мастера теней (предмет 4 из 4).",
+ "shieldArmoireMasteredShadowText": "Покоренная тень",
+ "shieldSpecialFall2019HealerText": "Гротескный гримуар",
+ "shieldSpecialFall2019HealerNotes": "Используйте темную сторону искусства целителей с этим гримуаром! Увеличивает телосложение на <%= con %>. Ограниченный выпуск осени 2019.",
+ "shieldSpecialFall2019WarriorNotes": "Темный блеск вороньего пера, спрессованного в прочный щит, сведет на нет все атаки. Увеличивает телосложение на <%= con %>. Ограниченный выпуск осени 2019.",
+ "shieldSpecialFall2019WarriorText": "Вороной щит",
+ "shieldSpecialKS2019Notes": "Этот великолепный щит, сверкающий, как скорлупа яйца грифона, научит вас помогать другим людям в свободное время. Увеличивает восприятие на <%= per %>.",
+ "shieldSpecialKS2019Text": "Щит мифического грифона",
+ "headArmoireShadowMastersHoodNotes": "Этот капюшон даст вам возможность видеть даже в самой глубокой тьме. Хотя, иногда вам будут нужны глазные капли. Увеличивает восприятие и телосложение на <%= attrs %>. Зачарованный сундук: Набор Мастера теней (предмет 2 из 4).",
+ "headArmoireShadowMastersHoodText": "Капюшон Мастера теней",
+ "headSpecialFall2019HealerNotes": "Наденьте эту темную митру, чтобы использовать силы ужасающего лича. Увеличивает интеллект на <%= int %>. Ограниченный выпуск осени 2019.",
+ "headSpecialFall2019HealerText": "Темная митра",
+ "headSpecialFall2019MageNotes": "Ее единственный зловещий глаз препятствует восприятию глубины, но это малая цена, которую стоит заплатить за то, как она фокусирует ваше внимание на одной точке. Увеличивает восприятие на <%= per %>. Ограниченный выпуск осени 2019.",
+ "headSpecialFall2019MageText": "Маска циклопа",
+ "headSpecialFall2019WarriorNotes": "Темные глазницы этого черепа испугают даже самых смелых врагов. Увеличивает силу на <%= str %>. Ограниченный выпуск осени 2019.",
+ "headSpecialFall2019WarriorText": "Череп из вулканического стекла",
+ "headSpecialFall2019RogueNotes": "Вы нашли этот головной убор на аукционе проклятых вещей или на чердаке эксцентричного дедушки? Независимо от его происхождения, его возраст и поношенность добавят к вашему образу таинственности. Увеличивает восприятие на <%= per %>. Ограниченный выпуск осени 2019.",
+ "headSpecialFall2019RogueText": "Старинная оперная шляпа",
+ "headSpecialKS2019Notes": "Этот великолепный шлем, украшенный изображением грифона и его перьями, символизирует то, как ваши умения и навыки служат примером для других. Увеличивает интеллект на <%= int %>.",
+ "headSpecialKS2019Text": "Шлем мифического грифона",
+ "armorArmoireShadowMastersRobeNotes": "Ткань этой струящейся мантии соткана из самых темных теней в самых глубоких пещерах Habitica. Увеличивает телосложение на <%= con %>. Зачарованный сундук: Набор Мастера теней (предмет 1 из 4).",
+ "armorArmoireShadowMastersRobeText": "Мантия Мастера теней",
+ "armorSpecialFall2019HealerNotes": "Говорят, что эта мантия сделана из чистой ночи. Используйте темную силу с умом! Увеличивает телосложение на <%= con %>. Ограниченный выпуск осени 2019.",
+ "armorSpecialFall2019HealerText": "Мантия тьмы",
+ "armorSpecialFall2019MageNotes": "Его тезку постигла страшная судьба. Но вас не так легко обмануть! Наденьте эту легендарную мантию, чтобы никто не смог превзойти вас. Увеличивает интеллект на <%= int %>. Ограниченный выпуск осени 2019.",
+ "armorSpecialFall2019MageText": "Мантия Полифема",
+ "armorSpecialKS2019Notes": "Светящаяся изнутри, словно благородное сердце грифона, эта великолепная броня побуждает вас гордиться своими достижениями. Увеличивает телосложение на <%= con %>.",
+ "armorSpecialKS2019Text": "Доспехи мифического грифона",
+ "weaponArmoireShadowMastersMaceNotes": "Существа тьмы будут подчиняться каждой вашей команде, когда вы машете этой светящейся булавой. Увеличивает восприятие на <%= per %>. Зачарованный сундук: Набор Мастера теней (предмет 3 из 4).",
+ "weaponArmoireShadowMastersMaceText": "Булава Мастера теней",
+ "weaponSpecialFall2019HealerNotes": "Эта филактерия способна вызывать духов задач, которые были давным давно выполнены, чтобы использовать их целительную силу. Увеличивает интеллект на <%= int %>. Ограниченный выпуск осени 2019.",
+ "weaponSpecialKS2019Notes": "Изогнутое, как клюв и когти грифона, это богато украшенное древковое оружие вселяет в вас энергию, когда задача, стоящая перед вами, кажется вам сложной. Увеличивает силу на <%= str %>.",
+ "weaponSpecialKS2019Text": "Глефа мифического грифона"
}
diff --git a/website/common/locales/ru/generic.json b/website/common/locales/ru/generic.json
index 9a69d26860..22a3bb98cb 100644
--- a/website/common/locales/ru/generic.json
+++ b/website/common/locales/ru/generic.json
@@ -293,5 +293,6 @@
"contactForm": "Связаться с командой модераторов",
"options": "Настройки",
"demo": "Демо",
- "loadEarlierMessages": "Загрузить предыдущие сообщения"
+ "loadEarlierMessages": "Загрузить предыдущие сообщения",
+ "finish": "Завершить"
}
diff --git a/website/common/locales/ru/groups.json b/website/common/locales/ru/groups.json
index 82f5d87775..91f528f35f 100644
--- a/website/common/locales/ru/groups.json
+++ b/website/common/locales/ru/groups.json
@@ -277,10 +277,10 @@
"confirmRemoveTag": "Вы точно хотите удалить \"<%= tag %>\"?",
"groupHomeTitle": "Главная",
"assignTask": "Назначить задачу",
- "claim": "Заявить",
+ "claim": "Требовать назначения задания",
"removeClaim": "Удалить претензию",
"onlyGroupLeaderCanManageSubscription": "Только лидер группы может управлять общей подпиской",
- "yourTaskHasBeenApproved": "Ваше задание <%= taskText %> было одобрено.",
+ "yourTaskHasBeenApproved": "Ваше задание <%= taskText %> было одобрено.",
"taskNeedsWork": "<%= managerName %> отметил <%= taskText %> как требующей дополнительной работы.",
"userHasRequestedTaskApproval": "<%= user %> просит одобрить <%= taskName %>",
"approve": "Одобрить",
@@ -341,7 +341,7 @@
"leaderCannotLeaveGroupWithActiveGroup": "Лидер не может покинуть группу, пока группа имеет активный групповой тариф",
"youHaveGroupPlan": "Вы получили бесплатную подписку, став участником группы с групповым тарифом. Подписка закончится, когда вы перестанете быть участником этой группы. Все время предварительно оплаченной подписки вернется по истечении группового тарифа.",
"cancelGroupSub": "Отменить групповой тариф",
- "confirmCancelGroupPlan": "Вы уверены, что хотите отказаться от группового тарифа и снять его бонусы со всех членов группы, включая их право бесплатной подписки?",
+ "confirmCancelGroupPlan": "Вы уверены, что хотите отказаться от группового тарифа? Все члены группы потеряют право бесплатной подписки и бонусы.",
"canceledGroupPlan": "Групповой тариф отменен",
"groupPlanCanceled": "Групповой тариф перестанет действовать",
"purchasedGroupPlanPlanExtraMonths": "У вас остается <%= months %> мес. оплаченного группового тарифа.",
@@ -480,5 +480,9 @@
"recurringCompletion": "Никто - Групповое задание не выполняется",
"singleCompletion": "Один - Выполняется, когда любой из назначенных игроков завершает задание",
"allAssignedCompletion": "Все - Выполняется, когда все назначенные игроки завершают задание",
- "pmReported": "Спасибо, что сообщили об этом сообщении."
+ "pmReported": "Спасибо, что сообщили об этом сообщении.",
+ "suggestedGroup": "Предложено, потому что вы новечок в Habitica.",
+ "groupActivityNotificationTitle": "Есть сообщение в <%= group %> от <%= user %>",
+ "taskClaimed": "<%= userName %> требует назначения задания <%= taskText %>.",
+ "youHaveBeenAssignedTask": "<%= managerName %> поручил вам задание <%= taskText %>."
}
diff --git a/website/common/locales/ru/pets.json b/website/common/locales/ru/pets.json
index 6df33ba9db..984c2632a0 100644
--- a/website/common/locales/ru/pets.json
+++ b/website/common/locales/ru/pets.json
@@ -144,5 +144,6 @@
"notEnoughMounts": "Вы не собрали достаточного количества скакунов",
"notEnoughPetsMounts": "Вы не собрали достаточного количества питомцев и скакунов",
"wackyPets": "Чокнутые питомцы",
- "filterByWacky": "Дурацкие"
+ "filterByWacky": "Дурацкие",
+ "gryphatrice": "Грифолиск"
}
diff --git a/website/common/locales/ru/quests.json b/website/common/locales/ru/quests.json
index db1686e901..bccf04eb4a 100644
--- a/website/common/locales/ru/quests.json
+++ b/website/common/locales/ru/quests.json
@@ -136,5 +136,6 @@
"chatQuestAborted": "<%= username %> отменил(а) квест <%= questName %>.",
"tavernBossTired": "<%= bossName %> пытается высвободить <%= rageName %>, но усталость не позволяет.",
"chatBossDefeated": "Вы победили <%= bossName %>! Участники квеста получают награду за победу.",
- "chatBossDontAttack": "<%= username %> атакует <%= bossName %> и наносит <%= userDamage %> урона. <%= bossName %> не атакует, потому что осознает тот факт, что имеются некоторые ошибки после техобслуживания, и не хочет никого поранить не по-спортивному. <%= bossName %> скоро продолжит буйство!"
+ "chatBossDontAttack": "<%= username %> атакует <%= bossName %> и наносит <%= userDamage %> урона. <%= bossName %> не атакует, потому что осознает тот факт, что имеются некоторые ошибки после техобслуживания, и не хочет никого поранить не по-спортивному. <%= bossName %> скоро продолжит буйство!",
+ "questInvitationNotificationInfo": "Вы были приглашены принять участие в квесте"
}
diff --git a/website/common/locales/ru/settings.json b/website/common/locales/ru/settings.json
index 782c8431ef..6a5245d0ae 100644
--- a/website/common/locales/ru/settings.json
+++ b/website/common/locales/ru/settings.json
@@ -119,8 +119,8 @@
"giftedSubscriptionInfo": "<%= name %> дарит вам <%= months %> месяцев подписки",
"giftedSubscriptionFull": "Привет <%= username %>, <%= sender %> подарил вам <%= monthCount %> месяцев подписки!",
"giftedSubscriptionWinterPromo": "Здравствуйте, <%= username %>, вы получили <%= monthCount %> месяцев подписки!",
- "invitedParty": "Приглашен в команду",
- "invitedGuild": "Приглашен в гильдию",
+ "invitedParty": "Вы были приглашены в команду",
+ "invitedGuild": "Вы были приглашены в гильдию",
"importantAnnouncements": "Напоминания о ежедневном входе для выполнения заданий и получения призов",
"weeklyRecaps": "Обзоры действий с вашего аккаунта за последние недели (Замечание: временно недоступно из-за проблем с производительностью, но мы надеемся, что скоро сможем вернуть все назад и отправлять письма снова!)",
"onboarding": "Руководство о создании вашего аккаунта в Habitica",
@@ -205,5 +205,6 @@
"usernameNotVerified": "Подтвердите свое имя пользователя.",
"changeUsernameDisclaimer": "В ближайшее время мы начнем использовать имена, которые будут уникальные, общедоступные. Имя пользователя будет использоваться для приглашений, @упоминаний в чате и для обмена сообщениями.",
"verifyUsernameVeteranPet": "Один из питомцев-ветеранов будет вашим после подтверждения!",
- "subscriptionReminders": "Напоминания о подписке"
+ "subscriptionReminders": "Напоминания о подписке",
+ "newPMNotificationTitle": "Новое сообщение от <%= name %>"
}
diff --git a/website/common/locales/sv/communityguidelines.json b/website/common/locales/sv/communityguidelines.json
index 4785391c3e..c3176628b5 100644
--- a/website/common/locales/sv/communityguidelines.json
+++ b/website/common/locales/sv/communityguidelines.json
@@ -18,7 +18,7 @@
"commGuideList02F": "Avoid extended discussions of divisive topics in the Tavern and where it would be off-topic. If you feel that someone has said something rude or hurtful, do not engage them. If someone mentions something that is allowed by the guidelines but which is hurtful to you, it’s okay to politely let someone know that. If it is against the guidelines or the Terms of Service, you should flag it and let a mod respond. When in doubt, flag the post.",
"commGuideList02G": "Comply immediately with any Mod request. This could include, but is not limited to, requesting you limit your posts in a particular space, editing your profile to remove unsuitable content, asking you to move your discussion to a more suitable space, etc.",
"commGuideList02H": "Take time to reflect instead of responding in anger if someone tells you that something you said or did made them uncomfortable. There is great strength in being able to sincerely apologize to someone. If you feel that the way they responded to you was inappropriate, contact a mod rather than calling them out on it publicly.",
- "commGuideList02I": "Divisive/contentious conversations should be reported to mods by flagging the messages involved or using the Moderator Contact Form. If you feel that a conversation is getting heated, overly emotional, or hurtful, cease to engage. Instead, report the posts to let us know about it. Moderators will respond as quickly as possible. It's our job to keep you safe. If you feel that more context is required, you can report the problem using the Moderator Contact Form.",
+ "commGuideList02I": "Splittrande/gräliga konversationer bör anmälas till moderatorerna genom att flagga de tillhörande meddelandena eller genom formuläret för moderatorkontakt. Om du känner att en konversation börjar bli hetsig, överdrivet känslostyrd, eller sårande: dra dig ur den. Låt oss få reda på det i stället genom att anmäla inläggen. Moderatorerna kommer svara så snabbt som möjligt. Det är vårt jobb att du ska känna dig trygg. Om du upplever att vi behöver veta mer om sammanhanget så kan du göra din anmälan genom formuläret för moderatorkontakt..",
"commGuideList02J": "Do not spam. Spamming may include, but is not limited to: posting the same comment or query in multiple places, posting links without explanation or context, posting nonsensical messages, posting multiple promotional messages about a Guild, Party or Challenge, or posting many messages in a row. Asking for gems or a subscription in any of the chat spaces or via Private Message is also considered spamming. If people clicking on a link will result in any benefit to you, you need to disclose that in the text of your message or that will also be considered spam.
It is up to the mods to decide if something constitutes spam or might lead to spam, even if you don’t feel that you have been spamming. For example, advertising a Guild is acceptable once or twice, but multiple posts in one day would probably constitute spam, no matter how useful the Guild is!",
"commGuideList02K": "Avoid posting large header text in the public chat spaces, particularly the Tavern. Much like ALL CAPS, it reads as if you were yelling, and interferes with the comfortable atmosphere.",
"commGuideList02L": "We highly discourage the exchange of personal information -- particularly information that can be used to identify you -- in public chat spaces. Identifying information can include but is not limited to: your address, your email address, and your API token/password. This is for your safety! Staff or moderators may remove such posts at their discretion. If you are asked for personal information in a private Guild, Party, or PM, we highly recommend that you politely refuse and alert the staff and moderators by either 1) flagging the message if it is in a Party or private Guild, or 2) filling out the Moderator Contact Form and including screenshots.",
@@ -125,4 +125,4 @@
"commGuideLink06": "The Art Trello: for submitting pixel art.",
"commGuideLink07": "The Quest Trello: for submitting quest writing.",
"commGuidePara069": "De följande talangfyllda konstnärerna har bidragit till dessa illustrationer:"
-}
\ No newline at end of file
+}
diff --git a/website/common/locales/tr/subscriber.json b/website/common/locales/tr/subscriber.json
index dea15a43d1..7cd32f515f 100644
--- a/website/common/locales/tr/subscriber.json
+++ b/website/common/locales/tr/subscriber.json
@@ -80,7 +80,7 @@
"buyGemsAllow1": "Bu ay",
"buyGemsAllow2": "Elmas daha satın alabilirsin",
"purchaseGemsSeparately": "Ek Elmas Satın Al",
- "subFreeGemsHow": "Habitica oyuncuları Elmas ödüllü mücadeleleri kazanarak veya Habitica'nın gelişimine yardımcı olup katılımcı ödülü olarak ücretsiz Elmas kazanabilirler.",
+ "subFreeGemsHow": "Habitica oyuncuları Elmas ödüllü mücadeleleri kazanarak veya Habitica'nın gelişimine yardımcı olup katılımcı ödülü olarak. ücretsiz Elmas kazanabilirler",
"seeSubscriptionDetails": "Ayarlar > Abonelik sekmesine giderek abonelik detaylarını görebilirsin!",
"timeTravelers": "Zaman Yolcuları",
"timeTravelersTitleNoSub": "<%= linkStartTyler %>Tyler<%= linkEnd %> ve <%= linkStartVicky %>Vicky<%= linkEnd %>",
diff --git a/website/common/locales/vi/achievements.json b/website/common/locales/vi/achievements.json
index 3340effbea..fcac3bab07 100755
--- a/website/common/locales/vi/achievements.json
+++ b/website/common/locales/vi/achievements.json
@@ -1,9 +1,11 @@
{
- "achievement": "Thành tích",
- "share": "Chia sẻ",
- "onwards": "Tiếp tục!",
- "levelup": "Bằng việc hoàn thành những mục tiêu ngoài đời thật, bạn đã lên cấp và đã được hồi đầy máu!",
- "reachedLevel": "Bạn đã lên cấp độ <%= level %>",
- "achievementLostMasterclasser": "Người hoàn thành nhiệm vụ: Chuỗi Bậc thầy Chức nghiệp",
- "achievementLostMasterclasserText": "Đã hoàn thành tất cả mười sáu nhiệm vụ trong Chuỗi Nhiệm vụ Bậc thầy Chức nghiệp và giải đáp bí ẩn của Bậc thầy Chức nghiệp Mất tích!"
+ "achievement": "Thành tích",
+ "share": "Chia sẻ",
+ "onwards": "Tiếp tục!",
+ "levelup": "Bằng việc hoàn thành những mục tiêu ngoài đời thật, bạn đã lên cấp và đã được hồi đầy máu!",
+ "reachedLevel": "Bạn đã lên cấp độ <%= level %>",
+ "achievementLostMasterclasser": "Người hoàn thành nhiệm vụ: Chuỗi Bậc thầy Chức nghiệp",
+ "achievementLostMasterclasserText": "Đã hoàn thành tất cả mười sáu nhiệm vụ trong Chuỗi Nhiệm vụ Bậc thầy Chức nghiệp và giải đáp bí ẩn của Bậc thầy Chức nghiệp Mất tích!",
+ "achievementJustAddWater": "Mới Thêm Nước",
+ "achievementLostMasterclasserModalText": "Bạn đã hoàn thành tất cả mười sáu nhiệm vụ trong Chuỗi Nhiệm vụ Bậc thầy Chức nghiệp và đã giải mã ra bí ẩn của Bậc thầy Chức nghiệp mất tích!"
}
diff --git a/website/common/locales/vi/defaulttasks.json b/website/common/locales/vi/defaulttasks.json
index 2e5e4dca88..a560a870e1 100755
--- a/website/common/locales/vi/defaulttasks.json
+++ b/website/common/locales/vi/defaulttasks.json
@@ -24,5 +24,42 @@
"defaultTag4": "Trường học",
"defaultTag5": "Theo đội",
"defaultTag6": "Việc vặt",
- "defaultTag7": "Sáng tạo."
-}
\ No newline at end of file
+ "defaultTag7": "Sáng tạo",
+ "defaultHabitNotes": "Hoặc xóa từ màn hình chỉnh sửa",
+ "defaultHabitText": "Bấm vào đây để chỉnh sửa cái này thành một thói quen xấu mà bạn muốn bỏ",
+ "creativityTodoNotes": "Chạm để xác định tên dự án của bạn",
+ "creativityTodoText": "Hoàn thành dự án sáng tạo",
+ "creativityDailyNotes": "Chạm để xác định tên của dự án hiện tại của bạn + xếp lịch!",
+ "creativityDailyText": "Làm dự án sáng tạo",
+ "creativityHabit": "Học một cách chế tạo đồ thủ công >> + Luyện tập một kĩ thuật sáng tạo mới",
+ "choresTodoNotes": "Chạm để xác định khu vực bừa bộn!",
+ "choresTodoText": "Dọn tủ quần áo >> Dọn dẹp sự bừa bộn",
+ "choresDailyNotes": "Chạm để chọn lịch trình của bạn!",
+ "choresDailyText": "Rửa chén",
+ "choresHabit": "10 phút lau dọn",
+ "selfCareTodoNotes": "Chạm để xác lập những gì bạn dự tính làm!",
+ "selfCareTodoText": "Tham gia vào một hoạt động vui nhộn",
+ "selfCareDailyNotes": "Chạm để chọn lịch trình cho bạn!",
+ "selfCareDailyText": "5 phút hít thở sâu",
+ "selfCareHabit": "Giải lao một lát",
+ "schoolTodoNotes": "Chạm để đặt tên công việc và chọn ngày đáo hạn!",
+ "schoolTodoText": "Hoàn thành công việc trên lớp",
+ "schoolDailyNotes": "Chạm để chọn lịch trình làm bài tập của bạn!",
+ "schoolDailyText": "Hoàn thành bài tập về nhà",
+ "schoolHabit": "Học/Xao nhãng",
+ "healthTodoNotes": "Chạm để thêm danh sách!",
+ "healthTodoText": "Xếp lịch kiểm tra >> Động não một sự thay đổi lành mạnh",
+ "healthDailyNotes": "Chạm vào để tạo bất cứ thay đổi gì!",
+ "healthDailyText": "Dùng chỉ nha khoa",
+ "healthHabit": "Ăn Thức ăn Lành mạnh/Vặt",
+ "exerciseTodoNotes": "Chạm để thêm một danh sách!",
+ "exerciseTodoText": "Thiết lập lịch trình tập thể dục",
+ "exerciseDailyNotes": "Chạm vào để chọn lịch trình của bạn và xác định bài tập!",
+ "exerciseDailyText": "Co duỗi >> Tập luyện thể dục thể thao hằng ngày",
+ "exerciseHabit": "10 phút tập thể dục >> +10 phút tập thể dục",
+ "workTodoProjectNotes": "Chạm để xác định tên của dự án hiện tại của bạn + đặt ngày đáo hạn!",
+ "workTodoProject": "Dự án công việc >> Hoàn thành dự án công việc",
+ "workDailyImportantTaskNotes": "Chạm vào để xác định những công việc quan trọng nhất của bạn",
+ "workDailyImportantTask": "Những công việc quan trọng >> Làm những công việc quan trọng nhất trong ngày",
+ "workHabitMail": "Xử lí email"
+}
diff --git a/website/common/locales/zh/achievements.json b/website/common/locales/zh/achievements.json
index 5fac76e81d..4209bd67c4 100644
--- a/website/common/locales/zh/achievements.json
+++ b/website/common/locales/zh/achievements.json
@@ -24,5 +24,7 @@
"achievementAridAuthority": "干旱管理局",
"achievementDustDevilModalText": "你集齐了所有沙漠宠物!",
"achievementDustDevilText": "已经集齐所有的沙漠宠物。",
- "achievementDustDevil": "沙尘恶魔"
+ "achievementDustDevil": "沙尘恶魔",
+ "achievementKickstarter2019Text": "参与了2019年Kickstarter的众筹活动",
+ "achievementKickstarter2019": "徽Kickstarter支持者"
}
diff --git a/website/common/locales/zh/backgrounds.json b/website/common/locales/zh/backgrounds.json
index 53aba91bf0..498935eb6a 100644
--- a/website/common/locales/zh/backgrounds.json
+++ b/website/common/locales/zh/backgrounds.json
@@ -464,5 +464,6 @@
"backgrounds072019": "第62组:2019年7月推出",
"backgroundUnderwaterVentsNotes": "深潜水下,直至水下通风口。",
"backgroundUnderwaterVentsText": "水下通风口",
- "backgroundSeasideCliffsNotes": "站在海边悬崖下的沙滩上。"
+ "backgroundSeasideCliffsNotes": "站在海边悬崖下的沙滩上。",
+ "backgrounds102019": "第65组:2019年10月推出"
}
diff --git a/website/common/locales/zh/content.json b/website/common/locales/zh/content.json
index bd4a09a3ee..f476476f4b 100644
--- a/website/common/locales/zh/content.json
+++ b/website/common/locales/zh/content.json
@@ -153,7 +153,7 @@
"questEggButterflyMountText": "蝴蝶",
"questEggButterflyAdjective": "一个可爱的",
"questEggNudibranchText": "海蛞蝓",
- "questEggNudibranchMountText": "裸鳃亚目动物",
+ "questEggNudibranchMountText": "海蛞蝓",
"questEggNudibranchAdjective": "一个俏皮的",
"questEggHippoText": "河马",
"questEggHippoMountText": "河马",
@@ -350,5 +350,6 @@
"questEggDolphinAdjective": "一只活泼的",
"questEggDolphinMountText": "海豚",
"questEggDolphinText": "海豚",
- "hatchingPotionShadow": "阴影"
+ "hatchingPotionShadow": "阴影",
+ "premiumPotionUnlimitedNotes": "无法用于副本宠物蛋。"
}
diff --git a/website/common/locales/zh/defaulttasks.json b/website/common/locales/zh/defaulttasks.json
index e9f26b690e..bdcbeed957 100644
--- a/website/common/locales/zh/defaulttasks.json
+++ b/website/common/locales/zh/defaulttasks.json
@@ -52,5 +52,14 @@
"selfCareHabit": "短短地休息一下",
"schoolTodoNotes": "点击以命名任务并选择一个截止日期!]",
"schoolTodoText": "为课堂完成任务",
- "schoolDailyNotes": "点击以选择你的作业日程!"
+ "schoolDailyNotes": "点击以选择你的作业日程!",
+ "defaultHabitNotes": "或者从编辑界面将其删去",
+ "defaultHabitText": "点击此处将其编辑为一个你想要戒掉的坏习惯",
+ "creativityTodoNotes": "点击以指定你项目的名称",
+ "creativityTodoText": "完成创造性项目",
+ "creativityDailyNotes": "点击以指定你目前项目的名称 + 设定计划!",
+ "creativityDailyText": "在创意项目上工作",
+ "creativityHabit": "学习大师工艺 >> + 练习一项新的创造性技术",
+ "choresTodoNotes": "点击以指定要清理的区域!",
+ "choresTodoText": "整理衣橱 >> 清理杂乱"
}
diff --git a/website/common/locales/zh/gear.json b/website/common/locales/zh/gear.json
index 6ee0dae07f..b8ab19150a 100644
--- a/website/common/locales/zh/gear.json
+++ b/website/common/locales/zh/gear.json
@@ -1058,20 +1058,20 @@
"headSpecialSummer2018WarriorNotes": "让所有人知道你是最A的斗鱼,戴上这顶浮夸的头盔!增加<%= str %>点力量。2018年夏季限定装备。",
"headSpecialSummer2018MageText": "狮子鱼脊冠",
"headSpecialSummer2018MageNotes": "向任何敢说你看起来“很好吃”的人投以哀怨的目光。增加<%= per %>点感知。2018年夏季限定装备。",
- "headSpecialSummer2018HealerText": "Merfolk Monarch Crown",
- "headSpecialSummer2018HealerNotes": "Adorned with aquamarine, this finned diadem marks leadership of folk, fish, and those who are a bit of both! Increases Intelligence by <%= int %>. Limited Edition 2018 Summer Gear.",
+ "headSpecialSummer2018HealerText": "人鱼帝王皇冠",
+ "headSpecialSummer2018HealerNotes": "这顶带鳍的王冕以海蓝宝石点缀,象征著拥有人类、鱼类,还有兼具两者的生物的统治权!增加 <%= int %> 点智力。 2018年夏季限定版装备。",
"headSpecialFall2018RogueText": "两面派",
"headSpecialFall2018RogueNotes": "大多数人的内心挣扎都是不动声色。这张面具即是“一念成佛,一念成魔”之象征。还有一顶可爱的礼帽!增加<%= per %>点感知。2018年秋季限时装备。",
"headSpecialFall2018WarriorText": "牛头人面具",
"headSpecialFall2018WarriorNotes": "戴上这可怕的面具,你能用角挑翻所有任务!增加<%= str %>点力量。2018年秋季限时装备。",
"headSpecialFall2018MageText": "糖果商人的帽子",
"headSpecialFall2018MageNotes": "灌注过超强甜蜜魔法的尖尖帽。小心点,如果它湿了的话会变黏的!增加<%= per %>点感知。2018秋季限时装备。",
- "headSpecialFall2018HealerText": "Ravenous Helm",
- "headSpecialFall2018HealerNotes": "This helm is fashioned from a carnivorous plant renowned for its ability to dispatch zombies and other inconveniences. Just watch out that it doesn't chew on your head. Increases Intelligence by <%= int %>. Limited Edition 2018 Autumn Gear.",
- "headSpecialNye2018Text": "Outlandish Party Hat",
- "headSpecialNye2018Notes": "You've received an Outlandish Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
- "headSpecialWinter2019RogueText": "Poinsettia Helm",
- "headSpecialWinter2019RogueNotes": "This leafy helm will attain its brightest red color right around the darkest days of winter, helping you blend in with holiday decor! Increases Perception by <%= per %>. Limited Edition 2018-2019 Winter Gear.",
+ "headSpecialFall2018HealerText": "狼吞虎咽头盔",
+ "headSpecialFall2018HealerNotes": "这顶头盔是由一种食肉植物所制成,它以能够制造僵尸和麻烦而闻名。要小心不要让它在您头上咀嚼。增加 <%= int %> 点智力。 2018年秋季限定版装备。",
+ "headSpecialNye2018Text": "怪异派对帽",
+ "headSpecialNye2018Notes": "恭喜您收到一顶怪异的派对庆生帽! 当新年钟声响起时,就自豪地戴上它吧! 无属性加成。",
+ "headSpecialWinter2019RogueText": "一品红圣诞头盔",
+ "headSpecialWinter2019RogueNotes": "这顶枝繁叶茂的头盔将在冬季最黑暗的日子里带来最闪亮的红色,帮助您融入节庆的气氛! 增加 <%= per %> 点感知。 2018-2019冬季限定版装备。",
"headSpecialWinter2019WarriorText": "冰河头盔",
"headSpecialWinter2019WarriorNotes": "战斗中时刻保持头脑冷静是非常重要的!这顶冰凉的盔能在任何敌人挑衅你的时候,保护你不被气昏头。增加<%= str %>点力量。2018—2019年冬季限定装备。",
"headSpecialWinter2019MageText": "烟花焰火",
@@ -1150,18 +1150,18 @@
"headMystery201805Notes": "这顶头盔将让你成为镇上最自豪最漂亮的(也可能是最吵闹的)的鸟。无属性加成。 2018年5月捐赠者物品。",
"headMystery201806Text": "安康鱼盔",
"headMystery201806Notes": "盔顶上的小灯有催眠作用,能让所有海洋生物围绕在你身边。我们强烈呼吁你以善良的方式使用发光吸引生物的能力!不增加属性,2018年6月会员赠品。",
- "headMystery201807Text": "Sea Serpent Helm",
- "headMystery201807Notes": "The strong scales on this helm will protect you from any manner of oceanic foe. Confers no benefit. July 2018 Subscriber Item.",
- "headMystery201808Text": "Lava Dragon Cowl",
- "headMystery201808Notes": "The glowing horns on this cowl will light your way through underground caverns. Confers no benefit. August 2018 Subscriber Item.",
- "headMystery201809Text": "Crown of Autumn Flowers",
- "headMystery201809Notes": "The last flowers of autumn's warm days are a reminder of the beauty of the season. Confers no benefit. September 2018 Subscriber Item.",
- "headMystery201810Text": "Dark Forest Helm",
- "headMystery201810Notes": "If you find yourself traveling through a spooky place, the glowing red eyes of this helm will surely scare away any enemies in your path. Confers no benefit. October 2018 Subscriber Item.",
- "headMystery201811Text": "Splendid Sorcerer's Hat",
- "headMystery201811Notes": "Wear this feathered hat to stand out at even the fanciest wizardly gatherings! Confers no benefit. November 2018 Subscriber Item.",
- "headMystery201901Text": "Polaris Helm",
- "headMystery201901Notes": "The glowing gems on this helm contain light magically captured from winter auroras. Confers no benefit. January 2019 Subscriber Item.",
+ "headMystery201807Text": "大海蛇头盔",
+ "headMystery201807Notes": "这顶头盔上坚韧的鱼鳞能保护您免于受到任何海洋中敌人的攻击。无属性加成。 2018年7月订阅者专属装备。",
+ "headMystery201808Text": "熔岩巨龙披风",
+ "headMystery201808Notes": "披风上那闪闪发亮的龙角能够在地底的洞穴中照亮您的路。无属性加成。 2018年8月订阅者专属装备。",
+ "headMystery201809Text": "秋季花朵皇冠",
+ "headMystery201809Notes": "来自秋季温暖日子中的最后一朵花正是纪念此季节中的美丽事物之最佳信物。无属性加成。 2018年9月订阅者专属装备。",
+ "headMystery201810Text": "黑暗森林头盔",
+ "headMystery201810Notes": "如果您正在穿越一个幽灵般的地方,这顶头盔上发红光的眼睛一定能吓跑沿路中的敌人。无属性加成。 2018年10月订阅者专属装备。",
+ "headMystery201811Text": "璀璨法师帽子",
+ "headMystery201811Notes": "戴上这顶有羽毛的帽子后就算是在最华丽的巫师聚会中也能脱颖而出! 无属性加成。 2018年11月订阅者专属装备。",
+ "headMystery201901Text": "北极星头盔",
+ "headMystery201901Notes": "这头盔上闪闪发亮的钻石拥有从冬季极光中捕获到的神奇光线。无属性加成。 2019年1月订阅者专属装备。",
"headMystery301404Text": "华丽礼帽",
"headMystery301404Notes": "上流社会佼佼者的华丽礼帽!3015年1月捐赠者物品。没有属性加成。",
"headMystery301405Text": "基础礼帽",
@@ -1191,7 +1191,7 @@
"headArmoireYellowHairbowText": "黄色蝴蝶结发饰",
"headArmoireYellowHairbowNotes": "戴上这款黄色蝴蝶结头饰,你将变得敏锐、坚强以及聪明。提升感知,力量和智力各<%= attrs %>点。魔法衣橱:黄色蝴蝶结发饰套装(2件套的第1件物品)。",
"headArmoireRedFloppyHatText": "红色软盘帽",
- "headArmoireRedFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a radiant red color. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Red Loungewear Set (Item 1 of 3).",
+ "headArmoireRedFloppyHatNotes": "这顶帽子是由附魔过的针线缝制而成的,让它呈现出闪闪发亮的红色。增加体质、智力、感知各 <%= attrs %> 点。 来自神祕宝箱: 浅红睡衣套装(1/3)。",
"headArmoirePlagueDoctorHatText": "瘟疫医生帽",
"headArmoirePlagueDoctorHatNotes": "瘟疫拖延症主治医生所穿的帽子。增加<%= str %>点力量,<%= int %>点智力,还有<%= con %>点体质。魔法衣橱: 瘟疫医生系列 (3件的第1件)。",
"headArmoireBlackCatText": "黑猫帽子",
@@ -1199,7 +1199,7 @@
"headArmoireOrangeCatText": "橙猫帽子",
"headArmoireOrangeCatNotes": "这顶橙色帽子在……发出呼噜声,还在翘尾巴,还在呼吸?对,你的头上顶了一只熟睡的猫咪。增加力量和体质各 <%= attrs %>点。魔法衣橱:独立装备。",
"headArmoireBlueFloppyHatText": "蓝色软盘帽",
- "headArmoireBlueFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a brilliant blue color. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Blue Loungewear Set (Item 1 of 3).",
+ "headArmoireBlueFloppyHatNotes": "这顶帽子是由附魔过的针线缝制而成的,让它呈现出闪亮光辉的蓝色。增加体质、智力、感知各 <%= attrs %> 点。 来自神祕宝箱: 浅蓝睡衣套装(1/3)。",
"headArmoireShepherdHeaddressText": "牧羊人头饰",
"headArmoireShepherdHeaddressNotes": "你的狮鹫有时喜欢咀嚼这个头饰,它让你看起来更聪明。增加智力 <%= int %> 点。魔法衣橱:牧羊人套装(3件的第3件)。",
"headArmoireCrystalCrescentHatText": "晶月帽",
@@ -1217,7 +1217,7 @@
"headArmoireGraduateCapText": "毕业生帽子",
"headArmoireGraduateCapNotes": "恭喜恭喜!你深邃的思想为你赢得了这顶思考帽。增加智力<%= int %> 点。魔法衣橱:毕业生套装(3件中的第3件)。",
"headArmoireGreenFloppyHatText": "绿色软盘帽",
- "headArmoireGreenFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a gorgeous green color. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Green Loungewear Set (Item 1 of 3).",
+ "headArmoireGreenFloppyHatNotes": "这顶帽子是由附魔过的针线缝制而成的,让它呈现出带有华丽感的绿色。增加体质、智力、感知各 <%= attrs %> 点。 来自神祕宝箱: 浅绿睡衣套装(1/3)。",
"headArmoireCannoneerBandannaText": "炮手头巾",
"headArmoireCannoneerBandannaNotes": "它对一个炮手来说如同生命!提升智力和感知各<%= attrs %>点。魔法衣橱:炮手套装(3件中的第3件)。",
"headArmoireFalconerCapText": "猎鹰者帽",
@@ -1262,12 +1262,12 @@
"headArmoireBigWigNotes": "有些扑粉假发是为了让人看起来更具权威性,但这顶只会让人发笑! 增加<%= str %>点力量。 魔法衣橱:独立装备。",
"headArmoireGlassblowersHatText": "玻璃吹制工的帽子",
"headArmoireGlassblowersHatNotes": "这顶帽子和你的其他作为防护的玻璃吹制工装备一起佩戴时看起来很不错! 通过。增加<%= per %>点感知。 魔法衣橱:玻璃吹制工套装(4件物品中的第3件)。",
- "headArmoirePiraticalPrincessHeaddressText": "Piratical Princess Headdress",
- "headArmoirePiraticalPrincessHeaddressNotes": "Fancy buccaneers are known for their fancy headwear! Increases Perception and Intelligence by <%= attrs %> each. Enchanted Armoire: Piratical Princess Set (Item 1 of 4).",
- "headArmoireJeweledArcherHelmText": "Jeweled Archer Helm",
- "headArmoireJeweledArcherHelmNotes": "This helm may look ornate, but it's also exceedingly light and strong. Increases Intelligence by <%= int %>. Enchanted Armoire: Jeweled Archer Set (Item 1 of 3).",
- "headArmoireVeilOfSpadesText": "Veil of Spades",
- "headArmoireVeilOfSpadesNotes": "A shadowy and mysterious veil that will boost your stealth. Increases Perception by <%= per %>. Enchanted Armoire: Ace of Spades Set (Item 1 of 3).",
+ "headArmoirePiraticalPrincessHeaddressText": "海盗公主头饰",
+ "headArmoirePiraticalPrincessHeaddressNotes": "自古以来经验老到的海盗皆是以拥有高档的头饰而闻名的! 增加感知、智力各 <%= attrs %> 点。 来自神祕宝箱: 海盗公主套装(1/4)。",
+ "headArmoireJeweledArcherHelmText": "射手宝石头盔",
+ "headArmoireJeweledArcherHelmNotes": "这顶头盔不仅看起来非常华丽,它还格外地轻颖和坚固。增加 <%= int %> 点智力。 来自神祕宝箱: 射手宝石套装(1/3)。",
+ "headArmoireVeilOfSpadesText": "黑桃面纱",
+ "headArmoireVeilOfSpadesNotes": "一件朦胧而神秘的面纱,可以增加您的潜行能力。增加 <%= per %> 点感知。 来自神祕宝箱: 黑桃长矛套装(1/3)。",
"offhand": "副手物品",
"offhandCapitalized": "副手物品",
"shieldBase0Text": "没有副手装备",
@@ -1409,29 +1409,29 @@
"shieldSpecialFall2017HealerText": "闹鬼的小球",
"shieldSpecialFall2017HealerNotes": "这个可爱的小球偶尔会发出尖叫声。我们深表歉意因为我们也没办法调查处切确原因。但它看起来确实很漂亮!增加<%= con %>体质。2017秋季限定装备。",
"shieldSpecialWinter2018RogueText": "薄荷钩",
- "shieldSpecialWinter2018RogueNotes": "Perfect for climbing walls or distracting your foes with sweet, sweet candy. Increases Strength by <%= str %>. Limited Edition 2017-2018 Winter Gear.",
+ "shieldSpecialWinter2018RogueNotes": "此装备极为适合用于攀爬围墙或利用挂钩上甜美多汁的糖果来分散敌人的注意力。增加 <%= str %> 点力量。 2017-2018冬季限定版装备。",
"shieldSpecialWinter2018WarriorText": "魔法禮物包",
- "shieldSpecialWinter2018WarriorNotes": "Just about any useful thing you need can be found in this sack, if you know the right magic words to whisper. Increases Constitution by <%= con %>. Limited Edition 2017-2018 Winter Gear.",
+ "shieldSpecialWinter2018WarriorNotes": "任何您想要的实用物品都可以在这个麻袋里找到。只要您能低语说出正确的通关咒语。增加 <%= con %> 点体质。 2017-2018冬季限定版装备。",
"shieldSpecialWinter2018HealerText": "槲寄生響鈴",
- "shieldSpecialWinter2018HealerNotes": "What's that sound? The sound of warmth and cheer for all to hear! Increases Constitution by <%= con %>. Limited Edition 2017-2018 Winter Gear.",
- "shieldSpecialSpring2018WarriorText": "Shield of the Morning",
- "shieldSpecialSpring2018WarriorNotes": "This sturdy shield glows with the glory of first light. Increases Constitution by <%= con %>. Limited Edition 2018 Spring Gear.",
- "shieldSpecialSpring2018HealerText": "Garnet Shield",
- "shieldSpecialSpring2018HealerNotes": "Despite its fancy appearance, this garnet shield is quite durable! Increases Constitution by <%= con %>. Limited Edition 2018 Spring Gear.",
- "shieldSpecialSummer2018WarriorText": "Betta Skull Shield",
- "shieldSpecialSummer2018WarriorNotes": "Fashioned from stone, this fearsome skull-styled shield strikes fear into fish foes while rallying your Skeleton pets and mounts. Increases Constitution by <%= con %>. Limited Edition 2018 Summer Gear.",
- "shieldSpecialSummer2018HealerText": "Merfolk Monarch Emblem",
- "shieldSpecialSummer2018HealerNotes": "This shield can produce a dome of air for the benefit of land-dwelling visitors to your watery realm. Increases Constitution by <%= con %>. Limited Edition 2018 Summer Gear.",
- "shieldSpecialFall2018RogueText": "Vial of Temptation",
- "shieldSpecialFall2018RogueNotes": "This bottle represents all the distractions and troubles that keep you from being your best self. Resist! We're cheering for you! Increases Strength by <%= str %>. Limited Edition 2018 Autumn Gear.",
- "shieldSpecialFall2018WarriorText": "Brilliant Shield",
- "shieldSpecialFall2018WarriorNotes": "Super shiny to dissuade any troublesome Gorgons from playing peek-a-boo around the corners! Increases Constitution by <%= con %>. Limited Edition 2018 Autumn Gear.",
- "shieldSpecialFall2018HealerText": "Hungry Shield",
- "shieldSpecialFall2018HealerNotes": "With its wide-open maw, this shield will absorb all your enemies' blows. Increases Constitution by <%= con %>. Limited Edition 2018 Autumn Gear.",
- "shieldSpecialWinter2019WarriorText": "Frozen Shield",
- "shieldSpecialWinter2019WarriorNotes": "This shield was fashioned using the thickest sheets of ice from the oldest glacier in the Stoïkalm Steppes. Increases Constitution by <%= con %>. Limited Edition 2018-2019 Winter Gear.",
- "shieldSpecialWinter2019HealerText": "Enchanted Ice Crystals",
- "shieldSpecialWinter2019HealerNotes": "Thin ice may break, but these perfect crystals will turn back any blow before it lands. Increases Constitution by <%= con %>. Limited Edition 2018-2019 Winter Gear.",
+ "shieldSpecialWinter2018HealerNotes": "那是甚么声音? 就是那所有人都能听见的暖心欢呼声! 增加 <%= con %> 点体质。 2017-2018冬季限定版装备。",
+ "shieldSpecialSpring2018WarriorText": "早晨护盾",
+ "shieldSpecialSpring2018WarriorNotes": "这面坚固的护盾能与辉煌的第一道曙光一同发光发热。增加 <%= con %> 点体质。 2018年春季限定版装备。",
+ "shieldSpecialSpring2018HealerText": "石榴石护盾",
+ "shieldSpecialSpring2018HealerNotes": "这面护盾不但拥有华丽的外表,还非常耐用呢! 增加 <%= con %> 点体质。 2018年春季限定版装备。",
+ "shieldSpecialSummer2018WarriorText": "斗鱼骨护盾",
+ "shieldSpecialSummer2018WarriorNotes": "以石头塑成,这面吓人的鱼骨护盾能在与骸骨宠物和坐骑们齐聚一堂时,让所有鱼类敌人都深感畏惧。增加 <%= con %> 点体质。 2018年夏季限量版装备。",
+ "shieldSpecialSummer2018HealerText": "人鱼帝王纹章",
+ "shieldSpecialSummer2018HealerNotes": "这面盾牌能够制造出充满空气的球状空间,以利来自陆地上的访客拜访您的水中王国时能够呼吸。增加 <%= con %> 点体质。2018年夏季限量版装备。",
+ "shieldSpecialFall2018RogueText": "迷惑药水瓶",
+ "shieldSpecialFall2018RogueNotes": "这瓶子代表了所有让您分心或让您不能成为最佳自我的杂事! 请忍住! 我们为您欢呼! 增加 <%= str %> 点力量。 2018年秋季限定版装备。",
+ "shieldSpecialFall2018WarriorText": "辉煌护盾",
+ "shieldSpecialFall2018WarriorNotes": "像黄金般地闪耀以阻止烦人的蛇发女妖不再跟您玩躲猫猫! 增加 <%= con %> 点体质。 2018年秋季限定版装备。",
+ "shieldSpecialFall2018HealerText": "饥饿护盾",
+ "shieldSpecialFall2018HealerNotes": "这面护盾拥有宽阔的嗦囊能够吸收所有敌人的轰炸。增加 <%= con %> 点体质。 2018年秋季限定版装备。",
+ "shieldSpecialWinter2019WarriorText": "冰霜护盾",
+ "shieldSpecialWinter2019WarriorNotes": "这面盾牌是使用来自Stoïkalm草原中最古老的冰川的冰块所制成的。增加体质 <%= con %> 点。 2018-2019冬季限定版装备。",
+ "shieldSpecialWinter2019HealerText": "附魔冰晶",
+ "shieldSpecialWinter2019HealerNotes": "这细薄的冰可能很脆弱,但这完美的冰晶会在它掉落前自动回避掉落。增加 <%= con %> 点体质。 2018-2019冬季限定版装备。",
"shieldMystery201601Text": "决心屠戮者",
"shieldMystery201601Notes": "这把剑能挡开所有的干扰。没有属性加成。2016年1月订阅者物品。",
"shieldMystery201701Text": "冻结时间之盾",
@@ -1440,8 +1440,8 @@
"shieldMystery201708Notes": "这顶坚固的熔岩护盾可以保护你不受坏习惯的伤害,抵挡伤害的时候甚至不会让你的手受到冲击。没有属性加成。2017年8月捐赠者物品。",
"shieldMystery201709Text": "《魔法入门手册》",
"shieldMystery201709Notes": "这本书将引导你初次接触魔法的奥秘。没有属性加成。2017年9月捐赠者物品。",
- "shieldMystery201802Text": "Love Bug Shield",
- "shieldMystery201802Notes": "Although it may look like brittle candy, this shield is resistant to even the strongest Shattering Heartbreak attacks! Confers no benefit. February 2018 Subscriber Item.",
+ "shieldMystery201802Text": "虫粉护盾",
+ "shieldMystery201802Notes": "这面护盾虽然看起来很像是颗易碎的糖果,但它甚至可以抵挡最强大的粉碎破心术攻击! 无属性加成。 2018年2月订阅者专属装备。",
"shieldMystery301405Text": "时钟之盾",
"shieldMystery301405Notes": "拥有这块高耸的时钟之盾,时间与你同在!没有属性加成。3015年6月捐赠者物品。",
"shieldMystery301704Text": "轻柔扇子",
@@ -1484,24 +1484,24 @@
"shieldArmoireHandmadeCandlestickNotes": "你的精美的蜡制品为心怀感激的哈比人提供了光明和温暖!增加<%= str %>点力量。魔法衣橱:烛台制造者套装(3件套第3件)。",
"shieldArmoireWeaversShuttleText": "编织者之梭",
"shieldArmoireWeaversShuttleNotes": "这件工具在你的经纬线之间穿梭,做成一块布!提升智力<%= int %>和感知<%= per %>。附魔衣柜:编织着套装(装备 3 of 3).",
- "shieldArmoireShieldOfDiamondsText": "Shield of Diamonds",
- "shieldArmoireShieldOfDiamondsNotes": "This radiant shield not only provides protection, it empowers you with endurance! Increases Constitution by <%= con %>. Enchanted Armoire: King of Diamonds Set (Item 4 of 4).",
- "shieldArmoireFlutteryFanText": "Fluttery Fan",
- "shieldArmoireFlutteryFanNotes": "On a hot day, there's nothing quite like a fancy fan to help you look and feel cool. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Fluttery Frock Set (Item 4 of 4).",
- "shieldArmoireFancyShoeText": "Fancy Shoe",
- "shieldArmoireFancyShoeNotes": "A very special shoe you're working on. It's fit for royalty! Increases Intelligence and Perception by <%= attrs %> each. Enchanted Armoire: Cobbler Set (Item 3 of 3).",
- "shieldArmoireFancyBlownGlassVaseText": "Fancy Blown Glass Vase",
- "shieldArmoireFancyBlownGlassVaseNotes": "What a fancy vase you've made! What will you put inside? Increases Intelligence by <%= int %>. Enchanted Armoire: Glassblower Set (Item 4 of 4).",
- "shieldArmoirePiraticalSkullShieldText": "Piratical Skull Shield",
- "shieldArmoirePiraticalSkullShieldNotes": "This enchanted shield will whisper the secret locations of your enemies' treasures- listen closely! Increases Perception and Intelligence by <%= attrs %> each. Enchanted Armoire: Piratical Princess Set (Item 4 of 4).",
+ "shieldArmoireShieldOfDiamondsText": "钻石护盾",
+ "shieldArmoireShieldOfDiamondsNotes": "这面闪耀的护盾不但能提供保护,还能赐予您耐力! 增加 <%= con %> 点体质。 来自神秘宝箱: 钻石王者套装(4/4)。",
+ "shieldArmoireFlutteryFanText": "翩翩飞舞纸扇",
+ "shieldArmoireFlutteryFanNotes": "炎炎夏日中,除了它,没有任何东西能同时让您看起来和感觉起来更清爽。 增加体质、智力、感知各 <%= attrs %> 点。 来自神秘宝箱: 飞舞连身裙套装(4/4)。",
+ "shieldArmoireFancyShoeText": "高级高跟鞋",
+ "shieldArmoireFancyShoeNotes": "这是您正在制作中的订制高跟鞋。它非常适合皇家成员! 增加智力、感知各 <%= attrs %> 点。 来自神秘宝箱: 鞋匠套装(3/3)。",
+ "shieldArmoireFancyBlownGlassVaseText": "华丽吹制玻璃花瓶",
+ "shieldArmoireFancyBlownGlassVaseNotes": "您做出来的花瓶是多么的高尚啊! 您会想要将甚么东西放在这里头呢? 增加 <%= int %> 点智力。 来自神秘宝箱: 玻璃吹制工套装(4/4)。",
+ "shieldArmoirePiraticalSkullShieldText": "海盗骷髅护盾",
+ "shieldArmoirePiraticalSkullShieldNotes": "这面附魔过的护盾将能窃听敌人宝藏的藏匿点。请仔细聆听! 增加感知、智力各 <%= attrs %> 点。来自神秘宝箱: 海盗公主套装(4/4)。",
"shieldArmoireUnfinishedTomeText": "未完成的巨著",
"shieldArmoireUnfinishedTomeNotes": "当你拿着这本书时,你感觉自己一会儿都不能拖了!装订工作必须尽快完成,这样才能让人们早点读到这本旷世之作!增加<%= int %>点智力。魔法衣橱:订书人套装(4件之4)。",
- "shieldArmoireSoftBluePillowText": "Soft Blue Pillow",
- "shieldArmoireSoftBluePillowNotes": "The sensible warrior packs a pillow for any expedition. Shield yourself from sharp tasks... even while you nap. Increases Constitution by <%= con %>. Enchanted Armoire: Blue Loungewear Set (Item 3 of 3).",
- "shieldArmoireSoftRedPillowText": "Soft Red Pillow",
- "shieldArmoireSoftRedPillowNotes": "The prepared warrior packs a pillow for any expedition. Protect yourself from those tough tasks... even while you nap. Increases Constitution and Strength by <%= attrs %> each. Enchanted Armoire: Red Loungewear Set (Item 3 of 3).",
- "shieldArmoireSoftGreenPillowText": "Soft Green Pillow",
- "shieldArmoireSoftGreenPillowNotes": "The practical warrior packs a pillow for any expedition. Ward off those pesky chores... even while you nap. Increases Constitution by <%= con %> and Intelligence by <%= int %>. Enchanted Armoire: Green Loungewear Set (Item 3 of 3).",
+ "shieldArmoireSoftBluePillowText": "柔软蓝枕头",
+ "shieldArmoireSoftBluePillowNotes": "明智的战士都会在远征时多准备一个枕头。可以保护自己免于被锋利的任务伤害...甚至是您正在小睡的时候。增加 <%= con %> 点体质。 来自神祕宝箱: 浅蓝睡衣套装(3/3)。",
+ "shieldArmoireSoftRedPillowText": "柔软红枕头",
+ "shieldArmoireSoftRedPillowNotes": "已做好万全准备的战士都会在远征前准备一块枕头。这块枕头能保护您不受艰难的任务伤害... 甚至是在您小睡的时候。增加体质、力量各 <%= attrs %> 点。 来自神祕宝箱: 浅红睡衣套装(3/3)。",
+ "shieldArmoireSoftGreenPillowText": "柔软绿枕头",
+ "shieldArmoireSoftGreenPillowNotes": "有经验的战士都会在远征前准备一块枕头。这块枕头能驱散那些讨厌的杂事... 甚至是在您小睡的时候。增加体质 <%= con %> 点和智力 <%= int %> 点。 来自神祕宝箱: 浅绿睡衣套装(3/3)。",
"shieldArmoireMightyQuillText": "笔力千钧",
"shieldArmoireMightyQuillNotes": "谚语有言:笔诛胜于剑伐。增加<%= per %>点感知。魔法衣橱:书吏套装(3个中之2)。",
"back": "背部挂件",
@@ -1599,18 +1599,18 @@
"bodySpecialSummer2015MageNotes": "这个搭扣并不能让你变强,但它很闪。无增益效果。2015年夏季限定版装备。",
"bodySpecialSummer2015HealerText": "航海家的领巾",
"bodySpecialSummer2015HealerNotes": "哟,嚯,嚯? 不, 不, 不! 没有增益效果。2015年夏季限定版装备。",
- "bodySpecialNamingDay2018Text": "Royal Purple Gryphon Cloak",
- "bodySpecialNamingDay2018Notes": "Happy Naming Day! Wear this fancy and feathery cloak as you celebrate Habitica. Confers no benefit.",
+ "bodySpecialNamingDay2018Text": "紫御狮鹫披风",
+ "bodySpecialNamingDay2018Notes": "命名节快乐! 快戴上这件典雅又柔软的披风一同前来为 Habitica 欢庆吧! 无属性加成。",
"bodyMystery201705Text": "斗士的折叠翅膀",
"bodyMystery201705Notes": "这些折叠的翅膀不只是看起来时髦:它们会给你一个狮鹫的速度和敏捷性!没有属性加成。2017年5月捐赠者物品。",
"bodyMystery201706Text": "衣衫褴褛的海盗船的斗篷",
"bodyMystery201706Notes": "这件斗篷有秘密的口袋,可以把你从任务中掠夺的金子藏起来。没有属性加成。2017年6月捐赠者物品。",
"bodyMystery201711Text": "飞毯驾驶员的围巾",
"bodyMystery201711Notes": "这个柔软的针织围巾在风中看起来相当雄伟。没有属性加成。2017年11月订阅者专享。",
- "bodyMystery201901Text": "Polaris Pauldrons",
- "bodyMystery201901Notes": "These shimmering pauldrons are strong, but will rest on your shoulders as weightlessly as a ray of dancing light. Confers no benefit. January 2019 Subscriber Item.",
+ "bodyMystery201901Text": "北极星护肩",
+ "bodyMystery201901Notes": "这套闪闪发光的护肩非常坚固,但却可以像一缕缕跳舞的光束一样轻盈地靠在您的肩膀上。没有属性加成。 2019年1月订阅者专属装备。",
"bodyArmoireCozyScarfText": "舒適溫暖的領巾",
- "bodyArmoireCozyScarfNotes": "This fine scarf will keep you warm as you go about your wintry business. Increases Constitution and Perception by <%= attrs %> each. Enchanted Armoire: Lamplighter's Set (Item 4 of 4).",
+ "bodyArmoireCozyScarfNotes": "这条上等的围巾能让您在寒冷环境下工作时,还能保持温暖。增加体质、感知各 <%= attrs %> 点。 来自神祕宝箱: 点灯伕套装(4/4)。",
"headAccessory": "头部配件",
"headAccessoryCapitalized": "头部配件",
"accessories": "附属道具",
@@ -1756,12 +1756,12 @@
"armorArmoireChefsJacketNotes": "这件厚夹克有着双重排扣,可以保护你免受液体泼溅(还具有便捷反穿设计)。智力上升了<%= int %>。魔法衣橱:厨师套装(4个中的第2件)。",
"armorArmoireVernalVestmentText": "春之外套",
"armorArmoireVernalVestmentNotes": "这件丝滑外套是享受温和春天的完美选择。力量和智力都上升了<%= attrs %>。魔法衣橱:春之外套(3个中的第2个)。",
- "headArmoireToqueBlancheText": "Toque·Blanche",
+ "headArmoireToqueBlancheText": "厨师帽",
"headArmoireToqueBlancheNotes": "传说,这顶帽子的褶皱数量代表了你熟知的煮鸡蛋方法数! 真的假的? 增加了<%= per%>的感知。 魔法衣橱:厨师套装(第1项,共4项)。",
"headArmoireVernalHenninText": "Vernal·Hennin",
"headArmoireVernalHenninNotes": "这个锥形的帽子不但相当好看,而且还能塞进一张卷起来的待办事项清单。增加了<%= per %>的感知。魔法衣橱:春之外套(3个中的第1个)。",
"shieldMystery201902Text": "神秘的五彩纸屑",
- "shieldMystery201902Notes": "这张来自魔法之心的闪光纸片悬在空中缓慢地舞蹈着。什么效果也没有。2019年二月 付费订阅 物品",
+ "shieldMystery201902Notes": "这张来自魔法之心的闪光纸片悬在空中缓慢地舞蹈着。什么效果也没有。2019年二月 付费订阅物品",
"shieldArmoireMightyPizzaText": "巨无霸披萨",
"shieldArmoireMightyPizzaNotes": "当然,这可以是一个相当不错的盾牌,但我们还是强烈建议你吃掉这个非常、非常好的披萨。增加<%= per %>点感知。魔法衣橱:厨师套装(4个中的第4个)。",
"eyewearMystery201902Text": "神秘芳心纵火犯",
@@ -1823,7 +1823,7 @@
"weaponArmoireFloridFanText": "炫彩扇子",
"weaponArmoireMagnifyingGlassNotes": "啊哈!一个证据!用这个精细的放大镜仔细检查它。增加<%= per%>点感知。魔法衣橱:侦探套装(第3项,共4项)。",
"armorArmoireAstronomersRobeText": "天文学家的长袍",
- "armorArmoireBoatingJacketNotes": "无论你是在一艘时髦的游艇上,还是在一辆破车上,你都会开心地穿着这件夹克和领带。力量智力和感知各增加 <%= attrs %>点。魔法衣柜:划船套装(第 1 项,共 3 项)。",
+ "armorArmoireBoatingJacketNotes": "无论你是在一艘时髦的游艇上,还是在一辆破车上,穿着这件夹克、戴着领带的你都将惹人注目。力量智力和感知各增加 <%= attrs %>点。魔法衣柜:划船套装(第 1 项,共 3 项)。",
"armorArmoireBoatingJacketText": "划船夹克",
"armorArmoireNephriteArmorNotes": "这款盔甲由坚固的钢环制成,饰有玉石,可保护您免受拖延!增加<%= str %>点力量和<%= per %>点感知。魔法衣柜:软玉射手套装(第3项,共3项)。",
"armorArmoireNephriteArmorText": "软玉盔甲",
@@ -1913,5 +1913,6 @@
"weaponSpecialFall2019MageNotes": "无论是制造雷电,制造工事,还是只是将恐怖袭击到凡人的心中,这只魔杖都赋予了巨人创造奇迹的力量。\n智力提高<%= int%>点,感知提高<%= per%>点。 \n2019年秋季限量版装备。",
"weaponSpecialFall2019MageText": "独眼魔杖",
"weaponSpecialFall2019WarriorNotes": "准备用乌鸦的爪子杀死敌人!\n增加<%= str%>点力量。 \n2019年秋季限量版装备。",
- "weaponSpecialFall2019WarriorText": "三叉脚爪"
+ "weaponSpecialFall2019WarriorText": "三叉脚爪",
+ "weaponSpecialKS2019Text": "虚幻狮鹫弯刀"
}
diff --git a/website/common/locales/zh/generic.json b/website/common/locales/zh/generic.json
index 77f47d6588..87f37d033d 100644
--- a/website/common/locales/zh/generic.json
+++ b/website/common/locales/zh/generic.json
@@ -95,7 +95,7 @@
"showMoreMore": "(显示更多)",
"showMoreLess": "(显示更少)",
"gemsWhatFor": "单击购买宝石!宝石能让你购置特殊道具如任务,自定义头像,和应季装备。",
- "veteran": "老兵",
+ "veteran": "退伍",
"veteranText": "经历过 Habit The Grey (原来的网站) ,身上带着多处其bug带来的伤疤。",
"originalUser": "原始用户!",
"originalUserText": "最原始的用户之一,来跟 Alpha 测试者打个招呼吧!",
diff --git a/website/common/locales/zh/groups.json b/website/common/locales/zh/groups.json
index 1075c7f728..c261a98f74 100644
--- a/website/common/locales/zh/groups.json
+++ b/website/common/locales/zh/groups.json
@@ -341,8 +341,8 @@
"leaderCannotLeaveGroupWithActiveGroup": "组长不能在付费订阅尚未过期时离开小组",
"youHaveGroupPlan": "因為你的小组擁有小组計畫, 所以你現在就有免費的訂閱. 如果你離開了小组, 你的訂閱便會被取消. 你購買的訂閱會加在小组計畫後.",
"cancelGroupSub": "取消团队套餐",
- "confirmCancelGroupPlan": "你确定要取消组内订购计划,并取消所有成员的免费订购的权利吗?",
- "canceledGroupPlan": "已取消的团队套餐",
+ "confirmCancelGroupPlan": "你确定要取消组内订购计划吗?组内所有成员会失去他们的订阅与收益。",
+ "canceledGroupPlan": "团队计划已取消",
"groupPlanCanceled": "团队套餐将失效于",
"purchasedGroupPlanPlanExtraMonths": "你有 <%= months %> 个月额外的组内订购的月数。",
"addManager": "分配管理员",
@@ -483,5 +483,6 @@
"pmReported": "感谢您的举报。",
"taskClaimed": "<%= userName %>已经领取了任务<%= taskText %>。",
"youHaveBeenAssignedTask": "<%= managerName%>为您分配了任务<%= taskText%> 。",
- "suggestedGroup": "由于你仍新到 Habitica。"
+ "suggestedGroup": "由于你仍新到 Habitica。",
+ "groupActivityNotificationTitle": "<%= user %>发布在<%= group %>"
}
diff --git a/website/common/locales/zh/maintenance.json b/website/common/locales/zh/maintenance.json
index 3b3f5046ab..d338f45054 100644
--- a/website/common/locales/zh/maintenance.json
+++ b/website/common/locales/zh/maintenance.json
@@ -1,34 +1,33 @@
{
- "habiticaBackSoon": "不要担心。Habitica很快就会回来!",
- "importantMaintenance": "我们正在做重要的维护,我们估计维护将会一直持续到太平洋时间晚上10点(5am UTC).",
- "maintenance": "维护",
- "maintenanceMoreInfo": "想知道更多的维护信息?<%= linkStart %>查看我们的信息页面<%= linkEnd %>。",
- "noDamageKeepStreaks": "您将不会受到伤害或失去连击数!",
- "thanksForPatience": "谢谢您的耐心!",
- "twitterMaintenanceUpdates": "对于最近的更新,查看我们的our Twitter,我们将在这里发布状态信息。",
- "veteranPetAward": "最终,您将获得一只老兵宠物!",
-
- "maintenanceInfoTitle": "关于即将来临的Habitica维护信息",
- "maintenanceInfoWhat": "发生了什么?",
- "maintenanceInfoWhatText": "在5月21日,Habitica将在1天中的大部分时间维护。你的账号将不会受到任何伤害在这个周末,虽然你不能及时登陆打卡你的每日任务!我们将会努力工作尽可能缩短维护时间,发布定期更新在我们的 Twitter账号。在维护结束,为感谢大家的耐心,你们所有人将收到一只稀有宠物!",
- "maintenanceInfoWhy": "为什么这会发生?",
- "maintenanceInfoWhyText": "再过去的几个月,我们已经在幕后彻底的改造了Habitica。特别地是,我们重写了API。它在表面看起来可能不会很不同,但它底层是一个完全不同的世界。这将允许我们的方式更灵活当我们想要去在以后构建特性,也导致了性能的提升!",
- "maintenanceInfoTechDetails": "想要更多技术上的处理过程?访问 铁匠铺,我们的开发部落格。",
- "maintenanceInfoMore": "更多信息",
- "maintenanceInfoAccountChanges": "在这次改写完成后,我的账户将能看到什么样的改变?",
- "maintenanceInfoAccountChangesText": "首先,这里不会有任何显着的变化了,除了对一些功能的改进,例如挑战。如果你注意到任何不该有的变化,请通过发送电子邮件<%= hrefTechAssistanceEmail %>来告知我们,我们会为你调查它们!",
- "maintenanceInfoAddFeatures": "这将允许Habitica添加哪种特性?",
- "maintenanceInfoAddFeaturesText": "完成这次修改后,我们就能开始建立:升级版的聊天和公会,给组织和家庭的计划,还有那些像每月任务和属性记录昨日活动这样的提高效率的特色功能!这些功能都有自己的特点,需要时间来完成它们,但除非我们完成这次重写,不然无法开始。",
- "maintenanceInfoHowLong": "维护持续多久?",
- "maintenanceInfoHowLongText": "我们必须移动所有一百三十万Habitica用户的任务和数据 -- 这不是一个容易的任务!我们预期将发生在大约太平洋时间下午1点 (8pm UTC)到太平洋时间晚10点 (5am UTC)。请放心,我们会竭尽所能使维护更快!你能关注我们Twitter上的更新。",
- "maintenanceInfoStatsAffected": "我的每日任务,连击数,增益魔法和探索任务将受到怎样的影响?",
- "maintenanceInfoStatsAffectedText1": "你将“不会”在这个周末受到任何伤害或丢失任何连击数,但是另外的,你的天数会正常复位!你打卡的每日任务将会变成未打卡状态,增益魔法将重置,等等。如果你在一个采集任务中,你仍然会找到物品。如果你在BOSS战中,你仍然对BOSS造成伤害,但BOSS不能伤害你。(甚至怪物也需要打个小盹!)",
- "maintenanceInfoStatsAffectedText2": "在思索了很多之后,我们团队得出结论,对于维护期间很多用户不能正常打卡的事,这是最公平的处理方法了。我们对此带来的不便感到非常抱歉!",
- "maintenanceInfoSeeTasks": "在当前状况下我是否需要去看我的任务列表?",
- "maintenanceInfoSeeTasksText": "你是否知道你需要在周六检视你的任务列表来提醒自己要做什么,我们建议在维护开始前这样做,对你的任务截图以便于能用来做参考。",
- "maintenanceInfoRarePet": "我将会得到哪种稀有宠物?",
- "maintenanceInfoRarePetText": "为了感谢你们在维护期间耐心等待,每个人都将得到一只稀有老兵宠物。如果你之前从未得到一个老兵宠物,你将得到一直老兵狼。如果你已经有一只老兵狼,你将会得到一只老兵老虎。如果你两只都有,你将会得到一只之前从未见过的老兵宠物!在迁移完成后,会有几小时才显示你的宠物,但不要担心,每人都会得到一只。",
- "maintenanceInfoWho": "谁工作于这个浩大的项目?",
- "maintenanceInfoWhoText": "我们很高兴你提到了这个!它有我们厉害的贡献者团体带领,从Blade,TheHollidayInn,SabreCat,Victor Pudeyev,TheUnknown,和 Alys得到了很多帮助。",
- "maintenanceInfoTesting": "新版本也会被我们厉害的开源志愿者不辞幸劳地测试。谢谢你们 -- 没有你们我们根本完成不了。"
+ "habiticaBackSoon": "不要担心。Habitica很快就会回来!",
+ "importantMaintenance": "我们正在做重要的维护,我们估计维护将会一直持续到太平洋时间晚上10点(5am UTC).",
+ "maintenance": "维护",
+ "maintenanceMoreInfo": "想知道更多的维护信息?<%= linkStart %>查看我们的信息页面<%= linkEnd %>。",
+ "noDamageKeepStreaks": "您将不会受到伤害或失去连击数!",
+ "thanksForPatience": "谢谢您的耐心!",
+ "twitterMaintenanceUpdates": "对于最近的更新,查看我们的our Twitter,我们将在这里发布状态信息。",
+ "veteranPetAward": "最终,您将获得一只退伍老兵系列宠物!",
+ "maintenanceInfoTitle": "关于即将来临的Habitica维护信息",
+ "maintenanceInfoWhat": "发生了什么?",
+ "maintenanceInfoWhatText": "在5月21日,Habitica将在1天中的大部分时间维护。你的账号将不会受到任何伤害在这个周末,虽然你不能及时登陆打卡你的每日任务!我们将会努力工作尽可能缩短维护时间,发布定期更新在我们的 Twitter账号。在维护结束,为感谢大家的耐心,你们所有人将收到一只稀有宠物!",
+ "maintenanceInfoWhy": "为什么这会发生?",
+ "maintenanceInfoWhyText": "再过去的几个月,我们已经在幕后彻底的改造了Habitica。特别地是,我们重写了API。它在表面看起来可能不会很不同,但它底层是一个完全不同的世界。这将允许我们的方式更灵活当我们想要去在以后构建特性,也导致了性能的提升!",
+ "maintenanceInfoTechDetails": "想要更多技术上的处理过程?访问 铁匠铺,我们的开发部落格。",
+ "maintenanceInfoMore": "更多信息",
+ "maintenanceInfoAccountChanges": "在这次改写完成后,我的账户将能看到什么样的改变?",
+ "maintenanceInfoAccountChangesText": "首先,这里不会有任何显着的变化了,除了对一些功能的改进,例如挑战。如果你注意到任何不该有的变化,请通过发送电子邮件<%= hrefTechAssistanceEmail %>来告知我们,我们会为你调查它们!",
+ "maintenanceInfoAddFeatures": "这将允许Habitica添加哪种特性?",
+ "maintenanceInfoAddFeaturesText": "完成这次修改后,我们就能开始建立:升级版的聊天和公会,给组织和家庭的计划,还有那些像每月任务和属性记录昨日活动这样的提高效率的特色功能!这些功能都有自己的特点,需要时间来完成它们,但除非我们完成这次重写,不然无法开始。",
+ "maintenanceInfoHowLong": "维护持续多久?",
+ "maintenanceInfoHowLongText": "我们必须移动所有一百三十万Habitica用户的任务和数据 -- 这不是一个容易的任务!我们预期将发生在大约太平洋时间下午1点 (8pm UTC)到太平洋时间晚10点 (5am UTC)。请放心,我们会竭尽所能使维护更快!你能关注我们Twitter上的更新。",
+ "maintenanceInfoStatsAffected": "我的每日任务,连击数,增益魔法和探索任务将受到怎样的影响?",
+ "maintenanceInfoStatsAffectedText1": "你将“不会”在这个周末受到任何伤害或丢失任何连击数,但是另外的,你的天数会正常复位!你打卡的每日任务将会变成未打卡状态,增益魔法将重置,等等。如果你在一个采集任务中,你仍然会找到物品。如果你在BOSS战中,你仍然对BOSS造成伤害,但BOSS不能伤害你。(甚至怪物也需要打个小盹!)",
+ "maintenanceInfoStatsAffectedText2": "在思索了很多之后,我们团队得出结论,对于维护期间很多用户不能正常打卡的事,这是最公平的处理方法了。我们对此带来的不便感到非常抱歉!",
+ "maintenanceInfoSeeTasks": "在当前状况下我是否需要去看我的任务列表?",
+ "maintenanceInfoSeeTasksText": "你是否知道你需要在周六检视你的任务列表来提醒自己要做什么,我们建议在维护开始前这样做,对你的任务截图以便于能用来做参考。",
+ "maintenanceInfoRarePet": "我将会得到哪种稀有宠物?",
+ "maintenanceInfoRarePetText": "为了感谢你们在维护期间耐心等待,每个人都将得到一只稀有退伍老兵系列宠物。如果你之前从未得到过该系列宠物,你将得到一只退伍军狼。如果你已经有一只退伍军狼,你将会得到一只退伍军虎。如果你两只都有,你将会得到一只之前从未见过的退伍老兵系列宠物!在迁移完成后,会有几小时才显示你的宠物,但不要担心,每人都会得到一只。",
+ "maintenanceInfoWho": "谁工作于这个浩大的项目?",
+ "maintenanceInfoWhoText": "我们很高兴你提到了这个!它有我们厉害的贡献者团体带领,从Blade,TheHollidayInn,SabreCat,Victor Pudeyev,TheUnknown,和 Alys得到了很多帮助。",
+ "maintenanceInfoTesting": "新版本也会被我们厉害的开源志愿者不辞幸劳地测试。谢谢你们 -- 没有你们我们根本完成不了。"
}
diff --git a/website/common/locales/zh/pets.json b/website/common/locales/zh/pets.json
index bb4e2b880f..9bc4d5615b 100644
--- a/website/common/locales/zh/pets.json
+++ b/website/common/locales/zh/pets.json
@@ -16,10 +16,10 @@
"rareMounts": "稀有坐骑",
"etherealLion": "灵狮",
"veteranWolf": "退伍军狼",
- "veteranTiger": "退伍老虎",
- "veteranLion": "老兵狮子",
+ "veteranTiger": "退伍军虎",
+ "veteranLion": "退伍军狮",
"veteranBear": "退伍军熊",
- "veteranFox": "退伍狐狸",
+ "veteranFox": "退伍军狐",
"cerberusPup": "地狱小狗",
"hydra": "三头蛇",
"mantisShrimp": "虾蛄",
@@ -144,5 +144,6 @@
"notEnoughMounts": "您还没有收集足够的坐骑",
"notEnoughPetsMounts": "您还没有收集足够的宠物和坐骑",
"filterByWacky": "古怪",
- "wackyPets": "古怪宠物"
+ "wackyPets": "古怪宠物",
+ "gryphatrice": "狮鹫"
}
diff --git a/website/common/locales/zh/quests.json b/website/common/locales/zh/quests.json
index 51b1a64dbf..cf246a1027 100644
--- a/website/common/locales/zh/quests.json
+++ b/website/common/locales/zh/quests.json
@@ -136,5 +136,6 @@
"chatBossDontAttack": "<%= username %>对<%= bossName %>造成了<%= userDamage %>点伤害。<%= bossName %>没有反击,因为它考虑到目前有些需要修复的错误,他不想不公平地伤害到任何人。但很快它将继续横冲直撞!",
"chatBossDamage": "<%= username %>对<%= bossName %>造成了<%= userDamage %>点伤害。<%= bossName %>对队伍造成了<%= bossDamage %>点伤害。",
"chatQuestStarted": "你们的任务<%= questName %>已经开始啦。",
- "hatchingPotionQuests": "魔法孵化药水副本"
+ "hatchingPotionQuests": "魔法孵化药水副本",
+ "questInvitationNotificationInfo": "您受邀参与副本"
}
diff --git a/website/common/locales/zh/questscontent.json b/website/common/locales/zh/questscontent.json
index 0e41994d88..150a3571df 100644
--- a/website/common/locales/zh/questscontent.json
+++ b/website/common/locales/zh/questscontent.json
@@ -311,7 +311,7 @@
"questSnailCompletion": "你把你的武器砸在巨大的蜗牛壳上,壳裂成两半,涌出了大量的水。粘液被冲走,Habitica居民在你身边欢呼。“看!” @Misceo 说,“在残留的淤泥中,有一小群的蜗牛蛋。”",
"questSnailBoss": "苦差事淤泥蜗牛",
"questSnailDropSnailEgg": "蜗牛(蛋)",
- "questSnailUnlockText": "解锁蜗牛蛋购买功能",
+ "questSnailUnlockText": "在市场上解锁蜗牛蛋以购买",
"questBewilderText": "迷失怪",
"questBewilderNotes": "派对开始的时候和任何一场没什么不同。
",
- "tourScrollDown": "一定要滾動看完所有的選項喔!再次點擊你的角色回到任務界面。",
+ "tourScrollDown": "一定要滾動看完所有的選項喔!再次點擊你的角色回到任務介面。",
"tourMuchMore": "完成新手教學後,你可以與朋友一起成立隊伍,在興趣相投的公會裡聊天,參與挑戰,還有更多的樂趣等著你!",
"tourStatsPage": "這是你的屬性頁面!完成任務列表來獲得成就。",
"tourTavernPage": "歡迎來到酒館,這是個適合各年齡的聊天室!如果您生病了或是正在外面旅行,您可以點擊「入住客棧」來防止未達成每日任務造成的傷害。快來跟大家說聲嗨!",
diff --git a/website/common/locales/zh_TW/overview.json b/website/common/locales/zh_TW/overview.json
index baf09e1da9..ddfdc02db8 100644
--- a/website/common/locales/zh_TW/overview.json
+++ b/website/common/locales/zh_TW/overview.json
@@ -1,7 +1,7 @@
{
"needTips": "需要一些提示該如何開始嗎?簡單的指南在這裡!",
"step1": "步驟一:輸入任務",
- "webStep1Text": "少了現實世界的目標 Habitica 就沒有意義了,所以來加入一些任務吧。您可以在之後想到時新增更多!所有任務都可以透過按下綠色的「建立」按鈕來進行新增。\n* **設置[待辦事項](http://habitica.fandom.com/wiki/To-Dos):**將一次性或次數較少的任務加入待辦事項欄位,一次一項。您可以點選任務進行編輯,並添加核取清單、到期日和其他資訊!\n* **設置[每日任務](http://habitica.fandom.com/wiki/Dailies):**將每天或每週、每月或每年某一天必須進行的活動新增至每日任務欄位。點選任務可編輯到期日或設定起始日期。您也可以設定重複性規則,例如每 3 天一次。\n* **設置[習慣](http://habitica.fandom.com/wiki/Habits):**將您希望建立的習慣新增至習慣欄位。您可以編輯習慣,將其變更為屬於好習慣 :heavy_plus_sign: 或壞習慣 :heavy_minus_sign:。\n* **設置[獎勵](http://habitica.fandom.com/wiki/Rewards):**除了遊戲中所提供的獎勵,也可以將您希望當作動力的活動或獎勵加入至獎勵欄位。讓自己喘口氣或適度放縱是很重要的!\n* 若您需要一些任務的靈感,可以在遊戲維基頁面查看[習慣範例](http://habitica.fandom.com/wiki/Sample_Habits)、[每日任務範例](http://habitica.fandom.com/wiki/Sample_Dailies)、[待辦事項範例](http://habitica.fandom.com/wiki/Sample_To-Dos)及[獎勵範例](http://habitica.fandom.com/wiki/Sample_Custom_Rewards)。",
+ "webStep1Text": "少了現實世界的目標 Habitica 就沒有意義了,所以來加入一些任務吧。您可以在之後想到時新增更多!所有任務都可以透過按下綠色的「建立」按鈕來進行新增。\n* **設置[待辦事項](http://habitica.fandom.com/wiki/To-Dos):**將一次性或次數較少的任務加入待辦事項欄位,一次一項。您可以點選任務進行編輯,並添加核對清單、到期日和其他資訊!\n* **設置[每日任務](http://habitica.fandom.com/wiki/Dailies):**將每天或每週、每月或每年某一天必須進行的活動新增至每日任務欄位。點選任務可編輯到期日或設定起始日期。您也可以設定重複性規則,例如每 3 天一次。\n* **設置[習慣](http://habitica.fandom.com/wiki/Habits):**將您希望建立的習慣新增至習慣欄位。您可以編輯習慣,將其變更為屬於好習慣 :heavy_plus_sign: 或壞習慣 :heavy_minus_sign:。\n* **設置[獎勵](http://habitica.fandom.com/wiki/Rewards):**除了遊戲中所提供的獎勵,也可以將您希望當作動力的活動或獎勵加入至獎勵欄位。讓自己喘口氣或適度放縱是很重要的!\n* 若您需要一些任務的靈感,可以在遊戲維基頁面查看[習慣範例](http://habitica.fandom.com/wiki/Sample_Habits)、[每日任務範例](http://habitica.fandom.com/wiki/Sample_Dailies)、[待辦事項範例](http://habitica.fandom.com/wiki/Sample_To-Dos)及[獎勵範例](http://habitica.fandom.com/wiki/Sample_Custom_Rewards)。",
"step2": "步驟二:透過現實生活中的任務來贏得點數",
"webStep2Text": "接著,開始處理您清單上的目標吧!完成任務並在 Habitica 中勾選完成後,您將會獲得[經驗值](http://habitica.fandom.com/wiki/Experience_Points),這能幫助您升級;另外也會獲得[金幣](http://habitica.fandom.com/wiki/Gold_Points),讓您購買獎勵。若您落入壞習慣或未完成某項每日任務,將會失去[生命值](http://habitica.fandom.com/wiki/Health_Points)。如此一來,Habitica 的經驗值和生命值顯示條即可作為呈現您目標進度的有趣指標。隨著您的角色在遊戲中成長,可以看到您的現實生活逐漸改善。",
"step3": "步驟三:個人化並探索 Habitica",
diff --git a/website/common/locales/zh_TW/pets.json b/website/common/locales/zh_TW/pets.json
index 557179edde..87aba68fac 100644
--- a/website/common/locales/zh_TW/pets.json
+++ b/website/common/locales/zh_TW/pets.json
@@ -144,5 +144,6 @@
"notEnoughMounts": "你還未收集足夠的坐騎",
"notEnoughPetsMounts": "你還未收集足夠的寵物和坐騎",
"wackyPets": "古怪寵物",
- "filterByWacky": "古怪"
+ "filterByWacky": "古怪",
+ "gryphatrice": "獅鷲"
}
diff --git a/website/common/locales/zh_TW/quests.json b/website/common/locales/zh_TW/quests.json
index 6e96c63b70..62745d89e1 100644
--- a/website/common/locales/zh_TW/quests.json
+++ b/website/common/locales/zh_TW/quests.json
@@ -25,7 +25,7 @@
"questInvitation": "副本邀請: ",
"questInvitationTitle": "副本邀請",
"questInvitationInfo": "〈<%= quest %>〉副本的邀請",
- "invitedToQuest": "您受邀加入〈<%= quest %>〉副本",
+ "invitedToQuest": "您受邀參與〈<%= quest %>〉副本",
"askLater": "稍後再問",
"questLater": "等會再進行副本",
"buyQuest": "購買副本",
@@ -136,5 +136,6 @@
"chatItemQuestFinish": "已經找齊所有物品!隊伍因此獲得了獎賞。",
"chatQuestAborted": "<%= username %> 放棄了隊伍副本〈<%= questName %>〉。",
"chatQuestCancelled": "<%= username %> 取消了隊伍副本〈<%= questName %>〉。",
- "tavernBossTired": "<%= bossName %> 試圖解放 <%= rageName %>,但因為實在太累而失敗了。"
+ "tavernBossTired": "<%= bossName %> 試圖解放 <%= rageName %>,但因為實在太累而失敗了。",
+ "questInvitationNotificationInfo": "您受邀參與副本"
}
diff --git a/website/common/locales/zh_TW/questscontent.json b/website/common/locales/zh_TW/questscontent.json
index c70391fc39..55644d3b6b 100644
--- a/website/common/locales/zh_TW/questscontent.json
+++ b/website/common/locales/zh_TW/questscontent.json
@@ -615,7 +615,7 @@
"questKangarooNotes": "Maybe you should have finished that last task… you know, the one you keep avoiding, even though it always comes back around? But @Mewrose and @LilithofAlfheim invited you and @stefalupagus to see a rare kangaroo troop hopping through the Sloensteadi Savannah; how could you say no?! As the troop comes into view, something hits you on the back of the head with a mighty whack!
Shaking the stars from your vision, you pick up the responsible object--a dark red boomerang, with the very task you continually push back etched into its surface. A quick glance around confirms the rest of your party met a similar fate. One larger kangaroo looks at you with a smug grin, like she’s daring you to face her and that dreaded task once and for all!",
"questKangarooCompletion": "“NOW!” You signal your party to throw the boomerangs back at the kangaroo. The beast hops further away with each hit until she flees, leaving nothing more than a dark red cloud of dust, a few eggs, and some gold coins.
@Mewrose walks forward to where the kangaroo once stood. “Hey, where did the boomerangs go?”
“They probably dissolved into dust, making that dark red cloud, when we finished our respective tasks,” @stefalupagus speculates.
@LilithofAlfheim squints at the horizon. “Is that another kangaroo troop heading our way?”
You all break into a run back to Habit City. Better to face your difficult tasks than take another lump to the back of the head!",
"questKangarooBoss": "Catastrophic Kangaroo",
- "questKangarooDropKangarooEgg": "Kangaroo (Egg)",
+ "questKangarooDropKangarooEgg": "袋鼠(寵物蛋)",
"questKangarooUnlockText": "Unlocks purchasable Kangaroo eggs in the Market",
"forestFriendsText": "Forest Friends Quest Bundle",
"forestFriendsNotes": "Contains 'The Spirit of Spring', 'The Hedgebeast', and 'The Tangle Tree'. Available until September 30.",
diff --git a/website/common/locales/zh_TW/settings.json b/website/common/locales/zh_TW/settings.json
index 8aa1728e5f..9b3bbcd807 100644
--- a/website/common/locales/zh_TW/settings.json
+++ b/website/common/locales/zh_TW/settings.json
@@ -119,8 +119,8 @@
"giftedSubscriptionInfo": "<%= name %> 贈送您 <%= months %> 個月的訂閱資格",
"giftedSubscriptionFull": "哈囉 <%= username %>,<%= sender %> 送您 <%= monthCount %> 個月的訂閱資格!",
"giftedSubscriptionWinterPromo": "哈囉 <%= username %>,您收到了 <%= monthCount %> 個月的訂閱資格以作為我們的假期送禮升級活動的一部份!",
- "invitedParty": "邀請至隊伍",
- "invitedGuild": "受邀至公會",
+ "invitedParty": "您受邀加入隊伍",
+ "invitedGuild": "您受邀加入公會",
"importantAnnouncements": "提醒:登入以完成任務以及獲得獎勵",
"weeklyRecaps": "您的帳號上星期的活動彙整 (注意:這個彙整目前因為伺服器效能問題而暫時關閉,但是我們會盡快修復並再一次定期發送電子郵件!)",
"onboarding": "引導設定您的 Habitica 帳號",
@@ -204,5 +204,7 @@
"usernameVerifiedConfirmation": "您的使用者名稱 <%= username %> 已確認!",
"usernameNotVerified": "請確認您的使用者名稱。",
"changeUsernameDisclaimer": "我們即將將登入名稱改為獨一無二的公開使用者名稱。此使用者名稱將用於邀請、聊天中的 @標記、和訊息。",
- "verifyUsernameVeteranPet": "完成確認後,其中一隻將領寵物將會等您前來領養!"
+ "verifyUsernameVeteranPet": "完成確認後,其中一隻將領寵物將會等您前來領養!",
+ "subscriptionReminders": "訂閱提醒",
+ "newPMNotificationTitle": "來自 <%= name %> 的新訊息"
}
diff --git a/website/common/locales/zh_TW/tasks.json b/website/common/locales/zh_TW/tasks.json
index 393f79ede1..9fdc212996 100644
--- a/website/common/locales/zh_TW/tasks.json
+++ b/website/common/locales/zh_TW/tasks.json
@@ -24,9 +24,9 @@
"greenblue": "經常",
"edit": "編輯",
"save": "儲存",
- "addChecklist": "增加清單",
- "checklist": "清單",
- "checklistText": "把一個任務拆解成較小的項目!被拆解的任務可以獲得更多的經驗值與金幣,並且減少每日任務帶來的傷害。",
+ "addChecklist": "增加核對清單",
+ "checklist": "核對清單",
+ "checklistText": "把一個任務拆解成較小的項目!核對清單可以獲得更多的經驗值與金幣,並且減少每日任務帶來的傷害。",
"newChecklistItem": "新核對清單項目",
"expandChecklist": "展開核對清單",
"collapseChecklist": "折疊核對清單",
diff --git a/website/common/script/.babelrc b/website/common/script/.babelrc
deleted file mode 100644
index c505a46261..0000000000
--- a/website/common/script/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["es2015"],
-}
\ No newline at end of file
diff --git a/website/common/script/.eslintrc b/website/common/script/.eslintrc
deleted file mode 100644
index 4acd626597..0000000000
--- a/website/common/script/.eslintrc
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "extends": [
- "habitrpg/browser",
- "habitrpg/esnext"
- ]
-}
diff --git a/website/common/script/.eslintrc.js b/website/common/script/.eslintrc.js
new file mode 100644
index 0000000000..4e0017fb61
--- /dev/null
+++ b/website/common/script/.eslintrc.js
@@ -0,0 +1,5 @@
+module.exports = {
+ extends: [
+ "habitrpg/lib/node",
+ ]
+}
diff --git a/website/common/script/constants.js b/website/common/script/constants.js
index 262596bf87..81c1782fd1 100644
--- a/website/common/script/constants.js
+++ b/website/common/script/constants.js
@@ -12,12 +12,13 @@ export const MIN_SHORTNAME_SIZE_FOR_CHALLENGES = 3;
export const CHAT_FLAG_LIMIT_FOR_HIDING = 2; // hide posts that have this many flags
export const CHAT_FLAG_FROM_MOD = 5; // a flag from a moderator counts as this many flags
-export const CHAT_FLAG_FROM_SHADOW_MUTE = 10; // a shadow-muted user's post starts with this many flags
+// a shadow-muted user's post starts with this many flags
+export const CHAT_FLAG_FROM_SHADOW_MUTE = 10;
// @TODO use those constants to replace hard-coded numbers
export const SUPPORTED_SOCIAL_NETWORKS = [
- {key: 'facebook', name: 'Facebook'},
- {key: 'google', name: 'Google'},
+ { key: 'facebook', name: 'Facebook' },
+ { key: 'google', name: 'Google' },
];
export const GUILDS_PER_PAGE = 30; // number of guilds to return per page when using pagination
diff --git a/website/common/script/content/achievements.js b/website/common/script/content/achievements.js
index c39939383d..011dcc40c8 100644
--- a/website/common/script/content/achievements.js
+++ b/website/common/script/content/achievements.js
@@ -1,8 +1,8 @@
import each from 'lodash/each';
-let achievementsData = {};
+const achievementsData = {};
-let worldQuestAchievs = {
+const worldQuestAchievs = {
dilatoryQuest: {
icon: 'achievement-dilatory',
titleKey: 'achievementDilatory',
@@ -31,7 +31,7 @@ let worldQuestAchievs = {
};
Object.assign(achievementsData, worldQuestAchievs);
-let seasonalSpellAchievs = {
+const seasonalSpellAchievs = {
snowball: {
icon: 'achievement-snowball',
titleKey: 'annoyingFriends',
@@ -55,7 +55,7 @@ let seasonalSpellAchievs = {
};
Object.assign(achievementsData, seasonalSpellAchievs);
-let masterAchievs = {
+const masterAchievs = {
beastMaster: {
icon: 'achievement-rat',
titleKey: 'beastMasterName',
@@ -77,7 +77,7 @@ let masterAchievs = {
};
Object.assign(achievementsData, masterAchievs);
-let basicAchievs = {
+const basicAchievs = {
partyUp: {
icon: 'achievement-partyUp',
titleKey: 'partyUpName',
@@ -157,10 +157,20 @@ let basicAchievs = {
titleKey: 'achievementAridAuthority',
textKey: 'achievementAridAuthorityText',
},
+ monsterMagus: {
+ icon: 'achievement-monsterMagus',
+ titleKey: 'achievementMonsterMagus',
+ textKey: 'achievementMonsterMagusText',
+ },
+ undeadUndertaker: {
+ icon: 'achievement-undeadUndertaker',
+ titleKey: 'achievementUndeadUndertaker',
+ textKey: 'achievementUndeadUndertakerText',
+ },
};
Object.assign(achievementsData, basicAchievs);
-let specialAchievs = {
+const specialAchievs = {
contributor: {
icon: 'achievement-boot',
titleKey: 'contribName',
@@ -201,7 +211,7 @@ let specialAchievs = {
};
Object.assign(achievementsData, specialAchievs);
-let holidayAchievs = {
+const holidayAchievs = {
habiticaDays: {
icon: 'achievement-habiticaDay',
singularTitleKey: 'habiticaDay',
@@ -226,7 +236,7 @@ let holidayAchievs = {
};
Object.assign(achievementsData, holidayAchievs);
-let ultimateGearAchievs = ['healer', 'rogue', 'warrior', 'mage'].reduce((achievs, type) => {
+const ultimateGearAchievs = ['healer', 'rogue', 'warrior', 'mage'].reduce((achievs, type) => {
achievs[`${type}UltimateGear`] = {
icon: `achievement-ultimate-${type}`,
titleKey: 'ultimGearName',
@@ -236,7 +246,7 @@ let ultimateGearAchievs = ['healer', 'rogue', 'warrior', 'mage'].reduce((achievs
}, {});
Object.assign(achievementsData, ultimateGearAchievs);
-let cardAchievs = ['greeting', 'thankyou', 'nye', 'valentine', 'birthday', 'congrats', 'getwell', 'goodluck'].reduce((achievs, type) => {
+const cardAchievs = ['greeting', 'thankyou', 'nye', 'valentine', 'birthday', 'congrats', 'getwell', 'goodluck'].reduce((achievs, type) => {
achievs[`${type}Cards`] = {
icon: `achievement-${type}`,
titleKey: `${type}CardAchievementTitle`,
@@ -250,4 +260,4 @@ each(achievementsData, (value, key) => {
value.key = key;
});
-module.exports = achievementsData;
+export default achievementsData;
diff --git a/website/common/script/content/appearance/backgrounds.js b/website/common/script/content/appearance/backgrounds.js
index 15a06aa79e..7686f95ee9 100644
--- a/website/common/script/content/appearance/backgrounds.js
+++ b/website/common/script/content/appearance/backgrounds.js
@@ -2,7 +2,7 @@ import forOwn from 'lodash/forOwn';
import t from '../translation';
/* eslint-disable camelcase */
-let backgrounds = {
+const backgrounds = {
backgrounds062014: {
beach: {
text: t('backgroundBeachText'),
@@ -948,10 +948,10 @@ let backgrounds = {
};
/* eslint-enable quote-props */
-let flat = {};
+const flat = {};
-forOwn(backgrounds, function prefillBackgroundSet (backgroundsInSet, set) {
- forOwn(backgroundsInSet, function prefillBackground (background, bgKey) {
+forOwn(backgrounds, (backgroundsInSet, set) => {
+ forOwn(backgroundsInSet, (background, bgKey) => {
background.key = bgKey;
background.set = set;
background.price = 7;
diff --git a/website/common/script/content/appearance/chair.js b/website/common/script/content/appearance/chair.js
index 4827b8caf4..4fad760d59 100644
--- a/website/common/script/content/appearance/chair.js
+++ b/website/common/script/content/appearance/chair.js
@@ -1,4 +1,4 @@
-import prefill from './prefill.js';
+import prefill from './prefill';
export default prefill({
none: {},
diff --git a/website/common/script/content/appearance/hair/bangs.js b/website/common/script/content/appearance/hair/bangs.js
index a540190cda..a112be50f3 100644
--- a/website/common/script/content/appearance/hair/bangs.js
+++ b/website/common/script/content/appearance/hair/bangs.js
@@ -1,6 +1,6 @@
-import prefill from '../prefill.js';
+import prefill from '../prefill';
-module.exports = prefill({
+export default prefill({
0: {},
1: {},
2: {},
diff --git a/website/common/script/content/appearance/hair/base.js b/website/common/script/content/appearance/hair/base.js
index 1b2bac626c..b8edd502d8 100644
--- a/website/common/script/content/appearance/hair/base.js
+++ b/website/common/script/content/appearance/hair/base.js
@@ -1,26 +1,26 @@
-import prefill from '../prefill.js';
-import sets from '../sets.js';
+import prefill from '../prefill';
+import sets from '../sets';
-module.exports = prefill({
+export default prefill({
0: {},
1: {},
- 2: {price: 2, set: sets.baseHair1},
+ 2: { price: 2, set: sets.baseHair1 },
3: {},
- 4: {price: 2, set: sets.baseHair1},
- 5: {price: 2, set: sets.baseHair1},
- 6: {price: 2, set: sets.baseHair1},
- 7: {price: 2, set: sets.baseHair1},
- 8: {price: 2, set: sets.baseHair1},
- 9: {price: 2, set: sets.baseHair2},
- 10: {price: 2, set: sets.baseHair2},
- 11: {price: 2, set: sets.baseHair2},
- 12: {price: 2, set: sets.baseHair2},
- 13: {price: 2, set: sets.baseHair2},
- 14: {price: 2, set: sets.baseHair2},
- 15: {price: 2, set: sets.baseHair3},
- 16: {price: 2, set: sets.baseHair3},
- 17: {price: 2, set: sets.baseHair3},
- 18: {price: 2, set: sets.baseHair3},
- 19: {price: 2, set: sets.baseHair3},
- 20: {price: 2, set: sets.baseHair3},
+ 4: { price: 2, set: sets.baseHair1 },
+ 5: { price: 2, set: sets.baseHair1 },
+ 6: { price: 2, set: sets.baseHair1 },
+ 7: { price: 2, set: sets.baseHair1 },
+ 8: { price: 2, set: sets.baseHair1 },
+ 9: { price: 2, set: sets.baseHair2 },
+ 10: { price: 2, set: sets.baseHair2 },
+ 11: { price: 2, set: sets.baseHair2 },
+ 12: { price: 2, set: sets.baseHair2 },
+ 13: { price: 2, set: sets.baseHair2 },
+ 14: { price: 2, set: sets.baseHair2 },
+ 15: { price: 2, set: sets.baseHair3 },
+ 16: { price: 2, set: sets.baseHair3 },
+ 17: { price: 2, set: sets.baseHair3 },
+ 18: { price: 2, set: sets.baseHair3 },
+ 19: { price: 2, set: sets.baseHair3 },
+ 20: { price: 2, set: sets.baseHair3 },
});
diff --git a/website/common/script/content/appearance/hair/beard.js b/website/common/script/content/appearance/hair/beard.js
index 56ef44045b..b0de3ff35c 100644
--- a/website/common/script/content/appearance/hair/beard.js
+++ b/website/common/script/content/appearance/hair/beard.js
@@ -1,9 +1,9 @@
-import sets from '../sets.js';
-import prefill from '../prefill.js';
+import sets from '../sets';
+import prefill from '../prefill';
-module.exports = prefill({
+export default prefill({
0: {},
- 1: {price: 2, set: sets.facialHair},
- 2: {price: 2, set: sets.facialHair},
- 3: {price: 2, set: sets.facialHair},
+ 1: { price: 2, set: sets.facialHair },
+ 2: { price: 2, set: sets.facialHair },
+ 3: { price: 2, set: sets.facialHair },
});
diff --git a/website/common/script/content/appearance/hair/color.js b/website/common/script/content/appearance/hair/color.js
index 63dc0496eb..afba6e21a1 100644
--- a/website/common/script/content/appearance/hair/color.js
+++ b/website/common/script/content/appearance/hair/color.js
@@ -1,50 +1,50 @@
-import sets from '../sets.js';
-import prefill from '../prefill.js';
+import sets from '../sets';
+import prefill from '../prefill';
-module.exports = prefill({
+export default prefill({
white: {},
brown: {},
blond: {},
red: {},
black: {},
- candycane: {price: 2, set: sets.winterHairColors},
- frost: {price: 2, set: sets.winterHairColors},
- winternight: {price: 2, set: sets.winterHairColors},
- holly: {price: 2, set: sets.winterHairColors},
+ candycane: { price: 2, set: sets.winterHairColors },
+ frost: { price: 2, set: sets.winterHairColors },
+ winternight: { price: 2, set: sets.winterHairColors },
+ holly: { price: 2, set: sets.winterHairColors },
- pblue: {price: 2, set: sets.pastelHairColors},
- pgreen: {price: 2, set: sets.pastelHairColors},
- porange: {price: 2, set: sets.pastelHairColors},
- ppink: {price: 2, set: sets.pastelHairColors},
- ppurple: {price: 2, set: sets.pastelHairColors},
- pyellow: {price: 2, set: sets.pastelHairColors},
+ pblue: { price: 2, set: sets.pastelHairColors },
+ pgreen: { price: 2, set: sets.pastelHairColors },
+ porange: { price: 2, set: sets.pastelHairColors },
+ ppink: { price: 2, set: sets.pastelHairColors },
+ ppurple: { price: 2, set: sets.pastelHairColors },
+ pyellow: { price: 2, set: sets.pastelHairColors },
- rainbow: {price: 2, set: sets.rainbowHairColors},
- yellow: {price: 2, set: sets.rainbowHairColors},
- green: {price: 2, set: sets.rainbowHairColors},
- purple: {price: 2, set: sets.rainbowHairColors},
- blue: {price: 2, set: sets.rainbowHairColors},
- TRUred: {price: 2, set: sets.rainbowHairColors},
+ rainbow: { price: 2, set: sets.rainbowHairColors },
+ yellow: { price: 2, set: sets.rainbowHairColors },
+ green: { price: 2, set: sets.rainbowHairColors },
+ purple: { price: 2, set: sets.rainbowHairColors },
+ blue: { price: 2, set: sets.rainbowHairColors },
+ TRUred: { price: 2, set: sets.rainbowHairColors },
- pblue2: {price: 2, set: sets.shimmerHairColors},
- pgreen2: {price: 2, set: sets.shimmerHairColors},
- porange2: {price: 2, set: sets.shimmerHairColors},
- ppink2: {price: 2, set: sets.shimmerHairColors},
- ppurple2: {price: 2, set: sets.shimmerHairColors},
- pyellow2: {price: 2, set: sets.shimmerHairColors},
+ pblue2: { price: 2, set: sets.shimmerHairColors },
+ pgreen2: { price: 2, set: sets.shimmerHairColors },
+ porange2: { price: 2, set: sets.shimmerHairColors },
+ ppink2: { price: 2, set: sets.shimmerHairColors },
+ ppurple2: { price: 2, set: sets.shimmerHairColors },
+ pyellow2: { price: 2, set: sets.shimmerHairColors },
- candycorn: {price: 2, set: sets.hauntedHairColors},
- ghostwhite: {price: 2, set: sets.hauntedHairColors},
- halloween: {price: 2, set: sets.hauntedHairColors},
- midnight: {price: 2, set: sets.hauntedHairColors},
- pumpkin: {price: 2, set: sets.hauntedHairColors},
- zombie: {price: 2, set: sets.hauntedHairColors},
+ candycorn: { price: 2, set: sets.hauntedHairColors },
+ ghostwhite: { price: 2, set: sets.hauntedHairColors },
+ halloween: { price: 2, set: sets.hauntedHairColors },
+ midnight: { price: 2, set: sets.hauntedHairColors },
+ pumpkin: { price: 2, set: sets.hauntedHairColors },
+ zombie: { price: 2, set: sets.hauntedHairColors },
- aurora: {price: 2, set: sets.winteryHairColors},
- festive: {price: 2, set: sets.winteryHairColors},
- hollygreen: {price: 2, set: sets.winteryHairColors},
- peppermint: {price: 2, set: sets.winteryHairColors},
- snowy: {price: 2, set: sets.winteryHairColors},
- winterstar: {price: 2, set: sets.winteryHairColors},
+ aurora: { price: 2, set: sets.winteryHairColors },
+ festive: { price: 2, set: sets.winteryHairColors },
+ hollygreen: { price: 2, set: sets.winteryHairColors },
+ peppermint: { price: 2, set: sets.winteryHairColors },
+ snowy: { price: 2, set: sets.winteryHairColors },
+ winterstar: { price: 2, set: sets.winteryHairColors },
});
diff --git a/website/common/script/content/appearance/hair/flower.js b/website/common/script/content/appearance/hair/flower.js
index 9b4b967748..5f9048f2ed 100644
--- a/website/common/script/content/appearance/hair/flower.js
+++ b/website/common/script/content/appearance/hair/flower.js
@@ -1,6 +1,6 @@
-import prefill from '../prefill.js';
+import prefill from '../prefill';
-module.exports = prefill({
+export default prefill({
0: {},
1: {},
2: {},
diff --git a/website/common/script/content/appearance/hair/index.js b/website/common/script/content/appearance/hair/index.js
index 35201d8b1c..4b087ef376 100644
--- a/website/common/script/content/appearance/hair/index.js
+++ b/website/common/script/content/appearance/hair/index.js
@@ -1,11 +1,11 @@
-import bangs from './bangs.js';
-import base from './base.js';
-import beard from './beard.js';
-import color from './color.js';
-import flower from './flower.js';
-import mustache from './mustache.js';
+import bangs from './bangs';
+import base from './base';
+import beard from './beard';
+import color from './color';
+import flower from './flower';
+import mustache from './mustache';
-module.exports = {
+export default {
color,
base,
bangs,
diff --git a/website/common/script/content/appearance/hair/mustache.js b/website/common/script/content/appearance/hair/mustache.js
index 972de3e718..231b8fef8b 100644
--- a/website/common/script/content/appearance/hair/mustache.js
+++ b/website/common/script/content/appearance/hair/mustache.js
@@ -1,8 +1,8 @@
-import sets from '../sets.js';
-import prefill from '../prefill.js';
+import sets from '../sets';
+import prefill from '../prefill';
-module.exports = prefill({
+export default prefill({
0: {},
- 1: {price: 2, set: sets.facialHair},
- 2: {price: 2, set: sets.facialHair},
+ 1: { price: 2, set: sets.facialHair },
+ 2: { price: 2, set: sets.facialHair },
});
diff --git a/website/common/script/content/appearance/hair/top-hair.js b/website/common/script/content/appearance/hair/top-hair.js
index 50610fbe03..508e03e0e6 100644
--- a/website/common/script/content/appearance/hair/top-hair.js
+++ b/website/common/script/content/appearance/hair/top-hair.js
@@ -1,12 +1,12 @@
-import prefill from '../prefill.js';
-import sets from '../sets.js';
+import prefill from '../prefill';
+import sets from '../sets';
-module.exports = prefill({
+export default prefill({
0: {},
- 1: {price: 2, set: sets.topHair},
- 2: {price: 2, set: sets.topHair},
- 3: {price: 2, set: sets.topHair},
- 4: {price: 2, set: sets.topHair},
- 5: {price: 2, set: sets.topHair},
- 6: {price: 2, set: sets.topHair},
+ 1: { price: 2, set: sets.topHair },
+ 2: { price: 2, set: sets.topHair },
+ 3: { price: 2, set: sets.topHair },
+ 4: { price: 2, set: sets.topHair },
+ 5: { price: 2, set: sets.topHair },
+ 6: { price: 2, set: sets.topHair },
});
diff --git a/website/common/script/content/appearance/index.js b/website/common/script/content/appearance/index.js
index 700a9f25b6..2c65beb9ce 100644
--- a/website/common/script/content/appearance/index.js
+++ b/website/common/script/content/appearance/index.js
@@ -1,17 +1,17 @@
-import hair from './hair';
-import shirts from './shirt.js';
-import skins from './skin.js';
-import sizes from './size.js';
-import backgrounds from './backgrounds.js';
-import chairs from './chair.js';
import forOwn from 'lodash/forOwn';
import clone from 'lodash/clone';
+import hair from './hair';
+import shirts from './shirt';
+import skins from './skin';
+import sizes from './size';
+import backgrounds from './backgrounds';
+import chairs from './chair';
-let reorderedBgs = {};
+const reorderedBgs = {};
-forOwn(backgrounds, function restructureBackgroundSet (value, key) {
- forOwn(value, function restructureBackground (bgObject, bgKey) {
- let bg = clone(bgObject);
+forOwn(backgrounds, (value, key) => {
+ forOwn(value, (bgObject, bgKey) => {
+ const bg = clone(bgObject);
bg.set = {
text: key,
key,
@@ -22,7 +22,7 @@ forOwn(backgrounds, function restructureBackgroundSet (value, key) {
});
-let appearances = {
+const appearances = {
hair,
shirt: shirts,
size: sizes,
@@ -31,4 +31,4 @@ let appearances = {
background: reorderedBgs,
};
-module.exports = appearances;
+export default appearances;
diff --git a/website/common/script/content/appearance/prefill.js b/website/common/script/content/appearance/prefill.js
index 3422ab10d9..8823a36fd3 100644
--- a/website/common/script/content/appearance/prefill.js
+++ b/website/common/script/content/appearance/prefill.js
@@ -1,11 +1,11 @@
import forOwn from 'lodash/forOwn';
-module.exports = function prefillAppearances (obj) {
- forOwn(obj, function prefillAppearance (value, key) {
+export default function prefillAppearances (obj) {
+ forOwn(obj, (value, key) => {
value.key = key;
if (!value.price) {
value.price = 0;
}
});
return obj;
-};
+}
diff --git a/website/common/script/content/appearance/sets.js b/website/common/script/content/appearance/sets.js
index 44768bd000..128a2c595f 100644
--- a/website/common/script/content/appearance/sets.js
+++ b/website/common/script/content/appearance/sets.js
@@ -1,23 +1,37 @@
import t from '../translation';
-import prefill from './prefill.js';
+import prefill from './prefill';
-module.exports = prefill({
- baseHair1: {setPrice: 5, text: t('hairSet1')},
- baseHair2: {setPrice: 5, text: t('hairSet2')},
- baseHair3: {setPrice: 5, text: t('hairSet3')},
- facialHair: {setPrice: 5, text: t('bodyFacialHair')},
- specialShirts: {setPrice: 5, text: t('specialShirts')},
- winterHairColors: {setPrice: 5, availableUntil: '2016-01-01'},
- pastelHairColors: {setPrice: 5, availableUntil: '2016-01-01'},
- rainbowHairColors: {setPrice: 5, text: t('rainbowColors')},
- shimmerHairColors: {setPrice: 5, availableFrom: '2019-04-09', availableUntil: '2019-05-02', text: t('shimmerColors')},
- hauntedHairColors: {setPrice: 5, availableFrom: '2018-10-11', availableUntil: '2018-11-02', text: t('hauntedColors')},
- winteryHairColors: {setPrice: 5, availableFrom: '2019-01-08', availableUntil: '2019-02-02', text: t('winteryColors')},
- rainbowSkins: {setPrice: 5, text: t('rainbowSkins')},
- animalSkins: {setPrice: 5, text: t('animalSkins')},
- pastelSkins: {setPrice: 5, availableFrom: '2019-04-09', availableUntil: '2019-05-02', text: t('pastelSkins')},
- spookySkins: {setPrice: 5, availableUntil: '2016-01-01', text: t('spookySkins')},
- supernaturalSkins: {setPrice: 5, availableFrom: '2018-10-11', availableUntil: '2018-11-02', text: t('supernaturalSkins')},
- splashySkins: {setPrice: 5, availableFrom: '2019-07-02', availableUntil: '2019-08-02', text: t('splashySkins')},
- winterySkins: {setPrice: 5, availableFrom: '2019-01-08', availableUntil: '2019-02-02', text: t('winterySkins')},
+export default prefill({
+ baseHair1: { setPrice: 5, text: t('hairSet1') },
+ baseHair2: { setPrice: 5, text: t('hairSet2') },
+ baseHair3: { setPrice: 5, text: t('hairSet3') },
+ facialHair: { setPrice: 5, text: t('bodyFacialHair') },
+ specialShirts: { setPrice: 5, text: t('specialShirts') },
+ winterHairColors: { setPrice: 5, availableUntil: '2016-01-01' },
+ pastelHairColors: { setPrice: 5, availableUntil: '2016-01-01' },
+ rainbowHairColors: { setPrice: 5, text: t('rainbowColors') },
+ shimmerHairColors: {
+ setPrice: 5, availableFrom: '2019-04-09', availableUntil: '2019-05-02', text: t('shimmerColors'),
+ },
+ hauntedHairColors: {
+ setPrice: 5, availableFrom: '2019-10-08', availableUntil: '2019-11-02', text: t('hauntedColors'),
+ },
+ winteryHairColors: {
+ setPrice: 5, availableFrom: '2019-01-08', availableUntil: '2019-02-02', text: t('winteryColors'),
+ },
+ rainbowSkins: { setPrice: 5, text: t('rainbowSkins') },
+ animalSkins: { setPrice: 5, text: t('animalSkins') },
+ pastelSkins: {
+ setPrice: 5, availableFrom: '2019-04-09', availableUntil: '2019-05-02', text: t('pastelSkins'),
+ },
+ spookySkins: { setPrice: 5, availableUntil: '2016-01-01', text: t('spookySkins') },
+ supernaturalSkins: {
+ setPrice: 5, availableFrom: '2019-10-08', availableUntil: '2019-11-02', text: t('supernaturalSkins'),
+ },
+ splashySkins: {
+ setPrice: 5, availableFrom: '2019-07-02', availableUntil: '2019-08-02', text: t('splashySkins'),
+ },
+ winterySkins: {
+ setPrice: 5, availableFrom: '2019-01-08', availableUntil: '2019-02-02', text: t('winterySkins'),
+ },
});
diff --git a/website/common/script/content/appearance/shirt.js b/website/common/script/content/appearance/shirt.js
index 3ab890dd0f..22f09a103d 100644
--- a/website/common/script/content/appearance/shirt.js
+++ b/website/common/script/content/appearance/shirt.js
@@ -1,7 +1,7 @@
-import sets from './sets.js';
-import prefill from './prefill.js';
+import sets from './sets';
+import prefill from './prefill';
-module.exports = prefill({
+export default prefill({
black: {},
blue: {},
green: {},
@@ -9,15 +9,15 @@ module.exports = prefill({
white: {},
yellow: {},
- convict: {price: 2, set: sets.specialShirts},
- cross: {price: 2, set: sets.specialShirts},
- fire: {price: 2, set: sets.specialShirts},
- horizon: {price: 2, set: sets.specialShirts},
- ocean: {price: 2, set: sets.specialShirts},
- purple: {price: 2, set: sets.specialShirts},
- rainbow: {price: 2, set: sets.specialShirts},
- redblue: {price: 2, set: sets.specialShirts},
- thunder: {price: 2, set: sets.specialShirts},
- tropical: {price: 2, set: sets.specialShirts},
- zombie: {price: 2, set: sets.specialShirts},
+ convict: { price: 2, set: sets.specialShirts },
+ cross: { price: 2, set: sets.specialShirts },
+ fire: { price: 2, set: sets.specialShirts },
+ horizon: { price: 2, set: sets.specialShirts },
+ ocean: { price: 2, set: sets.specialShirts },
+ purple: { price: 2, set: sets.specialShirts },
+ rainbow: { price: 2, set: sets.specialShirts },
+ redblue: { price: 2, set: sets.specialShirts },
+ thunder: { price: 2, set: sets.specialShirts },
+ tropical: { price: 2, set: sets.specialShirts },
+ zombie: { price: 2, set: sets.specialShirts },
});
diff --git a/website/common/script/content/appearance/size.js b/website/common/script/content/appearance/size.js
index 3b9b7433b8..a5a1922478 100644
--- a/website/common/script/content/appearance/size.js
+++ b/website/common/script/content/appearance/size.js
@@ -1,6 +1,6 @@
-import prefill from './prefill.js';
+import prefill from './prefill';
-module.exports = prefill({
+export default prefill({
slim: {},
broad: {},
});
diff --git a/website/common/script/content/appearance/skin.js b/website/common/script/content/appearance/skin.js
index ea23edd4ea..3b0357555a 100644
--- a/website/common/script/content/appearance/skin.js
+++ b/website/common/script/content/appearance/skin.js
@@ -1,7 +1,7 @@
-import prefill from './prefill.js';
-import sets from './sets.js';
+import prefill from './prefill';
+import sets from './sets';
-module.exports = prefill({
+export default prefill({
/* eslint-disable quote-props */
'ddc994': {},
'f5a76e': {},
@@ -12,66 +12,66 @@ module.exports = prefill({
'c3e1dc': {},
'6bd049': {},
- 'eb052b': {price: 2, set: sets.rainbowSkins},
- 'f69922': {price: 2, set: sets.rainbowSkins},
- 'f5d70f': {price: 2, set: sets.rainbowSkins},
- '0ff591': {price: 2, set: sets.rainbowSkins},
- '2b43f6': {price: 2, set: sets.rainbowSkins},
- 'd7a9f7': {price: 2, set: sets.rainbowSkins},
- '800ed0': {price: 2, set: sets.rainbowSkins},
- 'rainbow': {price: 2, set: sets.rainbowSkins},
+ 'eb052b': { price: 2, set: sets.rainbowSkins },
+ 'f69922': { price: 2, set: sets.rainbowSkins },
+ 'f5d70f': { price: 2, set: sets.rainbowSkins },
+ '0ff591': { price: 2, set: sets.rainbowSkins },
+ '2b43f6': { price: 2, set: sets.rainbowSkins },
+ 'd7a9f7': { price: 2, set: sets.rainbowSkins },
+ '800ed0': { price: 2, set: sets.rainbowSkins },
+ 'rainbow': { price: 2, set: sets.rainbowSkins },
- 'bear': {price: 2, set: sets.animalSkins},
- 'cactus': {price: 2, set: sets.animalSkins},
- 'fox': {price: 2, set: sets.animalSkins},
- 'lion': {price: 2, set: sets.animalSkins},
- 'panda': {price: 2, set: sets.animalSkins},
- 'pig': {price: 2, set: sets.animalSkins},
- 'tiger': {price: 2, set: sets.animalSkins},
- 'wolf': {price: 2, set: sets.animalSkins},
+ 'bear': { price: 2, set: sets.animalSkins },
+ 'cactus': { price: 2, set: sets.animalSkins },
+ 'fox': { price: 2, set: sets.animalSkins },
+ 'lion': { price: 2, set: sets.animalSkins },
+ 'panda': { price: 2, set: sets.animalSkins },
+ 'pig': { price: 2, set: sets.animalSkins },
+ 'tiger': { price: 2, set: sets.animalSkins },
+ 'wolf': { price: 2, set: sets.animalSkins },
- 'pastelPink': {price: 2, set: sets.pastelSkins},
- 'pastelOrange': {price: 2, set: sets.pastelSkins},
- 'pastelYellow': {price: 2, set: sets.pastelSkins},
- 'pastelGreen': {price: 2, set: sets.pastelSkins},
- 'pastelBlue': {price: 2, set: sets.pastelSkins},
- 'pastelPurple': {price: 2, set: sets.pastelSkins},
- 'pastelRainbowChevron': {price: 2, set: sets.pastelSkins},
- 'pastelRainbowDiagonal': {price: 2, set: sets.pastelSkins},
+ 'pastelPink': { price: 2, set: sets.pastelSkins },
+ 'pastelOrange': { price: 2, set: sets.pastelSkins },
+ 'pastelYellow': { price: 2, set: sets.pastelSkins },
+ 'pastelGreen': { price: 2, set: sets.pastelSkins },
+ 'pastelBlue': { price: 2, set: sets.pastelSkins },
+ 'pastelPurple': { price: 2, set: sets.pastelSkins },
+ 'pastelRainbowChevron': { price: 2, set: sets.pastelSkins },
+ 'pastelRainbowDiagonal': { price: 2, set: sets.pastelSkins },
- 'monster': {price: 2, set: sets.spookySkins},
- 'pumpkin': {price: 2, set: sets.spookySkins},
- 'skeleton': {price: 2, set: sets.spookySkins},
- 'zombie': {price: 2, set: sets.spookySkins},
- 'ghost': {price: 2, set: sets.spookySkins},
- 'shadow': {price: 2, set: sets.spookySkins},
+ 'monster': { price: 2, set: sets.spookySkins },
+ 'pumpkin': { price: 2, set: sets.spookySkins },
+ 'skeleton': { price: 2, set: sets.spookySkins },
+ 'zombie': { price: 2, set: sets.spookySkins },
+ 'ghost': { price: 2, set: sets.spookySkins },
+ 'shadow': { price: 2, set: sets.spookySkins },
- 'candycorn': {price: 2, set: sets.supernaturalSkins},
- 'ogre': {price: 2, set: sets.supernaturalSkins},
- 'pumpkin2': {price: 2, set: sets.supernaturalSkins},
- 'reptile': {price: 2, set: sets.supernaturalSkins},
- 'shadow2': {price: 2, set: sets.supernaturalSkins},
- 'skeleton2': {price: 2, set: sets.supernaturalSkins},
- 'transparent': {price: 2, set: sets.supernaturalSkins},
- 'zombie2': {price: 2, set: sets.supernaturalSkins},
+ 'candycorn': { price: 2, set: sets.supernaturalSkins },
+ 'ogre': { price: 2, set: sets.supernaturalSkins },
+ 'pumpkin2': { price: 2, set: sets.supernaturalSkins },
+ 'reptile': { price: 2, set: sets.supernaturalSkins },
+ 'shadow2': { price: 2, set: sets.supernaturalSkins },
+ 'skeleton2': { price: 2, set: sets.supernaturalSkins },
+ 'transparent': { price: 2, set: sets.supernaturalSkins },
+ 'zombie2': { price: 2, set: sets.supernaturalSkins },
- 'clownfish': {price: 2, set: sets.splashySkins},
- 'deepocean': {price: 2, set: sets.splashySkins},
- 'merblue': {price: 2, set: sets.splashySkins},
- 'mergold': {price: 2, set: sets.splashySkins},
- 'mergreen': {price: 2, set: sets.splashySkins},
- 'merruby': {price: 2, set: sets.splashySkins},
- 'shark': {price: 2, set: sets.splashySkins},
- 'tropicalwater': {price: 2, set: sets.splashySkins},
+ 'clownfish': { price: 2, set: sets.splashySkins },
+ 'deepocean': { price: 2, set: sets.splashySkins },
+ 'merblue': { price: 2, set: sets.splashySkins },
+ 'mergold': { price: 2, set: sets.splashySkins },
+ 'mergreen': { price: 2, set: sets.splashySkins },
+ 'merruby': { price: 2, set: sets.splashySkins },
+ 'shark': { price: 2, set: sets.splashySkins },
+ 'tropicalwater': { price: 2, set: sets.splashySkins },
- 'aurora': {price: 2, set: sets.winterySkins},
- 'dapper': {price: 2, set: sets.winterySkins},
- 'festive': {price: 2, set: sets.winterySkins},
- 'holly': {price: 2, set: sets.winterySkins},
- 'polar': {price: 2, set: sets.winterySkins},
- 'sugar': {price: 2, set: sets.winterySkins},
- 'snowy': {price: 2, set: sets.winterySkins},
- 'winterstar': {price: 2, set: sets.winterySkins},
+ 'aurora': { price: 2, set: sets.winterySkins },
+ 'dapper': { price: 2, set: sets.winterySkins },
+ 'festive': { price: 2, set: sets.winterySkins },
+ 'holly': { price: 2, set: sets.winterySkins },
+ 'polar': { price: 2, set: sets.winterySkins },
+ 'sugar': { price: 2, set: sets.winterySkins },
+ 'snowy': { price: 2, set: sets.winterySkins },
+ 'winterstar': { price: 2, set: sets.winterySkins },
/* eslint-enable quote-props */
});
diff --git a/website/common/script/content/constants.js b/website/common/script/content/constants.js
index 5cc052e1b7..1b210c5749 100644
--- a/website/common/script/content/constants.js
+++ b/website/common/script/content/constants.js
@@ -203,19 +203,19 @@ export const GEAR_TYPES = [
];
export const ITEM_LIST = {
- weapon: { localeKey: 'weapon', isEquipment: true },
- armor: { localeKey: 'armor', isEquipment: true },
- head: { localeKey: 'headgear', isEquipment: true },
- shield: { localeKey: 'offhand', isEquipment: true },
- back: { localeKey: 'back', isEquipment: true },
- body: { localeKey: 'body', isEquipment: true },
- headAccessory: { localeKey: 'headAccessory', isEquipment: true },
- eyewear: { localeKey: 'eyewear', isEquipment: true },
+ weapon: { localeKey: 'weapon', isEquipment: true },
+ armor: { localeKey: 'armor', isEquipment: true },
+ head: { localeKey: 'headgear', isEquipment: true },
+ shield: { localeKey: 'offhand', isEquipment: true },
+ back: { localeKey: 'back', isEquipment: true },
+ body: { localeKey: 'body', isEquipment: true },
+ headAccessory: { localeKey: 'headAccessory', isEquipment: true },
+ eyewear: { localeKey: 'eyewear', isEquipment: true },
hatchingPotions: { localeKey: 'hatchingPotion', isEquipment: false },
premiumHatchingPotions: { localeKey: 'hatchingPotion', isEquipment: false },
- eggs: { localeKey: 'eggSingular', isEquipment: false },
- quests: { localeKey: 'quest', isEquipment: false },
- food: { localeKey: 'foodTextThe', isEquipment: false },
+ eggs: { localeKey: 'eggSingular', isEquipment: false },
+ quests: { localeKey: 'quest', isEquipment: false },
+ food: { localeKey: 'foodTextThe', isEquipment: false },
Saddle: { localeKey: 'foodSaddleText', isEquipment: false },
bundles: { localeKey: 'discountBundle', isEquipment: false },
};
@@ -264,6 +264,13 @@ export const QUEST_SERIES_ACHIEVEMENTS = {
};
export const ANIMAL_COLOR_ACHIEVEMENTS = [
- {color: 'Base', petAchievement: 'backToBasics', petNotificationType: 'ACHIEVEMENT_BACK_TO_BASICS', mountAchievement: 'allYourBase', mountNotificationType: 'ACHIEVEMENT_ALL_YOUR_BASE'},
- {color: 'Desert', petAchievement: 'dustDevil', petNotificationType: 'ACHIEVEMENT_DUST_DEVIL', mountAchievement: 'aridAuthority', mountNotificationType: 'ACHIEVEMENT_ARID_AUTHORITY'},
+ {
+ color: 'Base', petAchievement: 'backToBasics', petNotificationType: 'ACHIEVEMENT_BACK_TO_BASICS', mountAchievement: 'allYourBase', mountNotificationType: 'ACHIEVEMENT_ALL_YOUR_BASE',
+ },
+ {
+ color: 'Desert', petAchievement: 'dustDevil', petNotificationType: 'ACHIEVEMENT_DUST_DEVIL', mountAchievement: 'aridAuthority', mountNotificationType: 'ACHIEVEMENT_ARID_AUTHORITY',
+ },
+ {
+ color: 'Zombie', petAchievement: 'monsterMagus', petNotificationType: 'ACHIEVEMENT_MONSTER_MAGUS', mountAchievement: 'undeadUndertaker', mountNotificationType: 'ACHIEVEMENT_UNDEAD_UNDERTAKER',
+ },
];
diff --git a/website/common/script/content/eggs.js b/website/common/script/content/eggs.js
index 0d48eb218c..77ddd4a209 100644
--- a/website/common/script/content/eggs.js
+++ b/website/common/script/content/eggs.js
@@ -19,13 +19,11 @@ function applyEggDefaults (set, config) {
}
function hasQuestAchievementFunction (key) {
- return (user) => {
- return user.achievements.quests &&
- user.achievements.quests[key] > 0;
- };
+ return user => user.achievements.quests
+ && user.achievements.quests[key] > 0;
}
-let drops = {
+const drops = {
Wolf: {
text: t('dropEggWolfText'),
mountText: t('dropEggWolfMountText'),
@@ -73,7 +71,7 @@ let drops = {
},
};
-let quests = {
+const quests = {
Gryphon: {
text: t('questEggGryphonText'),
mountText: t('questEggGryphonMountText'),
@@ -150,11 +148,11 @@ let quests = {
mountText: t('questEggTRexMountText'),
adjective: t('questEggTRexAdjective'),
canBuy (user) {
- let questAchievements = user.achievements.quests;
+ const questAchievements = user.achievements.quests;
return questAchievements && (
- questAchievements.trex > 0 ||
- questAchievements.trex_undead > 0
+ questAchievements.trex > 0
+ || questAchievements.trex_undead > 0
);
},
},
@@ -406,9 +404,9 @@ applyEggDefaults(quests, {
},
});
-let all = assign({}, drops, quests);
+const all = assign({}, drops, quests);
-module.exports = {
+export {
drops,
quests,
all,
diff --git a/website/common/script/content/faq.js b/website/common/script/content/faq.js
index e66b293ce8..6b640390bc 100644
--- a/website/common/script/content/faq.js
+++ b/website/common/script/content/faq.js
@@ -2,7 +2,7 @@ import t from './translation';
const NUMBER_OF_QUESTIONS = 12;
-let faq = {
+const faq = {
questions: [],
stillNeedHelp: {
ios: t('iosFaqStillNeedHelp'),
@@ -10,8 +10,8 @@ let faq = {
},
};
-for (let i = 0; i <= NUMBER_OF_QUESTIONS; i++) {
- let question = {
+for (let i = 0; i <= NUMBER_OF_QUESTIONS; i += 1) {
+ const question = {
question: t(`faqQuestion${i}`),
ios: t(`iosFaqAnswer${i}`),
android: t(`androidFaqAnswer${i}`),
@@ -25,4 +25,4 @@ for (let i = 0; i <= NUMBER_OF_QUESTIONS; i++) {
faq.questions.push(question);
}
-module.exports = faq;
+export default faq;
diff --git a/website/common/script/content/gear/armor.js b/website/common/script/content/gear/armor.js
index d14d6681bb..a090c56364 100644
--- a/website/common/script/content/gear/armor.js
+++ b/website/common/script/content/gear/armor.js
@@ -1,15 +1,15 @@
-import {armor as baseArmor} from './sets/base';
+import { armor as baseArmor } from './sets/base';
-import {armor as warriorArmor} from './sets/warrior';
-import {armor as rogueArmor} from './sets/rogue';
-import {armor as healerArmor} from './sets/healer';
-import {armor as wizardArmor} from './sets/wizard';
+import { armor as warriorArmor } from './sets/warrior';
+import { armor as rogueArmor } from './sets/rogue';
+import { armor as healerArmor } from './sets/healer';
+import { armor as wizardArmor } from './sets/wizard';
-import {armor as specialArmor} from './sets/special';
-import {armor as mysteryArmor} from './sets/mystery';
-import {armor as armoireArmor} from './sets/armoire';
+import { armor as specialArmor } from './sets/special';
+import { armor as mysteryArmor } from './sets/mystery';
+import { armor as armoireArmor } from './sets/armoire';
-let armor = {
+const armor = {
base: baseArmor,
warrior: warriorArmor,
@@ -22,4 +22,4 @@ let armor = {
armoire: armoireArmor,
};
-module.exports = armor;
+export default armor;
diff --git a/website/common/script/content/gear/back.js b/website/common/script/content/gear/back.js
index dd6bba12bf..0cfe855b70 100644
--- a/website/common/script/content/gear/back.js
+++ b/website/common/script/content/gear/back.js
@@ -1,13 +1,12 @@
-import {back as baseBack} from './sets/base';
+import { back as baseBack } from './sets/base';
-import {back as mysteryBack} from './sets/mystery';
-import {back as specialBack} from './sets/special';
+import { back as mysteryBack } from './sets/mystery';
+import { back as specialBack } from './sets/special';
-let back = {
+const back = {
base: baseBack,
mystery: mysteryBack,
special: specialBack,
};
-module.exports = back;
-
+export default back;
diff --git a/website/common/script/content/gear/body.js b/website/common/script/content/gear/body.js
index 2c0e7f3b9d..19349eb2a2 100644
--- a/website/common/script/content/gear/body.js
+++ b/website/common/script/content/gear/body.js
@@ -1,14 +1,14 @@
-import {body as baseBody} from './sets/base';
+import { body as baseBody } from './sets/base';
-import {body as mysteryBody} from './sets/mystery';
-import {body as specialBody} from './sets/special';
-import {body as armoireBody} from './sets/armoire';
+import { body as mysteryBody } from './sets/mystery';
+import { body as specialBody } from './sets/special';
+import { body as armoireBody } from './sets/armoire';
-let body = {
+const body = {
base: baseBody,
mystery: mysteryBody,
special: specialBody,
armoire: armoireBody,
};
-module.exports = body;
+export default body;
diff --git a/website/common/script/content/gear/eyewear.js b/website/common/script/content/gear/eyewear.js
index 747eed5f84..2fdf54e079 100644
--- a/website/common/script/content/gear/eyewear.js
+++ b/website/common/script/content/gear/eyewear.js
@@ -1,14 +1,14 @@
-import {eyewear as baseEyewear} from './sets/base';
+import { eyewear as baseEyewear } from './sets/base';
-import {eyewear as armoireEyewear} from './sets/armoire';
-import {eyewear as mysteryEyewear} from './sets/mystery';
-import {eyewear as specialEyewear} from './sets/special';
+import { eyewear as armoireEyewear } from './sets/armoire';
+import { eyewear as mysteryEyewear } from './sets/mystery';
+import { eyewear as specialEyewear } from './sets/special';
-let eyewear = {
+const eyewear = {
base: baseEyewear,
special: specialEyewear,
mystery: mysteryEyewear,
armoire: armoireEyewear,
};
-module.exports = eyewear;
+export default eyewear;
diff --git a/website/common/script/content/gear/gear-helper.js b/website/common/script/content/gear/gear-helper.js
index 5319e1eed6..408856ff8b 100644
--- a/website/common/script/content/gear/gear-helper.js
+++ b/website/common/script/content/gear/gear-helper.js
@@ -1,7 +1,5 @@
import isBoolean from 'lodash/isBoolean';
-export function ownsItem (item) {
- return (user) => {
- return item && isBoolean(user.items.gear.owned[item]);
- };
+export function ownsItem (item) { // eslint-disable-line import/prefer-default-export
+ return user => item && isBoolean(user.items.gear.owned[item]);
}
diff --git a/website/common/script/content/gear/head-accessory.js b/website/common/script/content/gear/head-accessory.js
index bef4dd52af..146c0e77b8 100644
--- a/website/common/script/content/gear/head-accessory.js
+++ b/website/common/script/content/gear/head-accessory.js
@@ -1,15 +1,14 @@
-import {headAccessory as baseHeadAccessory} from './sets/base';
+import { headAccessory as baseHeadAccessory } from './sets/base';
-import {headAccessory as specialHeadAccessory} from './sets/special';
-import {headAccessory as mysteryHeadAccessory} from './sets/mystery';
-import {headAccessory as armoireHeadAccessory} from './sets/armoire';
+import { headAccessory as specialHeadAccessory } from './sets/special';
+import { headAccessory as mysteryHeadAccessory } from './sets/mystery';
+import { headAccessory as armoireHeadAccessory } from './sets/armoire';
-let headAccessory = {
+const headAccessory = {
base: baseHeadAccessory,
special: specialHeadAccessory,
mystery: mysteryHeadAccessory,
armoire: armoireHeadAccessory,
};
-module.exports = headAccessory;
-
+export default headAccessory;
diff --git a/website/common/script/content/gear/head.js b/website/common/script/content/gear/head.js
index f8c58b313b..6eee326efb 100644
--- a/website/common/script/content/gear/head.js
+++ b/website/common/script/content/gear/head.js
@@ -1,15 +1,15 @@
-import {head as baseHead} from './sets/base';
+import { head as baseHead } from './sets/base';
-import {head as healerHead} from './sets/healer';
-import {head as rogueHead} from './sets/rogue';
-import {head as warriorHead} from './sets/warrior';
-import {head as wizardHead} from './sets/wizard';
+import { head as healerHead } from './sets/healer';
+import { head as rogueHead } from './sets/rogue';
+import { head as warriorHead } from './sets/warrior';
+import { head as wizardHead } from './sets/wizard';
-import {head as armoireHead} from './sets/armoire';
-import {head as mysteryHead} from './sets/mystery';
-import {head as specialHead} from './sets/special';
+import { head as armoireHead } from './sets/armoire';
+import { head as mysteryHead } from './sets/mystery';
+import { head as specialHead } from './sets/special';
-let head = {
+const head = {
base: baseHead,
warrior: warriorHead,
@@ -22,4 +22,4 @@ let head = {
armoire: armoireHead,
};
-module.exports = head;
+export default head;
diff --git a/website/common/script/content/gear/index.js b/website/common/script/content/gear/index.js
index 844fe2c5d4..2add1ebeb1 100644
--- a/website/common/script/content/gear/index.js
+++ b/website/common/script/content/gear/index.js
@@ -17,7 +17,7 @@ import body from './body';
import headAccessory from './head-accessory';
import eyewear from './eyewear';
-let gear = {
+const gear = {
weapon,
armor,
head,
@@ -29,18 +29,19 @@ let gear = {
};
/*
- The gear is exported as a tree (defined above), and a flat list (eg, {weapon_healer_1: .., shield_special_0: ...}) since
+ The gear is exported as a tree (defined above), and a flat list
+ (eg, {weapon_healer_1: .., shield_special_0: ...}) since
they are needed in different forms at different points in the app
*/
-let flat = {};
+const flat = {};
-each(GEAR_TYPES, (type) => {
- let allGearTypes = CLASSES.concat(['base', 'special', 'mystery', 'armoire']);
+each(GEAR_TYPES, type => {
+ const allGearTypes = CLASSES.concat(['base', 'special', 'mystery', 'armoire']);
- each(allGearTypes, (klass) => {
+ each(allGearTypes, klass => {
each(gear[type][klass], (item, index) => {
- let key = `${type}_${klass}_${index}`;
- let set = `${klass}-${index}`;
+ const key = `${type}_${klass}_${index}`;
+ const set = `${klass}-${index}`;
defaults(item, {
type,
@@ -52,21 +53,20 @@ each(GEAR_TYPES, (type) => {
int: 0,
per: 0,
con: 0,
- canBuy: () => {
- return false;
- },
+ canBuy: () => false,
});
if (item.event) {
- let canOwnFuncTrue = () => {
- return true;
- };
- let _canOwn = item.canOwn || canOwnFuncTrue;
+ const canOwnFuncTrue = () => true;
+ const _canOwn = item.canOwn || canOwnFuncTrue;
- item.canOwn = (user) => {
- let userHasOwnedItem = ownsItem(key)(user);
- let eventIsCurrent = moment().isAfter(item.event.start) && moment().isBefore(item.event.end);
- let compatibleWithUserClass = item.specialClass ? user.stats.class === item.specialClass : true;
+ item.canOwn = user => {
+ const userHasOwnedItem = ownsItem(key)(user);
+ const eventIsCurrent = moment()
+ .isAfter(item.event.start) && moment().isBefore(item.event.end);
+ const compatibleWithUserClass = item.specialClass
+ ? user.stats.class === item.specialClass
+ : true;
return _canOwn(user) && (userHasOwnedItem || eventIsCurrent) && compatibleWithUserClass;
};
@@ -81,7 +81,7 @@ each(GEAR_TYPES, (type) => {
});
});
-module.exports = {
+export default {
tree: gear,
flat,
};
diff --git a/website/common/script/content/gear/sets/armoire.js b/website/common/script/content/gear/sets/armoire.js
index 48bf788511..a6c761c711 100644
--- a/website/common/script/content/gear/sets/armoire.js
+++ b/website/common/script/content/gear/sets/armoire.js
@@ -1,7 +1,7 @@
import { ownsItem } from '../gear-helper';
import t from '../../translation';
-let armor = {
+const armor = {
lunarArmor: {
text: t('armorArmoireLunarArmorText'),
notes: t('armorArmoireLunarArmorNotes', { str: 7, int: 7 }),
@@ -500,7 +500,7 @@ let armor = {
},
};
-let body = {
+const body = {
cozyScarf: {
text: t('bodyArmoireCozyScarfText'),
notes: t('bodyArmoireCozyScarfNotes', { attrs: 5 }),
@@ -512,7 +512,7 @@ let body = {
},
};
-let eyewear = {
+const eyewear = {
plagueDoctorMask: {
text: t('eyewearArmoirePlagueDoctorMaskText'),
notes: t('eyewearArmoirePlagueDoctorMaskNotes', { attrs: 5 }),
@@ -531,7 +531,7 @@ let eyewear = {
},
};
-let head = {
+const head = {
lunarCrown: {
text: t('headArmoireLunarCrownText'),
notes: t('headArmoireLunarCrownNotes', { con: 7, per: 7 }),
@@ -1022,7 +1022,7 @@ let head = {
},
};
-let shield = {
+const shield = {
gladiatorShield: {
text: t('shieldArmoireGladiatorShieldText'),
notes: t('shieldArmoireGladiatorShieldNotes', { con: 5, str: 5 }),
@@ -1301,7 +1301,7 @@ let shield = {
},
};
-let headAccessory = {
+const headAccessory = {
comicalArrow: {
text: t('headAccessoryArmoireComicalArrowText'),
notes: t('headAccessoryArmoireComicalArrowNotes', { str: 10 }),
@@ -1319,7 +1319,7 @@ let headAccessory = {
},
};
-let weapon = {
+const weapon = {
basicCrossbow: {
text: t('weaponArmoireBasicCrossbowText'),
notes: t('weaponArmoireBasicCrossbowNotes', { str: 5, per: 5, con: 5 }),
@@ -1747,7 +1747,7 @@ let weapon = {
},
};
-let armoireSet = {
+export {
armor,
body,
eyewear,
@@ -1756,5 +1756,3 @@ let armoireSet = {
shield,
weapon,
};
-
-module.exports = armoireSet;
diff --git a/website/common/script/content/gear/sets/base.js b/website/common/script/content/gear/sets/base.js
index 58d45dda3e..f87562012a 100644
--- a/website/common/script/content/gear/sets/base.js
+++ b/website/common/script/content/gear/sets/base.js
@@ -1,6 +1,6 @@
import t from '../../translation';
-let armor = {
+const armor = {
0: {
text: t('armorBase0Text'),
notes: t('armorBase0Notes'),
@@ -8,7 +8,7 @@ let armor = {
},
};
-let back = {
+const back = {
0: {
text: t('backBase0Text'),
notes: t('backBase0Notes'),
@@ -16,7 +16,7 @@ let back = {
},
};
-let body = {
+const body = {
0: {
text: t('bodyBase0Text'),
notes: t('bodyBase0Notes'),
@@ -24,7 +24,7 @@ let body = {
},
};
-let eyewear = {
+const eyewear = {
0: {
text: t('eyewearBase0Text'),
notes: t('eyewearBase0Notes'),
@@ -33,7 +33,7 @@ let eyewear = {
},
};
-let head = {
+const head = {
0: {
text: t('headBase0Text'),
notes: t('headBase0Notes'),
@@ -41,7 +41,7 @@ let head = {
},
};
-let headAccessory = {
+const headAccessory = {
0: {
text: t('headAccessoryBase0Text'),
notes: t('headAccessoryBase0Notes'),
@@ -50,7 +50,7 @@ let headAccessory = {
},
};
-let shield = {
+const shield = {
0: {
text: t('shieldBase0Text'),
notes: t('shieldBase0Notes'),
@@ -58,7 +58,7 @@ let shield = {
},
};
-let weapon = {
+const weapon = {
0: {
text: t('weaponBase0Text'),
notes: t('weaponBase0Notes'),
@@ -66,7 +66,7 @@ let weapon = {
},
};
-let baseSet = {
+export {
armor,
back,
body,
@@ -76,5 +76,3 @@ let baseSet = {
shield,
weapon,
};
-
-module.exports = baseSet;
diff --git a/website/common/script/content/gear/sets/healer.js b/website/common/script/content/gear/sets/healer.js
index 0bfb6060ca..49cdbcf876 100644
--- a/website/common/script/content/gear/sets/healer.js
+++ b/website/common/script/content/gear/sets/healer.js
@@ -1,6 +1,6 @@
import t from '../../translation';
-let armor = {
+const armor = {
1: {
text: t('armorHealer1Text'),
notes: t('armorHealer1Notes', { con: 6 }),
@@ -34,7 +34,7 @@ let armor = {
},
};
-let head = {
+const head = {
1: {
text: t('headHealer1Text'),
notes: t('headHealer1Notes', { int: 2 }),
@@ -68,7 +68,7 @@ let head = {
},
};
-let shield = {
+const shield = {
1: {
text: t('shieldHealer1Text'),
notes: t('shieldHealer1Notes', { con: 2 }),
@@ -102,8 +102,7 @@ let shield = {
},
};
-let weapon = {
-
+const weapon = {
0: {
text: t('weaponHealer0Text'),
notes: t('weaponHealer0Notes'),
@@ -148,11 +147,9 @@ let weapon = {
},
};
-let healerSet = {
+export {
armor,
head,
shield,
weapon,
};
-
-module.exports = healerSet;
diff --git a/website/common/script/content/gear/sets/mystery.js b/website/common/script/content/gear/sets/mystery.js
index 124106b76f..8e6a232be6 100644
--- a/website/common/script/content/gear/sets/mystery.js
+++ b/website/common/script/content/gear/sets/mystery.js
@@ -1,6 +1,6 @@
import t from '../../translation';
-let armor = {
+const armor = {
201402: {
text: t('armorMystery201402Text'),
notes: t('armorMystery201402Notes'),
@@ -259,6 +259,12 @@ let armor = {
mystery: '201909',
value: 0,
},
+ 201910: {
+ text: t('armorMystery201910Text'),
+ notes: t('armorMystery201910Notes'),
+ mystery: '201910',
+ value: 0,
+ },
301404: {
text: t('armorMystery301404Text'),
notes: t('armorMystery301404Notes'),
@@ -279,7 +285,7 @@ let armor = {
},
};
-let back = {
+const back = {
201402: {
text: t('backMystery201402Text'),
notes: t('backMystery201402Notes'),
@@ -390,7 +396,7 @@ let back = {
},
};
-let body = {
+const body = {
201705: {
text: t('bodyMystery201705Text'),
notes: t('bodyMystery201705Notes'),
@@ -417,7 +423,7 @@ let body = {
},
};
-let eyewear = {
+const eyewear = {
201503: {
text: t('eyewearMystery201503Text'),
notes: t('eyewearMystery201503Notes'),
@@ -474,7 +480,7 @@ let eyewear = {
},
};
-let head = {
+const head = {
201402: {
text: t('headMystery201402Text'),
notes: t('headMystery201402Notes'),
@@ -745,6 +751,12 @@ let head = {
mystery: '201909',
value: 0,
},
+ 201910: {
+ text: t('headMystery201910Text'),
+ notes: t('headMystery201910Notes'),
+ mystery: '201910',
+ value: 0,
+ },
301404: {
text: t('headMystery301404Text'),
notes: t('headMystery301404Notes'),
@@ -771,7 +783,7 @@ let head = {
},
};
-let headAccessory = {
+const headAccessory = {
201403: {
text: t('headAccessoryMystery201403Text'),
notes: t('headAccessoryMystery201403Notes'),
@@ -846,7 +858,7 @@ let headAccessory = {
},
};
-let shield = {
+const shield = {
201601: {
text: t('shieldMystery201601Text'),
notes: t('shieldMystery201601Notes'),
@@ -897,7 +909,7 @@ let shield = {
},
};
-let weapon = {
+const weapon = {
201411: {
text: t('weaponMystery201411Text'),
notes: t('weaponMystery201411Notes'),
@@ -942,7 +954,7 @@ let weapon = {
},
};
-let mysterySet = {
+export {
armor,
back,
body,
@@ -952,5 +964,3 @@ let mysterySet = {
shield,
weapon,
};
-
-module.exports = mysterySet;
diff --git a/website/common/script/content/gear/sets/rogue.js b/website/common/script/content/gear/sets/rogue.js
index 45145e9f43..9c8c45a607 100644
--- a/website/common/script/content/gear/sets/rogue.js
+++ b/website/common/script/content/gear/sets/rogue.js
@@ -1,6 +1,6 @@
import t from '../../translation';
-let armor = {
+const armor = {
1: {
text: t('armorRogue1Text'),
notes: t('armorRogue1Notes', { per: 6 }),
@@ -34,7 +34,7 @@ let armor = {
},
};
-let head = {
+const head = {
1: {
text: t('headRogue1Text'),
notes: t('headRogue1Notes', { per: 2 }),
@@ -68,7 +68,7 @@ let head = {
},
};
-let weapon = {
+const weapon = {
0: {
text: t('weaponRogue0Text'),
notes: t('weaponRogue0Notes'),
@@ -114,7 +114,7 @@ let weapon = {
},
};
-let shield = {
+const shield = {
0: {
text: t('weaponRogue0Text'),
notes: t('weaponRogue0Notes'),
@@ -160,11 +160,9 @@ let shield = {
},
};
-let rogueSet = {
+export {
armor,
head,
shield,
weapon,
};
-
-module.exports = rogueSet;
diff --git a/website/common/script/content/gear/sets/special/index.js b/website/common/script/content/gear/sets/special/index.js
index 36917da31a..e505116e53 100644
--- a/website/common/script/content/gear/sets/special/index.js
+++ b/website/common/script/content/gear/sets/special/index.js
@@ -2,15 +2,15 @@ import {
EVENTS,
} from '../../../constants';
import { ownsItem } from '../../gear-helper';
-import backerGear from './special-backer';
-import contributorGear from './special-contributor';
-import takeThisGear from './special-takeThis';
-import wonderconGear from './special-wondercon';
+import * as backerGear from './special-backer';
+import * as contributorGear from './special-contributor';
+import * as takeThisGear from './special-takeThis';
+import * as wonderconGear from './special-wondercon';
import t from '../../../translation';
const CURRENT_SEASON = 'fall';
-let armor = {
+const armor = {
0: backerGear.armorSpecial0,
1: contributorGear.armorSpecial1,
2: backerGear.armorSpecial2,
@@ -114,9 +114,7 @@ let armor = {
notes: t('armorSpecialYetiNotes', { con: 9 }),
con: 9,
value: 90,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
ski: {
event: EVENTS.winter,
@@ -126,9 +124,7 @@ let armor = {
notes: t('armorSpecialSkiNotes', { per: 15 }),
per: 15,
value: 90,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
candycane: {
event: EVENTS.winter,
@@ -138,9 +134,7 @@ let armor = {
notes: t('armorSpecialCandycaneNotes', { int: 9 }),
int: 9,
value: 90,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
snowflake: {
event: EVENTS.winter,
@@ -150,14 +144,13 @@ let armor = {
notes: t('armorSpecialSnowflakeNotes', { con: 15 }),
con: 15,
value: 90,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
birthday: {
event: EVENTS.birthday,
text: t('armorSpecialBirthdayText'),
- notes: t('armorSpecialBirthdayNotes'), value: 0,
+ notes: t('armorSpecialBirthdayNotes'),
+ value: 0,
},
springRogue: {
event: EVENTS.spring,
@@ -167,9 +160,7 @@ let armor = {
notes: t('armorSpecialSpringRogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springWarrior: {
event: EVENTS.spring,
@@ -179,9 +170,7 @@ let armor = {
notes: t('armorSpecialSpringWarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springMage: {
event: EVENTS.spring,
@@ -191,9 +180,7 @@ let armor = {
notes: t('armorSpecialSpringMageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springHealer: {
event: EVENTS.spring,
@@ -203,9 +190,7 @@ let armor = {
notes: t('armorSpecialSpringHealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summerRogue: {
event: EVENTS.summer,
@@ -215,9 +200,7 @@ let armor = {
notes: t('armorSpecialSummerRogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerWarrior: {
event: EVENTS.summer,
@@ -227,9 +210,7 @@ let armor = {
notes: t('armorSpecialSummerWarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerMage: {
event: EVENTS.summer,
@@ -239,9 +220,7 @@ let armor = {
notes: t('armorSpecialSummerMageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerHealer: {
event: EVENTS.summer,
@@ -251,9 +230,7 @@ let armor = {
notes: t('armorSpecialSummerHealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fallRogue: {
event: EVENTS.fall,
@@ -263,9 +240,7 @@ let armor = {
notes: t('armorSpecialFallRogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fallWarrior: {
event: EVENTS.fall,
@@ -275,9 +250,7 @@ let armor = {
notes: t('armorSpecialFallWarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fallMage: {
event: EVENTS.fall,
@@ -287,9 +260,7 @@ let armor = {
notes: t('armorSpecialFallMageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fallHealer: {
event: EVENTS.fall,
@@ -299,9 +270,7 @@ let armor = {
notes: t('armorSpecialFallHealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2015Rogue: {
event: EVENTS.winter2015,
@@ -311,9 +280,7 @@ let armor = {
notes: t('armorSpecialWinter2015RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2015Warrior: {
event: EVENTS.winter2015,
@@ -323,9 +290,7 @@ let armor = {
notes: t('armorSpecialWinter2015WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2015Mage: {
event: EVENTS.winter2015,
@@ -335,9 +300,7 @@ let armor = {
notes: t('armorSpecialWinter2015MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2015Healer: {
event: EVENTS.winter2015,
@@ -347,9 +310,7 @@ let armor = {
notes: t('armorSpecialWinter2015HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
birthday2015: {
text: t('armorSpecialBirthday2015Text'),
@@ -365,9 +326,7 @@ let armor = {
notes: t('armorSpecialSpring2015RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Warrior: {
event: EVENTS.spring2015,
@@ -377,9 +336,7 @@ let armor = {
notes: t('armorSpecialSpring2015WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Mage: {
event: EVENTS.spring2015,
@@ -389,9 +346,7 @@ let armor = {
notes: t('armorSpecialSpring2015MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Healer: {
event: EVENTS.spring2015,
@@ -401,9 +356,7 @@ let armor = {
notes: t('armorSpecialSpring2015HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2015Rogue: {
event: EVENTS.summer2015,
@@ -413,9 +366,7 @@ let armor = {
notes: t('armorSpecialSummer2015RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Warrior: {
event: EVENTS.summer2015,
@@ -425,9 +376,7 @@ let armor = {
notes: t('armorSpecialSummer2015WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Mage: {
event: EVENTS.summer2015,
@@ -437,9 +386,7 @@ let armor = {
notes: t('armorSpecialSummer2015MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Healer: {
event: EVENTS.summer2015,
@@ -449,9 +396,7 @@ let armor = {
notes: t('armorSpecialSummer2015HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2015Rogue: {
event: EVENTS.fall2015,
@@ -461,9 +406,7 @@ let armor = {
notes: t('armorSpecialFall2015RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2015Warrior: {
event: EVENTS.fall2015,
@@ -473,9 +416,7 @@ let armor = {
notes: t('armorSpecialFall2015WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2015Mage: {
event: EVENTS.fall2015,
@@ -485,9 +426,7 @@ let armor = {
notes: t('armorSpecialFall2015MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2015Healer: {
event: EVENTS.fall2015,
@@ -497,9 +436,7 @@ let armor = {
notes: t('armorSpecialFall2015HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
gaymerx: {
event: EVENTS.gaymerx,
@@ -515,9 +452,7 @@ let armor = {
notes: t('armorSpecialWinter2016RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2016Warrior: {
event: EVENTS.winter2016,
@@ -527,9 +462,7 @@ let armor = {
notes: t('armorSpecialWinter2016WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2016Mage: {
event: EVENTS.winter2016,
@@ -539,9 +472,7 @@ let armor = {
notes: t('armorSpecialWinter2016MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2016Healer: {
event: EVENTS.winter2016,
@@ -551,9 +482,7 @@ let armor = {
notes: t('armorSpecialWinter2016HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
birthday2016: {
text: t('armorSpecialBirthday2016Text'),
@@ -569,9 +498,7 @@ let armor = {
notes: t('armorSpecialSpring2016RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Warrior: {
event: EVENTS.spring2016,
@@ -581,9 +508,7 @@ let armor = {
notes: t('armorSpecialSpring2016WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Mage: {
event: EVENTS.spring2016,
@@ -593,9 +518,7 @@ let armor = {
notes: t('armorSpecialSpring2016MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Healer: {
event: EVENTS.spring2016,
@@ -605,9 +528,7 @@ let armor = {
notes: t('armorSpecialSpring2016HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2016Rogue: {
event: EVENTS.summer2016,
@@ -617,9 +538,7 @@ let armor = {
notes: t('armorSpecialSummer2016RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2016Warrior: {
event: EVENTS.summer2016,
@@ -629,9 +548,7 @@ let armor = {
notes: t('armorSpecialSummer2016WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2016Mage: {
event: EVENTS.summer2016,
@@ -641,9 +558,7 @@ let armor = {
notes: t('armorSpecialSummer2016MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2016Healer: {
event: EVENTS.summer2016,
@@ -653,9 +568,7 @@ let armor = {
notes: t('armorSpecialSummer2016HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2016Rogue: {
event: EVENTS.fall2016,
@@ -665,9 +578,7 @@ let armor = {
notes: t('armorSpecialFall2016RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2016Warrior: {
event: EVENTS.fall2016,
@@ -677,9 +588,7 @@ let armor = {
notes: t('armorSpecialFall2016WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2016Mage: {
event: EVENTS.fall2016,
@@ -689,9 +598,7 @@ let armor = {
notes: t('armorSpecialFall2016MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2016Healer: {
event: EVENTS.fall2016,
@@ -701,9 +608,7 @@ let armor = {
notes: t('armorSpecialFall2016HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2017Rogue: {
event: EVENTS.winter2017,
@@ -713,9 +618,7 @@ let armor = {
notes: t('armorSpecialWinter2017RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2017Warrior: {
event: EVENTS.winter2017,
@@ -725,9 +628,7 @@ let armor = {
notes: t('armorSpecialWinter2017WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2017Mage: {
event: EVENTS.winter2017,
@@ -737,9 +638,7 @@ let armor = {
notes: t('armorSpecialWinter2017MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2017Healer: {
event: EVENTS.winter2017,
@@ -749,9 +648,7 @@ let armor = {
notes: t('armorSpecialWinter2017HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
birthday2017: {
text: t('armorSpecialBirthday2017Text'),
@@ -767,9 +664,7 @@ let armor = {
notes: t('armorSpecialSpring2017RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Warrior: {
event: EVENTS.spring2017,
@@ -779,9 +674,7 @@ let armor = {
notes: t('armorSpecialSpring2017WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Mage: {
event: EVENTS.spring2017,
@@ -791,9 +684,7 @@ let armor = {
notes: t('armorSpecialSpring2017MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Healer: {
event: EVENTS.spring2017,
@@ -803,9 +694,7 @@ let armor = {
notes: t('armorSpecialSpring2017HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2017Rogue: {
event: EVENTS.summer2017,
@@ -815,9 +704,7 @@ let armor = {
notes: t('armorSpecialSummer2017RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2017Warrior: {
event: EVENTS.summer2017,
@@ -827,9 +714,7 @@ let armor = {
notes: t('armorSpecialSummer2017WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2017Mage: {
event: EVENTS.summer2017,
@@ -839,9 +724,7 @@ let armor = {
notes: t('armorSpecialSummer2017MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2017Healer: {
event: EVENTS.summer2017,
@@ -851,9 +734,7 @@ let armor = {
notes: t('armorSpecialSummer2017HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2017Rogue: {
event: EVENTS.fall2017,
@@ -863,9 +744,7 @@ let armor = {
notes: t('armorSpecialFall2017RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2017Warrior: {
event: EVENTS.fall2017,
@@ -875,9 +754,7 @@ let armor = {
notes: t('armorSpecialFall2017WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2017Mage: {
event: EVENTS.fall2017,
@@ -887,9 +764,7 @@ let armor = {
notes: t('armorSpecialFall2017MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2017Healer: {
event: EVENTS.fall2017,
@@ -899,9 +774,7 @@ let armor = {
notes: t('armorSpecialFall2017HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2018Rogue: {
event: EVENTS.winter2018,
@@ -911,9 +784,7 @@ let armor = {
notes: t('armorSpecialWinter2018RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2018Warrior: {
event: EVENTS.winter2018,
@@ -923,9 +794,7 @@ let armor = {
notes: t('armorSpecialWinter2018WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2018Mage: {
event: EVENTS.winter2018,
@@ -935,9 +804,7 @@ let armor = {
notes: t('armorSpecialWinter2018MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2018Healer: {
event: EVENTS.winter2018,
@@ -947,9 +814,7 @@ let armor = {
notes: t('armorSpecialWinter2018HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
birthday2018: {
text: t('armorSpecialBirthday2018Text'),
@@ -965,9 +830,7 @@ let armor = {
notes: t('armorSpecialSpring2018RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2018Warrior: {
event: EVENTS.spring2018,
@@ -977,9 +840,7 @@ let armor = {
notes: t('armorSpecialSpring2018WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2018Mage: {
event: EVENTS.spring2018,
@@ -989,9 +850,7 @@ let armor = {
notes: t('armorSpecialSpring2018MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2018Healer: {
event: EVENTS.spring2018,
@@ -1001,9 +860,7 @@ let armor = {
notes: t('armorSpecialSpring2018HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2018Rogue: {
event: EVENTS.summer2018,
@@ -1013,9 +870,7 @@ let armor = {
notes: t('armorSpecialSummer2018RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2018Warrior: {
event: EVENTS.summer2018,
@@ -1025,9 +880,7 @@ let armor = {
notes: t('armorSpecialSummer2018WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2018Mage: {
event: EVENTS.summer2018,
@@ -1037,9 +890,7 @@ let armor = {
notes: t('armorSpecialSummer2018MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2018Healer: {
event: EVENTS.summer2018,
@@ -1049,9 +900,7 @@ let armor = {
notes: t('armorSpecialSummer2018HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2018Rogue: {
event: EVENTS.fall2018,
@@ -1061,9 +910,7 @@ let armor = {
notes: t('armorSpecialFall2018RogueNotes', { per: 15 }),
value: 90,
per: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2018Warrior: {
event: EVENTS.fall2018,
@@ -1073,9 +920,7 @@ let armor = {
notes: t('armorSpecialFall2018WarriorNotes', { con: 9 }),
value: 90,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2018Mage: {
event: EVENTS.fall2018,
@@ -1085,9 +930,7 @@ let armor = {
notes: t('armorSpecialFall2018MageNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2018Healer: {
event: EVENTS.fall2018,
@@ -1097,9 +940,7 @@ let armor = {
notes: t('armorSpecialFall2018HealerNotes', { con: 15 }),
value: 90,
con: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
turkeyArmorGilded: {
text: t('armorSpecialTurkeyArmorGildedText'),
@@ -1266,9 +1107,9 @@ let armor = {
},
};
-let back = {
- wondercon_red: wonderconGear.backSpecialWonderconRed, // eslint-disable-line camelcase
- wondercon_black: wonderconGear.backSpecialWonderconBlack, // eslint-disable-line camelcase
+const back = {
+ wondercon_red: wonderconGear.backSpecialWonderconRed, // eslint-disable-line camelcase
+ wondercon_black: wonderconGear.backSpecialWonderconBlack, // eslint-disable-line camelcase
takeThis: takeThisGear.backSpecialTakeThis,
snowdriftVeil: {
text: t('backSpecialSnowdriftVeilText'),
@@ -1294,9 +1135,7 @@ let back = {
notes: t('backBearTailNotes'),
value: 20,
canOwn: ownsItem('back_special_bearTail'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
cactusTail: {
gearSet: 'animal',
@@ -1304,9 +1143,7 @@ let back = {
notes: t('backCactusTailNotes'),
value: 20,
canOwn: ownsItem('back_special_cactusTail'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
foxTail: {
gearSet: 'animal',
@@ -1314,9 +1151,7 @@ let back = {
notes: t('backFoxTailNotes'),
value: 20,
canOwn: ownsItem('back_special_foxTail'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
lionTail: {
gearSet: 'animal',
@@ -1324,9 +1159,7 @@ let back = {
notes: t('backLionTailNotes'),
value: 20,
canOwn: ownsItem('back_special_lionTail'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
pandaTail: {
gearSet: 'animal',
@@ -1334,9 +1167,7 @@ let back = {
notes: t('backPandaTailNotes'),
value: 20,
canOwn: ownsItem('back_special_pandaTail'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
pigTail: {
gearSet: 'animal',
@@ -1344,9 +1175,7 @@ let back = {
notes: t('backPigTailNotes'),
value: 20,
canOwn: ownsItem('back_special_pigTail'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
tigerTail: {
gearSet: 'animal',
@@ -1354,9 +1183,7 @@ let back = {
notes: t('backTigerTailNotes'),
value: 20,
canOwn: ownsItem('back_special_tigerTail'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
wolfTail: {
gearSet: 'animal',
@@ -1364,9 +1191,7 @@ let back = {
notes: t('backWolfTailNotes'),
value: 20,
canOwn: ownsItem('back_special_wolfTail'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
turkeyTailGilded: {
text: t('backSpecialTurkeyTailGildedText'),
@@ -1376,10 +1201,10 @@ let back = {
},
};
-let body = {
- wondercon_red: wonderconGear.bodySpecialWonderconRed, // eslint-disable-line camelcase
- wondercon_gold: wonderconGear.bodySpecialWonderconGold, // eslint-disable-line camelcase
- wondercon_black: wonderconGear.bodySpecialWonderconBlack, // eslint-disable-line camelcase
+const body = {
+ wondercon_red: wonderconGear.bodySpecialWonderconRed, // eslint-disable-line camelcase
+ wondercon_gold: wonderconGear.bodySpecialWonderconGold, // eslint-disable-line camelcase
+ wondercon_black: wonderconGear.bodySpecialWonderconBlack, // eslint-disable-line camelcase
takeThis: takeThisGear.bodySpecialTakeThis,
summerHealer: {
event: EVENTS.summer,
@@ -1388,9 +1213,7 @@ let body = {
text: t('bodySpecialSummerHealerText'),
notes: t('bodySpecialSummerHealerNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerMage: {
event: EVENTS.summer,
@@ -1399,9 +1222,7 @@ let body = {
text: t('bodySpecialSummerMageText'),
notes: t('bodySpecialSummerMageNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Healer: {
event: EVENTS.summer2015,
@@ -1410,9 +1231,7 @@ let body = {
text: t('bodySpecialSummer2015HealerText'),
notes: t('bodySpecialSummer2015HealerNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Mage: {
event: EVENTS.summer2015,
@@ -1421,9 +1240,7 @@ let body = {
text: t('bodySpecialSummer2015MageText'),
notes: t('bodySpecialSummer2015MageNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Rogue: {
event: EVENTS.summer2015,
@@ -1432,9 +1249,7 @@ let body = {
text: t('bodySpecialSummer2015RogueText'),
notes: t('bodySpecialSummer2015RogueNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Warrior: {
event: EVENTS.summer2015,
@@ -1443,9 +1258,7 @@ let body = {
text: t('bodySpecialSummer2015WarriorText'),
notes: t('bodySpecialSummer2015WarriorNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
aetherAmulet: {
text: t('bodySpecialAetherAmuletText'),
@@ -1463,9 +1276,9 @@ let body = {
},
};
-let eyewear = {
- wondercon_red: wonderconGear.eyewearSpecialWonderconRed, // eslint-disable-line camelcase
- wondercon_black: wonderconGear.eyewearSpecialWonderconBlack, // eslint-disable-line camelcase
+const eyewear = {
+ wondercon_red: wonderconGear.eyewearSpecialWonderconRed, // eslint-disable-line camelcase
+ wondercon_black: wonderconGear.eyewearSpecialWonderconBlack, // eslint-disable-line camelcase
summerRogue: {
event: EVENTS.summer,
specialClass: 'rogue',
@@ -1473,9 +1286,7 @@ let eyewear = {
text: t('eyewearSpecialSummerRogueText'),
notes: t('eyewearSpecialSummerRogueNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerWarrior: {
event: EVENTS.summer,
@@ -1484,9 +1295,7 @@ let eyewear = {
text: t('eyewearSpecialSummerWarriorText'),
notes: t('eyewearSpecialSummerWarriorNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
blackTopFrame: {
gearSet: 'glasses',
@@ -1617,7 +1426,7 @@ let eyewear = {
},
};
-let head = {
+const head = {
0: backerGear.headSpecial0,
1: contributorGear.headSpecial1,
2: backerGear.headSpecial2,
@@ -1728,9 +1537,7 @@ let head = {
notes: t('headSpecialYetiNotes', { str: 9 }),
str: 9,
value: 60,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
ski: {
event: EVENTS.winter,
@@ -1740,9 +1547,7 @@ let head = {
notes: t('headSpecialSkiNotes', { per: 9 }),
per: 9,
value: 60,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
candycane: {
event: EVENTS.winter,
@@ -1752,9 +1557,7 @@ let head = {
notes: t('headSpecialCandycaneNotes', { per: 7 }),
per: 7,
value: 60,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
snowflake: {
event: EVENTS.winter,
@@ -1764,9 +1567,7 @@ let head = {
notes: t('headSpecialSnowflakeNotes', { int: 7 }),
int: 7,
value: 60,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
springRogue: {
event: EVENTS.spring,
@@ -1776,9 +1577,7 @@ let head = {
notes: t('headSpecialSpringRogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springWarrior: {
event: EVENTS.spring,
@@ -1788,9 +1587,7 @@ let head = {
notes: t('headSpecialSpringWarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springMage: {
event: EVENTS.spring,
@@ -1800,9 +1597,7 @@ let head = {
notes: t('headSpecialSpringMageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springHealer: {
event: EVENTS.spring,
@@ -1812,9 +1607,7 @@ let head = {
notes: t('headSpecialSpringHealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summerRogue: {
event: EVENTS.summer,
@@ -1824,9 +1617,7 @@ let head = {
notes: t('headSpecialSummerRogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerWarrior: {
event: EVENTS.summer,
@@ -1836,9 +1627,7 @@ let head = {
notes: t('headSpecialSummerWarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerMage: {
event: EVENTS.summer,
@@ -1848,9 +1637,7 @@ let head = {
notes: t('headSpecialSummerMageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerHealer: {
event: EVENTS.summer,
@@ -1860,9 +1647,7 @@ let head = {
notes: t('headSpecialSummerHealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fallRogue: {
event: EVENTS.fall,
@@ -1872,9 +1657,7 @@ let head = {
notes: t('headSpecialFallRogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fallWarrior: {
event: EVENTS.fall,
@@ -1884,9 +1667,7 @@ let head = {
notes: t('headSpecialFallWarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fallMage: {
event: EVENTS.fall,
@@ -1896,9 +1677,7 @@ let head = {
notes: t('headSpecialFallMageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fallHealer: {
event: EVENTS.fall,
@@ -1908,9 +1687,7 @@ let head = {
notes: t('headSpecialFallHealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2015Rogue: {
event: EVENTS.winter2015,
@@ -1920,9 +1697,7 @@ let head = {
notes: t('headSpecialWinter2015RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2015Warrior: {
event: EVENTS.winter2015,
@@ -1932,9 +1707,7 @@ let head = {
notes: t('headSpecialWinter2015WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2015Mage: {
event: EVENTS.winter2015,
@@ -1944,9 +1717,7 @@ let head = {
notes: t('headSpecialWinter2015MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2015Healer: {
event: EVENTS.winter2015,
@@ -1956,9 +1727,7 @@ let head = {
notes: t('headSpecialWinter2015HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
nye2014: {
text: t('headSpecialNye2014Text'),
@@ -1974,9 +1743,7 @@ let head = {
notes: t('headSpecialSpring2015RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Warrior: {
event: EVENTS.spring2015,
@@ -1986,9 +1753,7 @@ let head = {
notes: t('headSpecialSpring2015WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Mage: {
event: EVENTS.spring2015,
@@ -1998,9 +1763,7 @@ let head = {
notes: t('headSpecialSpring2015MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Healer: {
event: EVENTS.spring2015,
@@ -2010,9 +1773,7 @@ let head = {
notes: t('headSpecialSpring2015HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2015Rogue: {
event: EVENTS.summer2015,
@@ -2022,9 +1783,7 @@ let head = {
notes: t('headSpecialSummer2015RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Warrior: {
event: EVENTS.summer2015,
@@ -2034,9 +1793,7 @@ let head = {
notes: t('headSpecialSummer2015WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Mage: {
event: EVENTS.summer2015,
@@ -2046,9 +1803,7 @@ let head = {
notes: t('headSpecialSummer2015MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Healer: {
event: EVENTS.summer2015,
@@ -2058,9 +1813,7 @@ let head = {
notes: t('headSpecialSummer2015HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2015Rogue: {
event: EVENTS.fall2015,
@@ -2070,9 +1823,7 @@ let head = {
notes: t('headSpecialFall2015RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2015Warrior: {
event: EVENTS.fall2015,
@@ -2082,9 +1833,7 @@ let head = {
notes: t('headSpecialFall2015WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2015Mage: {
event: EVENTS.fall2015,
@@ -2094,9 +1843,7 @@ let head = {
notes: t('headSpecialFall2015MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2015Healer: {
event: EVENTS.fall2015,
@@ -2106,9 +1853,7 @@ let head = {
notes: t('headSpecialFall2015HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
gaymerx: {
event: EVENTS.gaymerx,
@@ -2124,9 +1869,7 @@ let head = {
notes: t('headSpecialWinter2016RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2016Warrior: {
event: EVENTS.winter2016,
@@ -2136,9 +1879,7 @@ let head = {
notes: t('headSpecialWinter2016WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2016Mage: {
event: EVENTS.winter2016,
@@ -2148,9 +1889,7 @@ let head = {
notes: t('headSpecialWinter2016MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2016Healer: {
event: EVENTS.winter2016,
@@ -2160,9 +1899,7 @@ let head = {
notes: t('headSpecialWinter2016HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
nye2015: {
text: t('headSpecialNye2015Text'),
@@ -2178,9 +1915,7 @@ let head = {
notes: t('headSpecialSpring2016RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Warrior: {
event: EVENTS.spring2016,
@@ -2190,9 +1925,7 @@ let head = {
notes: t('headSpecialSpring2016WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Mage: {
event: EVENTS.spring2016,
@@ -2202,9 +1935,7 @@ let head = {
notes: t('headSpecialSpring2016MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Healer: {
event: EVENTS.spring2016,
@@ -2214,9 +1945,7 @@ let head = {
notes: t('headSpecialSpring2016HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2016Rogue: {
event: EVENTS.summer2016,
@@ -2226,9 +1955,7 @@ let head = {
notes: t('headSpecialSummer2016RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2016Warrior: {
event: EVENTS.summer2016,
@@ -2238,9 +1965,7 @@ let head = {
notes: t('headSpecialSummer2016WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2016Mage: {
event: EVENTS.summer2016,
@@ -2250,9 +1975,7 @@ let head = {
notes: t('headSpecialSummer2016MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2016Healer: {
event: EVENTS.summer2016,
@@ -2262,9 +1985,7 @@ let head = {
notes: t('headSpecialSummer2016HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2016Rogue: {
event: EVENTS.fall2016,
@@ -2274,9 +1995,7 @@ let head = {
notes: t('headSpecialFall2016RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2016Warrior: {
event: EVENTS.fall2016,
@@ -2286,9 +2005,7 @@ let head = {
notes: t('headSpecialFall2016WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2016Mage: {
event: EVENTS.fall2016,
@@ -2298,9 +2015,7 @@ let head = {
notes: t('headSpecialFall2016MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2016Healer: {
event: EVENTS.fall2016,
@@ -2310,9 +2025,7 @@ let head = {
notes: t('headSpecialFall2016HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2017Rogue: {
event: EVENTS.winter2017,
@@ -2322,9 +2035,7 @@ let head = {
notes: t('headSpecialWinter2017RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2017Warrior: {
event: EVENTS.winter2017,
@@ -2334,9 +2045,7 @@ let head = {
notes: t('headSpecialWinter2017WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2017Mage: {
event: EVENTS.winter2017,
@@ -2346,9 +2055,7 @@ let head = {
notes: t('headSpecialWinter2017MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2017Healer: {
event: EVENTS.winter2017,
@@ -2358,9 +2065,7 @@ let head = {
notes: t('headSpecialWinter2017HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
nye2016: {
text: t('headSpecialNye2016Text'),
@@ -2376,9 +2081,7 @@ let head = {
notes: t('headSpecialSpring2017RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Warrior: {
event: EVENTS.spring2017,
@@ -2388,9 +2091,7 @@ let head = {
notes: t('headSpecialSpring2017WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Mage: {
event: EVENTS.spring2017,
@@ -2400,9 +2101,7 @@ let head = {
notes: t('headSpecialSpring2017MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Healer: {
event: EVENTS.spring2017,
@@ -2412,9 +2111,7 @@ let head = {
notes: t('headSpecialSpring2017HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2017Rogue: {
event: EVENTS.summer2017,
@@ -2424,9 +2121,7 @@ let head = {
notes: t('headSpecialSummer2017RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2017Warrior: {
event: EVENTS.summer2017,
@@ -2436,9 +2131,7 @@ let head = {
notes: t('headSpecialSummer2017WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2017Mage: {
event: EVENTS.summer2017,
@@ -2448,9 +2141,7 @@ let head = {
notes: t('headSpecialSummer2017MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2017Healer: {
event: EVENTS.summer2017,
@@ -2460,9 +2151,7 @@ let head = {
notes: t('headSpecialSummer2017HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
namingDay2017: {
text: t('headSpecialNamingDay2017Text'),
@@ -2478,9 +2167,7 @@ let head = {
notes: t('headSpecialFall2017RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2017Warrior: {
event: EVENTS.fall2017,
@@ -2490,9 +2177,7 @@ let head = {
notes: t('headSpecialFall2017WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2017Mage: {
event: EVENTS.fall2017,
@@ -2502,9 +2187,7 @@ let head = {
notes: t('headSpecialFall2017MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2017Healer: {
event: EVENTS.fall2017,
@@ -2514,9 +2197,7 @@ let head = {
notes: t('headSpecialFall2017HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
nye2017: {
text: t('headSpecialNye2017Text'),
@@ -2532,9 +2213,7 @@ let head = {
notes: t('headSpecialWinter2018RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2018Warrior: {
event: EVENTS.winter2018,
@@ -2544,9 +2223,7 @@ let head = {
notes: t('headSpecialWinter2018WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2018Mage: {
event: EVENTS.winter2018,
@@ -2556,9 +2233,7 @@ let head = {
notes: t('headSpecialWinter2018MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2018Healer: {
event: EVENTS.winter2018,
@@ -2568,9 +2243,7 @@ let head = {
notes: t('headSpecialWinter2018HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
spring2018Rogue: {
event: EVENTS.spring2018,
@@ -2580,9 +2253,7 @@ let head = {
notes: t('headSpecialSpring2018RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2018Warrior: {
event: EVENTS.spring2018,
@@ -2592,9 +2263,7 @@ let head = {
notes: t('headSpecialSpring2018WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2018Mage: {
event: EVENTS.spring2018,
@@ -2604,9 +2273,7 @@ let head = {
notes: t('headSpecialSpring2018MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2018Healer: {
event: EVENTS.spring2018,
@@ -2616,9 +2283,7 @@ let head = {
notes: t('headSpecialSpring2018HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2018Rogue: {
event: EVENTS.summer2018,
@@ -2628,9 +2293,7 @@ let head = {
notes: t('headSpecialSummer2018RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2018Warrior: {
event: EVENTS.summer2018,
@@ -2640,9 +2303,7 @@ let head = {
notes: t('headSpecialSummer2018WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2018Mage: {
event: EVENTS.summer2018,
@@ -2652,9 +2313,7 @@ let head = {
notes: t('headSpecialSummer2018MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2018Healer: {
event: EVENTS.summer2018,
@@ -2664,9 +2323,7 @@ let head = {
notes: t('headSpecialSummer2018HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2018Rogue: {
event: EVENTS.fall2018,
@@ -2676,9 +2333,7 @@ let head = {
notes: t('headSpecialFall2018RogueNotes', { per: 9 }),
value: 60,
per: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2018Warrior: {
event: EVENTS.fall2018,
@@ -2688,9 +2343,7 @@ let head = {
notes: t('headSpecialFall2018WarriorNotes', { str: 9 }),
value: 60,
str: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2018Mage: {
event: EVENTS.fall2018,
@@ -2700,9 +2353,7 @@ let head = {
notes: t('headSpecialFall2018MageNotes', { per: 7 }),
value: 60,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2018Healer: {
event: EVENTS.fall2018,
@@ -2712,9 +2363,7 @@ let head = {
notes: t('headSpecialFall2018HealerNotes', { int: 7 }),
value: 60,
int: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
turkeyHelmGilded: {
text: t('headSpecialTurkeyHelmGildedText'),
@@ -2887,7 +2536,7 @@ let head = {
},
};
-let headAccessory = {
+const headAccessory = {
springRogue: {
event: EVENTS.spring,
specialClass: 'rogue',
@@ -2895,9 +2544,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpringRogueText'),
notes: t('headAccessorySpecialSpringRogueNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springWarrior: {
event: EVENTS.spring,
@@ -2906,9 +2553,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpringWarriorText'),
notes: t('headAccessorySpecialSpringWarriorNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springMage: {
event: EVENTS.spring,
@@ -2917,9 +2562,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpringMageText'),
notes: t('headAccessorySpecialSpringMageNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springHealer: {
event: EVENTS.spring,
@@ -2928,9 +2571,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpringHealerText'),
notes: t('headAccessorySpecialSpringHealerNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Rogue: {
event: EVENTS.spring2015,
@@ -2939,9 +2580,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2015RogueText'),
notes: t('headAccessorySpecialSpring2015RogueNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Warrior: {
event: EVENTS.spring2015,
@@ -2950,9 +2589,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2015WarriorText'),
notes: t('headAccessorySpecialSpring2015WarriorNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Mage: {
event: EVENTS.spring2015,
@@ -2961,9 +2598,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2015MageText'),
notes: t('headAccessorySpecialSpring2015MageNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Healer: {
event: EVENTS.spring2015,
@@ -2972,9 +2607,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2015HealerText'),
notes: t('headAccessorySpecialSpring2015HealerNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
bearEars: {
gearSet: 'animal',
@@ -2982,9 +2615,7 @@ let headAccessory = {
notes: t('headAccessoryBearEarsNotes'),
value: 20,
canOwn: ownsItem('headAccessory_special_bearEars'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
cactusEars: {
gearSet: 'animal',
@@ -2992,9 +2623,7 @@ let headAccessory = {
notes: t('headAccessoryCactusEarsNotes'),
value: 20,
canOwn: ownsItem('headAccessory_special_cactusEars'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
foxEars: {
gearSet: 'animal',
@@ -3002,9 +2631,7 @@ let headAccessory = {
notes: t('headAccessoryFoxEarsNotes'),
value: 20,
canOwn: ownsItem('headAccessory_special_foxEars'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
lionEars: {
gearSet: 'animal',
@@ -3012,9 +2639,7 @@ let headAccessory = {
notes: t('headAccessoryLionEarsNotes'),
value: 20,
canOwn: ownsItem('headAccessory_special_lionEars'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
pandaEars: {
gearSet: 'animal',
@@ -3022,9 +2647,7 @@ let headAccessory = {
notes: t('headAccessoryPandaEarsNotes'),
value: 20,
canOwn: ownsItem('headAccessory_special_pandaEars'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
pigEars: {
gearSet: 'animal',
@@ -3032,9 +2655,7 @@ let headAccessory = {
notes: t('headAccessoryPigEarsNotes'),
value: 20,
canOwn: ownsItem('headAccessory_special_pigEars'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
tigerEars: {
gearSet: 'animal',
@@ -3042,9 +2663,7 @@ let headAccessory = {
notes: t('headAccessoryTigerEarsNotes'),
value: 20,
canOwn: ownsItem('headAccessory_special_tigerEars'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
wolfEars: {
gearSet: 'animal',
@@ -3052,9 +2671,7 @@ let headAccessory = {
notes: t('headAccessoryWolfEarsNotes'),
value: 20,
canOwn: ownsItem('headAccessory_special_wolfEars'),
- canBuy: () => {
- return true;
- },
+ canBuy: () => true,
},
spring2016Rogue: {
event: EVENTS.spring2016,
@@ -3063,9 +2680,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2016RogueText'),
notes: t('headAccessorySpecialSpring2016RogueNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Warrior: {
event: EVENTS.spring2016,
@@ -3074,9 +2689,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2016WarriorText'),
notes: t('headAccessorySpecialSpring2016WarriorNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Mage: {
event: EVENTS.spring2016,
@@ -3085,9 +2698,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2016MageText'),
notes: t('headAccessorySpecialSpring2016MageNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Healer: {
event: EVENTS.spring2016,
@@ -3096,9 +2707,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2016HealerText'),
notes: t('headAccessorySpecialSpring2016HealerNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Rogue: {
event: EVENTS.spring2017,
@@ -3107,9 +2716,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2017RogueText'),
notes: t('headAccessorySpecialSpring2017RogueNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Warrior: {
event: EVENTS.spring2017,
@@ -3118,9 +2725,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2017WarriorText'),
notes: t('headAccessorySpecialSpring2017WarriorNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Mage: {
event: EVENTS.spring2017,
@@ -3129,9 +2734,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2017MageText'),
notes: t('headAccessorySpecialSpring2017MageNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Healer: {
event: EVENTS.spring2017,
@@ -3140,9 +2743,7 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2017HealerText'),
notes: t('headAccessorySpecialSpring2017HealerNotes'),
value: 20,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
blackHeadband: {
gearSet: 'headband',
@@ -3195,7 +2796,7 @@ let headAccessory = {
},
};
-let shield = {
+const shield = {
0: backerGear.shieldSpecial0,
1: contributorGear.shieldSpecial1,
takeThis: takeThisGear.shieldSpecialTakeThis,
@@ -3264,9 +2865,7 @@ let shield = {
notes: t('shieldSpecialYetiNotes', { con: 7 }),
con: 7,
value: 70,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
ski: {
event: EVENTS.winter,
@@ -3276,9 +2875,7 @@ let shield = {
notes: t('weaponSpecialSkiNotes', { str: 8 }),
str: 8,
value: 90,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
snowflake: {
event: EVENTS.winter,
@@ -3288,9 +2885,7 @@ let shield = {
notes: t('shieldSpecialSnowflakeNotes', { con: 9 }),
con: 9,
value: 70,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
springRogue: {
event: EVENTS.spring,
@@ -3300,9 +2895,7 @@ let shield = {
notes: t('shieldSpecialSpringRogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springWarrior: {
event: EVENTS.spring,
@@ -3312,9 +2905,7 @@ let shield = {
notes: t('shieldSpecialSpringWarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springHealer: {
event: EVENTS.spring,
@@ -3324,9 +2915,7 @@ let shield = {
notes: t('shieldSpecialSpringHealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summerRogue: {
event: EVENTS.summer,
@@ -3336,9 +2925,7 @@ let shield = {
notes: t('shieldSpecialSummerRogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerWarrior: {
event: EVENTS.summer,
@@ -3348,9 +2935,7 @@ let shield = {
notes: t('shieldSpecialSummerWarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerHealer: {
event: EVENTS.summer,
@@ -3360,9 +2945,7 @@ let shield = {
notes: t('shieldSpecialSummerHealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fallRogue: {
event: EVENTS.fall,
@@ -3372,9 +2955,7 @@ let shield = {
notes: t('shieldSpecialFallRogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fallWarrior: {
event: EVENTS.fall,
@@ -3384,9 +2965,7 @@ let shield = {
notes: t('shieldSpecialFallWarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fallHealer: {
event: EVENTS.fall,
@@ -3396,9 +2975,7 @@ let shield = {
notes: t('shieldSpecialFallHealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2015Rogue: {
event: EVENTS.winter2015,
@@ -3408,9 +2985,7 @@ let shield = {
notes: t('shieldSpecialWinter2015RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2015Warrior: {
event: EVENTS.winter2015,
@@ -3420,9 +2995,7 @@ let shield = {
notes: t('shieldSpecialWinter2015WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2015Healer: {
event: EVENTS.winter2015,
@@ -3432,9 +3005,7 @@ let shield = {
notes: t('shieldSpecialWinter2015HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
spring2015Rogue: {
event: EVENTS.spring2015,
@@ -3444,9 +3015,7 @@ let shield = {
notes: t('shieldSpecialSpring2015RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Warrior: {
event: EVENTS.spring2015,
@@ -3456,9 +3025,7 @@ let shield = {
notes: t('shieldSpecialSpring2015WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Healer: {
event: EVENTS.spring2015,
@@ -3468,9 +3035,7 @@ let shield = {
notes: t('shieldSpecialSpring2015HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2015Rogue: {
event: EVENTS.summer2015,
@@ -3480,9 +3045,7 @@ let shield = {
notes: t('shieldSpecialSummer2015RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Warrior: {
event: EVENTS.summer2015,
@@ -3492,9 +3055,7 @@ let shield = {
notes: t('shieldSpecialSummer2015WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Healer: {
event: EVENTS.summer2015,
@@ -3504,9 +3065,7 @@ let shield = {
notes: t('shieldSpecialSummer2015HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2015Rogue: {
event: EVENTS.fall2015,
@@ -3516,9 +3075,7 @@ let shield = {
notes: t('shieldSpecialFall2015RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2015Warrior: {
event: EVENTS.fall2015,
@@ -3528,9 +3085,7 @@ let shield = {
notes: t('shieldSpecialFall2015WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2015Healer: {
event: EVENTS.fall2015,
@@ -3540,9 +3095,7 @@ let shield = {
notes: t('shieldSpecialFall2015HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2016Rogue: {
event: EVENTS.winter2016,
@@ -3552,9 +3105,7 @@ let shield = {
notes: t('shieldSpecialWinter2016RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2016Warrior: {
event: EVENTS.winter2016,
@@ -3564,9 +3115,7 @@ let shield = {
notes: t('shieldSpecialWinter2016WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2016Healer: {
event: EVENTS.winter2016,
@@ -3576,9 +3125,7 @@ let shield = {
notes: t('shieldSpecialWinter2016HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
spring2016Rogue: {
event: EVENTS.spring2016,
@@ -3588,9 +3135,7 @@ let shield = {
notes: t('shieldSpecialSpring2016RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Warrior: {
event: EVENTS.spring2016,
@@ -3600,9 +3145,7 @@ let shield = {
notes: t('shieldSpecialSpring2016WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Healer: {
event: EVENTS.spring2016,
@@ -3612,9 +3155,7 @@ let shield = {
notes: t('shieldSpecialSpring2016HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2016Rogue: {
event: EVENTS.summer2016,
@@ -3624,9 +3165,7 @@ let shield = {
notes: t('shieldSpecialSummer2016RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2016Warrior: {
event: EVENTS.summer2016,
@@ -3636,9 +3175,7 @@ let shield = {
notes: t('shieldSpecialSummer2016WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2016Healer: {
event: EVENTS.summer2016,
@@ -3648,9 +3185,7 @@ let shield = {
notes: t('shieldSpecialSummer2016HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2016Rogue: {
event: EVENTS.fall2016,
@@ -3660,9 +3195,7 @@ let shield = {
notes: t('shieldSpecialFall2016RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2016Warrior: {
event: EVENTS.fall2016,
@@ -3672,9 +3205,7 @@ let shield = {
notes: t('shieldSpecialFall2016WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2016Healer: {
event: EVENTS.fall2016,
@@ -3684,9 +3215,7 @@ let shield = {
notes: t('shieldSpecialFall2016HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2017Rogue: {
event: EVENTS.winter2017,
@@ -3696,9 +3225,7 @@ let shield = {
notes: t('shieldSpecialWinter2017RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2017Warrior: {
event: EVENTS.winter2017,
@@ -3708,9 +3235,7 @@ let shield = {
notes: t('shieldSpecialWinter2017WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2017Healer: {
event: EVENTS.winter2017,
@@ -3720,9 +3245,7 @@ let shield = {
notes: t('shieldSpecialWinter2017HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
spring2017Rogue: {
event: EVENTS.spring2017,
@@ -3732,9 +3255,7 @@ let shield = {
notes: t('shieldSpecialSpring2017RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Warrior: {
event: EVENTS.spring2017,
@@ -3744,9 +3265,7 @@ let shield = {
notes: t('shieldSpecialSpring2017WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Healer: {
event: EVENTS.spring2017,
@@ -3756,9 +3275,7 @@ let shield = {
notes: t('shieldSpecialSpring2017HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2017Rogue: {
event: EVENTS.summer2017,
@@ -3768,9 +3285,7 @@ let shield = {
notes: t('shieldSpecialSummer2017RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2017Warrior: {
event: EVENTS.summer2017,
@@ -3780,9 +3295,7 @@ let shield = {
notes: t('shieldSpecialSummer2017WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2017Healer: {
event: EVENTS.summer2017,
@@ -3792,9 +3305,7 @@ let shield = {
notes: t('shieldSpecialSummer2017HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2017Rogue: {
event: EVENTS.fall2017,
@@ -3804,9 +3315,7 @@ let shield = {
notes: t('shieldSpecialFall2017RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2017Warrior: {
event: EVENTS.fall2017,
@@ -3816,9 +3325,7 @@ let shield = {
notes: t('shieldSpecialFall2017WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2017Healer: {
event: EVENTS.fall2017,
@@ -3828,9 +3335,7 @@ let shield = {
notes: t('shieldSpecialFall2017HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2018Rogue: {
event: EVENTS.winter2018,
@@ -3840,9 +3345,7 @@ let shield = {
notes: t('shieldSpecialWinter2018RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2018Warrior: {
event: EVENTS.winter2018,
@@ -3852,9 +3355,7 @@ let shield = {
notes: t('shieldSpecialWinter2018WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2018Healer: {
event: EVENTS.winter2018,
@@ -3864,9 +3365,7 @@ let shield = {
notes: t('shieldSpecialWinter2018HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
spring2018Rogue: {
event: EVENTS.spring2018,
@@ -3876,9 +3375,7 @@ let shield = {
notes: t('weaponSpecialSpring2018RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2018Warrior: {
event: EVENTS.spring2018,
@@ -3888,9 +3385,7 @@ let shield = {
notes: t('shieldSpecialSpring2018WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2018Healer: {
event: EVENTS.spring2018,
@@ -3900,9 +3395,7 @@ let shield = {
notes: t('shieldSpecialSpring2018HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2018Rogue: {
event: EVENTS.summer2018,
@@ -3912,9 +3405,7 @@ let shield = {
notes: t('weaponSpecialSummer2018RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2018Warrior: {
event: EVENTS.summer2018,
@@ -3924,9 +3415,7 @@ let shield = {
notes: t('shieldSpecialSummer2018WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2018Healer: {
event: EVENTS.summer2018,
@@ -3936,9 +3425,7 @@ let shield = {
notes: t('shieldSpecialSummer2018HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2018Rogue: {
event: EVENTS.fall2018,
@@ -3948,9 +3435,7 @@ let shield = {
notes: t('shieldSpecialFall2018RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2018Warrior: {
event: EVENTS.fall2018,
@@ -3960,9 +3445,7 @@ let shield = {
notes: t('shieldSpecialFall2018WarriorNotes', { con: 7 }),
value: 70,
con: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2018Healer: {
event: EVENTS.fall2018,
@@ -3972,9 +3455,7 @@ let shield = {
notes: t('shieldSpecialFall2018HealerNotes', { con: 9 }),
value: 70,
con: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2019Rogue: {
event: EVENTS.winter2019,
@@ -4108,7 +3589,7 @@ let shield = {
},
};
-let weapon = {
+const weapon = {
0: backerGear.weaponSpecial0,
1: contributorGear.weaponSpecial1,
2: backerGear.weaponSpecial2,
@@ -4217,9 +3698,7 @@ let weapon = {
notes: t('weaponSpecialYetiNotes', { str: 15 }),
str: 15,
value: 90,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
ski: {
event: EVENTS.winter,
@@ -4229,9 +3708,7 @@ let weapon = {
notes: t('weaponSpecialSkiNotes', { str: 8 }),
str: 8,
value: 90,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
candycane: {
event: EVENTS.winter,
@@ -4243,9 +3720,7 @@ let weapon = {
int: 15,
per: 7,
value: 160,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
snowflake: {
event: EVENTS.winter,
@@ -4255,9 +3730,7 @@ let weapon = {
notes: t('weaponSpecialSnowflakeNotes', { int: 9 }),
int: 9,
value: 90,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
springRogue: {
event: EVENTS.spring,
@@ -4267,9 +3740,7 @@ let weapon = {
notes: t('weaponSpecialSpringRogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springWarrior: {
event: EVENTS.spring,
@@ -4279,9 +3750,7 @@ let weapon = {
notes: t('weaponSpecialSpringWarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springMage: {
event: EVENTS.spring,
@@ -4293,9 +3762,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
springHealer: {
event: EVENTS.spring,
@@ -4305,9 +3772,7 @@ let weapon = {
notes: t('weaponSpecialSpringHealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summerRogue: {
event: EVENTS.summer,
@@ -4317,9 +3782,7 @@ let weapon = {
notes: t('weaponSpecialSummerRogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerWarrior: {
event: EVENTS.summer,
@@ -4329,9 +3792,7 @@ let weapon = {
notes: t('weaponSpecialSummerWarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerMage: {
event: EVENTS.summer,
@@ -4343,9 +3804,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summerHealer: {
event: EVENTS.summer,
@@ -4355,9 +3814,7 @@ let weapon = {
notes: t('weaponSpecialSummerHealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fallRogue: {
event: EVENTS.fall,
@@ -4367,9 +3824,7 @@ let weapon = {
notes: t('weaponSpecialFallRogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fallWarrior: {
event: EVENTS.fall,
@@ -4379,9 +3834,7 @@ let weapon = {
notes: t('weaponSpecialFallWarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fallMage: {
event: EVENTS.fall,
@@ -4393,9 +3846,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fallHealer: {
event: EVENTS.fall,
@@ -4405,9 +3856,7 @@ let weapon = {
notes: t('weaponSpecialFallHealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2015Rogue: {
event: EVENTS.winter2015,
@@ -4417,9 +3866,7 @@ let weapon = {
notes: t('weaponSpecialWinter2015RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2015Warrior: {
event: EVENTS.winter2015,
@@ -4429,9 +3876,7 @@ let weapon = {
notes: t('weaponSpecialWinter2015WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2015Mage: {
event: EVENTS.winter2015,
@@ -4443,9 +3888,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2015Healer: {
event: EVENTS.winter2015,
@@ -4455,9 +3898,7 @@ let weapon = {
notes: t('weaponSpecialWinter2015HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
spring2015Rogue: {
event: EVENTS.spring2015,
@@ -4467,9 +3908,7 @@ let weapon = {
notes: t('weaponSpecialSpring2015RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Warrior: {
event: EVENTS.spring2015,
@@ -4479,9 +3918,7 @@ let weapon = {
notes: t('weaponSpecialSpring2015WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Mage: {
event: EVENTS.spring2015,
@@ -4493,9 +3930,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2015Healer: {
event: EVENTS.spring2015,
@@ -4505,9 +3940,7 @@ let weapon = {
notes: t('weaponSpecialSpring2015HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2015Rogue: {
event: EVENTS.summer2015,
@@ -4517,9 +3950,7 @@ let weapon = {
notes: t('weaponSpecialSummer2015RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Warrior: {
event: EVENTS.summer2015,
@@ -4529,9 +3960,7 @@ let weapon = {
notes: t('weaponSpecialSummer2015WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Mage: {
event: EVENTS.summer2015,
@@ -4543,9 +3972,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2015Healer: {
event: EVENTS.summer2015,
@@ -4555,9 +3982,7 @@ let weapon = {
notes: t('weaponSpecialSummer2015HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2015Rogue: {
event: EVENTS.fall2015,
@@ -4567,9 +3992,7 @@ let weapon = {
notes: t('weaponSpecialFall2015RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2015Warrior: {
event: EVENTS.fall2015,
@@ -4579,9 +4002,7 @@ let weapon = {
notes: t('weaponSpecialFall2015WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2015Mage: {
event: EVENTS.fall2015,
@@ -4593,9 +4014,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2015Healer: {
event: EVENTS.fall2015,
@@ -4605,9 +4024,7 @@ let weapon = {
notes: t('weaponSpecialFall2015HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2016Rogue: {
event: EVENTS.winter2016,
@@ -4617,9 +4034,7 @@ let weapon = {
notes: t('weaponSpecialWinter2016RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2016Warrior: {
event: EVENTS.winter2016,
@@ -4629,9 +4044,7 @@ let weapon = {
notes: t('weaponSpecialWinter2016WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2016Mage: {
event: EVENTS.winter2016,
@@ -4643,9 +4056,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2016Healer: {
event: EVENTS.winter2016,
@@ -4655,9 +4066,7 @@ let weapon = {
notes: t('weaponSpecialWinter2016HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
spring2016Rogue: {
event: EVENTS.spring2016,
@@ -4667,9 +4076,7 @@ let weapon = {
notes: t('weaponSpecialSpring2016RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Warrior: {
event: EVENTS.spring2016,
@@ -4679,9 +4086,7 @@ let weapon = {
notes: t('weaponSpecialSpring2016WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Mage: {
event: EVENTS.spring2016,
@@ -4693,9 +4098,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2016Healer: {
event: EVENTS.spring2016,
@@ -4705,9 +4108,7 @@ let weapon = {
notes: t('weaponSpecialSpring2016HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2016Rogue: {
event: EVENTS.summer2016,
@@ -4717,9 +4118,7 @@ let weapon = {
notes: t('weaponSpecialSummer2016RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2016Warrior: {
event: EVENTS.summer2016,
@@ -4729,9 +4128,7 @@ let weapon = {
notes: t('weaponSpecialSummer2016WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2016Mage: {
event: EVENTS.summer2016,
@@ -4743,9 +4140,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2016Healer: {
event: EVENTS.summer2016,
@@ -4755,9 +4150,7 @@ let weapon = {
notes: t('weaponSpecialSummer2016HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2016Rogue: {
event: EVENTS.fall2016,
@@ -4767,9 +4160,7 @@ let weapon = {
notes: t('weaponSpecialFall2016RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2016Warrior: {
event: EVENTS.fall2016,
@@ -4779,9 +4170,7 @@ let weapon = {
notes: t('weaponSpecialFall2016WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2016Mage: {
event: EVENTS.fall2016,
@@ -4793,9 +4182,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2016Healer: {
event: EVENTS.fall2016,
@@ -4805,9 +4192,7 @@ let weapon = {
notes: t('weaponSpecialFall2016HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2017Rogue: {
event: EVENTS.winter2017,
@@ -4817,9 +4202,7 @@ let weapon = {
notes: t('weaponSpecialWinter2017RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2017Warrior: {
event: EVENTS.winter2017,
@@ -4829,9 +4212,7 @@ let weapon = {
notes: t('weaponSpecialWinter2017WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2017Mage: {
event: EVENTS.winter2017,
@@ -4843,9 +4224,7 @@ let weapon = {
value: 170,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2017Healer: {
event: EVENTS.winter2017,
@@ -4855,9 +4234,7 @@ let weapon = {
notes: t('weaponSpecialWinter2017HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
spring2017Rogue: {
event: EVENTS.spring2017,
@@ -4867,9 +4244,7 @@ let weapon = {
notes: t('weaponSpecialSpring2017RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Warrior: {
event: EVENTS.spring2017,
@@ -4879,9 +4254,7 @@ let weapon = {
notes: t('weaponSpecialSpring2017WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Mage: {
event: EVENTS.spring2017,
@@ -4893,9 +4266,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2017Healer: {
event: EVENTS.spring2017,
@@ -4905,9 +4276,7 @@ let weapon = {
notes: t('weaponSpecialSpring2017HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2017Rogue: {
event: EVENTS.summer2017,
@@ -4917,9 +4286,7 @@ let weapon = {
notes: t('weaponSpecialSummer2017RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2017Warrior: {
event: EVENTS.summer2017,
@@ -4929,9 +4296,7 @@ let weapon = {
notes: t('weaponSpecialSummer2017WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2017Mage: {
event: EVENTS.summer2017,
@@ -4943,9 +4308,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2017Healer: {
event: EVENTS.summer2017,
@@ -4955,9 +4318,7 @@ let weapon = {
notes: t('weaponSpecialSummer2017HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2017Rogue: {
event: EVENTS.fall2017,
@@ -4967,9 +4328,7 @@ let weapon = {
notes: t('weaponSpecialFall2017RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2017Warrior: {
event: EVENTS.fall2017,
@@ -4979,9 +4338,7 @@ let weapon = {
notes: t('weaponSpecialFall2017WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2017Mage: {
event: EVENTS.fall2017,
@@ -4993,9 +4350,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2017Healer: {
event: EVENTS.fall2017,
@@ -5005,9 +4360,7 @@ let weapon = {
notes: t('weaponSpecialFall2017HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2018Rogue: {
event: EVENTS.winter2018,
@@ -5017,9 +4370,7 @@ let weapon = {
notes: t('weaponSpecialWinter2018RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2018Warrior: {
event: EVENTS.winter2018,
@@ -5029,9 +4380,7 @@ let weapon = {
notes: t('weaponSpecialWinter2018WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2018Mage: {
event: EVENTS.winter2018,
@@ -5043,9 +4392,7 @@ let weapon = {
value: 170,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
winter2018Healer: {
event: EVENTS.winter2018,
@@ -5055,9 +4402,7 @@ let weapon = {
notes: t('weaponSpecialWinter2018HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'winter';
- },
+ canBuy: () => CURRENT_SEASON === 'winter',
},
spring2018Rogue: {
event: EVENTS.spring2018,
@@ -5067,9 +4412,7 @@ let weapon = {
notes: t('weaponSpecialSpring2018RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2018Warrior: {
event: EVENTS.spring2018,
@@ -5079,9 +4422,7 @@ let weapon = {
notes: t('weaponSpecialSpring2018WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2018Mage: {
event: EVENTS.spring2018,
@@ -5093,9 +4434,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
spring2018Healer: {
event: EVENTS.spring2018,
@@ -5105,9 +4444,7 @@ let weapon = {
notes: t('weaponSpecialSpring2018HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'spring';
- },
+ canBuy: () => CURRENT_SEASON === 'spring',
},
summer2018Rogue: {
event: EVENTS.summer2018,
@@ -5117,9 +4454,7 @@ let weapon = {
notes: t('weaponSpecialSummer2018RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2018Warrior: {
event: EVENTS.summer2018,
@@ -5129,9 +4464,7 @@ let weapon = {
notes: t('weaponSpecialSummer2018WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2018Mage: {
event: EVENTS.summer2018,
@@ -5143,9 +4476,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
summer2018Healer: {
event: EVENTS.summer2018,
@@ -5155,9 +4486,7 @@ let weapon = {
notes: t('weaponSpecialSummer2018HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'summer';
- },
+ canBuy: () => CURRENT_SEASON === 'summer',
},
fall2018Rogue: {
event: EVENTS.fall2018,
@@ -5167,9 +4496,7 @@ let weapon = {
notes: t('weaponSpecialFall2018RogueNotes', { str: 8 }),
value: 80,
str: 8,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2018Warrior: {
event: EVENTS.fall2018,
@@ -5179,9 +4506,7 @@ let weapon = {
notes: t('weaponSpecialFall2018WarriorNotes', { str: 15 }),
value: 90,
str: 15,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2018Mage: {
event: EVENTS.fall2018,
@@ -5193,9 +4518,7 @@ let weapon = {
value: 160,
int: 15,
per: 7,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
fall2018Healer: {
event: EVENTS.fall2018,
@@ -5205,9 +4528,7 @@ let weapon = {
notes: t('weaponSpecialFall2018HealerNotes', { int: 9 }),
value: 90,
int: 9,
- canBuy: () => {
- return CURRENT_SEASON === 'fall';
- },
+ canBuy: () => CURRENT_SEASON === 'fall',
},
winter2019Rogue: {
event: EVENTS.winter2019,
@@ -5368,7 +4689,7 @@ let weapon = {
},
};
-let specialSet = {
+export {
armor,
back,
body,
@@ -5378,5 +4699,3 @@ let specialSet = {
shield,
weapon,
};
-
-module.exports = specialSet;
diff --git a/website/common/script/content/gear/sets/special/special-backer.js b/website/common/script/content/gear/sets/special/special-backer.js
index 22f7f98ed5..599009fce6 100644
--- a/website/common/script/content/gear/sets/special/special-backer.js
+++ b/website/common/script/content/gear/sets/special/special-backer.js
@@ -1,16 +1,14 @@
import { ownsItem } from '../../gear-helper';
import t from '../../../translation';
-let isBackerOfLevel = (tierRequirement, ownedItem) => {
- return (user) => {
- let backer = user.backer;
- let tier = Number(backer && backer.tier);
+const isBackerOfLevel = (tierRequirement, ownedItem) => user => {
+ const { backer } = user;
+ const tier = Number(backer && backer.tier);
- return tier >= tierRequirement || ownsItem(ownedItem)(user);
- };
+ return tier >= tierRequirement || ownsItem(ownedItem)(user);
};
-let armorSpecial0 = {
+const armorSpecial0 = {
text: t('armorSpecial0Text'),
notes: t('armorSpecial0Notes', { con: 20 }),
con: 20,
@@ -18,7 +16,7 @@ let armorSpecial0 = {
canOwn: isBackerOfLevel(45, 'armor_special_0'),
};
-let armorSpecial2 = {
+const armorSpecial2 = {
text: t('armorSpecial2Text'),
notes: t('armorSpecial2Notes', { attrs: 25 }),
int: 25,
@@ -27,7 +25,7 @@ let armorSpecial2 = {
canOwn: isBackerOfLevel(300, 'armor_special_2'),
};
-let headSpecial0 = {
+const headSpecial0 = {
text: t('headSpecial0Text'),
notes: t('headSpecial0Notes', { int: 20 }),
int: 20,
@@ -35,7 +33,7 @@ let headSpecial0 = {
canOwn: isBackerOfLevel(45, 'head_special_0'),
};
-let headSpecial2 = {
+const headSpecial2 = {
text: t('headSpecial2Text'),
notes: t('headSpecial2Notes', { attrs: 25 }),
int: 25,
@@ -44,7 +42,7 @@ let headSpecial2 = {
canOwn: isBackerOfLevel(300, 'head_special_2'),
};
-let shieldSpecial0 = {
+const shieldSpecial0 = {
text: t('shieldSpecial0Text'),
notes: t('shieldSpecial0Notes', { per: 20 }),
per: 20,
@@ -52,7 +50,7 @@ let shieldSpecial0 = {
canOwn: isBackerOfLevel(45, 'shield_special_0'),
};
-let weaponSpecial0 = {
+const weaponSpecial0 = {
text: t('weaponSpecial0Text'),
notes: t('weaponSpecial0Notes', { str: 20 }),
str: 20,
@@ -60,7 +58,7 @@ let weaponSpecial0 = {
canOwn: isBackerOfLevel(70, 'weapon_special_0'),
};
-let weaponSpecial2 = {
+const weaponSpecial2 = {
text: t('weaponSpecial2Text'),
notes: t('weaponSpecial2Notes', { attrs: 25 }),
str: 25,
@@ -69,7 +67,7 @@ let weaponSpecial2 = {
canOwn: isBackerOfLevel(300, 'weapon_special_2'),
};
-let weaponSpecial3 = {
+const weaponSpecial3 = {
text: t('weaponSpecial3Text'),
notes: t('weaponSpecial3Notes', { attrs: 17 }),
str: 17,
@@ -79,7 +77,7 @@ let weaponSpecial3 = {
canOwn: isBackerOfLevel(300, 'weapon_special_3'),
};
-let backerSet = {
+export {
armorSpecial0,
armorSpecial2,
headSpecial0,
@@ -89,5 +87,3 @@ let backerSet = {
weaponSpecial2,
weaponSpecial3,
};
-
-module.exports = backerSet;
diff --git a/website/common/script/content/gear/sets/special/special-contributor.js b/website/common/script/content/gear/sets/special/special-contributor.js
index 5c905a0d58..c5de25b1c6 100644
--- a/website/common/script/content/gear/sets/special/special-contributor.js
+++ b/website/common/script/content/gear/sets/special/special-contributor.js
@@ -1,16 +1,14 @@
import { ownsItem } from '../../gear-helper';
import t from '../../../translation';
-let isContributorOfLevel = (tierRequirement, ownedItem) => {
- return (user) => {
- let contributor = user.contributor;
- let tier = contributor && contributor.level;
+const isContributorOfLevel = (tierRequirement, ownedItem) => user => {
+ const { contributor } = user;
+ const tier = contributor && contributor.level;
- return Number(tier) >= tierRequirement || ownsItem(ownedItem)(user);
- };
+ return Number(tier) >= tierRequirement || ownsItem(ownedItem)(user);
};
-let armorSpecial1 = {
+const armorSpecial1 = {
text: t('armorSpecial1Text'),
notes: t('armorSpecial1Notes', { attrs: 6 }),
con: 6,
@@ -21,7 +19,7 @@ let armorSpecial1 = {
canOwn: isContributorOfLevel(2, 'armor_special_1'),
};
-let headSpecial1 = {
+const headSpecial1 = {
text: t('headSpecial1Text'),
notes: t('headSpecial1Notes', { attrs: 6 }),
con: 6,
@@ -32,7 +30,7 @@ let headSpecial1 = {
canOwn: isContributorOfLevel(3, 'head_special_1'),
};
-let shieldSpecial1 = {
+const shieldSpecial1 = {
text: t('shieldSpecial1Text'),
notes: t('shieldSpecial1Notes', { attrs: 6 }),
con: 6,
@@ -43,7 +41,7 @@ let shieldSpecial1 = {
canOwn: isContributorOfLevel(5, 'shield_special_1'),
};
-let weaponSpecial1 = {
+const weaponSpecial1 = {
text: t('weaponSpecial1Text'),
notes: t('weaponSpecial1Notes', { attrs: 6 }),
str: 6,
@@ -54,26 +52,24 @@ let weaponSpecial1 = {
canOwn: isContributorOfLevel(4, 'weapon_special_1'),
};
-let weaponSpecialCritical = {
+const weaponSpecialCritical = {
text: t('weaponSpecialCriticalText'),
notes: t('weaponSpecialCriticalNotes', { attrs: 40 }),
str: 40,
per: 40,
value: 200,
- canOwn: (user) => {
- let hasCriticalFlag = user.contributor && user.contributor.critical;
- let alreadyHasItem = ownsItem('weapon_special_critical')(user);
+ canOwn: user => {
+ const hasCriticalFlag = user.contributor && user.contributor.critical;
+ const alreadyHasItem = ownsItem('weapon_special_critical')(user);
return hasCriticalFlag || alreadyHasItem;
},
};
-let contributorSet = {
+export {
armorSpecial1,
headSpecial1,
shieldSpecial1,
weaponSpecial1,
weaponSpecialCritical,
};
-
-module.exports = contributorSet;
diff --git a/website/common/script/content/gear/sets/special/special-takeThis.js b/website/common/script/content/gear/sets/special/special-takeThis.js
index c58e23e8a6..2bab7ec50c 100644
--- a/website/common/script/content/gear/sets/special/special-takeThis.js
+++ b/website/common/script/content/gear/sets/special/special-takeThis.js
@@ -1,8 +1,8 @@
import t from '../../../translation';
-let armorSpecialTakeThis = {
+const armorSpecialTakeThis = {
text: t('armorSpecialTakeThisText'),
- notes: t('armorSpecialTakeThisNotes', {attrs: 5}),
+ notes: t('armorSpecialTakeThisNotes', { attrs: 5 }),
value: 0,
con: 5,
int: 5,
@@ -10,9 +10,9 @@ let armorSpecialTakeThis = {
str: 5,
};
-let backSpecialTakeThis = {
+const backSpecialTakeThis = {
text: t('backSpecialTakeThisText'),
- notes: t('backSpecialTakeThisNotes', {attrs: 1}),
+ notes: t('backSpecialTakeThisNotes', { attrs: 1 }),
value: 0,
con: 1,
int: 1,
@@ -20,9 +20,9 @@ let backSpecialTakeThis = {
str: 1,
};
-let bodySpecialTakeThis = {
+const bodySpecialTakeThis = {
text: t('bodySpecialTakeThisText'),
- notes: t('bodySpecialTakeThisNotes', {attrs: 1}),
+ notes: t('bodySpecialTakeThisNotes', { attrs: 1 }),
value: 0,
con: 1,
int: 1,
@@ -30,9 +30,9 @@ let bodySpecialTakeThis = {
str: 1,
};
-let headSpecialTakeThis = {
+const headSpecialTakeThis = {
text: t('headSpecialTakeThisText'),
- notes: t('headSpecialTakeThisNotes', {attrs: 5}),
+ notes: t('headSpecialTakeThisNotes', { attrs: 5 }),
value: 0,
con: 5,
int: 5,
@@ -40,9 +40,9 @@ let headSpecialTakeThis = {
str: 5,
};
-let shieldSpecialTakeThis = {
+const shieldSpecialTakeThis = {
text: t('shieldSpecialTakeThisText'),
- notes: t('shieldSpecialTakeThisNotes', {attrs: 5}),
+ notes: t('shieldSpecialTakeThisNotes', { attrs: 5 }),
value: 0,
con: 5,
int: 5,
@@ -50,9 +50,9 @@ let shieldSpecialTakeThis = {
str: 5,
};
-let weaponSpecialTakeThis = {
+const weaponSpecialTakeThis = {
text: t('weaponSpecialTakeThisText'),
- notes: t('weaponSpecialTakeThisNotes', {attrs: 5}),
+ notes: t('weaponSpecialTakeThisNotes', { attrs: 5 }),
value: 0,
con: 5,
int: 5,
@@ -60,7 +60,7 @@ let weaponSpecialTakeThis = {
str: 5,
};
-let takeThisSet = {
+export {
armorSpecialTakeThis,
backSpecialTakeThis,
bodySpecialTakeThis,
@@ -68,5 +68,3 @@ let takeThisSet = {
shieldSpecialTakeThis,
weaponSpecialTakeThis,
};
-
-module.exports = takeThisSet;
diff --git a/website/common/script/content/gear/sets/special/special-wondercon.js b/website/common/script/content/gear/sets/special/special-wondercon.js
index 80c6148f3b..13cf36b55d 100644
--- a/website/common/script/content/gear/sets/special/special-wondercon.js
+++ b/website/common/script/content/gear/sets/special/special-wondercon.js
@@ -1,55 +1,55 @@
import t from '../../../translation';
-let backSpecialWonderconRed = {
+const backSpecialWonderconRed = {
text: t('backSpecialWonderconRedText'),
notes: t('backSpecialWonderconRedNotes'),
value: 0,
mystery: 'wondercon',
};
-let backSpecialWonderconBlack = {
+const backSpecialWonderconBlack = {
text: t('backSpecialWonderconBlackText'),
notes: t('backSpecialWonderconBlackNotes'),
value: 0,
mystery: 'wondercon',
};
-let bodySpecialWonderconRed = {
+const bodySpecialWonderconRed = {
text: t('bodySpecialWonderconRedText'),
notes: t('bodySpecialWonderconRedNotes'),
value: 0,
mystery: 'wondercon',
};
-let bodySpecialWonderconGold = {
+const bodySpecialWonderconGold = {
text: t('bodySpecialWonderconGoldText'),
notes: t('bodySpecialWonderconGoldNotes'),
value: 0,
mystery: 'wondercon',
};
-let bodySpecialWonderconBlack = {
+const bodySpecialWonderconBlack = {
text: t('bodySpecialWonderconBlackText'),
notes: t('bodySpecialWonderconBlackNotes'),
value: 0,
mystery: 'wondercon',
};
-let eyewearSpecialWonderconRed = {
+const eyewearSpecialWonderconRed = {
text: t('eyewearSpecialWonderconRedText'),
notes: t('eyewearSpecialWonderconRedNotes'),
value: 0,
mystery: 'wondercon',
};
-let eyewearSpecialWonderconBlack = {
+const eyewearSpecialWonderconBlack = {
text: t('eyewearSpecialWonderconBlackText'),
notes: t('eyewearSpecialWonderconBlackNotes'),
value: 0,
mystery: 'wondercon',
};
-let wonderconSet = {
+export {
backSpecialWonderconRed,
backSpecialWonderconBlack,
bodySpecialWonderconRed,
@@ -58,5 +58,3 @@ let wonderconSet = {
eyewearSpecialWonderconRed,
eyewearSpecialWonderconBlack,
};
-
-module.exports = wonderconSet;
diff --git a/website/common/script/content/gear/sets/warrior.js b/website/common/script/content/gear/sets/warrior.js
index bb5272f5b9..2a479d6caa 100644
--- a/website/common/script/content/gear/sets/warrior.js
+++ b/website/common/script/content/gear/sets/warrior.js
@@ -1,6 +1,6 @@
import t from '../../translation';
-let armor = {
+const armor = {
1: {
text: t('armorWarrior1Text'),
notes: t('armorWarrior1Notes', { con: 3 }),
@@ -34,7 +34,7 @@ let armor = {
},
};
-let head = {
+const head = {
1: {
text: t('headWarrior1Text'),
notes: t('headWarrior1Notes', { str: 2 }),
@@ -68,7 +68,7 @@ let head = {
},
};
-let shield = {
+const shield = {
1: {
text: t('shieldWarrior1Text'),
notes: t('shieldWarrior1Notes', { con: 2 }),
@@ -102,10 +102,12 @@ let shield = {
},
};
-let weapon = {
+const weapon = {
0: {
text: t('weaponWarrior0Text'),
- notes: t('weaponWarrior0Notes'), value: 1 },
+ notes: t('weaponWarrior0Notes'),
+ value: 1,
+ },
1: {
text: t('weaponWarrior1Text'),
notes: t('weaponWarrior1Notes', { str: 3 }),
@@ -145,11 +147,9 @@ let weapon = {
},
};
-let warriorSet = {
+export {
armor,
head,
shield,
weapon,
};
-
-module.exports = warriorSet;
diff --git a/website/common/script/content/gear/sets/wizard.js b/website/common/script/content/gear/sets/wizard.js
index 69dd2b51c6..db1178714c 100644
--- a/website/common/script/content/gear/sets/wizard.js
+++ b/website/common/script/content/gear/sets/wizard.js
@@ -1,6 +1,6 @@
import t from '../../translation';
-let armor = {
+const armor = {
1: {
text: t('armorWizard1Text'),
notes: t('armorWizard1Notes', { int: 2 }),
@@ -34,7 +34,7 @@ let armor = {
},
};
-let head = {
+const head = {
1: {
text: t('headWizard1Text'),
notes: t('headWizard1Notes', { per: 2 }),
@@ -68,18 +68,20 @@ let head = {
},
};
-let shield = {
+const shield = {
// Wizard's weapons are two handed
// And thus do not have shields
// But the content structure still expects an object
};
-let weapon = {
+const weapon = {
0: {
twoHanded: true,
text: t('weaponWizard0Text'),
- notes: t('weaponWizard0Notes'), value: 0 },
+ notes: t('weaponWizard0Notes'),
+ value: 0,
+ },
1: {
twoHanded: true,
text: t('weaponWizard1Text'),
@@ -131,11 +133,9 @@ let weapon = {
},
};
-let wizardSet = {
+export {
armor,
head,
shield,
weapon,
};
-
-module.exports = wizardSet;
diff --git a/website/common/script/content/gear/shield.js b/website/common/script/content/gear/shield.js
index cc6ce3ffc9..46afefd3bb 100644
--- a/website/common/script/content/gear/shield.js
+++ b/website/common/script/content/gear/shield.js
@@ -1,19 +1,19 @@
import cloneDeep from 'lodash/cloneDeep';
-import {shield as baseShield} from './sets/base';
+import { shield as baseShield } from './sets/base';
-import {shield as healerShield} from './sets/healer';
-import {weapon as rogueWeapon} from './sets/rogue';
-import {shield as warriorShield} from './sets/warrior';
-import {shield as wizardShield} from './sets/wizard';
+import { shield as healerShield } from './sets/healer';
+import { weapon as rogueWeapon } from './sets/rogue';
+import { shield as warriorShield } from './sets/warrior';
+import { shield as wizardShield } from './sets/wizard';
-import {shield as armoireShield} from './sets/armoire';
-import {shield as mysteryShield} from './sets/mystery';
-import {shield as specialShield} from './sets/special';
+import { shield as armoireShield } from './sets/armoire';
+import { shield as mysteryShield } from './sets/mystery';
+import { shield as specialShield } from './sets/special';
-let rogueShield = cloneDeep(rogueWeapon);
+const rogueShield = cloneDeep(rogueWeapon);
-let shield = {
+const shield = {
base: baseShield,
warrior: warriorShield,
@@ -26,4 +26,4 @@ let shield = {
armoire: armoireShield,
};
-module.exports = shield;
+export default shield;
diff --git a/website/common/script/content/gear/weapon.js b/website/common/script/content/gear/weapon.js
index 62578e6310..9f3e2f0bdf 100644
--- a/website/common/script/content/gear/weapon.js
+++ b/website/common/script/content/gear/weapon.js
@@ -1,17 +1,17 @@
import t from '../translation';
-import {weapon as baseWeapon} from './sets/base';
+import { weapon as baseWeapon } from './sets/base';
-import {weapon as healerWeapon} from './sets/healer';
-import {weapon as rogueWeapon} from './sets/rogue';
-import {weapon as warriorWeapon} from './sets/warrior';
-import {weapon as wizardWeapon} from './sets/wizard';
+import { weapon as healerWeapon } from './sets/healer';
+import { weapon as rogueWeapon } from './sets/rogue';
+import { weapon as warriorWeapon } from './sets/warrior';
+import { weapon as wizardWeapon } from './sets/wizard';
-import {weapon as armoireWeapon} from './sets/armoire';
-import {weapon as mysteryWeapon} from './sets/mystery';
-import {weapon as specialWeapon} from './sets/special';
+import { weapon as armoireWeapon } from './sets/armoire';
+import { weapon as mysteryWeapon } from './sets/mystery';
+import { weapon as specialWeapon } from './sets/special';
-let weapon = {
+const weapon = {
base: baseWeapon,
warrior: warriorWeapon,
@@ -26,32 +26,33 @@ let weapon = {
// Add Two Handed message to all weapons
const rtlLanguages = [
- 'ae', /* Avestan */
- 'ar', /* 'العربية', Arabic */
- 'arc', /* Aramaic */
- 'bcc', /* 'بلوچی مکرانی', Southern Balochi */
- 'bqi', /* 'بختياري', Bakthiari */
- 'ckb', /* 'Soranî / کوردی', Sorani */
- 'dv', /* Dhivehi */
- 'fa', /* 'فارسی', Persian */
- 'glk', /* 'گیلکی', Gilaki */
- 'he', /* 'עברית', Hebrew */
- 'ku', /* 'Kurdî / كوردی', Kurdish */
- 'mzn', /* 'مازِرونی', Mazanderani */
- 'nqo', /* N'Ko */
- 'pnb', /* 'پنجابی', Western Punjabi */
- 'ps', /* 'پښتو', Pashto, */
- 'sd', /* 'سنڌي', Sindhi */
- 'ug', /* 'Uyghurche / ئۇيغۇرچە', Uyghur */
- 'ur', /* 'اردو', Urdu */
- 'yi', /* 'ייִדיש', Yiddish */
+ 'ae', /* Avestan */
+ 'ar', /* 'العربية', Arabic */
+ 'arc', /* Aramaic */
+ 'bcc', /* 'بلوچی مکرانی', Southern Balochi */
+ 'bqi', /* 'بختياري', Bakthiari */
+ 'ckb', /* 'Soranî / کوردی', Sorani */
+ 'dv', /* Dhivehi */
+ 'fa', /* 'فارسی', Persian */
+ 'glk', /* 'گیلکی', Gilaki */
+ 'he', /* 'עברית', Hebrew */
+ 'ku', /* 'Kurdî / كوردی', Kurdish */
+ 'mzn', /* 'مازِرونی', Mazanderani */
+ 'nqo', /* N'Ko */
+ 'pnb', /* 'پنجابی', Western Punjabi */
+ 'ps', /* 'پښتو', Pashto, */
+ 'sd', /* 'سنڌي', Sindhi */
+ 'ug', /* 'Uyghurche / ئۇيغۇرچە', Uyghur */
+ 'ur', /* 'اردو', Urdu */
+ 'yi', /* 'ייִדיש', Yiddish */
];
-for (let key in weapon) {
+
+for (const key of Object.keys(weapon)) {
const set = weapon[key];
- for (let weaponKey in set) {
+ for (const weaponKey of Object.keys(set)) {
const item = set[weaponKey];
const oldnotes = item.notes;
- item.notes = (lang) => {
+ item.notes = lang => {
const twoHandedText = item.twoHanded ? t('twoHandedItem')(lang) : '';
if (rtlLanguages.indexOf(lang) !== -1) {
@@ -64,4 +65,4 @@ for (let key in weapon) {
}
}
-module.exports = weapon;
+export default weapon;
diff --git a/website/common/script/content/hatching-potions.js b/website/common/script/content/hatching-potions.js
index a5e64449a2..90f2fce194 100644
--- a/website/common/script/content/hatching-potions.js
+++ b/website/common/script/content/hatching-potions.js
@@ -6,13 +6,11 @@ import t from './translation';
const CURRENT_SEASON = 'October';
function hasQuestAchievementFunction (key) {
- return (user) => {
- return user.achievements.quests &&
- user.achievements.quests[key] > 0;
- };
+ return user => user.achievements.quests
+ && user.achievements.quests[key] > 0;
}
-let drops = {
+const drops = {
Base: {
value: 2,
text: t('hatchingPotionBase'),
@@ -55,7 +53,7 @@ let drops = {
},
};
-let premium = {
+const premium = {
RoyalPurple: {
value: 2,
text: t('hatchingPotionRoyalPurple'),
@@ -198,6 +196,7 @@ let premium = {
text: t('hatchingPotionBronze'),
limited: true,
canBuy: hasQuestAchievementFunction('bronze'),
+ _addlNotes: t('premiumPotionUnlimitedNotes'),
},
Watery: {
value: 2,
@@ -210,6 +209,7 @@ let premium = {
text: t('hatchingPotionSilver'),
limited: true,
canBuy: hasQuestAchievementFunction('silver'),
+ _addlNotes: t('premiumPotionUnlimitedNotes'),
},
Shadow: {
value: 2,
@@ -279,9 +279,9 @@ each(wacky, (pot, key) => {
});
});
-let all = assign({}, drops, premium, wacky);
+const all = assign({}, drops, premium, wacky);
-module.exports = {
+export {
drops,
premium,
wacky,
diff --git a/website/common/script/content/index.js b/website/common/script/content/index.js
index 177fe2536b..a879fd9dfb 100644
--- a/website/common/script/content/index.js
+++ b/website/common/script/content/index.js
@@ -2,7 +2,7 @@ import defaults from 'lodash/defaults';
import each from 'lodash/each';
import moment from 'moment';
import t from './translation';
-import {tasksByCategory} from './tasks';
+import { tasksByCategory } from './tasks';
import {
CLASSES,
@@ -12,13 +12,11 @@ import {
ANIMAL_COLOR_ACHIEVEMENTS,
} from './constants';
-let api = module.exports;
-
import achievements from './achievements';
-import eggs from './eggs';
-import hatchingPotions from './hatching-potions';
-import stable from './stable';
+import * as eggs from './eggs';
+import * as hatchingPotions from './hatching-potions';
+import * as stable from './stable';
import gear from './gear';
import {
quests,
@@ -27,8 +25,8 @@ import {
} from './quests';
import appearances from './appearance';
-import {backgroundsTree, backgroundsFlat} from './appearance/backgrounds';
-import spells from './spells';
+import { backgroundsTree, backgroundsFlat } from './appearance/backgrounds';
+import spells from './spells'; // eslint-disable-line import/no-cycle
import subscriptionBlocks from './subscriptionBlocks';
import faq from './faq';
import timeTravelers from './time-travelers';
@@ -37,6 +35,8 @@ import loginIncentives from './loginIncentives';
import officialPinnedItems from './officialPinnedItems';
+const api = {};
+
api.achievements = achievements;
api.questSeriesAchievements = QUEST_SERIES_ACHIEVEMENTS;
api.animalColorAchievements = ANIMAL_COLOR_ACHIEVEMENTS;
@@ -122,7 +122,7 @@ api.bundles = {
'frog',
],
canBuy () {
- return moment().isBetween('2017-10-10', '2017-11-02');
+ return moment().isBetween('2019-10-15', '2019-11-02');
},
type: 'quests',
value: 7,
@@ -810,17 +810,15 @@ api.food = {
/* eslint-enable camelcase */
};
-each(api.food, (food, key) => {
- return defaults(food, {
- value: 1,
- key,
- notes: t('foodNotes'),
- canBuy () {
- return false;
- },
- canDrop: false,
- });
-});
+each(api.food, (food, key) => defaults(food, {
+ value: 1,
+ key,
+ notes: t('foodNotes'),
+ canBuy () {
+ return false;
+ },
+ canDrop: false,
+}));
api.appearances = appearances;
@@ -837,9 +835,9 @@ api.userDefaults = {
down: false,
attribute: 'per',
tags: [
- t('defaultTag1'), // Work
- t('defaultTag4'), // School
- t('defaultTag6'), // Chores
+ t('defaultTag1'), // Work
+ t('defaultTag4'), // School
+ t('defaultTag6'), // Chores
],
}, {
type: 'habit',
@@ -849,7 +847,7 @@ api.userDefaults = {
down: true,
attribute: 'str',
tags: [
- t('defaultTag3'), // Health + Wellness
+ t('defaultTag3'), // Health + Wellness
],
}, {
type: 'habit',
@@ -859,8 +857,8 @@ api.userDefaults = {
down: true,
attribute: 'str',
tags: [
- t('defaultTag2'), // Exercise
- t('defaultTag3'), // Health + Wellness
+ t('defaultTag2'), // Exercise
+ t('defaultTag3'), // Health + Wellness
],
},
],
@@ -912,3 +910,5 @@ api.userDefaultsMobile = {
api.faq = faq;
api.loginIncentives = loginIncentives(api);
+
+export default api;
diff --git a/website/common/script/content/loginIncentives.js b/website/common/script/content/loginIncentives.js
index 091f9b108f..c63b8b4fdd 100644
--- a/website/common/script/content/loginIncentives.js
+++ b/website/common/script/content/loginIncentives.js
@@ -3,8 +3,8 @@ import { MAX_INCENTIVES } from '../constants';
// NOTE do not import this file alone but only access it through common.content
// so that it's already compiled
-module.exports = function getLoginIncentives (api) {
- let loginIncentives = {
+export default function getLoginIncentives (api) {
+ const loginIncentives = {
1: {
rewardKey: ['armor_special_bardRobes'],
reward: [api.gear.flat.armor_special_bardRobes],
@@ -261,7 +261,10 @@ module.exports = function getLoginIncentives (api) {
},
110: {
rewardKey: ['Pet_Egg_Cactus', 'Pet_Egg_Dragon', 'Pet_Egg_Wolf'],
- reward: [api.eggs.BearCub, api.eggs.Cactus, api.eggs.Dragon, api.eggs.FlyingPig, api.eggs.Fox, api.eggs.LionCub, api.eggs.PandaCub, api.eggs.TigerCub, api.eggs.Wolf],
+ reward: [
+ api.eggs.BearCub, api.eggs.Cactus, api.eggs.Dragon, api.eggs.FlyingPig,
+ api.eggs.Fox, api.eggs.LionCub, api.eggs.PandaCub, api.eggs.TigerCub, api.eggs.Wolf,
+ ],
rewardName: 'oneOfAllPetEggs',
assignReward: function assignReward (user) {
if (!user.items.eggs.BearCub) user.items.eggs.BearCub = 0;
@@ -296,14 +299,24 @@ module.exports = function getLoginIncentives (api) {
},
120: {
rewardKey: ['Pet_HatchingPotion_Base', 'Pet_HatchingPotion_Red', 'Pet_HatchingPotion_Golden'],
- reward: [api.hatchingPotions.Base, api.hatchingPotions.CottonCandyBlue, api.hatchingPotions.CottonCandyPink, api.hatchingPotions.Desert, api.hatchingPotions.Golden, api.hatchingPotions.Red, api.hatchingPotions.Shade, api.hatchingPotions.Skeleton, api.hatchingPotions.White, api.hatchingPotions.Zombie],
+ reward: [
+ api.hatchingPotions.Base, api.hatchingPotions.CottonCandyBlue,
+ api.hatchingPotions.CottonCandyPink, api.hatchingPotions.Desert,
+ api.hatchingPotions.Golden, api.hatchingPotions.Red,
+ api.hatchingPotions.Shade, api.hatchingPotions.Skeleton,
+ api.hatchingPotions.White, api.hatchingPotions.Zombie,
+ ],
rewardName: 'oneOfAllHatchingPotions',
assignReward: function assignReward (user) {
if (!user.items.hatchingPotions.Base) user.items.hatchingPotions.Base = 0;
user.items.hatchingPotions.Base += 1;
- if (!user.items.hatchingPotions.CottonCandyBlue) user.items.hatchingPotions.CottonCandyBlue = 0;
+ if (!user.items.hatchingPotions.CottonCandyBlue) {
+ user.items.hatchingPotions.CottonCandyBlue = 0;
+ }
user.items.hatchingPotions.CottonCandyBlue += 1;
- if (!user.items.hatchingPotions.CottonCandyPink) user.items.hatchingPotions.CottonCandyPink = 0;
+ if (!user.items.hatchingPotions.CottonCandyPink) {
+ user.items.hatchingPotions.CottonCandyPink = 0;
+ }
user.items.hatchingPotions.CottonCandyPink += 1;
if (!user.items.hatchingPotions.Desert) user.items.hatchingPotions.Desert = 0;
user.items.hatchingPotions.Desert += 1;
@@ -333,7 +346,11 @@ module.exports = function getLoginIncentives (api) {
},
130: {
rewardKey: ['Pet_Food_Meat', 'Pet_Food_Potatoe', 'Pet_Food_Milk'],
- reward: [api.food.Meat, api.food.CottonCandyBlue, api.food.CottonCandyPink, api.food.Potatoe, api.food.Honey, api.food.Strawberry, api.food.Chocolate, api.food.Fish, api.food.Milk, api.food.RottenMeat],
+ reward: [
+ api.food.Meat, api.food.CottonCandyBlue, api.food.CottonCandyPink, api.food.Potatoe,
+ api.food.Honey, api.food.Strawberry, api.food.Chocolate, api.food.Fish, api.food.Milk,
+ api.food.RottenMeat,
+ ],
rewardName: 'threeOfEachFood',
assignReward: function assignReward (user) {
if (!user.items.food.Meat) user.items.food.Meat = 0;
@@ -388,7 +405,10 @@ module.exports = function getLoginIncentives (api) {
},
150: {
rewardKey: ['shop_head_special_clandestineCowl', 'shop_armor_special_sneakthiefRobes'],
- reward: [api.gear.flat.head_special_clandestineCowl, api.gear.flat.armor_special_sneakthiefRobes],
+ reward: [
+ api.gear.flat.head_special_clandestineCowl,
+ api.gear.flat.armor_special_sneakthiefRobes,
+ ],
assignReward: function assignReward (user) {
user.items.gear.owned.head_special_clandestineCowl = true; // eslint-disable-line camelcase
user.items.gear.owned.armor_special_sneakthiefRobes = true; // eslint-disable-line camelcase
@@ -406,10 +426,13 @@ module.exports = function getLoginIncentives (api) {
},
170: {
rewardKey: ['shop_head_special_snowSovereignCrown', 'shop_armor_special_snowSovereignRobes'],
- reward: [api.gear.flat.head_special_snowSovereignCrown, api.gear.flat.armor_special_snowSovereignRobes],
+ reward: [
+ api.gear.flat.head_special_snowSovereignCrown,
+ api.gear.flat.armor_special_snowSovereignRobes,
+ ],
assignReward: function assignReward (user) {
- user.items.gear.owned.head_special_snowSovereignCrown = true; // eslint-disable-line camelcase
- user.items.gear.owned.armor_special_snowSovereignRobes = true; // eslint-disable-line camelcase
+ user.items.gear.owned.head_special_snowSovereignCrown = true; // eslint-disable-line camelcase, max-len
+ user.items.gear.owned.armor_special_snowSovereignRobes = true; // eslint-disable-line camelcase, max-len
if (user.markModified) user.markModified('items.gear.owned');
},
},
@@ -451,7 +474,10 @@ module.exports = function getLoginIncentives (api) {
},
240: {
rewardKey: ['shop_weapon_special_nomadsScimitar', 'shop_armor_special_nomadsCuirass'],
- reward: [api.gear.flat.weapon_special_nomadsScimitar, api.gear.flat.armor_special_nomadsCuirass],
+ reward: [
+ api.gear.flat.weapon_special_nomadsScimitar,
+ api.gear.flat.armor_special_nomadsCuirass,
+ ],
assignReward: function assignReward (user) {
user.items.gear.owned.weapon_special_nomadsScimitar = true; // eslint-disable-line camelcase
user.items.gear.owned.armor_special_nomadsCuirass = true; // eslint-disable-line camelcase
@@ -468,7 +494,11 @@ module.exports = function getLoginIncentives (api) {
},
280: {
rewardKey: ['Pet_Food_Meat', 'Pet_Food_Potatoe', 'Pet_Food_Milk'],
- reward: [api.food.Meat, api.food.CottonCandyBlue, api.food.CottonCandyPink, api.food.Potatoe, api.food.Honey, api.food.Strawberry, api.food.Chocolate, api.food.Fish, api.food.Milk, api.food.RottenMeat],
+ reward: [
+ api.food.Meat, api.food.CottonCandyBlue, api.food.CottonCandyPink,
+ api.food.Potatoe, api.food.Honey, api.food.Strawberry, api.food.Chocolate,
+ api.food.Fish, api.food.Milk, api.food.RottenMeat,
+ ],
rewardName: 'threeOfEachFood',
assignReward: function assignReward (user) {
if (!user.items.food.Meat) user.items.food.Meat = 0;
@@ -496,7 +526,10 @@ module.exports = function getLoginIncentives (api) {
},
300: {
rewardKey: ['Pet_Egg_Cactus', 'Pet_Egg_Dragon', 'Pet_Egg_Wolf'],
- reward: [api.eggs.BearCub, api.eggs.Cactus, api.eggs.Dragon, api.eggs.FlyingPig, api.eggs.Fox, api.eggs.LionCub, api.eggs.PandaCub, api.eggs.TigerCub, api.eggs.Wolf],
+ reward: [
+ api.eggs.BearCub, api.eggs.Cactus, api.eggs.Dragon, api.eggs.FlyingPig,
+ api.eggs.Fox, api.eggs.LionCub, api.eggs.PandaCub, api.eggs.TigerCub, api.eggs.Wolf,
+ ],
rewardName: 'twoOfAllPetEggs',
assignReward: function assignReward (user) {
if (!user.items.eggs.BearCub) user.items.eggs.BearCub = 0;
@@ -549,7 +582,10 @@ module.exports = function getLoginIncentives (api) {
},
380: {
rewardKey: ['Pet_Egg_Cactus', 'Pet_Egg_Dragon', 'Pet_Egg_Wolf'],
- reward: [api.eggs.BearCub, api.eggs.Cactus, api.eggs.Dragon, api.eggs.FlyingPig, api.eggs.Fox, api.eggs.LionCub, api.eggs.PandaCub, api.eggs.TigerCub, api.eggs.Wolf],
+ reward: [
+ api.eggs.BearCub, api.eggs.Cactus, api.eggs.Dragon, api.eggs.FlyingPig,
+ api.eggs.Fox, api.eggs.LionCub, api.eggs.PandaCub, api.eggs.TigerCub, api.eggs.Wolf,
+ ],
rewardName: 'threeOfAllPetEggs',
assignReward: function assignReward (user) {
if (!user.items.eggs.BearCub) user.items.eggs.BearCub = 0;
@@ -575,7 +611,11 @@ module.exports = function getLoginIncentives (api) {
},
400: {
rewardKey: ['Pet_Food_Meat', 'Pet_Food_Potatoe', 'Pet_Food_Milk'],
- reward: [api.food.Meat, api.food.CottonCandyBlue, api.food.CottonCandyPink, api.food.Potatoe, api.food.Honey, api.food.Strawberry, api.food.Chocolate, api.food.Fish, api.food.Milk, api.food.RottenMeat],
+ reward: [
+ api.food.Meat, api.food.CottonCandyBlue, api.food.CottonCandyPink,
+ api.food.Potatoe, api.food.Honey, api.food.Strawberry, api.food.Chocolate,
+ api.food.Fish, api.food.Milk, api.food.RottenMeat,
+ ],
rewardName: 'fourOfEachFood',
assignReward: function assignReward (user) {
if (!user.items.food.Meat) user.items.food.Meat = 0;
@@ -638,14 +678,16 @@ module.exports = function getLoginIncentives (api) {
},
},
};
- // When the final check-in prize is added here, change checkinReceivedAllRewardsMessage in website/common/locales/en/loginIncentives.json
+ // When the final check-in prize is added here,
+ // change checkinReceivedAllRewardsMessage in website/common/locales/en/loginIncentives.json
// to say "You have received the final Check-In prize!". Confirm the message with Lemoness first.
- // Add reference link to next reward and add filler days so we have a map to reference the next reward from any day
+ // Add reference link to next reward and add filler days
+ // so we have a map to reference the next reward from any day
// We could also, use a list, but then we would be cloning each of the rewards.
// Create a new array if we want the loginIncentives to be immutable in the future
let nextRewardKey;
- range(MAX_INCENTIVES + 1).reverse().forEach(function addNextRewardLink (index) {
+ range(MAX_INCENTIVES + 1).reverse().forEach(index => {
if (loginIncentives[index] && loginIncentives[index].rewardKey) {
loginIncentives[index].nextRewardAt = nextRewardKey;
nextRewardKey = index;
@@ -659,10 +701,10 @@ module.exports = function getLoginIncentives (api) {
});
let prevRewardKey;
- range(MAX_INCENTIVES + 1).forEach(function addPrevRewardLink (index) {
+ range(MAX_INCENTIVES + 1).forEach(index => {
loginIncentives[index].prevRewardKey = prevRewardKey;
if (loginIncentives[index].rewardKey) prevRewardKey = index;
});
return loginIncentives;
-};
+}
diff --git a/website/common/script/content/mystery-sets.js b/website/common/script/content/mystery-sets.js
index 0c72b44e71..969bdd461f 100644
--- a/website/common/script/content/mystery-sets.js
+++ b/website/common/script/content/mystery-sets.js
@@ -1,7 +1,7 @@
import each from 'lodash/each';
import t from './translation';
-let mysterySets = {
+const mysterySets = {
201402: {
start: '2014-02-22',
end: '2014-02-28',
@@ -274,6 +274,10 @@ let mysterySets = {
start: '2019-09-25',
end: '2019-10-02',
},
+ 201910: {
+ start: '2019-10-24',
+ end: '2019-11-02',
+ },
301404: {
start: '3014-03-24',
end: '3014-04-02',
@@ -303,4 +307,4 @@ each(mysterySets, (value, key) => {
value.class = `shop_set_mystery_${key}`;
});
-module.exports = mysterySets;
+export default mysterySets;
diff --git a/website/common/script/content/quests.js b/website/common/script/content/quests.js
index 00605f500b..748223cd16 100644
--- a/website/common/script/content/quests.js
+++ b/website/common/script/content/quests.js
@@ -6,9 +6,9 @@ import {
USER_CAN_OWN_QUEST_CATEGORIES,
} from './constants';
-let userCanOwnQuestCategories = USER_CAN_OWN_QUEST_CATEGORIES;
+const userCanOwnQuestCategories = USER_CAN_OWN_QUEST_CATEGORIES;
-let quests = {
+const quests = {
dilatory: {
text: t('questDilatoryText'),
notes: t('questDilatoryNotes'),
@@ -2261,7 +2261,7 @@ let quests = {
unlockCondition: {
condition: 'party invite',
incentiveThreshold: 7,
- text: t('loginReward', {count: 7}),
+ text: t('loginReward', { count: 7 }),
},
collect: {
shard: {
@@ -2292,7 +2292,7 @@ let quests = {
unlockCondition: {
condition: 'party invite',
incentiveThreshold: 22,
- text: t('loginReward', {count: 22}),
+ text: t('loginReward', { count: 22 }),
},
boss: {
name: t('questMoon2Boss'),
@@ -2322,7 +2322,7 @@ let quests = {
unlockCondition: {
condition: 'party invite',
incentiveThreshold: 40,
- text: t('loginReward', {count: 40}),
+ text: t('loginReward', { count: 40 }),
},
boss: {
name: t('questMoon3Boss'),
@@ -3505,21 +3505,22 @@ let quests = {
};
each(quests, (v, key) => {
- let b;
defaults(v, {
key,
canBuy () {
return true;
},
});
- b = v.boss;
+
+ const b = v.boss;
+
if (b) {
defaults(b, {
str: 1,
def: 1,
});
if (b.rage) {
- return defaults(b.rage, {
+ defaults(b.rage, {
title: t('bossRageTitle'),
description: t('bossRageDescription'),
});
@@ -3527,11 +3528,9 @@ each(quests, (v, key) => {
}
});
-let questsByLevel = sortBy(quests, (quest) => {
- return quest.lvl || 0;
-});
+const questsByLevel = sortBy(quests, quest => quest.lvl || 0);
-module.exports = {
+export {
quests,
questsByLevel,
userCanOwnQuestCategories,
diff --git a/website/common/script/content/shop-featuredItems.js b/website/common/script/content/shop-featuredItems.js
index e0f4fcc768..b5c965a4a8 100644
--- a/website/common/script/content/shop-featuredItems.js
+++ b/website/common/script/content/shop-featuredItems.js
@@ -22,8 +22,8 @@ const featuredItems = {
],
quests: [
{
- type: 'quests',
- path: 'quests.bronze',
+ type: 'bundles',
+ path: 'bundles.witchyFamiliars',
},
{
type: 'quests',
diff --git a/website/common/script/content/spells.js b/website/common/script/content/spells.js
index d17e708730..48c82c695e 100644
--- a/website/common/script/content/spells.js
+++ b/website/common/script/content/spells.js
@@ -1,8 +1,8 @@
-import t from './translation';
import each from 'lodash/each';
+import t from './translation';
import { NotAuthorized } from '../libs/errors';
-import statsComputed from '../libs/statsComputed';
-import crit from '../fns/crit';
+import statsComputed from '../libs/statsComputed'; // eslint-disable-line import/no-cycle
+import crit from '../fns/crit'; // eslint-disable-line import/no-cycle
import updateStats from '../fns/updateStats';
/*
@@ -11,23 +11,32 @@ import updateStats from '../fns/updateStats';
---------------------------------------------------------------
Text, notes, and mana are obvious. The rest:
- * {target}: one of [task, self, party, user]. This is very important, because if the cast() function is expecting one
- thing and receives another, it will cause errors. `self` is used for self buffs, multi-task debuffs, AOEs (eg, meteor-shower),
+ * {target}: one of [task, self, party, user].
+ * This is very important, because if the cast() function is expecting one
+ thing and receives another, it will cause errors.
+ `self` is used for self buffs, multi-task debuffs, AOEs (eg, meteor-shower),
etc. Basically, use self for anything that's not [task, party, user] and is an instant-cast
- * {cast}: the function that's run to perform the ability's action. This is pretty slick - because this is exported to the
- web, this function can be performed on the client and on the server. `user` param is self (needed for determining your
- own stats for effectiveness of cast), and `target` param is one of [task, party, user]. In the case of `self` skills,
- you act on `user` instead of `target`. You can trust these are the correct objects, as long as the `target` attr of the
- spell is correct. Take a look at habitrpg/website/server/models/user.js and habitrpg/website/server/models/task.js for what attributes are
- available on each model. Note `task.value` is its "redness". If party is passed in, it's an array of users,
+ * {cast}: the function that's run to perform the ability's action.
+ This is pretty slick - because this is exported to the
+ web, this function can be performed on the client and on the server.
+ `user` param is self (needed for determining your
+ own stats for effectiveness of cast), and `target` param is one of [task, party, user].
+ In the case of `self` skills,
+ you act on `user` instead of `target`. You can trust these are the correct objects,
+ as long as the `target` attr of the
+ spell is correct. Take a look at habitrpg/website/server/models/user.js and
+ habitrpg/website/server/models/task.js for what attributes are
+ available on each model. Note `task.value` is its "redness".
+ If party is passed in, it's an array of users,
so you'll want to iterate over them like: `_.each(target,function(member){...})`
- Note, user.stats.mp is docked after automatically (it's appended to functions automatically down below in an _.each)
+ Note, user.stats.mp is docked after automatically
+ (it's appended to functions automatically down below in an _.each)
*/
function diminishingReturns (bonus, max, halfway) {
- if (!halfway) halfway = max / 2;
+ if (!halfway) halfway = max / 2; // eslint-disable-line no-param-reassign
return max * (bonus / (bonus + halfway));
}
@@ -35,7 +44,7 @@ function calculateBonus (value, stat, critVal = 1, statScale = 0.5) {
return (value < 0 ? 1 : value + 1) + stat * statScale * critVal;
}
-let spells = {};
+const spells = {};
spells.wizard = {
fireball: { // Burst of Flames
@@ -60,8 +69,8 @@ spells.wizard = {
target: 'party',
notes: t('spellWizardMPHealNotes'),
cast (user, target) {
- each(target, (member) => {
- let bonus = statsComputed(user).int;
+ each(target, member => {
+ const bonus = statsComputed(user).int;
if (user._id !== member._id && member.stats.class !== 'wizard') {
member.stats.mp += Math.ceil(diminishingReturns(bonus, 25, 125));
}
@@ -75,8 +84,8 @@ spells.wizard = {
target: 'party',
notes: t('spellWizardEarthNotes'),
cast (user, target) {
- each(target, (member) => {
- let bonus = statsComputed(user).int - user.stats.buffs.int;
+ each(target, member => {
+ const bonus = statsComputed(user).int - user.stats.buffs.int;
if (!member.stats.buffs.int) member.stats.buffs.int = 0;
member.stats.buffs.int += Math.ceil(diminishingReturns(bonus, 30, 200));
});
@@ -102,7 +111,7 @@ spells.warrior = {
target: 'task',
notes: t('spellWarriorSmashNotes'),
cast (user, target) {
- let bonus = statsComputed(user).str * crit.crit(user, 'con');
+ const bonus = statsComputed(user).str * crit.crit(user, 'con');
target.value += diminishingReturns(bonus, 2.5, 35);
if (!user.party.quest.progress.up) user.party.quest.progress.up = 0;
user.party.quest.progress.up += diminishingReturns(bonus, 55, 70);
@@ -115,7 +124,7 @@ spells.warrior = {
target: 'self',
notes: t('spellWarriorDefensiveStanceNotes'),
cast (user) {
- let bonus = statsComputed(user).con - user.stats.buffs.con;
+ const bonus = statsComputed(user).con - user.stats.buffs.con;
if (!user.stats.buffs.con) user.stats.buffs.con = 0;
user.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 40, 200));
},
@@ -127,8 +136,8 @@ spells.warrior = {
target: 'party',
notes: t('spellWarriorValorousPresenceNotes'),
cast (user, target) {
- each(target, (member) => {
- let bonus = statsComputed(user).str - user.stats.buffs.str;
+ each(target, member => {
+ const bonus = statsComputed(user).str - user.stats.buffs.str;
if (!member.stats.buffs.str) member.stats.buffs.str = 0;
member.stats.buffs.str += Math.ceil(diminishingReturns(bonus, 20, 200));
});
@@ -141,8 +150,8 @@ spells.warrior = {
target: 'party',
notes: t('spellWarriorIntimidateNotes'),
cast (user, target) {
- each(target, (member) => {
- let bonus = statsComputed(user).con - user.stats.buffs.con;
+ each(target, member => {
+ const bonus = statsComputed(user).con - user.stats.buffs.con;
if (!member.stats.buffs.con) member.stats.buffs.con = 0;
member.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 24, 200));
});
@@ -158,7 +167,7 @@ spells.rogue = {
target: 'task',
notes: t('spellRoguePickPocketNotes'),
cast (user, target) {
- let bonus = calculateBonus(target.value, statsComputed(user).per);
+ const bonus = calculateBonus(target.value, statsComputed(user).per);
user.stats.gp += diminishingReturns(bonus, 25, 75);
},
},
@@ -169,8 +178,8 @@ spells.rogue = {
target: 'task',
notes: t('spellRogueBackStabNotes'),
cast (user, target, req) {
- let _crit = crit.crit(user, 'str', 0.3);
- let bonus = calculateBonus(target.value, statsComputed(user).str, _crit);
+ const _crit = crit.crit(user, 'str', 0.3);
+ const bonus = calculateBonus(target.value, statsComputed(user).str, _crit);
user.stats.exp += diminishingReturns(bonus, 75, 50);
user.stats.gp += diminishingReturns(bonus, 18, 75);
updateStats(user, user.stats, req);
@@ -183,8 +192,8 @@ spells.rogue = {
target: 'party',
notes: t('spellRogueToolsOfTradeNotes'),
cast (user, target) {
- each(target, (member) => {
- let bonus = statsComputed(user).per - user.stats.buffs.per;
+ each(target, member => {
+ const bonus = statsComputed(user).per - user.stats.buffs.per;
if (!member.stats.buffs.per) member.stats.buffs.per = 0;
member.stats.buffs.per += Math.ceil(diminishingReturns(bonus, 100, 50));
});
@@ -198,7 +207,9 @@ spells.rogue = {
notes: t('spellRogueStealthNotes'),
cast (user) {
if (!user.stats.buffs.stealth) user.stats.buffs.stealth = 0;
- user.stats.buffs.stealth += Math.ceil(diminishingReturns(statsComputed(user).per, user.tasksOrder.dailys.length * 0.64, 55));
+ user.stats.buffs.stealth += Math.ceil(diminishingReturns(
+ statsComputed(user).per, user.tasksOrder.dailys.length * 0.64, 55,
+ ));
},
},
};
@@ -223,7 +234,7 @@ spells.healer = {
target: 'tasks',
notes: t('spellHealerBrightnessNotes'),
cast (user, tasks) {
- each(tasks, (task) => {
+ each(tasks, task => {
if (task.type !== 'reward') {
task.value += 4 * (statsComputed(user).int / (statsComputed(user).int + 40));
}
@@ -237,8 +248,8 @@ spells.healer = {
target: 'party',
notes: t('spellHealerProtectAuraNotes'),
cast (user, target) {
- each(target, (member) => {
- let bonus = statsComputed(user).con - user.stats.buffs.con;
+ each(target, member => {
+ const bonus = statsComputed(user).con - user.stats.buffs.con;
if (!member.stats.buffs.con) member.stats.buffs.con = 0;
member.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 200, 200));
});
@@ -251,7 +262,7 @@ spells.healer = {
target: 'party',
notes: t('spellHealerHealAllNotes'),
cast (user, target) {
- each(target, (member) => {
+ each(target, member => {
member.stats.hp += (statsComputed(user).con + statsComputed(user).int + 5) * 0.04;
if (member.stats.hp > 50) member.stats.hp = 50;
});
@@ -274,8 +285,8 @@ spells.special = {
target.stats.buffs.shinySeed = false;
target.stats.buffs.seafoam = false;
if (!target.achievements.snowball) target.achievements.snowball = 0;
- target.achievements.snowball++;
- user.items.special.snowball--;
+ target.achievements.snowball += 1;
+ user.items.special.snowball -= 1;
},
},
salt: {
@@ -307,8 +318,8 @@ spells.special = {
target.stats.buffs.shinySeed = false;
target.stats.buffs.seafoam = false;
if (!target.achievements.spookySparkles) target.achievements.spookySparkles = 0;
- target.achievements.spookySparkles++;
- user.items.special.spookySparkles--;
+ target.achievements.spookySparkles += 1;
+ user.items.special.spookySparkles -= 1;
},
},
opaquePotion: {
@@ -340,8 +351,8 @@ spells.special = {
target.stats.buffs.shinySeed = true;
target.stats.buffs.seafoam = false;
if (!target.achievements.shinySeed) target.achievements.shinySeed = 0;
- target.achievements.shinySeed++;
- user.items.special.shinySeed--;
+ target.achievements.shinySeed += 1;
+ user.items.special.shinySeed -= 1;
},
},
petalFreePotion: {
@@ -373,8 +384,8 @@ spells.special = {
target.stats.buffs.shinySeed = false;
target.stats.buffs.seafoam = true;
if (!target.achievements.seafoam) target.achievements.seafoam = 0;
- target.achievements.seafoam++;
- user.items.special.seafoam--;
+ target.achievements.seafoam += 1;
+ user.items.special.seafoam -= 1;
},
},
sand: {
@@ -402,11 +413,11 @@ spells.special = {
cast (user, target) {
if (user === target) {
if (!user.achievements.nye) user.achievements.nye = 0;
- user.achievements.nye++;
+ user.achievements.nye += 1;
} else {
- each([user, target], (u) => {
+ each([user, target], u => {
if (!u.achievements.nye) u.achievements.nye = 0;
- u.achievements.nye++;
+ u.achievements.nye += 1;
});
}
@@ -414,13 +425,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.nyeReceived.push(senderName);
- if (target.addNotification) target.addNotification('CARD_RECEIVED', {
- card: 'nye',
- from: {
- id: user._id,
- name: senderName,
- },
- });
+ if (target.addNotification) {
+ target.addNotification('CARD_RECEIVED', {
+ card: 'nye',
+ from: {
+ id: user._id,
+ name: senderName,
+ },
+ });
+ }
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -437,11 +450,11 @@ spells.special = {
cast (user, target) {
if (user === target) {
if (!user.achievements.valentine) user.achievements.valentine = 0;
- user.achievements.valentine++;
+ user.achievements.valentine += 1;
} else {
- each([user, target], (u) => {
+ each([user, target], u => {
if (!u.achievements.valentine) u.achievements.valentine = 0;
- u.achievements.valentine++;
+ u.achievements.valentine += 1;
});
}
@@ -449,13 +462,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.valentineReceived.push(senderName);
- if (target.addNotification) target.addNotification('CARD_RECEIVED', {
- card: 'valentine',
- from: {
- id: user._id,
- name: senderName,
- },
- });
+ if (target.addNotification) {
+ target.addNotification('CARD_RECEIVED', {
+ card: 'valentine',
+ from: {
+ id: user._id,
+ name: senderName,
+ },
+ });
+ }
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -472,11 +487,11 @@ spells.special = {
cast (user, target) {
if (user === target) {
if (!user.achievements.greeting) user.achievements.greeting = 0;
- user.achievements.greeting++;
+ user.achievements.greeting += 1;
} else {
- each([user, target], (u) => {
+ each([user, target], u => {
if (!u.achievements.greeting) u.achievements.greeting = 0;
- u.achievements.greeting++;
+ u.achievements.greeting += 1;
});
}
@@ -484,13 +499,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.greetingReceived.push(senderName);
- if (target.addNotification) target.addNotification('CARD_RECEIVED', {
- card: 'greeting',
- from: {
- id: user._id,
- name: senderName,
- },
- });
+ if (target.addNotification) {
+ target.addNotification('CARD_RECEIVED', {
+ card: 'greeting',
+ from: {
+ id: user._id,
+ name: senderName,
+ },
+ });
+ }
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -507,11 +524,11 @@ spells.special = {
cast (user, target) {
if (user === target) {
if (!user.achievements.thankyou) user.achievements.thankyou = 0;
- user.achievements.thankyou++;
+ user.achievements.thankyou += 1;
} else {
- each([user, target], (u) => {
+ each([user, target], u => {
if (!u.achievements.thankyou) u.achievements.thankyou = 0;
- u.achievements.thankyou++;
+ u.achievements.thankyou += 1;
});
}
@@ -519,13 +536,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.thankyouReceived.push(senderName);
- if (target.addNotification) target.addNotification('CARD_RECEIVED', {
- card: 'thankyou',
- from: {
- id: user._id,
- name: senderName,
- },
- });
+ if (target.addNotification) {
+ target.addNotification('CARD_RECEIVED', {
+ card: 'thankyou',
+ from: {
+ id: user._id,
+ name: senderName,
+ },
+ });
+ }
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -542,11 +561,11 @@ spells.special = {
cast (user, target) {
if (user === target) {
if (!user.achievements.birthday) user.achievements.birthday = 0;
- user.achievements.birthday++;
+ user.achievements.birthday += 1;
} else {
- each([user, target], (u) => {
+ each([user, target], u => {
if (!u.achievements.birthday) u.achievements.birthday = 0;
- u.achievements.birthday++;
+ u.achievements.birthday += 1;
});
}
@@ -554,13 +573,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.birthdayReceived.push(senderName);
- if (target.addNotification) target.addNotification('CARD_RECEIVED', {
- card: 'birthday',
- from: {
- id: user._id,
- name: senderName,
- },
- });
+ if (target.addNotification) {
+ target.addNotification('CARD_RECEIVED', {
+ card: 'birthday',
+ from: {
+ id: user._id,
+ name: senderName,
+ },
+ });
+ }
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -577,11 +598,11 @@ spells.special = {
cast (user, target) {
if (user === target) {
if (!user.achievements.congrats) user.achievements.congrats = 0;
- user.achievements.congrats++;
+ user.achievements.congrats += 1;
} else {
- each([user, target], (u) => {
+ each([user, target], u => {
if (!u.achievements.congrats) u.achievements.congrats = 0;
- u.achievements.congrats++;
+ u.achievements.congrats += 1;
});
}
@@ -589,13 +610,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.congratsReceived.push(senderName);
- if (target.addNotification) target.addNotification('CARD_RECEIVED', {
- card: 'congrats',
- from: {
- id: user._id,
- name: senderName,
- },
- });
+ if (target.addNotification) {
+ target.addNotification('CARD_RECEIVED', {
+ card: 'congrats',
+ from: {
+ id: user._id,
+ name: senderName,
+ },
+ });
+ }
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -612,11 +635,11 @@ spells.special = {
cast (user, target) {
if (user === target) {
if (!user.achievements.getwell) user.achievements.getwell = 0;
- user.achievements.getwell++;
+ user.achievements.getwell += 1;
} else {
- each([user, target], (u) => {
+ each([user, target], u => {
if (!u.achievements.getwell) u.achievements.getwell = 0;
- u.achievements.getwell++;
+ u.achievements.getwell += 1;
});
}
@@ -624,13 +647,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.getwellReceived.push(senderName);
- if (target.addNotification) target.addNotification('CARD_RECEIVED', {
- card: 'getwell',
- from: {
- id: user._id,
- name: senderName,
- },
- });
+ if (target.addNotification) {
+ target.addNotification('CARD_RECEIVED', {
+ card: 'getwell',
+ from: {
+ id: user._id,
+ name: senderName,
+ },
+ });
+ }
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -647,11 +672,11 @@ spells.special = {
cast (user, target) {
if (user === target) {
if (!user.achievements.goodluck) user.achievements.goodluck = 0;
- user.achievements.goodluck++;
+ user.achievements.goodluck += 1;
} else {
- each([user, target], (u) => {
+ each([user, target], u => {
if (!u.achievements.goodluck) u.achievements.goodluck = 0;
- u.achievements.goodluck++;
+ u.achievements.goodluck += 1;
});
}
@@ -659,13 +684,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.goodluckReceived.push(senderName);
- if (target.addNotification) target.addNotification('CARD_RECEIVED', {
- card: 'goodluck',
- from: {
- id: user._id,
- name: senderName,
- },
- });
+ if (target.addNotification) {
+ target.addNotification('CARD_RECEIVED', {
+ card: 'goodluck',
+ from: {
+ id: user._id,
+ name: senderName,
+ },
+ });
+ }
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -673,10 +700,10 @@ spells.special = {
},
};
-each(spells, (spellClass) => {
+each(spells, spellClass => {
each(spellClass, (spell, key) => {
spell.key = key;
- let _cast = spell.cast;
+ const _cast = spell.cast;
spell.cast = function castSpell (user, target, req) {
_cast(user, target, req);
user.stats.mp -= spell.mana;
@@ -684,4 +711,4 @@ each(spells, (spellClass) => {
});
});
-module.exports = spells;
+export default spells;
diff --git a/website/common/script/content/stable.js b/website/common/script/content/stable.js
index 4ee406ca80..387633d220 100644
--- a/website/common/script/content/stable.js
+++ b/website/common/script/content/stable.js
@@ -10,16 +10,16 @@ import {
} from './hatching-potions';
import t from './translation';
-let petInfo = {};
-let mountInfo = {};
+const petInfo = {};
+const mountInfo = {};
function constructSet (type, eggs, potions) {
- let pets = {};
- let mounts = {};
+ const pets = {};
+ const mounts = {};
- each(eggs, (egg) => {
- each(potions, (potion) => {
- let key = `${egg.key}-${potion.key}`;
+ each(eggs, egg => {
+ each(potions, potion => {
+ const key = `${egg.key}-${potion.key}`;
function getAnimalData (text) {
return {
@@ -49,11 +49,11 @@ function constructSet (type, eggs, potions) {
}
function constructPetOnlySet (type, eggs, potions) {
- let pets = {};
+ const pets = {};
- each(eggs, (egg) => {
- each(potions, (potion) => {
- let key = `${egg.key}-${potion.key}`;
+ each(eggs, egg => {
+ each(potions, potion => {
+ const key = `${egg.key}-${potion.key}`;
function getAnimalData (text) {
return {
@@ -76,12 +76,12 @@ function constructPetOnlySet (type, eggs, potions) {
return pets;
}
-let [dropPets, dropMounts] = constructSet('drop', dropEggs, dropPotions);
-let [premiumPets, premiumMounts] = constructSet('premium', dropEggs, premiumPotions);
-let [questPets, questMounts] = constructSet('quest', questEggs, dropPotions);
-let wackyPets = constructPetOnlySet('wacky', dropEggs, wackyPotions);
+const [dropPets, dropMounts] = constructSet('drop', dropEggs, dropPotions);
+const [premiumPets, premiumMounts] = constructSet('premium', dropEggs, premiumPotions);
+const [questPets, questMounts] = constructSet('quest', questEggs, dropPotions);
+const wackyPets = constructPetOnlySet('wacky', dropEggs, wackyPotions);
-let specialPets = {
+const specialPets = {
'Wolf-Veteran': 'veteranWolf',
'Wolf-Cerberus': 'cerberusPup',
'Dragon-Hydra': 'hydra',
@@ -106,7 +106,7 @@ let specialPets = {
'Gryphon-Gryphatrice': 'gryphatrice',
};
-let specialMounts = {
+const specialMounts = {
'BearCub-Polar': 'polarBear',
'LionCub-Ethereal': 'etherealLion',
'MantisShrimp-Base': 'mantisShrimp',
@@ -141,7 +141,7 @@ each(specialMounts, (translationString, key) => {
};
});
-module.exports = {
+export {
dropPets,
premiumPets,
questPets,
diff --git a/website/common/script/content/subscriptionBlocks.js b/website/common/script/content/subscriptionBlocks.js
index f3131cb5a5..760588772e 100644
--- a/website/common/script/content/subscriptionBlocks.js
+++ b/website/common/script/content/subscriptionBlocks.js
@@ -1,7 +1,7 @@
/* eslint-disable camelcase */
import each from 'lodash/each';
-let subscriptionBlocks = {
+const subscriptionBlocks = {
basic_earned: {
target: 'user',
canSubscribe: true,
@@ -50,8 +50,6 @@ let subscriptionBlocks = {
},
};
-each(subscriptionBlocks, function createKeys (b, k) {
- return b.key = k;
-});
+each(subscriptionBlocks, (b, k) => { b.key = k; });
-module.exports = subscriptionBlocks;
+export default subscriptionBlocks;
diff --git a/website/common/script/content/tasks.js b/website/common/script/content/tasks.js
index 1b14a99fd0..26d3d9d039 100644
--- a/website/common/script/content/tasks.js
+++ b/website/common/script/content/tasks.js
@@ -1,6 +1,6 @@
import t from './translation';
-export const tasksByCategory = {
+export const tasksByCategory = { // eslint-disable-line import/prefer-default-export
work: [
{
type: 'habit',
diff --git a/website/common/script/content/time-travelers.js b/website/common/script/content/time-travelers.js
index 29de903e1d..4a83330399 100644
--- a/website/common/script/content/time-travelers.js
+++ b/website/common/script/content/time-travelers.js
@@ -7,19 +7,19 @@ import reduce from 'lodash/reduce';
import mysterySets from './mystery-sets';
import gear from './gear';
-let mystery = mysterySets;
+const mystery = mysterySets;
each(mystery, (v, k) => {
- return v.items = filter(gear.flat, {
+ v.items = filter(gear.flat, {
mystery: k,
});
});
-let timeTravelerStore = (user) => {
+const timeTravelerStore = user => {
let ownedKeys;
- let owned = user.items.gear.owned;
- let mysteryItems = user.purchased.plan.mysteryItems;
- let unopenedGifts = typeof mysteryItems.toObject === 'function' ? mysteryItems.toObject() : mysteryItems;
+ const { owned } = user.items.gear;
+ const { mysteryItems } = user.purchased.plan;
+ const unopenedGifts = typeof mysteryItems.toObject === 'function' ? mysteryItems.toObject() : mysteryItems;
ownedKeys = keys(typeof owned.toObject === 'function' ? owned.toObject() : owned);
ownedKeys = union(ownedKeys, unopenedGifts);
return reduce(mystery, (m, v, k) => {
@@ -31,7 +31,7 @@ let timeTravelerStore = (user) => {
}, {});
};
-module.exports = {
+export default {
timeTravelerStore,
mystery,
-};
\ No newline at end of file
+};
diff --git a/website/common/script/content/translation.js b/website/common/script/content/translation.js
index baa93f7a8a..eb6a39f8f0 100644
--- a/website/common/script/content/translation.js
+++ b/website/common/script/content/translation.js
@@ -1,6 +1,6 @@
import i18n from '../i18n';
-module.exports = function translator (string, vars = { a: 'a' }) {
+export default function translator (string, vars = { a: 'a' }) {
function func (lang) {
return i18n.t(string, vars, lang);
}
@@ -8,4 +8,4 @@ module.exports = function translator (string, vars = { a: 'a' }) {
func.i18nLangFunc = true; // Trick to recognize this type of function
return func;
-};
+}
diff --git a/website/common/script/count.js b/website/common/script/count.js
index 0a840e029d..803fd76498 100644
--- a/website/common/script/count.js
+++ b/website/common/script/count.js
@@ -6,80 +6,68 @@ import content from './content/index';
const DROP_ANIMALS = keys(content.pets);
-function beastMasterProgress (pets = {}) {
+export function beastMasterProgress (pets = {}) {
let count = 0;
- each(DROP_ANIMALS, (animal) => {
- if (pets[animal] > 0 || pets[animal] === -1)
- count++;
+ each(DROP_ANIMALS, animal => {
+ if (pets[animal] > 0 || pets[animal] === -1) count += 1;
});
return count;
}
-function beastCount (pets = {}) {
+export function beastCount (pets = {}) {
let count = 0;
- each(DROP_ANIMALS, (animal) => {
- if (pets[animal] > 0) count++;
+ each(DROP_ANIMALS, animal => {
+ if (pets[animal] > 0) count += 1;
});
return count;
}
-function dropPetsCurrentlyOwned (pets = {}) {
+export function dropPetsCurrentlyOwned (pets = {}) {
let count = 0;
- each(DROP_ANIMALS, (animal) => {
- if (pets[animal] > 0)
- count++;
+ each(DROP_ANIMALS, animal => {
+ if (pets[animal] > 0) count += 1;
});
return count;
}
-function mountMasterProgress (mounts = {}) {
+export function mountMasterProgress (mounts = {}) {
let count = 0;
- each(DROP_ANIMALS, (animal) => {
- if (mounts[animal])
- count++;
+ each(DROP_ANIMALS, animal => {
+ if (mounts[animal]) count += 1;
});
return count;
}
-function remainingGearInSet (userGear = {}, set) {
- let gear = filter(content.gear.flat, (item) => {
- let setMatches = item.klass === set;
- let hasItem = userGear[item.key];
+export function remainingGearInSet (userGear = {}, set) {
+ const gear = filter(content.gear.flat, item => {
+ const setMatches = item.klass === set;
+ const hasItem = userGear[item.key];
return setMatches && !hasItem;
});
- let count = size(gear);
+ const count = size(gear);
return count;
}
-function questsOfCategory (userQuests = {}, category) {
- let quests = filter(content.quests, (quest) => {
- let categoryMatches = quest.category === category;
- let hasQuest = userQuests[quest.key];
+export function questsOfCategory (userQuests = {}, category) {
+ const quests = filter(content.quests, quest => {
+ const categoryMatches = quest.category === category;
+ const hasQuest = userQuests[quest.key];
return categoryMatches && hasQuest;
});
- let count = size(quests);
+ const count = size(quests);
return count;
}
-
-module.exports = {
- beastMasterProgress,
- beastCount,
- dropPetsCurrentlyOwned,
- mountMasterProgress,
- remainingGearInSet,
- questsOfCategory,
-};
diff --git a/website/common/script/cron.js b/website/common/script/cron.js
index b93df4b80e..53be939a4e 100644
--- a/website/common/script/cron.js
+++ b/website/common/script/cron.js
@@ -23,18 +23,20 @@ export const DAY_MAPPING_STRING_TO_NUMBER = invert(DAY_MAPPING);
/*
Each time we perform date maths (cron, task-due-days, etc), we need to consider user preferences.
- Specifically {dayStart} (custom day start) and {timezoneOffset}. This function sanitizes / defaults those values.
- {now} is also passed in for various purposes, one example being the test scripts scripts testing different "now" times.
+ Specifically {dayStart} (custom day start) and {timezoneOffset}.
+ This function sanitizes / defaults those values.
+ {now} is also passed in for various purposes,
+ one example being the test scripts scripts testing different "now" times.
*/
function sanitizeOptions (o) {
- let ref = Number(o.dayStart || 0);
- let dayStart = !Number.isNaN(ref) && ref >= 0 && ref <= 24 ? ref : 0;
+ const ref = Number(o.dayStart || 0);
+ const dayStart = !Number.isNaN(ref) && ref >= 0 && ref <= 24 ? ref : 0;
let timezoneOffset;
- let timezoneOffsetDefault = Number(moment().zone());
+ const timezoneOffsetDefault = Number(moment().zone());
- if (isFinite(o.timezoneOffsetOverride)) {
+ if (Number.isFinite(o.timezoneOffsetOverride)) {
timezoneOffset = Number(o.timezoneOffsetOverride);
} else if (Number.isFinite(o.timezoneOffset)) {
timezoneOffset = Number(o.timezoneOffset);
@@ -46,7 +48,7 @@ function sanitizeOptions (o) {
timezoneOffset = timezoneOffsetDefault;
}
- let now = o.now ? moment(o.now).zone(timezoneOffset) : moment().zone(timezoneOffset);
+ const now = o.now ? moment(o.now).zone(timezoneOffset) : moment().zone(timezoneOffset);
// return a new object, we don't want to add "now" to user object
return {
dayStart,
@@ -56,21 +58,28 @@ function sanitizeOptions (o) {
}
export function startOfWeek (options = {}) {
- let o = sanitizeOptions(options);
+ const o = sanitizeOptions(options);
return moment(o.now).startOf('week');
}
/*
- This is designed for use with any date that has an important time portion (e.g., when comparing the current date-time with the previous cron's date-time for determing if cron should run now).
- It changes the time portion of the date-time to be the Custom Day Start hour, so that the date-time is now the user's correct start of day.
- It SUBTRACTS a day if the date-time's original hour is before CDS (e.g., if your CDS is 5am and it's currently 4am, it's still the previous day).
- This is NOT suitable for manipulating any dates that are displayed to the user as a date with no time portion, such as a Daily's Start Dates (e.g., a Start Date of today shows only the date, so it should be considered to be today even if the hidden time portion is before CDS).
+ This is designed for use with any date that has an important time portion
+ (e.g., when comparing the current date-time with the previous cron's date-time
+ for determing if cron should run now).
+ It changes the time portion of the date-time to be the Custom Day Start hour,
+ so that the date-time is now the user's correct start of day.
+ It SUBTRACTS a day if the date-time's original hour is before CDS
+ (e.g., if your CDS is 5am and it's currently 4am, it's still the previous day).
+ This is NOT suitable for manipulating any dates that are displayed to the user
+ as a date with no time portion, such as a Daily's Start Dates
+ (e.g., a Start Date of today shows only the date,
+ so it should be considered to be today even if the hidden time portion is before CDS).
*/
export function startOfDay (options = {}) {
- let o = sanitizeOptions(options);
- let dayStart = moment(o.now).startOf('day').add({ hours: o.dayStart });
+ const o = sanitizeOptions(options);
+ const dayStart = moment(o.now).startOf('day').add({ hours: o.dayStart });
if (moment(o.now).hour() < o.dayStart) {
dayStart.subtract({ days: 1 });
@@ -84,74 +93,78 @@ export function startOfDay (options = {}) {
*/
export function daysSince (yesterday, options = {}) {
- let o = sanitizeOptions(options);
- let startOfNow = startOfDay(defaults({ now: o.now }, o));
- let startOfYesterday = startOfDay(defaults({ now: yesterday }, o));
+ const o = sanitizeOptions(options);
+ const startOfNow = startOfDay(defaults({ now: o.now }, o));
+ const startOfYesterday = startOfDay(defaults({ now: yesterday }, o));
return startOfNow.diff(startOfYesterday, 'days');
}
/*
- Should the user do this task on this date, given the task's repeat options and user.preferences.dayStart?
+ Should the user do this task on this date,
+ given the task's repeat options and user.preferences.dayStart?
*/
export function shouldDo (day, dailyTask, options = {}) {
if (dailyTask.type !== 'daily' || dailyTask.startDate === null || dailyTask.everyX < 1 || dailyTask.everyX > 9999) {
return false;
}
- let o = sanitizeOptions(options);
- let startOfDayWithCDSTime = startOfDay(defaults({ now: day }, o));
+ const o = sanitizeOptions(options);
+ const startOfDayWithCDSTime = startOfDay(defaults({ now: day }, o));
- // The time portion of the Start Date is never visible to or modifiable by the user so we must ignore it.
- // Therefore, we must also ignore the time portion of the user's day start (startOfDayWithCDSTime), otherwise the date comparison will be wrong for some times.
- // NB: The user's day start date has already been converted to the PREVIOUS day's date if the time portion was before CDS.
+ // The time portion of the Start Date is never visible to
+ // or modifiable by the user so we must ignore it.
+ // Therefore, we must also ignore the time portion of the user's day start
+ // (startOfDayWithCDSTime), otherwise the date comparison will be wrong for some times.
+ // NB: The user's day start date has already been converted to the PREVIOUS
+ // day's date if the time portion was before CDS.
- let startDate = moment(dailyTask.startDate).zone(o.timezoneOffset).startOf('day');
+ const startDate = moment(dailyTask.startDate).zone(o.timezoneOffset).startOf('day');
if (startDate > startOfDayWithCDSTime.startOf('day') && !options.nextDue) {
return false; // Daily starts in the future
}
- let daysOfTheWeek = [];
+ const daysOfTheWeek = [];
if (dailyTask.repeat) {
- for (let [repeatDay, active] of Object.entries(dailyTask.repeat)) {
- if (!isFinite(DAY_MAPPING_STRING_TO_NUMBER[repeatDay])) continue; // eslint-disable-line no-continue
+ for (const [repeatDay, active] of Object.entries(dailyTask.repeat)) {
+ if (!Number.isFinite(parseInt(DAY_MAPPING_STRING_TO_NUMBER[repeatDay], 10))) continue; // eslint-disable-line no-continue, max-len
if (active) daysOfTheWeek.push(parseInt(DAY_MAPPING_STRING_TO_NUMBER[repeatDay], 10));
}
}
if (dailyTask.frequency === 'daily') {
if (!dailyTask.everyX) return false; // error condition
- let schedule = moment(startDate).recur()
+ const schedule = moment(startDate).recur()
.every(dailyTask.everyX).days();
if (options.nextDue) {
- let filteredDates = [];
- for (let i = 1; filteredDates.length < 6; i++) {
- let calcDate = moment(startDate).add(dailyTask.everyX * i, 'days');
+ const filteredDates = [];
+ for (let i = 1; filteredDates.length < 6; i += 1) {
+ const calcDate = moment(startDate).add(dailyTask.everyX * i, 'days');
if (calcDate > startOfDayWithCDSTime) filteredDates.push(calcDate);
}
return filteredDates;
}
return schedule.matches(startOfDayWithCDSTime);
- } else if (dailyTask.frequency === 'weekly') {
+ } if (dailyTask.frequency === 'weekly') {
let schedule = moment(startDate).recur();
- let differenceInWeeks = moment(startOfDayWithCDSTime).diff(moment(startDate), 'week');
- let matchEveryX = differenceInWeeks % dailyTask.everyX === 0;
+ const differenceInWeeks = moment(startOfDayWithCDSTime).diff(moment(startDate), 'week');
+ const matchEveryX = differenceInWeeks % dailyTask.everyX === 0;
if (daysOfTheWeek.length === 0) return false;
schedule = schedule.every(daysOfTheWeek).daysOfWeek();
if (options.nextDue) {
- let filteredDates = [];
- for (let i = 0; filteredDates.length < 6; i++) {
- for (let j = 0; j < daysOfTheWeek.length && filteredDates.length < 6; j++) {
- let calcDate = moment(startDate).day(daysOfTheWeek[j]).add(dailyTask.everyX * i, 'weeks');
+ const filteredDates = [];
+ for (let i = 0; filteredDates.length < 6; i += 1) {
+ for (let j = 0; j < daysOfTheWeek.length && filteredDates.length < 6; j += 1) {
+ const calcDate = moment(startDate).day(daysOfTheWeek[j]).add(dailyTask.everyX * i, 'weeks');
if (calcDate > startOfDayWithCDSTime) filteredDates.push(calcDate);
}
}
- let sortedDates = filteredDates.sort((date1, date2) => {
+ const sortedDates = filteredDates.sort((date1, date2) => {
if (date1.toDate() > date2.toDate()) return 1;
if (date2.toDate() > date1.toDate()) return -1;
return 0;
@@ -160,15 +173,15 @@ export function shouldDo (day, dailyTask, options = {}) {
}
return schedule.matches(startOfDayWithCDSTime) && matchEveryX;
- } else if (dailyTask.frequency === 'monthly') {
+ } if (dailyTask.frequency === 'monthly') {
let schedule = moment(startDate).recur();
// Use startOf to ensure that we are always comparing month
// to the next rather than a month from the day
- let differenceInMonths = moment(startOfDayWithCDSTime).startOf('month')
+ const differenceInMonths = moment(startOfDayWithCDSTime).startOf('month')
.diff(moment(startDate).startOf('month'), 'month', true);
- let matchEveryX = differenceInMonths % dailyTask.everyX === 0;
+ const matchEveryX = differenceInMonths % dailyTask.everyX === 0;
if (dailyTask.weeksOfMonth && dailyTask.weeksOfMonth.length > 0) {
if (daysOfTheWeek.length === 0) return false;
@@ -176,13 +189,13 @@ export function shouldDo (day, dailyTask, options = {}) {
.every(dailyTask.weeksOfMonth).weeksOfMonthByDay();
if (options.nextDue) {
- let filteredDates = [];
- for (let i = 1; filteredDates.length < 6; i++) {
- let recurDate = moment(startDate).add(dailyTask.everyX * i, 'months');
- let calcDate = recurDate.clone();
+ const filteredDates = [];
+ for (let i = 1; filteredDates.length < 6; i += 1) {
+ const recurDate = moment(startDate).add(dailyTask.everyX * i, 'months');
+ const calcDate = recurDate.clone();
calcDate.day(daysOfTheWeek[0]);
- let startDateWeek = Math.ceil(moment(startDate).date() / 7);
+ const startDateWeek = Math.ceil(moment(startDate).date() / 7);
let calcDateWeek = Math.ceil(calcDate.date() / 7);
// adjust week since weeks will rollover to other months
@@ -193,19 +206,22 @@ export function shouldDo (day, dailyTask, options = {}) {
calcDateWeek = Math.ceil(calcDate.date() / 7);
- if (calcDate >= startOfDayWithCDSTime &&
- calcDateWeek === startDateWeek && calcDate.month() === recurDate.month()) filteredDates.push(calcDate);
+ if (
+ calcDate >= startOfDayWithCDSTime
+ && calcDateWeek === startDateWeek
+ && calcDate.month() === recurDate.month()
+ ) filteredDates.push(calcDate);
}
return filteredDates;
}
return schedule.matches(startOfDayWithCDSTime) && matchEveryX;
- } else if (dailyTask.daysOfMonth && dailyTask.daysOfMonth.length > 0) {
+ } if (dailyTask.daysOfMonth && dailyTask.daysOfMonth.length > 0) {
schedule = schedule.every(dailyTask.daysOfMonth).daysOfMonth();
if (options.nextDue) {
- let filteredDates = [];
- for (let i = 1; filteredDates.length < 6; i++) {
- let calcDate = moment(startDate).add(dailyTask.everyX * i, 'months');
+ const filteredDates = [];
+ for (let i = 1; filteredDates.length < 6; i += 1) {
+ const calcDate = moment(startDate).add(dailyTask.everyX * i, 'months');
if (calcDate >= startOfDayWithCDSTime) filteredDates.push(calcDate);
}
return filteredDates;
@@ -213,15 +229,15 @@ export function shouldDo (day, dailyTask, options = {}) {
}
return schedule.matches(startOfDayWithCDSTime) && matchEveryX;
- } else if (dailyTask.frequency === 'yearly') {
+ } if (dailyTask.frequency === 'yearly') {
let schedule = moment(startDate).recur();
schedule = schedule.every(dailyTask.everyX).years();
if (options.nextDue) {
- let filteredDates = [];
- for (let i = 1; filteredDates.length < 6; i++) {
- let calcDate = moment(startDate).add(dailyTask.everyX * i, 'years');
+ const filteredDates = [];
+ for (let i = 1; filteredDates.length < 6; i += 1) {
+ const calcDate = moment(startDate).add(dailyTask.everyX * i, 'years');
if (calcDate > startOfDayWithCDSTime) filteredDates.push(calcDate);
}
return filteredDates;
diff --git a/website/common/errors/apiErrorMessages.js b/website/common/script/errors/apiErrorMessages.js
similarity index 98%
rename from website/common/errors/apiErrorMessages.js
rename to website/common/script/errors/apiErrorMessages.js
index f10747b12c..1a99ec1d2e 100644
--- a/website/common/errors/apiErrorMessages.js
+++ b/website/common/script/errors/apiErrorMessages.js
@@ -1,5 +1,5 @@
// When this file grows, it can be split into multiple ones.
-module.exports = {
+export default {
taskIdRequired: 'req.params.taskId must contain a task id.',
keepOrRemove: 'req.query.keep must be either "keep" or "remove".',
keepOrRemoveAll: 'req.query.keep must be either "keep-all" or "remove-all".',
diff --git a/website/common/errors/commonErrorMessages.js b/website/common/script/errors/commonErrorMessages.js
similarity index 97%
rename from website/common/errors/commonErrorMessages.js
rename to website/common/script/errors/commonErrorMessages.js
index a9c4173405..7f0530f5ff 100644
--- a/website/common/errors/commonErrorMessages.js
+++ b/website/common/script/errors/commonErrorMessages.js
@@ -1,5 +1,5 @@
// When this file grows, it can be split into multiple ones.
-module.exports = {
+export default {
invalidAttribute: '"<%= attr %>" is not a valid Stat.',
statsObjectRequired: '"stats" object is required',
diff --git a/website/common/script/fns/autoAllocate.js b/website/common/script/fns/autoAllocate.js
index e32db7ec84..7c5858369c 100644
--- a/website/common/script/fns/autoAllocate.js
+++ b/website/common/script/fns/autoAllocate.js
@@ -10,23 +10,24 @@ import splitWhitespace from '../libs/splitWhitespace';
/*
Updates user stats with new stats. Handles death, leveling up, etc
{stats} new stats
- {update} if aggregated changes, pass in userObj as update. otherwise commits will be made immediately
+ {update} if aggregated changes, pass in userObj as update.
+ otherwise commits will be made immediately
*/
function getStatToAllocate (user) {
let suggested;
- let statsObj = user.stats.toObject ? user.stats.toObject() : user.stats;
+ const statsObj = user.stats.toObject ? user.stats.toObject() : user.stats;
switch (user.preferences.allocationMode) {
case 'flat': {
- let stats = pick(statsObj, splitWhitespace('con str per int'));
+ const stats = pick(statsObj, splitWhitespace('con str per int'));
return invert(stats)[min(values(stats))];
}
case 'classbased': {
let preference;
- let lvlDiv7 = statsObj.lvl / 7;
- let ideal = [lvlDiv7 * 3, lvlDiv7 * 2, lvlDiv7, lvlDiv7];
+ const lvlDiv7 = statsObj.lvl / 7;
+ const ideal = [lvlDiv7 * 3, lvlDiv7 * 2, lvlDiv7, lvlDiv7];
switch (statsObj.class) {
case 'wizard': {
@@ -46,16 +47,14 @@ function getStatToAllocate (user) {
}
}
- let diff = [
+ const diff = [
statsObj[preference[0]] - ideal[0],
statsObj[preference[1]] - ideal[1],
statsObj[preference[2]] - ideal[2],
statsObj[preference[3]] - ideal[3],
];
- suggested = findIndex(diff, (val) => {
- if (val === min(diff)) return true;
- });
+ suggested = findIndex(diff, val => val === min(diff));
return suggested !== -1 ? preference[suggested] : 'str';
}
@@ -75,8 +74,8 @@ function getStatToAllocate (user) {
}
}
-module.exports = function autoAllocate (user) {
- let statToIncrease = getStatToAllocate(user);
-
- return user.stats[statToIncrease]++;
-};
+export default function autoAllocate (user) {
+ const statToIncrease = getStatToAllocate(user);
+ user.stats[statToIncrease] += 1;
+ return user.stats[statToIncrease];
+}
diff --git a/website/common/script/fns/crit.js b/website/common/script/fns/crit.js
index 0ea2aaddeb..8281a615d1 100644
--- a/website/common/script/fns/crit.js
+++ b/website/common/script/fns/crit.js
@@ -1,13 +1,12 @@
import predictableRandom from './predictableRandom';
-import statsComputed from '../libs/statsComputed';
+import statsComputed from '../libs/statsComputed'; // eslint-disable-line import/no-cycle
function crit (user, stat = 'str', chance = 0.03) {
- let s = statsComputed(user)[stat];
+ const s = statsComputed(user)[stat];
if (predictableRandom(user) <= chance * (1 + s / 100)) {
- return 1.5 + 4 * s / (s + 200);
- } else {
- return 1;
+ return 1.5 + (4 * s) / (s + 200);
}
+ return 1;
}
-module.exports = { crit };
+export default { crit };
diff --git a/website/common/script/fns/handleTwoHanded.js b/website/common/script/fns/handleTwoHanded.js
index a861a10e68..d793e0a9d6 100644
--- a/website/common/script/fns/handleTwoHanded.js
+++ b/website/common/script/fns/handleTwoHanded.js
@@ -1,9 +1,9 @@
import content from '../content/index';
import i18n from '../i18n';
-module.exports = function handleTwoHanded (user, item, type = 'equipped', req = {}) {
- let currentShield = content.gear.flat[user.items.gear[type].shield];
- let currentWeapon = content.gear.flat[user.items.gear[type].weapon];
+export default function handleTwoHanded (user, item, type = 'equipped', req = {}) {
+ const currentShield = content.gear.flat[user.items.gear[type].shield];
+ const currentWeapon = content.gear.flat[user.items.gear[type].weapon];
let message;
@@ -20,4 +20,4 @@ module.exports = function handleTwoHanded (user, item, type = 'equipped', req =
}
return message;
-};
+}
diff --git a/website/common/script/fns/index.js b/website/common/script/fns/index.js
index 15359bedd7..cf181bf4fc 100644
--- a/website/common/script/fns/index.js
+++ b/website/common/script/fns/index.js
@@ -6,7 +6,7 @@ import autoAllocate from './autoAllocate';
import updateStats from './updateStats';
import ultimateGear from './ultimateGear';
-module.exports = {
+export default {
handleTwoHanded,
predictableRandom,
crit,
diff --git a/website/common/script/fns/predictableRandom.js b/website/common/script/fns/predictableRandom.js
index ea2f7b6dab..aae5c94dcd 100644
--- a/website/common/script/fns/predictableRandom.js
+++ b/website/common/script/fns/predictableRandom.js
@@ -2,25 +2,27 @@ import omit from 'lodash/omit';
import reduce from 'lodash/reduce';
import isNumber from 'lodash/isNumber';
-// Because the same op needs to be performed on the client and the server (critical hits, item drops, etc),
+// Because the same op needs to be performed on the client and the server
+// (critical hits, item drops, etc),
// we need things to be "random", but technically predictable so that they don't go out-of-sync
-module.exports = function predictableRandom (user, seed) {
+export default function predictableRandom (user, seed) {
if (!seed || seed === Math.PI) {
let stats = user.stats.toObject ? user.stats.toObject() : user.stats;
- // These items are not part of the stat object but exists on the server (see controllers/user#getUser)
+ // These items are not part of the stat object but exists on the server
+ // (see controllers/user#getUser)
// we remove them in order to use the same user.stats both on server and on client
stats = omit(stats, ['toNextLevel', 'maxHealth', 'maxMP']);
- seed = reduce(stats, (accumulator, val) => {
+ seed = reduce(stats, (accumulator, val) => { // eslint-disable-line no-param-reassign
if (isNumber(val)) {
return accumulator + val;
- } else {
- return accumulator;
}
+ return accumulator;
}, 0);
}
- let x = Math.sin(seed++) * 10000;
+ seed += 1; // eslint-disable-line no-param-reassign
+ const x = Math.sin(seed) * 10000;
return x - Math.floor(x);
-};
+}
diff --git a/website/common/script/fns/randomDrop.js b/website/common/script/fns/randomDrop.js
index 6061b3f83f..a3f8101424 100644
--- a/website/common/script/fns/randomDrop.js
+++ b/website/common/script/fns/randomDrop.js
@@ -14,41 +14,43 @@ import statsComputed from '../libs/statsComputed';
// TODO This is only used on the server
// move to user model as an instance method?
-// Clone a drop object maintaining its functions so that we can change it without affecting the original item
+// Clone a drop object maintaining its functions
+// so that we can change it without affecting the original item
function cloneDropItem (drop) {
- return cloneDeepWith(drop, (val) => {
- return isFunction(val) ? val : undefined; // undefined will be handled by lodash
- });
+ return cloneDeepWith(drop, val => (isFunction(val) ? val : undefined));
}
function trueRandom () {
return Math.random();
}
-module.exports = function randomDrop (user, options, req = {}, analytics) {
+export default function randomDrop (user, options, req = {}, analytics) {
let acceptableDrops;
let drop;
let dropMultiplier;
let rarity;
- let predictableRandom = options.predictableRandom || trueRandom;
- let task = options.task;
+ const predictableRandom = options.predictableRandom || trueRandom;
+ const { task } = options;
let chance = min([Math.abs(task.value - 21.27), 37.5]) / 150 + 0.02;
- chance *= task.priority * // Task priority: +50% for Medium, +100% for Hard
- (1 + (task.streak / 100 || 0)) * // Streak bonus: +1% per streak
- (1 + statsComputed(user).per / 100) * // PERception: +1% per point
- (1 + (user.contributor.level / 40 || 0)) * // Contrib levels: +2.5% per level
- (1 + (user.achievements.rebirths / 20 || 0)) * // Rebirths: +5% per achievement
- (1 + (user.achievements.streak / 200 || 0)) * // Streak achievements: +0.5% per achievement
- (user._tmp.crit || 1) * (1 + 0.5 * (reduce(task.checklist, (m, i) => { // +50% per checklist item complete. TODO: make this into X individual drop chances instead
- return m + (i.completed ? 1 : 0); // eslint-disable-line indent
- }, 0) || 0)); // eslint-disable-line indent
+ chance *= task.priority // Task priority: +50% for Medium, +100% for Hard
+ * (1 + (task.streak / 100 || 0)) // Streak bonus: +1% per streak
+ * (1 + statsComputed(user).per / 100) // PERception: +1% per point
+ * (1 + (user.contributor.level / 40 || 0)) // Contrib levels: +2.5% per level
+ * (1 + (user.achievements.rebirths / 20 || 0)) // Rebirths: +5% per achievement
+ * (1 + (user.achievements.streak / 200 || 0)) // Streak achievements: +0.5% per achievement
+ // +50% per checklist item complete. TODO: make this into X individual drop chances instead
+ * (user._tmp.crit || 1)
+ * (1 + 0.5 * (reduce(
+ task.checklist, (m, i) => m + (i.completed ? 1 : 0), // eslint-disable-line indent
+ 0,
+) || 0)); // eslint-disable-line indent
chance = diminishingReturns(chance, 0.75);
if (predictableRandom() < chance) {
user.party.quest.progress.collectedItems = user.party.quest.progress.collectedItems || 0;
- user.party.quest.progress.collectedItems++;
+ user.party.quest.progress.collectedItems += 1;
user._tmp.quest = user._tmp.quest || {};
user._tmp.quest.collection = 1;
if (user.markModified) user.markModified('party.quest.progress');
@@ -60,8 +62,12 @@ module.exports = function randomDrop (user, options, req = {}, analytics) {
dropMultiplier = 1;
}
- if (daysSince(user.items.lastDrop.date, user.preferences) === 0 &&
- user.items.lastDrop.count >= dropMultiplier * (5 + Math.floor(statsComputed(user).per / 25) + (user.contributor.level || 0))) {
+ const maxDropCount = dropMultiplier * (5 + Math.floor(statsComputed(user).per / 25) + (user.contributor.level || 0)); // eslint-disable-line max-len
+
+ if (
+ daysSince(user.items.lastDrop.date, user.preferences) === 0
+ && user.items.lastDrop.count >= maxDropCount
+ ) {
return;
}
@@ -86,7 +92,7 @@ module.exports = function randomDrop (user, options, req = {}, analytics) {
drop = cloneDropItem(randomVal(content.dropEggs));
user.items.eggs[drop.key] = user.items.eggs[drop.key] || 0;
- user.items.eggs[drop.key]++;
+ user.items.eggs[drop.key] += 1;
if (user.markModified) user.markModified('items.eggs');
drop.type = 'Egg';
@@ -104,12 +110,12 @@ module.exports = function randomDrop (user, options, req = {}, analytics) {
} else { // common, 40% of 30%
acceptableDrops = ['Base', 'White', 'Desert'];
}
- drop = cloneDropItem(randomVal(pickBy(content.hatchingPotions, (v, k) => {
- return acceptableDrops.indexOf(k) >= 0;
- })));
+ drop = cloneDropItem(
+ randomVal(pickBy(content.hatchingPotions, (v, k) => acceptableDrops.indexOf(k) >= 0)),
+ );
user.items.hatchingPotions[drop.key] = user.items.hatchingPotions[drop.key] || 0;
- user.items.hatchingPotions[drop.key]++;
+ user.items.hatchingPotions[drop.key] += 1;
if (user.markModified) user.markModified('items.hatchingPotions');
drop.type = 'HatchingPotion';
@@ -131,6 +137,6 @@ module.exports = function randomDrop (user, options, req = {}, analytics) {
user._tmp.drop = drop;
user.items.lastDrop.date = Number(new Date());
- user.items.lastDrop.count++;
+ user.items.lastDrop.count += 1;
}
-};
+}
diff --git a/website/common/script/fns/resetGear.js b/website/common/script/fns/resetGear.js
index 0a60635676..008b1a13b9 100644
--- a/website/common/script/fns/resetGear.js
+++ b/website/common/script/fns/resetGear.js
@@ -1,10 +1,10 @@
import each from 'lodash/each';
import content from '../content/index';
-module.exports = function resetGear (user) {
- let gear = user.items.gear;
+export default function resetGear (user) {
+ const { gear } = user.items;
- each(['equipped', 'costume'], function resetUserGear (type) {
+ each(['equipped', 'costume'], type => {
gear[type] = {};
gear[type].armor = 'armor_base_0';
gear[type].weapon = 'weapon_warrior_0';
@@ -14,7 +14,7 @@ module.exports = function resetGear (user) {
// Gear.owned is (was) a Mongo object so the _.each function iterates over hidden properties.
// The content.gear.flat[k] check should prevent this causing an error
- each(gear.owned, function resetOwnedGear (v, k) {
+ each(gear.owned, (v, k) => {
if (gear.owned[k] && content.gear.flat[k] && content.gear.flat[k].value) {
gear.owned[k] = false;
}
@@ -24,4 +24,4 @@ module.exports = function resetGear (user) {
if (user.markModified) user.markModified('items.gear.owned');
user.preferences.costume = false;
-};
+}
diff --git a/website/common/script/fns/ultimateGear.js b/website/common/script/fns/ultimateGear.js
index ea5101bb97..969311e53a 100644
--- a/website/common/script/fns/ultimateGear.js
+++ b/website/common/script/fns/ultimateGear.js
@@ -1,15 +1,17 @@
-import content from '../content/index';
import lodashFind from 'lodash/find';
import reduce from 'lodash/reduce';
import includes from 'lodash/includes';
+import content from '../content/index';
-module.exports = function ultimateGear (user) {
- let owned = user.items.gear.owned.toObject ? user.items.gear.owned.toObject() : user.items.gear.owned;
+export default function ultimateGear (user) {
+ const owned = user.items.gear.owned.toObject
+ ? user.items.gear.owned.toObject()
+ : user.items.gear.owned;
- content.classes.forEach((klass) => {
+ content.classes.forEach(klass => {
if (user.achievements.ultimateGearSets[klass] !== true) {
user.achievements.ultimateGearSets[klass] = reduce(['armor', 'shield', 'head', 'weapon'], (soFarGood, type) => {
- let found = lodashFind(content.gear.tree[type][klass], {
+ const found = lodashFind(content.gear.tree[type][klass], {
last: true,
});
return soFarGood && (!found || owned[found.key] === true);
@@ -28,11 +30,9 @@ module.exports = function ultimateGear (user) {
ultimateGearSetValues = Object.values(user.achievements.ultimateGearSets);
}
- let hasFullSet = includes(ultimateGearSetValues, true);
+ const hasFullSet = includes(ultimateGearSetValues, true);
if (hasFullSet && user.flags.armoireEnabled !== true) {
user.flags.armoireEnabled = true;
}
-
- return;
-};
+}
diff --git a/website/common/script/fns/updateStats.js b/website/common/script/fns/updateStats.js
index 669fb46fd2..49ca605959 100644
--- a/website/common/script/fns/updateStats.js
+++ b/website/common/script/fns/updateStats.js
@@ -6,7 +6,7 @@ import {
import { toNextLevel } from '../statHelpers';
import autoAllocate from './autoAllocate';
-module.exports = function updateStats (user, stats, req = {}, analytics) {
+export default function updateStats (user, stats, req = {}, analytics) {
let allocatedStatPoints;
let totalStatPoints;
let experienceToNextLevel;
@@ -24,7 +24,7 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
while (stats.exp >= experienceToNextLevel) {
stats.exp -= experienceToNextLevel;
- user.stats.lvl++;
+ user.stats.lvl += 1;
experienceToNextLevel = toNextLevel(user.stats.lvl);
user.stats.hp = MAX_HEALTH;
@@ -71,7 +71,7 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
if (user.addNotification) user.addNotification('DROPS_ENABLED');
if (user.items.eggs.Wolf > 0) {
- user.items.eggs.Wolf++;
+ user.items.eggs.Wolf += 1;
} else {
user.items.eggs.Wolf = 1;
}
@@ -89,7 +89,7 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
if (user.markModified) user.markModified('flags.levelDrops');
if (!user.items.quests[k]) user.items.quests[k] = 0;
- user.items.quests[k]++;
+ user.items.quests[k] += 1;
if (user.markModified) user.markModified('items.quests');
if (analytics) {
@@ -111,4 +111,4 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
if (user.addNotification) user.addNotification('REBIRTH_ENABLED');
user.flags.rebirthEnabled = true;
}
-};
+}
diff --git a/website/common/script/i18n.js b/website/common/script/i18n.js
index 3b8331e892..782504cf87 100644
--- a/website/common/script/i18n.js
+++ b/website/common/script/i18n.js
@@ -2,24 +2,25 @@ import isString from 'lodash/isString';
import clone from 'lodash/clone';
import template from 'lodash/template';
-let i18n = {
+const i18n = {
strings: null,
translations: {},
t, // eslint-disable-line no-use-before-define
};
function t (stringName) {
- let vars = arguments[1];
+ const args = Array.from(arguments); // eslint-disable-line prefer-rest-params
+ let vars = args[1];
let locale;
- if (isString(arguments[1])) {
+ if (isString(args[1])) {
vars = null;
- locale = arguments[1];
- } else if (arguments[2]) {
- locale = arguments[2];
+ locale = args[1]; // eslint-disable-line prefer-destructuring
+ } else if (args[2]) {
+ locale = args[2]; // eslint-disable-line prefer-destructuring
}
- let i18nNotSetup = !i18n.strings && !i18n.translations[locale];
+ const i18nNotSetup = !i18n.strings && !i18n.translations[locale];
if (!locale || i18nNotSetup) {
locale = 'en';
@@ -33,7 +34,7 @@ function t (stringName) {
string = i18n.translations[locale] && i18n.translations[locale][stringName];
}
- let clonedVars = clone(vars) || {};
+ const clonedVars = clone(vars) || {};
clonedVars.locale = locale;
@@ -62,4 +63,4 @@ function t (stringName) {
}
}
-module.exports = i18n;
+export default i18n;
diff --git a/website/common/script/index.js b/website/common/script/index.js
index ea552db6a0..da23f74ee7 100644
--- a/website/common/script/index.js
+++ b/website/common/script/index.js
@@ -1,20 +1,16 @@
// When using a common module from the website or the server NEVER import the module directly
-// but access it through `api` (the main common) module, otherwise you would require the non transpiled version of the file in production.
-let api = module.exports = {};
-
+// but access it through `api` (the main common) module,
+// otherwise you would require the non transpiled version of the file in production.
import content from './content/index';
-api.content = content;
import * as errors from './libs/errors';
-api.errors = errors;
import i18n from './i18n';
-api.i18n = i18n;
+
+import commonErrors from './errors/commonErrorMessages';
+import apiErrors from './errors/apiErrorMessages';
// TODO under api.libs.cron?
import { shouldDo, daysSince, DAY_MAPPING } from './cron';
-api.shouldDo = shouldDo;
-api.daysSince = daysSince;
-api.DAY_MAPPING = DAY_MAPPING;
import {
MAX_HEALTH,
@@ -34,48 +30,20 @@ import {
CHAT_FLAG_FROM_SHADOW_MUTE,
} from './constants';
-api.constants = {
- MAX_INCENTIVES,
- LARGE_GROUP_COUNT_MESSAGE_CUTOFF,
- MAX_SUMMARY_SIZE_FOR_GUILDS,
- MAX_SUMMARY_SIZE_FOR_CHALLENGES,
- MIN_SHORTNAME_SIZE_FOR_CHALLENGES,
- SUPPORTED_SOCIAL_NETWORKS,
- GUILDS_PER_PAGE,
- PARTY_LIMIT_MEMBERS,
- CHAT_FLAG_LIMIT_FOR_HIDING,
- CHAT_FLAG_FROM_MOD,
- CHAT_FLAG_FROM_SHADOW_MUTE,
-};
-// TODO Move these under api.constants
-api.maxLevel = MAX_LEVEL;
-api.maxHealth = MAX_HEALTH;
-api.maxStatPoints = MAX_STAT_POINTS;
-api.TAVERN_ID = TAVERN_ID;
-
// TODO under api.libs.statHelpers?
import * as statHelpers from './statHelpers';
-api.capByLevel = statHelpers.capByLevel;
-api.tnl = statHelpers.toNextLevel;
-api.diminishingReturns = statHelpers.diminishingReturns;
import splitWhitespace from './libs/splitWhitespace';
-api.$w = splitWhitespace;
import refPush from './libs/refPush';
-api.refPush = refPush;
import planGemLimits from './libs/planGemLimits';
-api.planGemLimits = planGemLimits;
import preenTodos from './libs/preenTodos';
-api.preenTodos = preenTodos;
import updateStore from './libs/updateStore';
-api.updateStore = updateStore;
import inAppRewards from './libs/inAppRewards';
-api.inAppRewards = inAppRewards;
import setDebuffPotionItems from './libs/setDebuffPotionItems';
api.setDebuffPotionItems = setDebuffPotionItems;
@@ -84,46 +52,32 @@ import getDebuffPotionItems from './libs/getDebuffPotionItems';
api.getDebuffPotionItems = getDebuffPotionItems;
import uuid from './libs/uuid';
-api.uuid = uuid;
import taskDefaults from './libs/taskDefaults';
-api.taskDefaults = taskDefaults;
import percent from './libs/percent';
-api.percent = percent;
import gold from './libs/gold';
-api.gold = gold;
import silver from './libs/silver';
-api.silver = silver;
import noTags from './libs/noTags';
-api.noTags = noTags;
import appliedTags from './libs/appliedTags';
-api.appliedTags = appliedTags;
import pickDeep from './libs/pickDeep';
-api.pickDeep = pickDeep;
-import count from './count';
-api.count = count;
+import * as count from './count';
import statsComputed from './libs/statsComputed';
-api.statsComputed = statsComputed;
import shops from './libs/shops';
-api.shops = shops;
import achievements from './libs/achievements';
-api.achievements = achievements;
import randomVal from './libs/randomVal';
-api.randomVal = randomVal;
import hasClass from './libs/hasClass';
-api.hasClass = hasClass;
import autoAllocate from './fns/autoAllocate';
import crit from './fns/crit';
@@ -134,17 +88,6 @@ import resetGear from './fns/resetGear';
import ultimateGear from './fns/ultimateGear';
import updateStats from './fns/updateStats';
-api.fns = {
- autoAllocate,
- crit,
- handleTwoHanded,
- predictableRandom,
- randomDrop,
- resetGear,
- ultimateGear,
- updateStats,
-};
-
import scoreTask from './ops/scoreTask';
import sleep from './ops/sleep';
import allocateNow from './ops/stats/allocateNow';
@@ -170,7 +113,68 @@ import blockUser from './ops/blockUser';
import reroll from './ops/reroll';
import reset from './ops/reset';
import markPmsRead from './ops/markPMSRead';
-import pinnedGearUtils from './ops/pinnedGearUtils';
+import * as pinnedGearUtils from './ops/pinnedGearUtils';
+
+const api = {};
+api.content = content;
+api.errors = errors;
+api.i18n = i18n;
+api.shouldDo = shouldDo;
+api.daysSince = daysSince;
+api.DAY_MAPPING = DAY_MAPPING;
+
+api.constants = {
+ MAX_INCENTIVES,
+ LARGE_GROUP_COUNT_MESSAGE_CUTOFF,
+ MAX_SUMMARY_SIZE_FOR_GUILDS,
+ MAX_SUMMARY_SIZE_FOR_CHALLENGES,
+ MIN_SHORTNAME_SIZE_FOR_CHALLENGES,
+ SUPPORTED_SOCIAL_NETWORKS,
+ GUILDS_PER_PAGE,
+ PARTY_LIMIT_MEMBERS,
+ CHAT_FLAG_LIMIT_FOR_HIDING,
+ CHAT_FLAG_FROM_MOD,
+ CHAT_FLAG_FROM_SHADOW_MUTE,
+};
+// TODO Move these under api.constants
+api.maxLevel = MAX_LEVEL;
+api.maxHealth = MAX_HEALTH;
+api.maxStatPoints = MAX_STAT_POINTS;
+api.TAVERN_ID = TAVERN_ID;
+api.capByLevel = statHelpers.capByLevel;
+api.tnl = statHelpers.toNextLevel;
+api.diminishingReturns = statHelpers.diminishingReturns;
+api.$w = splitWhitespace;
+api.refPush = refPush;
+api.planGemLimits = planGemLimits;
+api.preenTodos = preenTodos;
+api.updateStore = updateStore;
+api.inAppRewards = inAppRewards;
+api.uuid = uuid;
+api.taskDefaults = taskDefaults;
+api.percent = percent;
+api.gold = gold;
+api.silver = silver;
+api.noTags = noTags;
+api.appliedTags = appliedTags;
+api.pickDeep = pickDeep;
+api.count = count;
+api.statsComputed = statsComputed;
+api.shops = shops;
+api.achievements = achievements;
+api.randomVal = randomVal;
+api.hasClass = hasClass;
+
+api.fns = {
+ autoAllocate,
+ crit,
+ handleTwoHanded,
+ predictableRandom,
+ randomDrop,
+ resetGear,
+ ultimateGear,
+ updateStats,
+};
api.ops = {
scoreTask,
@@ -200,3 +204,10 @@ api.ops = {
markPmsRead,
pinnedGearUtils,
};
+
+api.errorMessages = {
+ common: commonErrors,
+ api: apiErrors,
+};
+
+export default api;
diff --git a/website/common/script/libs/achievements.js b/website/common/script/libs/achievements.js
index 64ac15b06c..c1e6048d3e 100644
--- a/website/common/script/libs/achievements.js
+++ b/website/common/script/libs/achievements.js
@@ -1,15 +1,16 @@
+import get from 'lodash/get';
import content from '../content/index';
import i18n from '../i18n';
-import get from 'lodash/get';
-let achievs = {};
-let achievsContent = content.achievements;
+const achievs = {};
+const achievsContent = content.achievements;
let index = 0;
function contribText (contrib, backer, language) {
- if (!contrib && !backer) return;
+ if (!contrib && !backer) return null;
if (backer && backer.npc) return backer.npc;
- let lvl = contrib && contrib.level;
+
+ const lvl = contrib && contrib.level;
if (lvl && lvl > 0) {
let contribTitle = '';
@@ -29,6 +30,8 @@ function contribText (contrib, backer, language) {
return `${contribTitle} ${contrib.text}`;
}
+
+ return null;
}
function _add (result, data) {
@@ -38,17 +41,17 @@ function _add (result, data) {
icon: data.icon,
earned: data.earned,
value: data.value,
- index: index++,
+ index: index += 1,
optionalCount: data.optionalCount,
};
}
function _addSimpleWithCustomPath (result, user, data) {
- let value = get(user, data.path);
- let thisContent = achievsContent[data.key];
+ const value = get(user, data.path);
+ const thisContent = achievsContent[data.key];
_add(result, {
- title: i18n.t(thisContent.titleKey, {key: value}, data.language),
+ title: i18n.t(thisContent.titleKey, { key: value }, data.language),
text: i18n.t(thisContent.textKey, data.language),
icon: thisContent.icon,
key: data.key,
@@ -64,10 +67,10 @@ function _addQuest (result, user, data) {
}
function _addSimple (result, user, data) {
- let value = user.achievements[data.path];
+ const value = user.achievements[data.path];
- let key = data.key || data.path;
- let thisContent = achievsContent[key];
+ const key = data.key || data.path;
+ const thisContent = achievsContent[key];
_add(result, {
title: i18n.t(thisContent.titleKey, data.language),
@@ -80,14 +83,14 @@ function _addSimple (result, user, data) {
}
function _addSimpleWithMasterCount (result, user, data) {
- let language = data.language;
- let value = user.achievements[`${data.path}Count`] || 0;
+ const { language } = data;
+ const value = user.achievements[`${data.path}Count`] || 0;
- let thisContent = achievsContent[data.path];
+ const thisContent = achievsContent[data.path];
let text = i18n.t(thisContent.textKey, language);
if (value > 0) {
- text += i18n.t(thisContent.text2Key, {count: value}, language);
+ text += i18n.t(thisContent.text2Key, { count: value }, language);
}
_add(result, {
@@ -102,14 +105,14 @@ function _addSimpleWithMasterCount (result, user, data) {
}
function _addSimpleWithCount (result, user, data) {
- let value = user.achievements[data.path] || 0;
+ const value = user.achievements[data.path] || 0;
- let key = data.key || data.path;
- let thisContent = achievsContent[key];
+ const key = data.key || data.path;
+ const thisContent = achievsContent[key];
_add(result, {
title: i18n.t(thisContent.titleKey, data.language),
- text: i18n.t(thisContent.textKey, {count: value}, data.language),
+ text: i18n.t(thisContent.textKey, { count: value }, data.language),
icon: thisContent.icon,
key,
value,
@@ -119,10 +122,10 @@ function _addSimpleWithCount (result, user, data) {
}
function _addPlural (result, user, data) {
- let value = user.achievements[data.path] || 0;
+ const value = user.achievements[data.path] || 0;
- let key = data.key || data.path;
- let thisContent = achievsContent[key];
+ const key = data.key || data.path;
+ const thisContent = achievsContent[key];
let titleKey;
let textKey;
@@ -137,8 +140,8 @@ function _addPlural (result, user, data) {
}
_add(result, {
- title: i18n.t(titleKey, {count: value}, data.language),
- text: i18n.t(textKey, {count: value}, data.language),
+ title: i18n.t(titleKey, { count: value }, data.language),
+ text: i18n.t(textKey, { count: value }, data.language),
icon: thisContent.icon,
key,
value,
@@ -152,14 +155,14 @@ function _addUltimateGear (result, user, data) {
data.altPath = data.path;
}
- let value = user.achievements.ultimateGearSets[data.altPath];
+ const value = user.achievements.ultimateGearSets[data.altPath];
- let key = `${data.path}UltimateGear`;
- let thisContent = achievsContent[key];
+ const key = `${data.path}UltimateGear`;
+ const thisContent = achievsContent[key];
- let localizedClass = i18n.t(data.path, data.language);
- let title = i18n.t(thisContent.titleKey, {ultClass: localizedClass}, data.language);
- let text = i18n.t(thisContent.textKey, {ultClass: localizedClass}, data.language);
+ const localizedClass = i18n.t(data.path, data.language);
+ const title = i18n.t(thisContent.titleKey, { ultClass: localizedClass }, data.language);
+ const text = i18n.t(thisContent.textKey, { ultClass: localizedClass }, data.language);
_add(result, {
title,
@@ -172,44 +175,46 @@ function _addUltimateGear (result, user, data) {
}
function _getBasicAchievements (user, language) {
- let result = {};
+ const result = {};
- _addPlural(result, user, {path: 'streak', language});
- _addPlural(result, user, {path: 'perfect', language});
+ _addPlural(result, user, { path: 'streak', language });
+ _addPlural(result, user, { path: 'perfect', language });
- _addSimple(result, user, {path: 'partyUp', language});
- _addSimple(result, user, {path: 'partyOn', language});
- _addSimple(result, user, {path: 'joinedGuild', language});
- _addSimple(result, user, {path: 'royallyLoyal', language});
- _addSimple(result, user, {path: 'joinedChallenge', language});
- _addSimple(result, user, {path: 'invitedFriend', language});
- _addSimple(result, user, {path: 'lostMasterclasser', language});
- _addSimple(result, user, {path: 'mindOverMatter', language});
- _addSimple(result, user, {path: 'justAddWater', language});
- _addSimple(result, user, {path: 'backToBasics', language});
- _addSimple(result, user, {path: 'allYourBase', language});
- _addSimple(result, user, {path: 'dustDevil', language});
- _addSimple(result, user, {path: 'aridAuthority', language});
+ _addSimple(result, user, { path: 'partyUp', language });
+ _addSimple(result, user, { path: 'partyOn', language });
+ _addSimple(result, user, { path: 'joinedGuild', language });
+ _addSimple(result, user, { path: 'royallyLoyal', language });
+ _addSimple(result, user, { path: 'joinedChallenge', language });
+ _addSimple(result, user, { path: 'invitedFriend', language });
+ _addSimple(result, user, { path: 'lostMasterclasser', language });
+ _addSimple(result, user, { path: 'mindOverMatter', language });
+ _addSimple(result, user, { path: 'justAddWater', language });
+ _addSimple(result, user, { path: 'backToBasics', language });
+ _addSimple(result, user, { path: 'allYourBase', language });
+ _addSimple(result, user, { path: 'dustDevil', language });
+ _addSimple(result, user, { path: 'aridAuthority', language });
+ _addSimple(result, user, { path: 'monsterMagus', language });
+ _addSimple(result, user, { path: 'undeadUndertaker', language });
- _addSimpleWithMasterCount(result, user, {path: 'beastMaster', language});
- _addSimpleWithMasterCount(result, user, {path: 'mountMaster', language});
- _addSimpleWithMasterCount(result, user, {path: 'triadBingo', language});
+ _addSimpleWithMasterCount(result, user, { path: 'beastMaster', language });
+ _addSimpleWithMasterCount(result, user, { path: 'mountMaster', language });
+ _addSimpleWithMasterCount(result, user, { path: 'triadBingo', language });
- _addUltimateGear(result, user, {path: 'healer', language});
- _addUltimateGear(result, user, {path: 'rogue', language});
- _addUltimateGear(result, user, {path: 'warrior', language});
- _addUltimateGear(result, user, {path: 'mage', altPath: 'wizard', language});
+ _addUltimateGear(result, user, { path: 'healer', language });
+ _addUltimateGear(result, user, { path: 'rogue', language });
+ _addUltimateGear(result, user, { path: 'warrior', language });
+ _addUltimateGear(result, user, { path: 'mage', altPath: 'wizard', language });
- let cardAchievements = ['greeting', 'thankyou', 'birthday', 'congrats', 'getwell', 'goodluck'];
+ const cardAchievements = ['greeting', 'thankyou', 'birthday', 'congrats', 'getwell', 'goodluck'];
cardAchievements.forEach(path => {
- _addSimpleWithCount(result, user, {path, key: `${path}Cards`, language});
+ _addSimpleWithCount(result, user, { path, key: `${path}Cards`, language });
});
let rebirthTitle;
let rebirthText;
if (user.achievements.rebirths > 1) {
- rebirthTitle = i18n.t('rebirthText', {rebirths: user.achievements.rebirths}, language);
+ rebirthTitle = i18n.t('rebirthText', { rebirths: user.achievements.rebirths }, language);
} else {
rebirthTitle = i18n.t('rebirthBegan', language);
}
@@ -217,7 +222,7 @@ function _getBasicAchievements (user, language) {
if (!user.achievements.rebirthLevel) {
rebirthText = i18n.t('rebirthOrbNoLevel', language);
} else if (user.achievements.rebirthLevel < 100) {
- rebirthText = i18n.t('rebirthOrb', {level: user.achievements.rebirthLevel}, language);
+ rebirthText = i18n.t('rebirthOrb', { level: user.achievements.rebirthLevel }, language);
} else {
rebirthText = i18n.t('rebirthOrb100', language);
}
@@ -235,41 +240,41 @@ function _getBasicAchievements (user, language) {
}
function _getSeasonalAchievements (user, language) {
- let result = {};
+ const result = {};
- _addPlural(result, user, {path: 'habiticaDays', language});
- _addPlural(result, user, {path: 'habitBirthdays', language});
+ _addPlural(result, user, { path: 'habiticaDays', language });
+ _addPlural(result, user, { path: 'habitBirthdays', language });
- let spellAchievements = ['snowball', 'spookySparkles', 'shinySeed', 'seafoam'];
+ const spellAchievements = ['snowball', 'spookySparkles', 'shinySeed', 'seafoam'];
spellAchievements.forEach(path => {
- _addSimpleWithCount(result, user, {path, language});
+ _addSimpleWithCount(result, user, { path, language });
});
- let questAchievements = ['dilatory', 'stressbeast', 'burnout', 'bewilder', 'dysheartener'];
+ const questAchievements = ['dilatory', 'stressbeast', 'burnout', 'bewilder', 'dysheartener'];
questAchievements.forEach(path => {
if (user.achievements.quests[path]) {
- _addQuest(result, user, {path, language});
+ _addQuest(result, user, { path, language });
}
});
- _addPlural(result, user, {path: 'costumeContests', language});
+ _addPlural(result, user, { path: 'costumeContests', language });
- let cardAchievements = ['nye', 'valentine'];
+ const cardAchievements = ['nye', 'valentine'];
cardAchievements.forEach(path => {
- _addSimpleWithCount(result, user, {path, key: `${path}Cards`, language});
+ _addSimpleWithCount(result, user, { path, key: `${path}Cards`, language });
});
return result;
}
function _getSpecialAchievements (user, language) {
- let result = {};
+ const result = {};
- _addPlural(result, user, {path: 'habitSurveys', language});
+ _addPlural(result, user, { path: 'habitSurveys', language });
- let contribKey = 'contributor';
- let contribContent = achievsContent[contribKey];
- let contributorAchiev = {
+ const contribKey = 'contributor';
+ const contribContent = achievsContent[contribKey];
+ const contributorAchiev = {
key: contribKey,
text: i18n.t(contribContent.textKey, language),
icon: contribContent.icon,
@@ -285,23 +290,23 @@ function _getSpecialAchievements (user, language) {
_add(result, contributorAchiev);
if (user.backer && user.backer.npc) {
- _addSimpleWithCustomPath(result, user, {key: 'npc', path: 'backer.npc', language});
+ _addSimpleWithCustomPath(result, user, { key: 'npc', path: 'backer.npc', language });
}
if (user.backer && user.backer.tier) {
- _addSimpleWithCustomPath(result, user, {key: 'kickstarter', path: 'backer.tier', language});
+ _addSimpleWithCustomPath(result, user, { key: 'kickstarter', path: 'backer.tier', language });
}
if (user.achievements.veteran) {
- _addSimple(result, user, {path: 'veteran', language});
+ _addSimple(result, user, { path: 'veteran', language });
}
if (user.achievements.originalUser) {
- _addSimple(result, user, {path: 'originalUser', language});
+ _addSimple(result, user, { path: 'originalUser', language });
}
if (user.achievements.kickstarter2019) {
- _addSimple(result, user, {path: 'kickstarter2019', language});
+ _addSimple(result, user, { path: 'kickstarter2019', language });
}
return result;
@@ -309,7 +314,7 @@ function _getSpecialAchievements (user, language) {
// Build and return the given user's achievement data.
achievs.getAchievementsForProfile = function getAchievementsForProfile (user, language) {
- let result = {
+ const result = {
basic: {
label: 'Basic',
achievements: _getBasicAchievements(user, language),
@@ -328,4 +333,4 @@ achievs.getAchievementsForProfile = function getAchievementsForProfile (user, la
achievs.getContribText = contribText;
-module.exports = achievs;
+export default achievs;
diff --git a/website/common/script/libs/appliedTags.js b/website/common/script/libs/appliedTags.js
index ded2a9de23..cfbb8da2cc 100644
--- a/website/common/script/libs/appliedTags.js
+++ b/website/common/script/libs/appliedTags.js
@@ -4,11 +4,7 @@ Are there tags applied?
// TODO move to client
-module.exports = function appliedTags (userTags, taskTags = []) {
- let arr = userTags.filter(tag => {
- return taskTags.indexOf(tag.id) !== -1;
- }).map(tag => {
- return tag.name;
- });
+export default function appliedTags (userTags, taskTags = []) {
+ const arr = userTags.filter(tag => taskTags.indexOf(tag.id) !== -1).map(tag => tag.name);
return arr.join(', ');
-};
+}
diff --git a/website/common/script/libs/dotGet.js b/website/common/script/libs/dotGet.js
index 589792755a..abcf80ad65 100644
--- a/website/common/script/libs/dotGet.js
+++ b/website/common/script/libs/dotGet.js
@@ -2,4 +2,4 @@ import get from 'lodash/get';
// TODO remove completely, only used in client
-module.exports = get;
+export default get;
diff --git a/website/common/script/libs/dotSet.js b/website/common/script/libs/dotSet.js
index db88f19619..78234a2d49 100644
--- a/website/common/script/libs/dotSet.js
+++ b/website/common/script/libs/dotSet.js
@@ -2,4 +2,4 @@ import set from 'lodash/set';
// TODO remove completely, only used in client
-module.exports = set;
+export default set;
diff --git a/website/common/script/libs/errorMessage.js b/website/common/script/libs/errorMessage.js
index d083e6cdfa..bac71bd265 100644
--- a/website/common/script/libs/errorMessage.js
+++ b/website/common/script/libs/errorMessage.js
@@ -3,13 +3,13 @@
import _clone from 'lodash/clone';
import _template from 'lodash/template';
-import messages from '../../errors/commonErrorMessages';
+import messages from '../errors/commonErrorMessages';
export default function (msgKey, vars = {}) {
- let message = messages[msgKey];
+ const message = messages[msgKey];
if (!message) throw new Error(`Error processing the common message "${msgKey}".`);
- let clonedVars = vars ? _clone(vars) : {};
+ const clonedVars = vars ? _clone(vars) : {};
// TODO cache the result of template() ? More memory usage, faster output
return _template(message)(clonedVars);
diff --git a/website/common/script/libs/errors.js b/website/common/script/libs/errors.js
index 8e82afa7a8..acdbe237d2 100644
--- a/website/common/script/libs/errors.js
+++ b/website/common/script/libs/errors.js
@@ -1,3 +1,4 @@
+/* eslint-disable max-classes-per-file */
import extendableBuiltin from './extendableBuiltin';
// Base class for custom application errors
diff --git a/website/common/script/libs/extendableBuiltin.js b/website/common/script/libs/extendableBuiltin.js
index 56186301c4..b6af4adb4c 100644
--- a/website/common/script/libs/extendableBuiltin.js
+++ b/website/common/script/libs/extendableBuiltin.js
@@ -1,11 +1,12 @@
+// TODO use https://babeljs.io/docs/en/babel-plugin-transform-classes
// Babel 6 doesn't support extending native class (Error, Array, ...)
// This function makes it possible to extend native classes with the same results as Babel 5
-module.exports = function extendableBuiltin (klass) {
+export default function extendableBuiltin (klass) {
function ExtendableBuiltin () {
- klass.apply(this, arguments);
+ klass.apply(this, arguments); // eslint-disable-line prefer-rest-params
}
ExtendableBuiltin.prototype = Object.create(klass.prototype);
Object.setPrototypeOf(ExtendableBuiltin, klass);
return ExtendableBuiltin;
-};
+}
diff --git a/website/common/script/libs/getItemByPathAndType.js b/website/common/script/libs/getItemByPathAndType.js
index 9e844cff3b..039593e5b0 100644
--- a/website/common/script/libs/getItemByPathAndType.js
+++ b/website/common/script/libs/getItemByPathAndType.js
@@ -1,11 +1,11 @@
-import content from '../content/index';
import get from 'lodash/get';
+import content from '../content/index';
-module.exports = function getItemByPathAndType (type, path) {
+export default function getItemByPathAndType (type, path) {
let item = get(content, path);
if (type === 'timeTravelersStable') {
- let [, animalType, key] = path.split('.');
+ const [, animalType, key] = path.split('.');
item = {
key,
@@ -14,4 +14,4 @@ module.exports = function getItemByPathAndType (type, path) {
}
return item;
-};
+}
diff --git a/website/common/script/libs/getItemInfo.js b/website/common/script/libs/getItemInfo.js
index d71b99f0d1..16228f5f16 100644
--- a/website/common/script/libs/getItemInfo.js
+++ b/website/common/script/libs/getItemInfo.js
@@ -1,13 +1,13 @@
+import _mapValues from 'lodash/mapValues';
import i18n from '../i18n';
import content from '../content/index';
import { BadRequest } from './errors';
-import count from '../count';
+import * as count from '../count';
import isPinned from './isPinned';
import isFreeRebirth from './isFreeRebirth';
import getOfficialPinnedItems from './getOfficialPinnedItems';
-import _mapValues from 'lodash/mapValues';
function lockQuest (quest, user) {
if (quest.key === 'lostMasterclasser1') return !(user.achievements.quests.dilatoryDistress3 && user.achievements.quests.mayhemMistiflying3 && user.achievements.quests.stoikalmCalamity3 && user.achievements.quests.taskwoodsTerror3);
@@ -20,7 +20,7 @@ function lockQuest (quest, user) {
}
function isItemSuggested (officialPinnedItems, itemInfo) {
- return officialPinnedItems.findIndex(officialItem => {
+ return officialPinnedItems.findIndex(officialItem => { // eslint-disable-line arrow-body-style
return officialItem.type === itemInfo.pinType && officialItem.path === itemInfo.path;
}) > -1;
}
@@ -46,18 +46,18 @@ function getDefaultGearProps (item, language) {
};
}
-module.exports = function getItemInfo (user, type, item, officialPinnedItems, language = 'en') {
+export default function getItemInfo (user, type, item, officialPinnedItems, language = 'en') {
if (officialPinnedItems === undefined) {
- officialPinnedItems = getOfficialPinnedItems(user);
+ officialPinnedItems = getOfficialPinnedItems(user); // eslint-disable-line no-param-reassign
}
let itemInfo;
- switch (type) {
+ switch (type) { // eslint-disable-line default-case
case 'eggs':
itemInfo = {
key: item.key,
- text: i18n.t('egg', {eggType: item.text(language)}, language),
+ text: i18n.t('egg', { eggType: item.text(language) }, language),
notes: item.notes(language),
value: item.value,
class: `Pet_Egg_${item.key}`,
@@ -71,7 +71,7 @@ module.exports = function getItemInfo (user, type, item, officialPinnedItems, la
case 'hatchingPotions':
itemInfo = {
key: item.key,
- text: i18n.t('potion', {potionType: item.text(language)}),
+ text: i18n.t('potion', { potionType: item.text(language) }),
notes: item.notes(language),
class: `Pet_HatchingPotion_${item.key}`,
value: item.value,
@@ -85,7 +85,7 @@ module.exports = function getItemInfo (user, type, item, officialPinnedItems, la
case 'premiumHatchingPotion':
itemInfo = {
key: item.key,
- text: i18n.t('potion', {potionType: item.text(language)}),
+ text: i18n.t('potion', { potionType: item.text(language) }),
notes: `${item.notes(language)} ${item._addlNotes(language)}`,
class: `Pet_HatchingPotion_${item.key}`,
value: item.value,
@@ -124,7 +124,7 @@ module.exports = function getItemInfo (user, type, item, officialPinnedItems, la
};
break;
case 'quests': // eslint-disable-line no-case-declarations
- const locked = lockQuest(item, user);
+ const locked = lockQuest(item, user); // eslint-disable-line no-case-declarations
itemInfo = {
key: item.key,
@@ -133,16 +133,16 @@ module.exports = function getItemInfo (user, type, item, officialPinnedItems, la
group: item.group,
value: item.goldValue ? item.goldValue : item.value,
locked,
- previous: content.quests[item.previous] ? content.quests[item.previous].text(language) : null,
+ previous: content.quests[item.previous]
+ ? content.quests[item.previous].text(language)
+ : null,
unlockCondition: item.unlockCondition,
drop: item.drop,
boss: item.boss,
- collect: item.collect ? _mapValues(item.collect, (o) => {
- return {
- count: o.count,
- text: o.text(),
- };
- }) : undefined,
+ collect: item.collect ? _mapValues(item.collect, o => ({
+ count: o.count,
+ text: o.text(),
+ })) : undefined,
lvl: item.lvl,
class: locked ? `inventory_quest_scroll_${item.key}_locked` : `inventory_quest_scroll_${item.key}`,
purchaseType: 'quests',
@@ -283,7 +283,7 @@ module.exports = function getItemInfo (user, type, item, officialPinnedItems, la
};
break;
case 'card': {
- let spellInfo = content.spells.special[item.key];
+ const spellInfo = content.spells.special[item.key];
itemInfo = {
key: item.key,
@@ -366,8 +366,8 @@ module.exports = function getItemInfo (user, type, item, officialPinnedItems, la
itemInfo.isSuggested = isItemSuggested(officialPinnedItems, itemInfo);
itemInfo.pinned = isPinned(user, itemInfo, officialPinnedItems);
} else {
- throw new BadRequest(i18n.t('wrongItemType', {type}, language));
+ throw new BadRequest(i18n.t('wrongItemType', { type }, language));
}
return itemInfo;
-};
+}
diff --git a/website/common/script/libs/getOfficialPinnedItems.js b/website/common/script/libs/getOfficialPinnedItems.js
index 7e0826d7a0..72f27b0534 100644
--- a/website/common/script/libs/getOfficialPinnedItems.js
+++ b/website/common/script/libs/getOfficialPinnedItems.js
@@ -1,28 +1,28 @@
-import content from '../content/index';
-import SeasonalShopConfig from '../libs/shops-seasonal.config';
import toArray from 'lodash/toArray';
+import content from '../content/index';
+import SeasonalShopConfig from './shops-seasonal.config';
-const officialPinnedItems = content.officialPinnedItems;
+const { officialPinnedItems } = content;
-let flatGearArray = toArray(content.gear.flat);
+const flatGearArray = toArray(content.gear.flat);
-module.exports = function getOfficialPinnedItems (user) {
- let officialItemsArray = [...officialPinnedItems];
+export default function getOfficialPinnedItems (user) {
+ const officialItemsArray = [...officialPinnedItems];
if (SeasonalShopConfig.pinnedSets && Boolean(user) && user.stats.class) {
- let setToAdd = SeasonalShopConfig.pinnedSets[user.stats.class];
+ const setToAdd = SeasonalShopConfig.pinnedSets[user.stats.class];
// pinnedSets == current seasonal class set are always gold purchaseable
- flatGearArray.filter((gear) => {
- return user.items.gear.owned[gear.key] === undefined && gear.set === setToAdd;
- }).map((gear) => {
- officialItemsArray.push({
- type: 'marketGear',
- path: `gear.flat.${gear.key}`,
+ flatGearArray
+ .filter(gear => user.items.gear.owned[gear.key] === undefined && gear.set === setToAdd)
+ .forEach(gear => {
+ officialItemsArray.push({
+ type: 'marketGear',
+ path: `gear.flat.${gear.key}`,
+ });
});
- });
}
return officialItemsArray;
-};
+}
diff --git a/website/common/script/libs/gold.js b/website/common/script/libs/gold.js
index 83d9531d5e..0553035d25 100644
--- a/website/common/script/libs/gold.js
+++ b/website/common/script/libs/gold.js
@@ -1,9 +1,8 @@
// TODO move to client
-module.exports = function gold (num) {
+export default function gold (num) {
if (num) {
return Math.floor(num);
- } else {
- return '0';
}
-};
+ return '0';
+}
diff --git a/website/common/script/libs/hasClass.js b/website/common/script/libs/hasClass.js
index f9eeabfd5a..9f0b84e2d3 100644
--- a/website/common/script/libs/hasClass.js
+++ b/website/common/script/libs/hasClass.js
@@ -1,8 +1,8 @@
// Check if user has Class system enabled
-module.exports = function hasClass (member) {
+export default function hasClass (member) {
return (
- member.stats.lvl >= 10 &&
- !member.preferences.disableClasses &&
- member.flags.classSelected
+ member.stats.lvl >= 10
+ && !member.preferences.disableClasses
+ && member.flags.classSelected
);
-};
+}
diff --git a/website/common/script/libs/inAppRewards.js b/website/common/script/libs/inAppRewards.js
index 203df6cf7c..a0ffaf91da 100644
--- a/website/common/script/libs/inAppRewards.js
+++ b/website/common/script/libs/inAppRewards.js
@@ -1,10 +1,10 @@
+import compactArray from 'lodash/compact';
import getItemInfo from './getItemInfo';
import shops from './shops';
import getOfficialPinnedItems from './getOfficialPinnedItems';
-import compactArray from 'lodash/compact';
import getItemByPathAndType from './getItemByPathAndType';
-import {checkPinnedAreasForNullEntries} from '../ops/pinnedGearUtils';
+import { checkPinnedAreasForNullEntries } from '../ops/pinnedGearUtils';
/**
* Orders the pinned items so we always get our inAppRewards in the order
@@ -15,12 +15,12 @@ import {checkPinnedAreasForNullEntries} from '../ops/pinnedGearUtils';
* @return items of ordered inAppRewards
*/
function sortInAppRewards (user, items) {
- let pinnedItemsOrder = user.pinnedItemsOrder;
+ const { pinnedItemsOrder } = user;
let orderedItems = [];
- let unorderedItems = []; // what we want to add later
+ const unorderedItems = []; // what we want to add later
items.forEach((item, index) => {
- let i = pinnedItemsOrder[index] === item.path ? index : pinnedItemsOrder.indexOf(item.path);
+ const i = pinnedItemsOrder[index] === item.path ? index : pinnedItemsOrder.indexOf(item.path);
if (i === -1) {
unorderedItems.push(item);
} else {
@@ -32,27 +32,28 @@ function sortInAppRewards (user, items) {
return orderedItems;
}
-module.exports = function getPinnedItems (user) {
+export default function getPinnedItems (user) {
checkPinnedAreasForNullEntries(user);
- let officialPinnedItems = getOfficialPinnedItems(user);
+ const officialPinnedItems = getOfficialPinnedItems(user);
const officialPinnedItemsNotUnpinned = officialPinnedItems.filter(officialPin => {
- const isUnpinned = user.unpinnedItems.findIndex(unpinned => unpinned.path === officialPin.path) > -1;
+ const isUnpinned = user.unpinnedItems
+ .findIndex(unpinned => unpinned.path === officialPin.path) > -1;
return !isUnpinned;
});
const pinnedItems = officialPinnedItemsNotUnpinned.concat(user.pinnedItems);
- let items = pinnedItems
- .map(({type, path}) => {
- let item = getItemByPathAndType(type, path);
+ const items = pinnedItems
+ .map(({ type, path }) => {
+ const item = getItemByPathAndType(type, path);
return getItemInfo(user, type, item, officialPinnedItems);
});
shops.checkMarketGearLocked(user, items);
- let orderedItems = sortInAppRewards(user, items);
+ const orderedItems = sortInAppRewards(user, items);
return orderedItems;
-};
+}
diff --git a/website/common/script/libs/isFreeRebirth.js b/website/common/script/libs/isFreeRebirth.js
index 16a42c2c63..e7425322de 100644
--- a/website/common/script/libs/isFreeRebirth.js
+++ b/website/common/script/libs/isFreeRebirth.js
@@ -1,7 +1,7 @@
import moment from 'moment';
import { MAX_LEVEL } from '../constants';
-module.exports = function isFreeRebirth (user) {
+export default function isFreeRebirth (user) {
let daysFromLastFreeRebirth = user.flags.lastFreeRebirth;
if (daysFromLastFreeRebirth) {
@@ -11,4 +11,4 @@ module.exports = function isFreeRebirth (user) {
}
return user.stats.lvl >= MAX_LEVEL && daysFromLastFreeRebirth > 45;
-};
+}
diff --git a/website/common/script/libs/isPinned.js b/website/common/script/libs/isPinned.js
index 92a9ff5e2c..bb06c8b817 100644
--- a/website/common/script/libs/isPinned.js
+++ b/website/common/script/libs/isPinned.js
@@ -1,14 +1,14 @@
+export default function isPinned (user, item, checkOfficialPinnedItems) {
+ if (user === null) return false;
-module.exports = function isPinned (user, item, checkOfficialPinnedItems /* getOfficialPinnedItems */) {
- if (user === null)
- return false;
+ const isPinnedOfficial = checkOfficialPinnedItems !== undefined
+ && checkOfficialPinnedItems.findIndex(pinned => pinned.path === item.path) > -1;
+ const isItemUnpinned = user.unpinnedItems !== undefined
+ && user.unpinnedItems.findIndex(unpinned => unpinned.path === item.path) > -1;
+ const isItemPinned = user.pinnedItems !== undefined
+ && user.pinnedItems.findIndex(pinned => pinned.path === item.path) > -1;
- const isPinnedOfficial = checkOfficialPinnedItems !== undefined && checkOfficialPinnedItems.findIndex(pinned => pinned.path === item.path) > -1;
- const isItemUnpinned = user.unpinnedItems !== undefined && user.unpinnedItems.findIndex(unpinned => unpinned.path === item.path) > -1;
- const isItemPinned = user.pinnedItems !== undefined && user.pinnedItems.findIndex(pinned => pinned.path === item.path) > -1;
-
- if (isPinnedOfficial && !isItemUnpinned)
- return true;
+ if (isPinnedOfficial && !isItemUnpinned) return true;
return isItemPinned;
-};
+}
diff --git a/website/common/script/libs/noTags.js b/website/common/script/libs/noTags.js
index a31f6ad0d5..aff2d45b8f 100644
--- a/website/common/script/libs/noTags.js
+++ b/website/common/script/libs/noTags.js
@@ -7,8 +7,6 @@ are any tags active?
// TODO move to client
-module.exports = function noTags (tags) {
- return isEmpty(tags) || isEmpty(filter(tags, (t) => {
- return t;
- }));
-};
+export default function noTags (tags) {
+ return isEmpty(tags) || isEmpty(filter(tags, t => t));
+}
diff --git a/website/common/script/libs/percent.js b/website/common/script/libs/percent.js
index d7622474dd..c50fa26c06 100644
--- a/website/common/script/libs/percent.js
+++ b/website/common/script/libs/percent.js
@@ -1,6 +1,6 @@
// TODO move to client
-module.exports = function percent (x, y, dir) {
+export default function percent (x, y, dir) {
let roundFn;
switch (dir) {
case 'up':
@@ -13,7 +13,7 @@ module.exports = function percent (x, y, dir) {
roundFn = Math.round;
}
if (x === 0) {
- x = 1;
+ x = 1; // eslint-disable-line no-param-reassign
}
- return Math.max(0, roundFn(x / y * 100));
-};
+ return Math.max(0, roundFn((x / y) * 100));
+}
diff --git a/website/common/script/libs/pickDeep.js b/website/common/script/libs/pickDeep.js
index 7b4ccacc00..24eaf07275 100644
--- a/website/common/script/libs/pickDeep.js
+++ b/website/common/script/libs/pickDeep.js
@@ -5,11 +5,11 @@ import each from 'lodash/each';
import set from 'lodash/set';
import get from 'lodash/get';
-module.exports = function pickDeep (obj, properties) {
+export default function pickDeep (obj, properties) {
if (!Array.isArray(properties)) throw new Error('"properties" must be an array');
- let result = {};
- each(properties, (prop) => set(result, prop, get(obj, prop)));
+ const result = {};
+ each(properties, prop => set(result, prop, get(obj, prop)));
return result;
-};
+}
diff --git a/website/common/script/libs/planGemLimits.js b/website/common/script/libs/planGemLimits.js
index e719c7695d..2824598947 100644
--- a/website/common/script/libs/planGemLimits.js
+++ b/website/common/script/libs/planGemLimits.js
@@ -1,4 +1,4 @@
-module.exports = {
+export default {
convRate: 20,
convCap: 25,
};
diff --git a/website/common/script/libs/preenTodos.js b/website/common/script/libs/preenTodos.js
index 93d57d13e2..b1e3c6419c 100644
--- a/website/common/script/libs/preenTodos.js
+++ b/website/common/script/libs/preenTodos.js
@@ -3,10 +3,8 @@ import filter from 'lodash/filter';
// TODO used only in v2
-module.exports = function preenTodos (tasks) {
- return filter(tasks, (t) => {
- return !t.completed || t.challenge && t.challenge.id || moment(t.dateCompleted).isAfter(moment().subtract({
- days: 3,
- }));
- });
-};
+export default function preenTodos (tasks) {
+ return filter(tasks, t => !t.completed || t.challenge && t.challenge.id || moment(t.dateCompleted).isAfter(moment().subtract({ // eslint-disable-line
+ days: 3,
+ })));
+}
diff --git a/website/common/script/libs/randomVal.js b/website/common/script/libs/randomVal.js
index 49cbf6aba9..acd13ebb59 100644
--- a/website/common/script/libs/randomVal.js
+++ b/website/common/script/libs/randomVal.js
@@ -1,21 +1,19 @@
import values from 'lodash/values';
import keys from 'lodash/keys';
-function trueRandom () {
+export function trueRandom () {
return Math.random();
}
// Get a random property from an object
// returns random property (the value)
-module.exports = function randomVal (obj, options = {}) {
- let array = options.key ? keys(obj) : values(obj);
- let random = options.predictableRandom || trueRandom();
+export default function randomVal (obj, options = {}) {
+ const array = options.key ? keys(obj) : values(obj);
+ const random = options.predictableRandom || trueRandom();
array.sort();
- let randomIndex = Math.floor(random * array.length);
+ const randomIndex = Math.floor(random * array.length);
return array[randomIndex];
-};
-
-module.exports.trueRandom = trueRandom;
+}
diff --git a/website/common/script/libs/refPush.js b/website/common/script/libs/refPush.js
index 1a9bb39698..6451a7b4a5 100644
--- a/website/common/script/libs/refPush.js
+++ b/website/common/script/libs/refPush.js
@@ -4,12 +4,14 @@ import values from 'lodash/values';
import uuid from './uuid';
/*
- Reflists are arrays, but stored as objects. Mongoose has a helluvatime working with arrays (the main problem for our
- syncing issues) - so the goal is to move away from arrays to objects, since mongoose can reference elements by ID
+ Reflists are arrays, but stored as objects.
+ Mongoose has a helluvatime working with arrays (the main problem for our
+ syncing issues) - so the goal is to move away from arrays to objects,
+ since mongoose can reference elements by ID
no problem. To maintain sorting, we use these helper functions:
*/
-module.exports = function refPush (reflist, item) {
+export default function refPush (reflist, item) {
item.sort = isEmpty(reflist) ? 0 : maxBy(values(reflist), 'sort').sort + 1;
if (!(item.id && !reflist[item.id])) {
@@ -19,4 +21,4 @@ module.exports = function refPush (reflist, item) {
reflist[item.id] = item;
return reflist[item.id];
-};
+}
diff --git a/website/common/script/libs/shops-seasonal.config.js b/website/common/script/libs/shops-seasonal.config.js
index 169ad8999f..1ffb23cd0b 100644
--- a/website/common/script/libs/shops-seasonal.config.js
+++ b/website/common/script/libs/shops-seasonal.config.js
@@ -1,6 +1,6 @@
import { SEASONAL_SETS } from '../content/constants';
-module.exports = {
+export default {
opened: true,
currentSeason: 'Fall',
diff --git a/website/common/script/libs/shops.js b/website/common/script/libs/shops.js
index dda9ca7c11..9fd1a7e27c 100644
--- a/website/common/script/libs/shops.js
+++ b/website/common/script/libs/shops.js
@@ -17,7 +17,7 @@ import featuredItems from '../content/shop-featuredItems';
import getOfficialPinnedItems from './getOfficialPinnedItems';
-let shops = {};
+const shops = {};
/* Market */
@@ -30,18 +30,16 @@ shops.getMarketShop = function getMarketShop (user, language) {
categories: shops.getMarketCategories(user, language),
featured: {
text: i18n.t('featuredItems'),
- items: featuredItems.market.map(i => {
- return getItemInfo(user, i.type, get(content, i.path));
- }),
+ items: featuredItems.market.map(i => getItemInfo(user, i.type, get(content, i.path))),
},
};
};
shops.getMarketCategories = function getMarket (user, language) {
- let officialPinnedItems = getOfficialPinnedItems(user);
+ const officialPinnedItems = getOfficialPinnedItems(user);
- let categories = [];
- let eggsCategory = {
+ const categories = [];
+ const eggsCategory = {
identifier: 'eggs',
text: i18n.t('eggs', language),
notes: i18n.t('dropsExplanationEggs', language),
@@ -50,47 +48,39 @@ shops.getMarketCategories = function getMarket (user, language) {
eggsCategory.items = sortBy(values(content.questEggs)
.filter(egg => egg.canBuy(user))
.concat(values(content.dropEggs))
- .map(egg => {
- return getItemInfo(user, 'eggs', egg, officialPinnedItems, language);
- }), 'key');
+ .map(egg => getItemInfo(user, 'eggs', egg, officialPinnedItems, language)), 'key');
categories.push(eggsCategory);
- let hatchingPotionsCategory = {
+ const hatchingPotionsCategory = {
identifier: 'hatchingPotions',
text: i18n.t('hatchingPotions', language),
notes: i18n.t('dropsExplanation', language),
};
hatchingPotionsCategory.items = sortBy(values(content.hatchingPotions)
.filter(hp => !hp.limited)
- .map(hatchingPotion => {
- return getItemInfo(user, 'hatchingPotions', hatchingPotion, officialPinnedItems, language);
- }), 'key');
+ .map(hatchingPotion => getItemInfo(user, 'hatchingPotions', hatchingPotion, officialPinnedItems, language)), 'key');
categories.push(hatchingPotionsCategory);
- let premiumHatchingPotionsCategory = {
+ const premiumHatchingPotionsCategory = {
identifier: 'premiumHatchingPotions',
text: i18n.t('magicHatchingPotions', language),
notes: i18n.t('premiumPotionNoDropExplanation', language),
};
premiumHatchingPotionsCategory.items = sortBy(values(content.hatchingPotions)
.filter(hp => hp.limited && hp.canBuy(user))
- .map(premiumHatchingPotion => {
- return getItemInfo(user, 'premiumHatchingPotion', premiumHatchingPotion, officialPinnedItems, language);
- }), 'key');
+ .map(premiumHatchingPotion => getItemInfo(user, 'premiumHatchingPotion', premiumHatchingPotion, officialPinnedItems, language)), 'key');
if (premiumHatchingPotionsCategory.items.length > 0) {
categories.push(premiumHatchingPotionsCategory);
}
- let foodCategory = {
+ const foodCategory = {
identifier: 'food',
text: i18n.t('food', language),
notes: i18n.t('dropsExplanation', language),
};
foodCategory.items = sortBy(values(content.food)
.filter(food => food.canDrop || food.key === 'Saddle')
- .map(foodItem => {
- return getItemInfo(user, 'food', foodItem, officialPinnedItems, language);
- }), 'key');
+ .map(foodItem => getItemInfo(user, 'food', foodItem, officialPinnedItems, language)), 'key');
categories.push(foodCategory);
return categories;
@@ -99,27 +89,26 @@ shops.getMarketCategories = function getMarket (user, language) {
function getClassName (classType, language) {
if (classType === 'wizard') {
return i18n.t('mage', language);
- } else {
- return i18n.t(classType, language);
}
+ return i18n.t(classType, language);
}
// TODO Refactor the `.locked` logic
shops.checkMarketGearLocked = function checkMarketGearLocked (user, items) {
- let result = filter(items, ['pinType', 'marketGear']);
+ const result = filter(items, ['pinType', 'marketGear']);
const officialPinnedItems = getOfficialPinnedItems(user);
- let availableGear = map(updateStore(user), (item) => getItemInfo(user, 'marketGear', item, officialPinnedItems).path);
- for (let gear of result) {
+ const availableGear = map(updateStore(user), item => getItemInfo(user, 'marketGear', item, officialPinnedItems).path);
+ for (const gear of result) {
if (gear.klass !== user.stats.class) {
gear.locked = true;
}
- if (!gear.locked && !availableGear.includes(gear.path)) {
+ if (!gear.locked && !availableGear.includes(gear.path)) {
gear.locked = true;
}
if (Boolean(gear.specialClass) && Boolean(gear.set)) {
- let currentSet = gear.set === seasonalShopConfig.pinnedSets[gear.specialClass];
+ const currentSet = gear.set === seasonalShopConfig.pinnedSets[gear.specialClass];
gear.locked = currentSet && user.stats.class !== gear.specialClass;
}
@@ -128,7 +117,7 @@ shops.checkMarketGearLocked = function checkMarketGearLocked (user, items) {
gear.locked = !gear.canOwn(user);
}
- let itemOwned = user.items.gear.owned[gear.key];
+ const itemOwned = user.items.gear.owned[gear.key];
if (itemOwned === false && !availableGear.includes(gear.path)) {
gear.locked = true;
@@ -145,37 +134,37 @@ shops.checkMarketGearLocked = function checkMarketGearLocked (user, items) {
};
shops.getMarketGearCategories = function getMarketGear (user, language) {
- let categories = [];
- let officialPinnedItems = getOfficialPinnedItems(user);
+ const categories = [];
+ const officialPinnedItems = getOfficialPinnedItems(user);
- for (let classType of content.classes) {
- let category = {
+ for (const classType of content.classes) {
+ const category = {
identifier: classType,
text: getClassName(classType, language),
};
- let result = filter(content.gear.flat, function findClassGear (gearItem) {
+ const result = filter(content.gear.flat, gearItem => {
if (gearItem.klass === classType) return true;
- let classShift = {
+ const classShift = {
items: user.items,
stats: {
class: classType,
},
};
- if (gearItem.specialClass === classType && user.items.gear.owned[gearItem.key] !== false) return gearItem.canOwn(classShift);
+ if (
+ gearItem.specialClass === classType
+ && user.items.gear.owned[gearItem.key] !== false
+ ) return gearItem.canOwn(classShift);
+ return false;
});
- category.items = map(result, (e) => {
- return getItemInfo(user, 'marketGear', e, officialPinnedItems);
- });
+ category.items = map(result, e => getItemInfo(user, 'marketGear', e, officialPinnedItems));
- let specialGear = filter(content.gear.flat, (gear) => {
- return user.items.gear.owned[gear.key] === false &&
- gear.specialClass === classType &&
- gear.klass === 'special';
- });
+ const specialGear = filter(content.gear.flat, gear => user.items.gear.owned[gear.key] === false
+ && gear.specialClass === classType
+ && gear.klass === 'special');
- each(specialGear, (gear) => {
+ each(specialGear, gear => {
category.items.push(getItemInfo(user, 'marketGear', gear));
});
@@ -183,21 +172,17 @@ shops.getMarketGearCategories = function getMarketGear (user, language) {
categories.push(category);
}
- let nonClassCategory = {
+ const nonClassCategory = {
identifier: 'none',
text: i18n.t('none', language),
};
- let specialNonClassGear = filter(content.gear.flat, (gear) => {
- return !user.items.gear.owned[gear.key] &&
- content.classes.indexOf(gear.klass) === -1 &&
- content.classes.indexOf(gear.specialClass) === -1 &&
- (gear.canOwn && gear.canOwn(user));
- });
+ const specialNonClassGear = filter(content.gear.flat, gear => !user.items.gear.owned[gear.key]
+ && content.classes.indexOf(gear.klass) === -1
+ && content.classes.indexOf(gear.specialClass) === -1
+ && (gear.canOwn && gear.canOwn(user)));
- nonClassCategory.items = map(specialNonClassGear, (e) => {
- return getItemInfo(user, 'marketGear', e);
- });
+ nonClassCategory.items = map(specialNonClassGear, e => getItemInfo(user, 'marketGear', e));
shops.checkMarketGearLocked(user, nonClassCategory.items);
categories.push(nonClassCategory);
@@ -215,16 +200,14 @@ shops.getQuestShop = function getQuestShop (user, language) {
categories: shops.getQuestShopCategories(user, language),
featured: {
text: i18n.t('featuredQuests'),
- items: featuredItems.quests.map(i => {
- return getItemInfo(user, i.type, get(content, i.path));
- }),
+ items: featuredItems.quests.map(i => getItemInfo(user, i.type, get(content, i.path))),
},
};
};
shops.getQuestShopCategories = function getQuestShopCategories (user, language) {
- let categories = [];
- let officialPinnedItems = getOfficialPinnedItems(user);
+ const categories = [];
+ const officialPinnedItems = getOfficialPinnedItems(user);
/*
* ---------------------------------------------------------------
@@ -280,32 +263,28 @@ shops.getQuestShopCategories = function getQuestShopCategories (user, language)
*
*/
- let bundleCategory = {
+ const bundleCategory = {
identifier: 'bundle',
text: i18n.t('questBundles', language),
};
bundleCategory.items = sortBy(values(content.bundles)
.filter(bundle => bundle.type === 'quests' && bundle.canBuy())
- .map(bundle => {
- return getItemInfo(user, 'bundles', bundle, officialPinnedItems, language);
- }));
+ .map(bundle => getItemInfo(user, 'bundles', bundle, officialPinnedItems, language)));
if (bundleCategory.items.length > 0) {
categories.push(bundleCategory);
}
each(content.userCanOwnQuestCategories, type => {
- let category = {
+ const category = {
identifier: type,
text: i18n.t(`${type}Quests`, language),
};
category.items = content.questsByLevel
.filter(quest => quest.canBuy(user) && quest.category === type)
- .map(quest => {
- return getItemInfo(user, 'quests', quest, officialPinnedItems, language);
- });
+ .map(quest => getItemInfo(user, 'quests', quest, officialPinnedItems, language));
categories.push(category);
});
@@ -316,7 +295,7 @@ shops.getQuestShopCategories = function getQuestShopCategories (user, language)
/* Time Travelers */
shops.getTimeTravelersShop = function getTimeTravelersShop (user, language) {
- let hasTrinkets = user.purchased.plan.consecutive.trinkets > 0;
+ const hasTrinkets = user.purchased.plan.consecutive.trinkets > 0;
return {
identifier: 'timeTravelersShop',
@@ -329,78 +308,71 @@ shops.getTimeTravelersShop = function getTimeTravelersShop (user, language) {
};
shops.getTimeTravelersCategories = function getTimeTravelersCategories (user, language) {
- let categories = [];
- let stable = {pets: 'Pet-', mounts: 'Mount_Icon_'};
+ const categories = [];
+ const stable = { pets: 'Pet-', mounts: 'Mount_Icon_' };
- let officialPinnedItems = getOfficialPinnedItems(user);
+ const officialPinnedItems = getOfficialPinnedItems(user);
- let questCategory = {
+ const questCategory = {
identifier: 'quests',
text: i18n.t('quests', language),
items: [],
};
- for (let key in content.quests) {
+ for (const key in content.quests) {
if (content.quests[key].category === 'timeTravelers') {
- let item = getItemInfo(user, 'quests', content.quests[key], officialPinnedItems, language);
+ const item = getItemInfo(user, 'quests', content.quests[key], officialPinnedItems, language);
questCategory.items.push(item);
}
}
categories.push(questCategory);
- for (let type in stable) {
- if (stable.hasOwnProperty(type)) {
- let category = {
- identifier: type,
- text: i18n.t(type, language),
- items: [],
- };
+ for (const type of Object.keys(stable)) {
+ const category = {
+ identifier: type,
+ text: i18n.t(type, language),
+ items: [],
+ };
- for (let key in content.timeTravelStable[type]) {
- if (content.timeTravelStable[type].hasOwnProperty(key)) {
- if (!user.items[type][key]) {
- let item = getItemInfo(user, 'timeTravelersStable', {
- key,
- type,
- }, officialPinnedItems, language);
- category.items.push(item);
- }
- }
- }
- if (category.items.length > 0) {
- categories.push(category);
+ for (const key of Object.keys(content.timeTravelStable[type])) {
+ if (!user.items[type][key]) {
+ const item = getItemInfo(user, 'timeTravelersStable', {
+ key,
+ type,
+ }, officialPinnedItems, language);
+ category.items.push(item);
}
}
+
+ if (category.items.length > 0) {
+ categories.push(category);
+ }
}
- let sets = content.timeTravelerStore(user);
- for (let setKey in sets) {
- if (sets.hasOwnProperty(setKey)) {
- let set = sets[setKey];
- let category = {
- identifier: set.key,
- text: set.text(language),
- path: `mystery.${set.key}`,
- pinType: 'mystery_set',
- purchaseAll: true,
- };
+ const sets = content.timeTravelerStore(user);
+ for (const setKey of Object.keys(sets)) {
+ const set = sets[setKey];
+ const category = {
+ identifier: set.key,
+ text: set.text(language),
+ path: `mystery.${set.key}`,
+ pinType: 'mystery_set',
+ purchaseAll: true,
+ };
- category.items = map(set.items, item => {
- return {
- key: item.key,
- text: item.text(language),
- notes: item.notes(language),
- type: item.type,
- purchaseType: 'gear',
- value: 1,
- locked: false,
- currency: 'hourglasses',
- class: `shop_${item.key}`,
- pinKey: `timeTravelers!gear.flat.${item.key}`,
- };
- });
- if (category.items.length > 0) {
- categories.push(category);
- }
+ category.items = map(set.items, item => ({
+ key: item.key,
+ text: item.text(language),
+ notes: item.notes(language),
+ type: item.type,
+ purchaseType: 'gear',
+ value: 1,
+ locked: false,
+ currency: 'hourglasses',
+ class: `shop_${item.key}`,
+ pinKey: `timeTravelers!gear.flat.${item.key}`,
+ }));
+ if (category.items.length > 0) {
+ categories.push(category);
}
}
@@ -410,19 +382,21 @@ shops.getTimeTravelersCategories = function getTimeTravelersCategories (user, la
/* Seasonal */
-let flatGearArray = toArray(content.gear.flat);
+const flatGearArray = toArray(content.gear.flat);
-shops.getSeasonalGearBySet = function getSeasonalGearBySet (user, set, officialPinnedItems, language, ignoreAlreadyOwned = false) {
- return flatGearArray.filter((gear) => {
- if (!ignoreAlreadyOwned && user.items.gear.owned[gear.key] !== undefined)
- return false;
+shops.getSeasonalGearBySet = function getSeasonalGearBySet (
+ user, set, officialPinnedItems,
+ language, ignoreAlreadyOwned = false,
+) {
+ return flatGearArray.filter(gear => {
+ if (!ignoreAlreadyOwned && user.items.gear.owned[gear.key] !== undefined) return false;
return gear.set === set;
}).map(gear => {
- let currentSet = gear.set === seasonalShopConfig.pinnedSets[gear.specialClass];
+ const currentSet = gear.set === seasonalShopConfig.pinnedSets[gear.specialClass];
// only the current season set can be purchased by gold
- let itemInfo = getItemInfo(null, currentSet ? 'marketGear' : 'gear', gear, officialPinnedItems, language);
+ const itemInfo = getItemInfo(null, currentSet ? 'marketGear' : 'gear', gear, officialPinnedItems, language);
itemInfo.locked = currentSet && user.stats.class !== gear.specialClass;
return itemInfo;
@@ -430,9 +404,9 @@ shops.getSeasonalGearBySet = function getSeasonalGearBySet (user, set, officialP
};
shops.getSeasonalShop = function getSeasonalShop (user, language) {
- let officialPinnedItems = getOfficialPinnedItems(user);
+ const officialPinnedItems = getOfficialPinnedItems(user);
- let resObject = {
+ const resObject = {
identifier: 'seasonalShop',
text: i18n.t('seasonalShop'),
notes: i18n.t(`seasonalShop${seasonalShopConfig.currentSeason}Text`),
@@ -441,7 +415,13 @@ shops.getSeasonalShop = function getSeasonalShop (user, language) {
categories: this.getSeasonalShopCategories(user, language),
featured: {
text: i18n.t(seasonalShopConfig.featuredSet),
- items: shops.getSeasonalGearBySet(user, seasonalShopConfig.featuredSet, officialPinnedItems, language, true),
+ items: shops.getSeasonalGearBySet(
+ user,
+ seasonalShopConfig.featuredSet,
+ officialPinnedItems,
+ language,
+ true,
+ ),
},
};
@@ -453,7 +433,7 @@ shops.getSeasonalShop = function getSeasonalShop (user, language) {
// setKey: i18n.t('setTranslationString', language),
// };
shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, language) {
- let officialPinnedItems = getOfficialPinnedItems(user);
+ const officialPinnedItems = getOfficialPinnedItems(user);
const AVAILABLE_SPELLS = [
...seasonalShopConfig.availableSpells,
@@ -463,44 +443,42 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang
...seasonalShopConfig.availableQuests,
];
- let categories = [];
+ const categories = [];
- let spells = pickBy(content.spells.special, (spell, key) => {
- return AVAILABLE_SPELLS.indexOf(key) !== -1;
- });
+ const spells = pickBy(
+ content.spells.special,
+ (spell, key) => AVAILABLE_SPELLS.indexOf(key) !== -1,
+ );
if (keys(spells).length > 0) {
- let category = {
+ const category = {
identifier: 'spells',
text: i18n.t('seasonalItems', language),
};
- category.items = map(spells, (spell) => {
- return getItemInfo(user, 'seasonalSpell', spell, officialPinnedItems, language);
- });
+ category.items = map(
+ spells,
+ spell => getItemInfo(user, 'seasonalSpell', spell, officialPinnedItems, language),
+ );
categories.push(category);
}
- let quests = pickBy(content.quests, (quest, key) => {
- return AVAILABLE_QUESTS.indexOf(key) !== -1;
- });
+ const quests = pickBy(content.quests, (quest, key) => AVAILABLE_QUESTS.indexOf(key) !== -1);
if (keys(quests).length > 0) {
- let category = {
+ const category = {
identifier: 'quests',
text: i18n.t('quests', language),
};
- category.items = map(quests, (quest) => {
- return getItemInfo(user, 'seasonalQuest', quest, officialPinnedItems, language);
- });
+ category.items = map(quests, quest => getItemInfo(user, 'seasonalQuest', quest, officialPinnedItems, language));
categories.push(category);
}
- for (let set of seasonalShopConfig.availableSets) {
- let category = {
+ for (const set of seasonalShopConfig.availableSets) {
+ const category = {
identifier: set,
text: i18n.t(set),
};
@@ -508,7 +486,7 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang
category.items = shops.getSeasonalGearBySet(user, set, officialPinnedItems, language, false);
if (category.items.length > 0) {
- let item = category.items[0];
+ const item = category.items[0];
category.specialClass = item.specialClass;
category.event = item.event;
@@ -520,18 +498,16 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang
};
shops.getBackgroundShopSets = function getBackgroundShopSets (language) {
- let sets = [];
- let officialPinnedItems = getOfficialPinnedItems();
+ const sets = [];
+ const officialPinnedItems = getOfficialPinnedItems();
eachRight(content.backgrounds, (group, key) => {
- let set = {
+ const set = {
identifier: key,
text: i18n.t(key, language),
};
- set.items = map(group, (background) => {
- return getItemInfo(null, 'background', background, officialPinnedItems, language);
- });
+ set.items = map(group, background => getItemInfo(null, 'background', background, officialPinnedItems, language));
sets.push(set);
});
@@ -539,4 +515,4 @@ shops.getBackgroundShopSets = function getBackgroundShopSets (language) {
return sets;
};
-module.exports = shops;
+export default shops;
diff --git a/website/common/script/libs/silver.js b/website/common/script/libs/silver.js
index 1d3620f602..96ec97531a 100644
--- a/website/common/script/libs/silver.js
+++ b/website/common/script/libs/silver.js
@@ -4,11 +4,10 @@ Silver amount from their money
// TODO move to client
-module.exports = function silver (num) {
+export default function silver (num) {
if (num) {
- let centCount = Math.floor((num - Math.floor(num)) * 100);
+ const centCount = Math.floor((num - Math.floor(num)) * 100);
return `0${centCount}`.slice(-2);
- } else {
- return '00';
}
-};
+ return '00';
+}
diff --git a/website/common/script/libs/splitWhitespace.js b/website/common/script/libs/splitWhitespace.js
index 2f8276bcb3..59c6b80f25 100644
--- a/website/common/script/libs/splitWhitespace.js
+++ b/website/common/script/libs/splitWhitespace.js
@@ -1,4 +1,3 @@
-
-module.exports = function splitWhitespace (s) {
+export default function splitWhitespace (s) {
return s.split(' ');
-};
+}
diff --git a/website/common/script/libs/statsComputed.js b/website/common/script/libs/statsComputed.js
index 1239b6d9d5..150200f4da 100644
--- a/website/common/script/libs/statsComputed.js
+++ b/website/common/script/libs/statsComputed.js
@@ -1,27 +1,27 @@
import each from 'lodash/each';
import get from 'lodash/get';
import values from 'lodash/values';
-import content from '../content/index';
+import content from '../content/index'; // eslint-disable-line import/no-cycle
import * as statHelpers from '../statHelpers';
function equipmentStatBonusComputed (stat, user) {
- let gear = content.gear.flat;
+ const gear = content.gear.flat;
let gearBonus = 0;
let classBonus = 0;
// toObject is required here due to lodash values not working well with mongoose doc objects.
// if toObject doesn't exist, we can assume the object is already plain JSON
// see http://stackoverflow.com/questions/25767334/underscore-js-keys-and-omit-not-working-as-expected
- let equipped = user.items.gear.equipped;
- let equippedKeys = values(!equipped.toObject ? equipped : equipped.toObject());
+ const { equipped } = user.items.gear;
+ const equippedKeys = values(!equipped.toObject ? equipped : equipped.toObject());
- each(equippedKeys, (equippedItem) => {
- let item = gear[equippedItem];
+ each(equippedKeys, equippedItem => {
+ const item = gear[equippedItem];
if (item) {
- let equipmentStat = item[stat];
- let classBonusMultiplier = item.klass === user.stats.class ||
- item.specialClass === user.stats.class ? 0.5 : 0;
+ const equipmentStat = item[stat];
+ const classBonusMultiplier = item.klass === user.stats.class
+ || item.specialClass === user.stats.class ? 0.5 : 0;
gearBonus += equipmentStat;
classBonus += equipmentStat * classBonusMultiplier;
}
@@ -33,18 +33,18 @@ function equipmentStatBonusComputed (stat, user) {
};
}
-module.exports = function statsComputed (user) {
- let statBreakdown = {
+export default function statsComputed (user) {
+ const statBreakdown = {
gearBonus: {},
classBonus: {},
baseStat: {},
buff: {},
levelBonus: {},
};
- each(['per', 'con', 'str', 'int'], (stat) => {
- let baseStat = get(user, 'stats')[stat];
- let buff = get(user, 'stats.buffs')[stat];
- let equipmentBonus = equipmentStatBonusComputed(stat, user);
+ each(['per', 'con', 'str', 'int'], stat => {
+ const baseStat = get(user, 'stats')[stat];
+ const buff = get(user, 'stats.buffs')[stat];
+ const equipmentBonus = equipmentStatBonusComputed(stat, user);
statBreakdown[stat] = equipmentBonus.gearBonus + equipmentBonus.classBonus + baseStat + buff;
statBreakdown[stat] += Math.floor(statHelpers.capByLevel(user.stats.lvl) / 2);
@@ -59,4 +59,4 @@ module.exports = function statsComputed (user) {
statBreakdown.maxMP = statBreakdown.int * 2 + 30;
return statBreakdown;
-};
+}
diff --git a/website/common/script/libs/taskDefaults.js b/website/common/script/libs/taskDefaults.js
index 8408119585..69ba53824b 100644
--- a/website/common/script/libs/taskDefaults.js
+++ b/website/common/script/libs/taskDefaults.js
@@ -2,20 +2,21 @@ import { v4 as uuid } from 'uuid';
import defaults from 'lodash/defaults';
import moment from 'moment';
-// Even though Mongoose handles task defaults, we want to make sure defaults are set on the client-side before
+// Even though Mongoose handles task defaults,
+// we want to make sure defaults are set on the client-side before
// sending up to the server for performance
// TODO move to client code?
const tasksTypes = ['habit', 'daily', 'todo', 'reward'];
-module.exports = function taskDefaults (task, user) {
+export default function taskDefaults (task, user) {
if (!task.type || tasksTypes.indexOf(task.type) === -1) {
task.type = 'habit';
}
- let defaultId = uuid();
- let defaultTaskObj = {
+ const defaultId = uuid();
+ const defaultTaskObj = {
_id: defaultId,
text: task._id || defaultId,
notes: '',
@@ -65,9 +66,9 @@ module.exports = function taskDefaults (task, user) {
}
if (task.type === 'daily') {
- let now = moment().zone(user.preferences.timezoneOffset);
- let startOfDay = now.clone().startOf('day');
- let startOfDayWithCDSTime = startOfDay
+ const now = moment().zone(user.preferences.timezoneOffset);
+ const startOfDay = now.clone().startOf('day');
+ const startOfDayWithCDSTime = startOfDay
.clone()
.add({
hours: user.preferences.dayStart,
@@ -85,9 +86,9 @@ module.exports = function taskDefaults (task, user) {
su: true,
},
// If cron will happen today, start the daily yesterday
- startDate: startOfDayWithCDSTime.isAfter(now) ?
- startOfDay.clone().subtract(1, 'day').toDate() :
- startOfDay.toDate(),
+ startDate: startOfDayWithCDSTime.isAfter(now)
+ ? startOfDay.clone().subtract(1, 'day').toDate()
+ : startOfDay.toDate(),
everyX: 1,
frequency: 'weekly',
daysOfMonth: [],
@@ -97,4 +98,4 @@ module.exports = function taskDefaults (task, user) {
}
return task;
-};
+}
diff --git a/website/common/script/libs/updateStore.js b/website/common/script/libs/updateStore.js
index c64ee53d3e..52633a32fd 100644
--- a/website/common/script/libs/updateStore.js
+++ b/website/common/script/libs/updateStore.js
@@ -8,29 +8,29 @@ import content from '../content/index';
// Return the list of gear items available for purchase
// TODO: Remove updateStore once the new client is live
-let sortOrder = reduce(content.gearTypes, (accumulator, val, key) => {
+const sortOrder = reduce(content.gearTypes, (accumulator, val, key) => {
accumulator[val] = key;
return accumulator;
}, {});
-module.exports = function updateStore (user) {
+export default function updateStore (user) {
let changes = [];
- each(content.gearTypes, (type) => {
- let found = lodashFind(content.gear.tree[type][user.stats.class], (item) => {
- return !user.items.gear.owned[item.key];
- });
+ each(content.gearTypes, type => {
+ const found = lodashFind(
+ content.gear.tree[type][user.stats.class],
+ item => !user.items.gear.owned[item.key],
+ );
if (found) changes.push(found);
});
- changes = changes.concat(filter(content.gear.flat, (val) => {
+ changes = changes.concat(filter(content.gear.flat, val => {
if (['special', 'mystery', 'armoire'].indexOf(val.klass) !== -1 && !user.items.gear.owned[val.key] && (val.canOwn ? val.canOwn(user) : false)) {
return true;
- } else {
- return false;
}
+ return false;
}));
- return sortBy(changes, (change) => sortOrder[change.type]);
-};
+ return sortBy(changes, change => sortOrder[change.type]);
+}
diff --git a/website/common/script/libs/uuid.js b/website/common/script/libs/uuid.js
index 63f75cf398..df41b6cca4 100644
--- a/website/common/script/libs/uuid.js
+++ b/website/common/script/libs/uuid.js
@@ -1,4 +1,4 @@
import uuid from 'uuid';
// TODO remove this file completely
-module.exports = uuid.v4;
+export default uuid.v4;
diff --git a/website/common/script/ops/addTag.js b/website/common/script/ops/addTag.js
index e7d831ec74..0e9db409e2 100644
--- a/website/common/script/ops/addTag.js
+++ b/website/common/script/ops/addTag.js
@@ -1,9 +1,9 @@
-import uuid from '../libs/uuid';
import get from 'lodash/get';
+import uuid from '../libs/uuid';
// TODO used only in client, move there?
-module.exports = function addTag (user, req = {}) {
+export default function addTag (user, req = {}) {
if (!user.tags) {
user.tags = [];
}
@@ -14,4 +14,4 @@ module.exports = function addTag (user, req = {}) {
});
return user.tags;
-};
+}
diff --git a/website/common/script/ops/addTask.js b/website/common/script/ops/addTask.js
index 92badf72fc..e89485bb3c 100644
--- a/website/common/script/ops/addTask.js
+++ b/website/common/script/ops/addTask.js
@@ -1,10 +1,10 @@
-import taskDefaults from '../libs/taskDefaults';
import clone from 'lodash/clone';
+import taskDefaults from '../libs/taskDefaults';
// TODO move to client since it's only used there?
-module.exports = function addTask (user, req = {body: {}}) {
- let task = taskDefaults(req.body, user);
+export default function addTask (user, req = { body: {} }) {
+ const task = taskDefaults(req.body, user);
user.tasksOrder[`${task.type}s`].unshift(task._id);
user[`${task.type}s`].unshift(task);
@@ -15,4 +15,4 @@ module.exports = function addTask (user, req = {body: {}}) {
task._advanced = !user.preferences.advancedCollapsed;
return task;
-};
+}
diff --git a/website/common/script/ops/blockUser.js b/website/common/script/ops/blockUser.js
index fe347a4b1d..9e9f58f675 100644
--- a/website/common/script/ops/blockUser.js
+++ b/website/common/script/ops/blockUser.js
@@ -4,11 +4,11 @@ import {
BadRequest,
} from '../libs/errors';
-module.exports = function blockUser (user, req = {}) {
+export default function blockUser (user, req = {}) {
if (!validator.isUUID(req.params.uuid)) throw new BadRequest(i18n.t('invalidUUID', req.language));
if (req.params.uuid === user._id) throw new BadRequest(i18n.t('blockYourself', req.language));
- let i = user.inbox.blocks.indexOf(req.params.uuid);
+ const i = user.inbox.blocks.indexOf(req.params.uuid);
if (i === -1) {
user.inbox.blocks.push(req.params.uuid);
} else {
@@ -19,4 +19,4 @@ module.exports = function blockUser (user, req = {}) {
return [
user.inbox.blocks,
];
-};
+}
diff --git a/website/common/script/ops/buy/abstractBuyOperation.js b/website/common/script/ops/buy/abstractBuyOperation.js
index 3f87f08694..aaaf89ee38 100644
--- a/website/common/script/ops/buy/abstractBuyOperation.js
+++ b/website/common/script/ops/buy/abstractBuyOperation.js
@@ -1,11 +1,12 @@
+/* eslint-disable max-classes-per-file */
+import _merge from 'lodash/merge';
+import _get from 'lodash/get';
import i18n from '../../i18n';
import {
NotAuthorized,
NotImplementedError,
BadRequest,
} from '../../libs/errors';
-import _merge from 'lodash/merge';
-import _get from 'lodash/get';
export class AbstractBuyOperation {
/**
@@ -18,7 +19,7 @@ export class AbstractBuyOperation {
this.req = req || {};
this.analytics = analytics;
- let quantity = _get(req, 'quantity');
+ const quantity = _get(req, 'quantity');
this.quantity = quantity ? Number(quantity) : 1;
if (this.quantity < 1 || !Number.isInteger(this.quantity)) throw new BadRequest(this.i18n('invalidQuantity'));
@@ -29,7 +30,7 @@ export class AbstractBuyOperation {
* @param item
* @returns {number}
*/
- getItemValue (item) {
+ getItemValue (item) { // eslint-disable-line class-methods-use-this
return item.value;
}
@@ -38,7 +39,7 @@ export class AbstractBuyOperation {
* @param item
* @returns {String}
*/
- getItemKey (item) {
+ getItemKey (item) { // eslint-disable-line class-methods-use-this
return item.key;
}
@@ -47,9 +48,8 @@ export class AbstractBuyOperation {
* @param item
* @returns {String}
*/
- getItemType (item) {
- if (!item.type)
- throw new NotImplementedError('item doesn\'t have a type property');
+ getItemType (item) { // eslint-disable-line class-methods-use-this
+ if (!item.type) throw new NotImplementedError('item doesn\'t have a type property');
return item.type;
}
@@ -62,29 +62,29 @@ export class AbstractBuyOperation {
*/
// eslint-disable-next-line no-unused-vars
i18n (key, params = {}) {
- return i18n.t.apply(null, [...arguments, this.req.language]);
+ return i18n.t.apply(null, [...arguments, this.req.language]); // eslint-disable-line prefer-rest-params, max-len
}
/**
* If the Operation allows purchasing items by quantity
* @returns Boolean
*/
- multiplePurchaseAllowed () {
+ multiplePurchaseAllowed () { // eslint-disable-line class-methods-use-this
throw new NotImplementedError('multiplePurchaseAllowed');
}
/**
* Method is called to save the params as class-fields in order to access them
*/
- extractAndValidateParams () {
+ extractAndValidateParams () { // eslint-disable-line class-methods-use-this
throw new NotImplementedError('extractAndValidateParams');
}
- executeChanges () {
+ executeChanges () { // eslint-disable-line class-methods-use-this
throw new NotImplementedError('executeChanges');
}
- analyticsData () {
+ analyticsData () { // eslint-disable-line class-methods-use-this
throw new NotImplementedError('sendToAnalytics');
}
@@ -95,7 +95,7 @@ export class AbstractBuyOperation {
this.extractAndValidateParams(this.user, this.req);
- let resultObj = this.executeChanges(this.user, this.item, this.req);
+ const resultObj = this.executeChanges(this.user, this.item, this.req);
if (this.analytics) {
this.sendToAnalytics(this.analyticsData());
@@ -104,13 +104,13 @@ export class AbstractBuyOperation {
return resultObj;
}
- analyticsLabel () {
+ analyticsLabel () { // eslint-disable-line class-methods-use-this
return 'acquire item';
}
sendToAnalytics (additionalData = {}) {
// spread-operator produces an "unexpected token" error
- let analyticsData = _merge(additionalData, {
+ const analyticsData = _merge(additionalData, {
// ...additionalData,
uuid: this.user._id,
category: 'behavior',
@@ -126,15 +126,11 @@ export class AbstractBuyOperation {
}
export class AbstractGoldItemOperation extends AbstractBuyOperation {
- constructor (user, req, analytics) {
- super(user, req, analytics);
- }
-
canUserPurchase (user, item) {
this.item = item;
- let itemValue = this.getItemValue(item);
+ const itemValue = this.getItemValue(item);
- let userGold = user.stats.gp;
+ const userGold = user.stats.gp;
if (userGold < itemValue * this.quantity) {
throw new NotAuthorized(this.i18n('messageNotEnoughGold'));
@@ -146,7 +142,7 @@ export class AbstractGoldItemOperation extends AbstractBuyOperation {
}
subtractCurrency (user, item) {
- let itemValue = this.getItemValue(item);
+ const itemValue = this.getItemValue(item);
user.stats.gp -= itemValue * this.quantity;
}
@@ -162,13 +158,9 @@ export class AbstractGoldItemOperation extends AbstractBuyOperation {
}
export class AbstractGemItemOperation extends AbstractBuyOperation {
- constructor (user, req, analytics) {
- super(user, req, analytics);
- }
-
canUserPurchase (user, item) {
this.item = item;
- let itemValue = this.getItemValue(item);
+ const itemValue = this.getItemValue(item);
if (!item.canBuy(user)) {
throw new NotAuthorized(this.i18n('messageNotAvailable'));
@@ -180,7 +172,7 @@ export class AbstractGemItemOperation extends AbstractBuyOperation {
}
subtractCurrency (user, item) {
- let itemValue = this.getItemValue(item);
+ const itemValue = this.getItemValue(item);
user.balance -= itemValue * this.quantity;
}
@@ -196,10 +188,6 @@ export class AbstractGemItemOperation extends AbstractBuyOperation {
}
export class AbstractHourglassItemOperation extends AbstractBuyOperation {
- constructor (user, req, analytics) {
- super(user, req, analytics);
- }
-
canUserPurchase (user, item) {
this.item = item;
@@ -208,8 +196,8 @@ export class AbstractHourglassItemOperation extends AbstractBuyOperation {
}
}
- subtractCurrency (user) {
- user.purchased.plan.consecutive.trinkets--;
+ subtractCurrency (user) { // eslint-disable-line class-methods-use-this
+ user.purchased.plan.consecutive.trinkets -= 1;
}
analyticsData () {
diff --git a/website/common/script/ops/buy/buy.js b/website/common/script/ops/buy/buy.js
index b0cc98c053..7b9795986d 100644
--- a/website/common/script/ops/buy/buy.js
+++ b/website/common/script/ops/buy/buy.js
@@ -2,28 +2,30 @@ import get from 'lodash/get';
import {
BadRequest,
} from '../../libs/errors';
-import {BuyArmoireOperation} from './buyArmoire';
-import {BuyHealthPotionOperation} from './buyHealthPotion';
-import {BuyMarketGearOperation} from './buyMarketGear';
+import { BuyArmoireOperation } from './buyArmoire';
+import { BuyHealthPotionOperation } from './buyHealthPotion';
+import { BuyMarketGearOperation } from './buyMarketGear';
import buyMysterySet from './buyMysterySet';
-import {BuyQuestWithGoldOperation} from './buyQuestGold';
-import {BuySpellOperation} from './buySpell';
+import { BuyQuestWithGoldOperation } from './buyQuestGold';
+import { BuySpellOperation } from './buySpell';
import purchaseOp from './purchase';
import hourglassPurchase from './hourglassPurchase';
import errorMessage from '../../libs/errorMessage';
-import {BuyGemOperation} from './buyGem';
-import {BuyQuestWithGemOperation} from './buyQuestGem';
-import {BuyHourglassMountOperation} from './buyMount';
+import { BuyGemOperation } from './buyGem';
+import { BuyQuestWithGemOperation } from './buyQuestGem';
+import { BuyHourglassMountOperation } from './buyMount';
// @TODO: remove the req option style. Dependency on express structure is an anti-pattern
// We should either have more params or a set structure validated by a Type checker
// @TODO: when we are sure buy is the only function used, let's move the buy files to a folder
-module.exports = function buy (user, req = {}, analytics, options = {quantity: 1, hourglass: false}) {
- let key = get(req, 'params.key');
- const hourglass = options.hourglass;
- const quantity = options.quantity;
+export default function buy (
+ user, req = {}, analytics, options = { quantity: 1, hourglass: false },
+) {
+ const key = get(req, 'params.key');
+ const { hourglass } = options;
+ const { quantity } = options;
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
// @TODO: Slowly remove the need for key and use type instead
@@ -103,4 +105,4 @@ module.exports = function buy (user, req = {}, analytics, options = {quantity: 1
}
return buyRes;
-};
+}
diff --git a/website/common/script/ops/buy/buyArmoire.js b/website/common/script/ops/buy/buyArmoire.js
index cd4eb796af..97d5213aca 100644
--- a/website/common/script/ops/buy/buyArmoire.js
+++ b/website/common/script/ops/buy/buyArmoire.js
@@ -1,15 +1,15 @@
-import content from '../../content/index';
import filter from 'lodash/filter';
import isEmpty from 'lodash/isEmpty';
import pick from 'lodash/pick';
-import count from '../../count';
+import content from '../../content/index';
+import * as count from '../../count';
import splitWhitespace from '../../libs/splitWhitespace';
import {
NotAuthorized,
} from '../../libs/errors';
-import randomVal from '../../libs/randomVal';
-import {removeItemByPath} from '../pinnedGearUtils';
-import {AbstractGoldItemOperation} from './abstractBuyOperation';
+import randomVal, * as randomValFns from '../../libs/randomVal';
+import { removeItemByPath } from '../pinnedGearUtils';
+import { AbstractGoldItemOperation } from './abstractBuyOperation';
// TODO this is only used on the server
// move out of common?
@@ -17,17 +17,13 @@ import {AbstractGoldItemOperation} from './abstractBuyOperation';
const YIELD_EQUIPMENT_THRESHOLD = 0.6;
const YIELD_FOOD_THRESHOLD = 0.8;
-export class BuyArmoireOperation extends AbstractGoldItemOperation {
- constructor (user, req, analytics) {
- super(user, req, analytics);
- }
-
- multiplePurchaseAllowed () {
+export class BuyArmoireOperation extends AbstractGoldItemOperation { // eslint-disable-line import/prefer-default-export, max-len
+ multiplePurchaseAllowed () { // eslint-disable-line class-methods-use-this
return false;
}
extractAndValidateParams (user) {
- let item = content.armoire;
+ const item = content.armoire;
this.canUserPurchase(user, item);
}
@@ -35,15 +31,19 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
executeChanges (user, item) {
let result = {};
- let armoireResult = randomVal.trueRandom();
- let eligibleEquipment = filter(content.gear.flat, (eligible) => {
- return eligible.klass === 'armoire' && !user.items.gear.owned[eligible.key];
- });
- let armoireHasEquipment = !isEmpty(eligibleEquipment);
+ const armoireResult = randomValFns.trueRandom();
+ const eligibleEquipment = filter(content.gear.flat, eligible => eligible.klass === 'armoire' && !user.items.gear.owned[eligible.key]);
+ const armoireHasEquipment = !isEmpty(eligibleEquipment);
- if (armoireHasEquipment && (armoireResult < YIELD_EQUIPMENT_THRESHOLD || !user.flags.armoireOpened)) {
+ if (
+ armoireHasEquipment
+ && (armoireResult < YIELD_EQUIPMENT_THRESHOLD || !user.flags.armoireOpened)
+ ) {
result = this._gearResult(user, eligibleEquipment);
- } else if ((armoireHasEquipment && armoireResult < YIELD_FOOD_THRESHOLD) || armoireResult < 0.5) { // eslint-disable-line no-extra-parens
+ } else if (
+ (armoireHasEquipment && armoireResult < YIELD_FOOD_THRESHOLD)
+ || armoireResult < 0.5
+ ) {
result = this._foodResult(user);
} else {
result = this._experienceResult(user);
@@ -51,7 +51,8 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
this.subtractCurrency(user, item);
- let {message, armoireResp} = result;
+ let { message } = result;
+ const { armoireResp } = result;
if (!message) {
message = this.i18n('messageBought', {
@@ -59,7 +60,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
});
}
- let resData = pick(user, splitWhitespace('items flags'));
+ const resData = pick(user, splitWhitespace('items flags'));
if (armoireResp) resData.armoire = armoireResp;
return [
@@ -83,7 +84,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
_gearResult (user, eligibleEquipment) {
eligibleEquipment.sort();
- let drop = randomVal(eligibleEquipment);
+ const drop = randomVal(eligibleEquipment);
if (user.items.gear.owned[drop.key]) {
throw new NotAuthorized(this.i18n('equipmentAlreadyOwned'));
@@ -93,7 +94,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
if (user.markModified) user.markModified('items.gear.owned');
user.flags.armoireOpened = true;
- let message = this.i18n('armoireEquipment', {
+ const message = this.i18n('armoireEquipment', {
image: ``,
dropText: drop.text(this.req.language),
});
@@ -108,7 +109,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
this._trackDropAnalytics(user._id, drop.key);
}
- let armoireResp = {
+ const armoireResp = {
type: 'gear',
dropKey: drop.key,
dropText: drop.text(this.req.language),
@@ -121,7 +122,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
}
_foodResult (user) {
- let drop = randomVal(filter(content.food, {
+ const drop = randomVal(filter(content.food, {
canDrop: true,
}));
@@ -147,7 +148,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
}
_experienceResult (user) {
- let armoireExp = Math.floor(randomVal.trueRandom() * 40 + 10);
+ const armoireExp = Math.floor(randomValFns.trueRandom() * 40 + 10);
user.stats.exp += armoireExp;
return {
diff --git a/website/common/script/ops/buy/buyGem.js b/website/common/script/ops/buy/buyGem.js
index b2ea03046e..e2793fcb35 100644
--- a/website/common/script/ops/buy/buyGem.js
+++ b/website/common/script/ops/buy/buyGem.js
@@ -1,39 +1,36 @@
import pick from 'lodash/pick';
+import get from 'lodash/get';
import splitWhitespace from '../../libs/splitWhitespace';
import {
BadRequest,
NotAuthorized,
} from '../../libs/errors';
-import {AbstractGoldItemOperation} from './abstractBuyOperation';
-import get from 'lodash/get';
+import { AbstractGoldItemOperation } from './abstractBuyOperation';
import planGemLimits from '../../libs/planGemLimits';
-export class BuyGemOperation extends AbstractGoldItemOperation {
- constructor (user, req, analytics) {
- super(user, req, analytics);
- }
-
- multiplePurchaseAllowed () {
+export class BuyGemOperation extends AbstractGoldItemOperation { // eslint-disable-line import/prefer-default-export, max-len
+ multiplePurchaseAllowed () { // eslint-disable-line class-methods-use-this
return true;
}
- getItemValue () {
+ getItemValue () { // eslint-disable-line class-methods-use-this
return planGemLimits.convRate;
}
- getItemKey () {
+ getItemKey () { // eslint-disable-line class-methods-use-this
return 'gem';
}
- getItemType () {
+ getItemType () { // eslint-disable-line class-methods-use-this
return 'gems';
}
extractAndValidateParams (user, req) {
- let key = this.key = get(req, 'params.key');
+ this.key = get(req, 'params.key');
+ const { key } = this;
if (!key) throw new BadRequest(this.i18n('missingKeyParam'));
- let convCap = planGemLimits.convCap;
+ let { convCap } = planGemLimits;
convCap += user.purchased.plan.consecutive.gemCapExtra;
// todo better name?
@@ -50,7 +47,7 @@ export class BuyGemOperation extends AbstractGoldItemOperation {
super.canUserPurchase(user, item);
if (user.purchased.plan.gemsBought >= this.convCap) {
- throw new NotAuthorized(this.i18n('reachedGoldToGemCap', {convCap: this.convCap}));
+ throw new NotAuthorized(this.i18n('reachedGoldToGemCap', { convCap: this.convCap }));
}
if (user.purchased.plan.gemsBought + this.quantity > this.convCap) {
@@ -69,11 +66,11 @@ export class BuyGemOperation extends AbstractGoldItemOperation {
return [
pick(user, splitWhitespace('stats balance')),
- this.i18n('plusGem', {count: this.quantity}),
+ this.i18n('plusGem', { count: this.quantity }),
];
}
- analyticsLabel () {
+ analyticsLabel () { // eslint-disable-line class-methods-use-this
return 'purchase gems';
}
}
diff --git a/website/common/script/ops/buy/buyHealthPotion.js b/website/common/script/ops/buy/buyHealthPotion.js
index e3d6c1062a..1f21ec459e 100644
--- a/website/common/script/ops/buy/buyHealthPotion.js
+++ b/website/common/script/ops/buy/buyHealthPotion.js
@@ -3,20 +3,16 @@ import {
NotAuthorized,
} from '../../libs/errors';
-import { AbstractGoldItemOperation} from './abstractBuyOperation';
+import { AbstractGoldItemOperation } from './abstractBuyOperation';
-export class BuyHealthPotionOperation extends AbstractGoldItemOperation {
- constructor (user, req, analytics) {
- super(user, req, analytics);
- }
-
- multiplePurchaseAllowed () {
+export class BuyHealthPotionOperation extends AbstractGoldItemOperation { // eslint-disable-line import/prefer-default-export, max-len
+ multiplePurchaseAllowed () { // eslint-disable-line class-methods-use-this
return true;
}
extractAndValidateParams (user) {
- let item = content.potion;
- let userHp = user.stats.hp;
+ const item = content.potion;
+ const userHp = user.stats.hp;
super.canUserPurchase(user, item);
@@ -37,7 +33,7 @@ export class BuyHealthPotionOperation extends AbstractGoldItemOperation {
this.subtractCurrency(user, item, this.quantity);
- let message = this.i18n('messageBought', {
+ const message = this.i18n('messageBought', {
itemText: this.item.text(this.req.language),
});
diff --git a/website/common/script/ops/buy/buyMarketGear.js b/website/common/script/ops/buy/buyMarketGear.js
index 5f8728bf53..f3fcf8d35b 100644
--- a/website/common/script/ops/buy/buyMarketGear.js
+++ b/website/common/script/ops/buy/buyMarketGear.js
@@ -1,6 +1,6 @@
-import content from '../../content/index';
import get from 'lodash/get';
import pick from 'lodash/pick';
+import content from '../../content/index';
import splitWhitespace from '../../libs/splitWhitespace';
import {
BadRequest,
@@ -10,21 +10,17 @@ import {
import handleTwoHanded from '../../fns/handleTwoHanded';
import ultimateGear from '../../fns/ultimateGear';
-import {removePinnedGearAddPossibleNewOnes} from '../pinnedGearUtils';
+import { removePinnedGearAddPossibleNewOnes } from '../pinnedGearUtils';
import { AbstractGoldItemOperation } from './abstractBuyOperation';
import errorMessage from '../../libs/errorMessage';
-export class BuyMarketGearOperation extends AbstractGoldItemOperation {
- constructor (user, req, analytics) {
- super(user, req, analytics);
- }
-
- multiplePurchaseAllowed () {
+export class BuyMarketGearOperation extends AbstractGoldItemOperation { // eslint-disable-line import/prefer-default-export, max-len
+ multiplePurchaseAllowed () { // eslint-disable-line class-methods-use-this
return false;
}
- canUserPurchase (user, item) {
+ canUserPurchase (user, item) {
super.canUserPurchase(user, item);
const checkKlass = item.klass && !['special', 'armoire', user.stats.class].includes(item.klass);
@@ -37,11 +33,12 @@ export class BuyMarketGearOperation extends AbstractGoldItemOperation {
}
extractAndValidateParams (user, req) {
- let key = this.key = get(req, 'params.key');
+ this.key = get(req, 'params.key');
+ const { key } = this;
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
- let item = content.gear.flat[key];
- if (!item) throw new NotFound(errorMessage('itemNotFound', {key}));
+ const item = content.gear.flat[key];
+ if (!item) throw new NotFound(errorMessage('itemNotFound', { key }));
this.canUserPurchase(user, item);
@@ -49,12 +46,12 @@ export class BuyMarketGearOperation extends AbstractGoldItemOperation {
throw new NotAuthorized(this.i18n('equipmentAlreadyOwned'));
}
- let itemIndex = Number(item.index);
+ const itemIndex = Number(item.index);
if (Number.isInteger(itemIndex) && content.classes.includes(item.klass)) {
- let previousLevelGear = key.replace(/[0-9]/, itemIndex - 1);
- let hasPreviousLevelGear = user.items.gear.owned[previousLevelGear];
- let checkIndexToType = itemIndex > (item.type === 'weapon' || item.type === 'shield' && item.klass === 'rogue' ? 0 : 1);
+ const previousLevelGear = key.replace(/[0-9]/, itemIndex - 1);
+ const hasPreviousLevelGear = user.items.gear.owned[previousLevelGear];
+ const checkIndexToType = itemIndex > (item.type === 'weapon' || (item.type === 'shield' && item.klass === 'rogue') ? 0 : 1);
if (checkIndexToType && !hasPreviousLevelGear) {
throw new NotAuthorized(this.i18n('previousGearNotOwned'));
diff --git a/website/common/script/ops/buy/buyMount.js b/website/common/script/ops/buy/buyMount.js
index ced5cddfc8..660b78b1dd 100644
--- a/website/common/script/ops/buy/buyMount.js
+++ b/website/common/script/ops/buy/buyMount.js
@@ -1,25 +1,22 @@
+import get from 'lodash/get';
+import includes from 'lodash/includes';
+import keys from 'lodash/keys';
import content from '../../content/index';
import {
BadRequest,
NotAuthorized,
} from '../../libs/errors';
-import {AbstractHourglassItemOperation} from './abstractBuyOperation';
-import get from 'lodash/get';
-import includes from 'lodash/includes';
-import keys from 'lodash/keys';
+import { AbstractHourglassItemOperation } from './abstractBuyOperation';
-export class BuyHourglassMountOperation extends AbstractHourglassItemOperation {
- constructor (user, req, analytics) {
- super(user, req, analytics);
- }
-
- multiplePurchaseAllowed () {
+export class BuyHourglassMountOperation extends AbstractHourglassItemOperation { // eslint-disable-line import/prefer-default-export, max-len
+ multiplePurchaseAllowed () { // eslint-disable-line class-methods-use-this
return false;
}
extractAndValidateParams (user, req) {
- let key = this.key = get(req, 'params.key');
+ this.key = get(req, 'params.key');
+ const { key } = this;
if (!key) throw new BadRequest(this.i18n('missingKeyParam'));
@@ -43,7 +40,7 @@ export class BuyHourglassMountOperation extends AbstractHourglassItemOperation {
this.subtractCurrency(user);
- let message = this.i18n('hourglassPurchase');
+ const message = this.i18n('hourglassPurchase');
return [
{ items: user.items, purchasedPlanConsecutive: user.purchased.plan.consecutive },
@@ -52,7 +49,7 @@ export class BuyHourglassMountOperation extends AbstractHourglassItemOperation {
}
analyticsData () {
- let data = super.analyticsData();
+ const data = super.analyticsData();
data.itemType = 'mounts';
return data;
}
diff --git a/website/common/script/ops/buy/buyMysterySet.js b/website/common/script/ops/buy/buyMysterySet.js
index db9ca557f2..018322cba8 100644
--- a/website/common/script/ops/buy/buyMysterySet.js
+++ b/website/common/script/ops/buy/buyMysterySet.js
@@ -1,7 +1,7 @@
-import i18n from '../../i18n';
-import content from '../../content/index';
import get from 'lodash/get';
import each from 'lodash/each';
+import i18n from '../../i18n';
+import content from '../../content/index';
import {
BadRequest,
NotAuthorized,
@@ -9,16 +9,16 @@ import {
} from '../../libs/errors';
import errorMessage from '../../libs/errorMessage';
-module.exports = function buyMysterySet (user, req = {}, analytics) {
- let key = get(req, 'params.key');
+export default function buyMysterySet (user, req = {}, analytics) {
+ const key = get(req, 'params.key');
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
if (!(user.purchased.plan.consecutive.trinkets > 0)) {
throw new NotAuthorized(i18n.t('notEnoughHourglasses', req.language));
}
- let ref = content.timeTravelerStore(user);
- let mysterySet = ref ? ref[key] : undefined;
+ const ref = content.timeTravelerStore(user);
+ const mysterySet = ref ? ref[key] : undefined;
if (!mysterySet) {
throw new NotFound(i18n.t('mysterySetNotFound', req.language));
@@ -40,10 +40,10 @@ module.exports = function buyMysterySet (user, req = {}, analytics) {
if (user.markModified) user.markModified('items.gear.owned');
- user.purchased.plan.consecutive.trinkets--;
+ user.purchased.plan.consecutive.trinkets -= 1;
return [
{ items: user.items, purchasedPlanConsecutive: user.purchased.plan.consecutive },
i18n.t('hourglassPurchaseSet', req.language),
];
-};
+}
diff --git a/website/common/script/ops/buy/buyQuestGem.js b/website/common/script/ops/buy/buyQuestGem.js
index 63ba528ce3..3f099d2a3a 100644
--- a/website/common/script/ops/buy/buyQuestGem.js
+++ b/website/common/script/ops/buy/buyQuestGem.js
@@ -1,20 +1,16 @@
+import get from 'lodash/get';
import {
BadRequest,
NotAuthorized,
NotFound,
} from '../../libs/errors';
import content from '../../content/index';
-import get from 'lodash/get';
import errorMessage from '../../libs/errorMessage';
-import {AbstractGemItemOperation} from './abstractBuyOperation';
+import { AbstractGemItemOperation } from './abstractBuyOperation';
-export class BuyQuestWithGemOperation extends AbstractGemItemOperation {
- constructor (user, req, analytics) {
- super(user, req, analytics);
- }
-
- multiplePurchaseAllowed () {
+export class BuyQuestWithGemOperation extends AbstractGemItemOperation { // eslint-disable-line import/prefer-default-export, max-len
+ multiplePurchaseAllowed () { // eslint-disable-line class-methods-use-this
return true;
}
@@ -22,31 +18,35 @@ export class BuyQuestWithGemOperation extends AbstractGemItemOperation {
return this.key;
}
- getItemValue (item) {
+ getItemValue (item) { // eslint-disable-line class-methods-use-this
return item.value / 4;
}
- getItemType () {
+ getItemType () { // eslint-disable-line class-methods-use-this
return 'quest';
}
extractAndValidateParams (user, req) {
- let key = this.key = get(req, 'params.key');
+ this.key = get(req, 'params.key');
+ const { key } = this;
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
- let item = content.quests[key];
+ const item = content.quests[key];
- if (!item) throw new NotFound(errorMessage('questNotFound', {key}));
+ if (!item) throw new NotFound(errorMessage('questNotFound', { key }));
if (item.category === 'gold') {
- throw new NotAuthorized(this.i18n('questNotGemPurchasable', {key}));
+ throw new NotAuthorized(this.i18n('questNotGemPurchasable', { key }));
}
this.canUserPurchase(user, item);
}
executeChanges (user, item, req) {
- if (!user.items.quests[item.key] || user.items.quests[item.key] < 0) user.items.quests[item.key] = 0;
+ if (
+ !user.items.quests[item.key]
+ || user.items.quests[item.key] < 0
+ ) user.items.quests[item.key] = 0;
user.items.quests[item.key] += this.quantity;
if (user.markModified) user.markModified('items.quests');
diff --git a/website/common/script/ops/buy/buyQuestGold.js b/website/common/script/ops/buy/buyQuestGold.js
index 09f04dcb59..ead059829c 100644
--- a/website/common/script/ops/buy/buyQuestGold.js
+++ b/website/common/script/ops/buy/buyQuestGold.js
@@ -1,52 +1,49 @@
+import get from 'lodash/get';
import {
BadRequest,
NotAuthorized,
NotFound,
} from '../../libs/errors';
import content from '../../content/index';
-import get from 'lodash/get';
-import {AbstractGoldItemOperation} from './abstractBuyOperation';
+import { AbstractGoldItemOperation } from './abstractBuyOperation';
import errorMessage from '../../libs/errorMessage';
-export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation {
- constructor (user, req, analytics) {
- super(user, req, analytics);
- }
-
- multiplePurchaseAllowed () {
+export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation { // eslint-disable-line import/prefer-default-export, max-len
+ multiplePurchaseAllowed () { // eslint-disable-line class-methods-use-this
return true;
}
- userAbleToStartMasterClasser (user) {
- return user.achievements.quests.dilatoryDistress3 &&
- user.achievements.quests.mayhemMistiflying3 &&
- user.achievements.quests.stoikalmCalamity3 &&
- user.achievements.quests.taskwoodsTerror3;
+ userAbleToStartMasterClasser (user) { // eslint-disable-line class-methods-use-this
+ return user.achievements.quests.dilatoryDistress3
+ && user.achievements.quests.mayhemMistiflying3
+ && user.achievements.quests.stoikalmCalamity3
+ && user.achievements.quests.taskwoodsTerror3;
}
getItemKey () {
return this.key;
}
- getItemValue (item) {
+ getItemValue (item) { // eslint-disable-line class-methods-use-this
return item.goldValue;
}
- getItemType () {
+ getItemType () { // eslint-disable-line class-methods-use-this
return 'quest';
}
extractAndValidateParams (user, req) {
- let key = this.key = get(req, 'params.key');
+ this.key = get(req, 'params.key');
+ const { key } = this;
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
- let item = content.quests[key];
+ const item = content.quests[key];
- if (!item) throw new NotFound(errorMessage('questNotFound', {key}));
+ if (!item) throw new NotFound(errorMessage('questNotFound', { key }));
if (!(item.category === 'gold' && item.goldValue)) {
- throw new NotAuthorized(this.i18n('questNotGoldPurchasable', {key}));
+ throw new NotAuthorized(this.i18n('questNotGoldPurchasable', { key }));
}
this.checkPrerequisites(user, key);
@@ -61,12 +58,15 @@ export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation {
}
if (item && item.previous && !user.achievements.quests[item.previous]) {
- throw new NotAuthorized(this.i18n('mustComplete', {quest: item.previous}));
+ throw new NotAuthorized(this.i18n('mustComplete', { quest: item.previous }));
}
}
executeChanges (user, item, req) {
- if (!user.items.quests[item.key] || user.items.quests[item.key] < 0) user.items.quests[item.key] = 0;
+ if (
+ !user.items.quests[item.key]
+ || user.items.quests[item.key] < 0
+ ) user.items.quests[item.key] = 0;
user.items.quests[item.key] += this.quantity;
if (user.markModified) user.markModified('items.quests');
diff --git a/website/common/script/ops/buy/buySpell.js b/website/common/script/ops/buy/buySpell.js
index 46e73a5d81..dc583bd0d6 100644
--- a/website/common/script/ops/buy/buySpell.js
+++ b/website/common/script/ops/buy/buySpell.js
@@ -1,37 +1,34 @@
-import content from '../../content/index';
import get from 'lodash/get';
import pick from 'lodash/pick';
+import content from '../../content/index';
import splitWhitespace from '../../libs/splitWhitespace';
import {
BadRequest,
NotFound,
} from '../../libs/errors';
-import {AbstractGoldItemOperation} from './abstractBuyOperation';
+import { AbstractGoldItemOperation } from './abstractBuyOperation';
import errorMessage from '../../libs/errorMessage';
-export class BuySpellOperation extends AbstractGoldItemOperation {
- constructor (user, req, analytics) {
- super(user, req, analytics);
- }
-
+export class BuySpellOperation extends AbstractGoldItemOperation { // eslint-disable-line import/prefer-default-export, max-len
getItemKey () {
return this.key;
}
- getItemType () {
+ getItemType () { // eslint-disable-line class-methods-use-this
return 'spell';
}
- multiplePurchaseAllowed () {
+ multiplePurchaseAllowed () { // eslint-disable-line class-methods-use-this
return true;
}
extractAndValidateParams (user, req) {
- let key = this.key = get(req, 'params.key');
+ this.key = get(req, 'params.key');
+ const { key } = this;
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
- let item = content.special[key];
- if (!item) throw new NotFound(errorMessage('spellNotFound', {spellId: key}));
+ const item = content.special[key];
+ if (!item) throw new NotFound(errorMessage('spellNotFound', { spellId: key }));
this.canUserPurchase(user, item);
}
diff --git a/website/common/script/ops/buy/hourglassPurchase.js b/website/common/script/ops/buy/hourglassPurchase.js
index 61ae2de568..f721acbc43 100644
--- a/website/common/script/ops/buy/hourglassPurchase.js
+++ b/website/common/script/ops/buy/hourglassPurchase.js
@@ -1,19 +1,19 @@
-import content from '../../content/index';
-import i18n from '../../i18n';
import get from 'lodash/get';
import includes from 'lodash/includes';
import keys from 'lodash/keys';
+import i18n from '../../i18n';
+import content from '../../content/index';
import {
BadRequest,
NotAuthorized,
} from '../../libs/errors';
import errorMessage from '../../libs/errorMessage';
-module.exports = function purchaseHourglass (user, req = {}, analytics, quantity = 1) {
- let key = get(req, 'params.key');
+export default function purchaseHourglass (user, req = {}, analytics, quantity = 1) {
+ const key = get(req, 'params.key');
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
- let type = get(req, 'params.type');
+ const type = get(req, 'params.type');
if (!type) throw new BadRequest(errorMessage('missingTypeParam'));
if (type === 'quests') {
@@ -29,7 +29,7 @@ module.exports = function purchaseHourglass (user, req = {}, analytics, quantity
if (user.markModified) user.markModified('items.quests');
} else {
if (!content.timeTravelStable[type]) {
- throw new NotAuthorized(i18n.t('typeNotAllowedHourglass', {allowedTypes: keys(content.timeTravelStable).toString()}, req.language));
+ throw new NotAuthorized(i18n.t('typeNotAllowedHourglass', { allowedTypes: keys(content.timeTravelStable).toString() }, req.language));
}
if (!includes(keys(content.timeTravelStable[type]), key)) {
@@ -44,7 +44,7 @@ module.exports = function purchaseHourglass (user, req = {}, analytics, quantity
throw new NotAuthorized(i18n.t('notEnoughHourglasses', req.language));
}
- user.purchased.plan.consecutive.trinkets--;
+ user.purchased.plan.consecutive.trinkets -= 1;
if (type === 'pets') {
user.items.pets[key] = 5;
@@ -72,4 +72,4 @@ module.exports = function purchaseHourglass (user, req = {}, analytics, quantity
{ items: user.items, purchasedPlanConsecutive: user.purchased.plan.consecutive },
i18n.t('hourglassPurchase', req.language),
];
-};
+}
diff --git a/website/common/script/ops/buy/purchase.js b/website/common/script/ops/buy/purchase.js
index 20975506f0..f4156f7683 100644
--- a/website/common/script/ops/buy/purchase.js
+++ b/website/common/script/ops/buy/purchase.js
@@ -1,8 +1,8 @@
-import content from '../../content/index';
-import i18n from '../../i18n';
import get from 'lodash/get';
import pick from 'lodash/pick';
import forEach from 'lodash/forEach';
+import i18n from '../../i18n';
+import content from '../../content/index';
import splitWhitespace from '../../libs/splitWhitespace';
import {
NotFound,
@@ -21,7 +21,7 @@ function getItemAndPrice (user, type, key, req) {
item = content.gear.flat[key];
if (!item) {
- throw new NotFound(i18n.t('contentKeyNotFound', {type}, req.language));
+ throw new NotFound(i18n.t('contentKeyNotFound', { type }, req.language));
}
if (user.items.gear.owned[key]) {
@@ -33,13 +33,13 @@ function getItemAndPrice (user, type, key, req) {
item = content[type][key];
if (!item) {
- throw new NotFound(i18n.t('contentKeyNotFound', {type}, req.language));
+ throw new NotFound(i18n.t('contentKeyNotFound', { type }, req.language));
}
price = item.value / 4;
}
- return {item, price};
+ return { item, price };
}
function purchaseItem (user, item, price, type, key) {
@@ -49,30 +49,30 @@ function purchaseItem (user, item, price, type, key) {
user.items.gear.owned[key] = true;
if (user.markModified) user.markModified('items.gear.owned');
} else if (type === 'bundles') {
- let subType = item.type;
- forEach(item.bundleKeys, function addBundledItems (bundledKey) {
+ const subType = item.type;
+ forEach(item.bundleKeys, bundledKey => {
if (!user.items[subType][bundledKey] || user.items[subType][key] < 0) {
user.items[subType][bundledKey] = 0;
}
- user.items[subType][bundledKey]++;
+ user.items[subType][bundledKey] += 1;
});
if (user.markModified) user.markModified(`items.${subType}`);
} else {
if (!user.items[type][key] || user.items[type][key] < 0) {
user.items[type][key] = 0;
}
- user.items[type][key]++;
+ user.items[type][key] += 1;
if (user.markModified) user.markModified(`items.${type}`);
}
}
const acceptedTypes = ['eggs', 'hatchingPotions', 'food', 'gear', 'bundles'];
const singlePurchaseTypes = ['gear'];
-module.exports = function purchase (user, req = {}, analytics) {
- let type = get(req.params, 'type');
- let key = get(req.params, 'key');
+export default function purchase (user, req = {}, analytics) {
+ const type = get(req.params, 'type');
+ const key = get(req.params, 'key');
- let quantity = req.quantity ? Number(req.quantity) : 1;
+ const quantity = req.quantity ? Number(req.quantity) : 1;
if (quantity < 1 || !Number.isInteger(quantity)) throw new BadRequest(i18n.t('invalidQuantity', req.language));
if (!type) {
@@ -87,7 +87,7 @@ module.exports = function purchase (user, req = {}, analytics) {
throw new NotFound(i18n.t('notAccteptedType', req.language));
}
- let {price, item} = getItemAndPrice(user, type, key, req);
+ const { price, item } = getItemAndPrice(user, type, key, req);
if (!item.canBuy(user)) {
throw new NotAuthorized(i18n.t('messageNotAvailable', req.language));
@@ -98,7 +98,7 @@ module.exports = function purchase (user, req = {}, analytics) {
}
if (singlePurchaseTypes.includes(type)) {
- let itemInfo = getItemInfo(user, type, item);
+ const itemInfo = getItemInfo(user, type, item);
removeItemByPath(user, itemInfo.path);
}
@@ -122,4 +122,4 @@ module.exports = function purchase (user, req = {}, analytics) {
return [
pick(user, splitWhitespace('items balance')),
];
-};
+}
diff --git a/website/common/script/ops/changeClass.js b/website/common/script/ops/changeClass.js
index 49af6f481a..460786c6bd 100644
--- a/website/common/script/ops/changeClass.js
+++ b/website/common/script/ops/changeClass.js
@@ -1,6 +1,6 @@
-import i18n from '../i18n';
import get from 'lodash/get';
import pick from 'lodash/pick';
+import i18n from '../i18n';
import splitWhitespace from '../libs/splitWhitespace';
import { capByLevel } from '../statHelpers';
import {
@@ -33,14 +33,15 @@ function resetClass (user, req = {}) {
return balanceRemoved;
}
-module.exports = function changeClass (user, req = {}, analytics) {
- let klass = get(req, 'query.class');
+export default function changeClass (user, req = {}, analytics) {
+ const klass = get(req, 'query.class');
let balanceRemoved = 0;
// user.flags.classSelected is set to false after the user paid the 3 gems
if (user.stats.lvl < 10) {
throw new NotAuthorized(i18n.t('lvl10ChangeClass', req.language));
} else if (!klass) {
- // if no class is specified, reset points and set user.flags.classSelected to false. User will have paid 3 gems and will be prompted to select class.
+ // if no class is specified, reset points and set user.flags.classSelected to false.
+ // User will have paid 3 gems and will be prompted to select class.
balanceRemoved = resetClass(user, req);
} else if (klass === 'warrior' || klass === 'rogue' || klass === 'wizard' || klass === 'healer') {
if (user.flags.classSelected) {
@@ -75,4 +76,4 @@ module.exports = function changeClass (user, req = {}, analytics) {
return [
pick(user, splitWhitespace('stats flags items preferences')),
];
-};
+}
diff --git a/website/common/script/ops/deleteTag.js b/website/common/script/ops/deleteTag.js
index becf6d3c7f..70249c3a5b 100644
--- a/website/common/script/ops/deleteTag.js
+++ b/website/common/script/ops/deleteTag.js
@@ -1,15 +1,15 @@
-import i18n from '../i18n';
import get from 'lodash/get';
import findIndex from 'lodash/findIndex';
import each from 'lodash/each';
+import i18n from '../i18n';
import { NotFound } from '../libs/errors';
// TODO used only in client, move there?
-module.exports = function deleteTag (user, req = {}) {
- let tid = get(req, 'params.id');
+export default function deleteTag (user, req = {}) {
+ const tid = get(req, 'params.id');
- let index = findIndex(user.tags, {
+ const index = findIndex(user.tags, {
id: tid,
});
@@ -17,18 +17,16 @@ module.exports = function deleteTag (user, req = {}) {
throw new NotFound(i18n.t('messageTagNotFound', req.language));
}
- let tag = user.tags[index];
+ const tag = user.tags[index];
delete user.filters[tag.id];
user.tags.splice(index, 1);
- each(user.tasks, (task) => {
- return delete task.tags[tag.id];
- });
+ each(user.tasks, task => delete task.tags[tag.id]);
- each(['habits', 'dailys', 'todos', 'rewards'], (type) => {
+ each(['habits', 'dailys', 'todos', 'rewards'], type => {
if (user.markModified) user.markModified(type);
});
return user.tags;
-};
+}
diff --git a/website/common/script/ops/deleteTask.js b/website/common/script/ops/deleteTask.js
index 3d90325483..6a9cff9a6b 100644
--- a/website/common/script/ops/deleteTask.js
+++ b/website/common/script/ops/deleteTask.js
@@ -1,17 +1,15 @@
-import i18n from '../i18n';
-import { NotFound } from '../libs/errors';
import get from 'lodash/get';
import findIndex from 'lodash/findIndex';
+import i18n from '../i18n';
+import { NotFound } from '../libs/errors';
// TODO used only in client, move there?
-module.exports = function deleteTask (user, req = {}) {
- let tid = get(req, 'params.id');
- let taskType = get(req, 'params.taskType');
+export default function deleteTask (user, req = {}) {
+ const tid = get(req, 'params.id');
+ const taskType = get(req, 'params.taskType');
- let index = findIndex(user[`${taskType}s`], function findById (task) {
- return task._id === tid;
- });
+ const index = findIndex(user[`${taskType}s`], task => task._id === tid);
if (index === -1) {
throw new NotFound(i18n.t('messageTaskNotFound', req.language));
@@ -20,4 +18,4 @@ module.exports = function deleteTask (user, req = {}) {
user[`${taskType}s`].splice(index, 1);
return {};
-};
+}
diff --git a/website/common/script/ops/disableClasses.js b/website/common/script/ops/disableClasses.js
index c12861ed35..b499b84b9b 100644
--- a/website/common/script/ops/disableClasses.js
+++ b/website/common/script/ops/disableClasses.js
@@ -1,8 +1,8 @@
+import pick from 'lodash/pick';
import splitWhitespace from '../libs/splitWhitespace';
import { capByLevel } from '../statHelpers';
-import pick from 'lodash/pick';
-module.exports = function disableClasses (user) {
+export default function disableClasses (user) {
user.stats.class = 'warrior';
user.flags.classSelected = true;
user.preferences.disableClasses = true;
@@ -13,4 +13,4 @@ module.exports = function disableClasses (user) {
return [
pick(user, splitWhitespace('stats flags preferences')),
];
-};
+}
diff --git a/website/common/script/ops/equip.js b/website/common/script/ops/equip.js
index 329eb46a8b..4d764c33e0 100644
--- a/website/common/script/ops/equip.js
+++ b/website/common/script/ops/equip.js
@@ -1,3 +1,4 @@
+import get from 'lodash/get';
import content from '../content/index';
import i18n from '../i18n';
import handleTwoHanded from '../fns/handleTwoHanded';
@@ -5,14 +6,13 @@ import {
NotFound,
BadRequest,
} from '../libs/errors';
-import get from 'lodash/get';
import errorMessage from '../libs/errorMessage';
-module.exports = function equip (user, req = {}) {
+export default function equip (user, req = {}) {
// Being type a parameter followed by another parameter
// when using the API it must be passes specifically in the URL, it's won't default to equipped
- let type = get(req, 'params.type', 'equipped');
- let key = get(req, 'params.key');
+ const type = get(req, 'params.type', 'equipped');
+ const key = get(req, 'params.key');
if (!key || !type) throw new BadRequest(errorMessage('missingTypeKeyEquip'));
if (['mount', 'pet', 'costume', 'equipped'].indexOf(type) === -1) {
@@ -21,7 +21,7 @@ module.exports = function equip (user, req = {}) {
let message;
- switch (type) {
+ switch (type) { // eslint-disable-line default-case
case 'mount': {
if (!user.items.mounts[key]) {
throw new NotFound(i18n.t('mountNotOwned', req.language));
@@ -44,25 +44,33 @@ module.exports = function equip (user, req = {}) {
throw new NotFound(i18n.t('gearNotOwned', req.language));
}
- let item = content.gear.flat[key];
+ const item = content.gear.flat[key];
if (user.items.gear[type][item.type] === key) {
- user.items.gear[type] = Object.assign(
- {},
- user.items.gear[type].toObject ? user.items.gear[type].toObject() : user.items.gear[type],
- {[item.type]: `${item.type}_base_0`}
- );
+ user.items.gear[type] = {
+
+ ...(
+ user.items.gear[type].toObject
+ ? user.items.gear[type].toObject()
+ : user.items.gear[type]
+ ),
+ [item.type]: `${item.type}_base_0`,
+ };
if (user.markModified && type === 'owned') user.markModified('items.gear.owned');
message = i18n.t('messageUnEquipped', {
itemText: item.text(req.language),
}, req.language);
} else {
- user.items.gear[type] = Object.assign(
- {},
- user.items.gear[type].toObject ? user.items.gear[type].toObject() : user.items.gear[type],
- {[item.type]: item.key}
- );
+ user.items.gear[type] = {
+
+ ...(
+ user.items.gear[type].toObject
+ ? user.items.gear[type].toObject()
+ : user.items.gear[type]
+ ),
+ [item.type]: item.key,
+ };
if (user.markModified && type === 'owned') user.markModified('items.gear.owned');
message = handleTwoHanded(user, item, type, req);
@@ -71,7 +79,7 @@ module.exports = function equip (user, req = {}) {
}
}
- let res = [user.items];
+ const res = [user.items];
if (message) res.push(message);
return res;
-};
+}
diff --git a/website/common/script/ops/feed.js b/website/common/script/ops/feed.js
index c91eb42c94..92fb47bd92 100644
--- a/website/common/script/ops/feed.js
+++ b/website/common/script/ops/feed.js
@@ -1,10 +1,10 @@
-import content from '../content/index';
-import i18n from '../i18n';
import forEach from 'lodash/forEach';
import findIndex from 'lodash/findIndex';
import get from 'lodash/get';
import keys from 'lodash/keys';
import upperFirst from 'lodash/upperFirst';
+import i18n from '../i18n';
+import content from '../content/index';
import {
BadRequest,
NotAuthorized,
@@ -30,9 +30,9 @@ function evolve (user, pet, req) {
}, req.language);
}
-module.exports = function feed (user, req = {}) {
+export default function feed (user, req = {}) {
let pet = get(req, 'params.pet');
- let foodK = get(req, 'params.food');
+ const foodK = get(req, 'params.food');
if (!pet || !foodK) throw new BadRequest(errorMessage('missingPetFoodFeed'));
@@ -42,12 +42,12 @@ module.exports = function feed (user, req = {}) {
throw new BadRequest(errorMessage('invalidPetName'));
}
- let food = content.food[foodK];
+ const food = content.food[foodK];
if (!food) {
throw new NotFound(errorMessage('invalidFoodName', req.language));
}
- let userPets = user.items.pets;
+ const userPets = user.items.pets;
if (!userPets[pet.key]) {
throw new NotFound(i18n.t('messagePetNotFound', req.language));
@@ -70,7 +70,7 @@ module.exports = function feed (user, req = {}) {
if (food.key === 'Saddle') {
message = evolve(user, pet, req);
} else {
- let messageParams = {
+ const messageParams = {
egg: pet.text(req.language),
foodText: food.textThe(req.language),
};
@@ -90,14 +90,12 @@ module.exports = function feed (user, req = {}) {
}
}
- user.items.food[food.key]--;
+ user.items.food[food.key] -= 1;
if (user.markModified) user.markModified('items.food');
- forEach(content.animalColorAchievements, (achievement) => {
+ forEach(content.animalColorAchievements, achievement => {
if (!user.achievements[achievement.mountAchievement]) {
- const mountIndex = findIndex(keys(content.dropEggs), (animal) => {
- return !user.items.mounts[`${animal}-${achievement.color}`];
- });
+ const mountIndex = findIndex(keys(content.dropEggs), animal => !user.items.mounts[`${animal}-${achievement.color}`]);
if (mountIndex === -1) {
user.achievements[achievement.mountAchievement] = true;
if (user.addNotification) {
@@ -116,4 +114,4 @@ module.exports = function feed (user, req = {}) {
userPets[pet.key],
message,
];
-};
+}
diff --git a/website/common/script/ops/hatch.js b/website/common/script/ops/hatch.js
index 88ebb96f36..7a60e92ac1 100644
--- a/website/common/script/ops/hatch.js
+++ b/website/common/script/ops/hatch.js
@@ -1,10 +1,10 @@
-import content from '../content/index';
-import i18n from '../i18n';
import findIndex from 'lodash/findIndex';
import forEach from 'lodash/forEach';
import get from 'lodash/get';
import keys from 'lodash/keys';
import upperFirst from 'lodash/upperFirst';
+import i18n from '../i18n';
+import content from '../content/index';
import {
BadRequest,
NotAuthorized,
@@ -12,9 +12,9 @@ import {
} from '../libs/errors';
import errorMessage from '../libs/errorMessage';
-module.exports = function hatch (user, req = {}) {
- let egg = get(req, 'params.egg');
- let hatchingPotion = get(req, 'params.hatchingPotion');
+export default function hatch (user, req = {}) {
+ const egg = get(req, 'params.egg');
+ const hatchingPotion = get(req, 'params.hatchingPotion');
if (!(egg && hatchingPotion)) {
throw new BadRequest(errorMessage('missingEggHatchingPotion'));
@@ -24,30 +24,37 @@ module.exports = function hatch (user, req = {}) {
throw new NotFound(i18n.t('messageMissingEggPotion', req.language));
}
- if ((content.hatchingPotions[hatchingPotion].premium || content.hatchingPotions[hatchingPotion].wacky) && !content.dropEggs[egg]) {
+ if (
+ (
+ content.hatchingPotions[hatchingPotion].premium
+ || content.hatchingPotions[hatchingPotion].wacky
+ )
+ && !content.dropEggs[egg]
+ ) {
throw new BadRequest(i18n.t('messageInvalidEggPotionCombo', req.language));
}
- let pet = `${egg}-${hatchingPotion}`;
+ const pet = `${egg}-${hatchingPotion}`;
if (user.items.pets[pet] && user.items.pets[pet] > 0) {
throw new NotAuthorized(i18n.t('messageAlreadyPet', req.language));
}
user.items.pets[pet] = 5;
- user.items.eggs[egg]--;
- user.items.hatchingPotions[hatchingPotion]--;
+ user.items.eggs[egg] -= 1;
+ user.items.hatchingPotions[hatchingPotion] -= 1;
if (user.markModified) {
user.markModified('items.pets');
user.markModified('items.eggs');
user.markModified('items.hatchingPotions');
}
- forEach(content.animalColorAchievements, (achievement) => {
+ forEach(content.animalColorAchievements, achievement => {
if (!user.achievements[achievement.petAchievement]) {
- const petIndex = findIndex(keys(content.dropEggs), (animal) => {
- return isNaN(user.items.pets[`${animal}-${achievement.color}`]) || user.items.pets[`${animal}-${achievement.color}`] <= 0;
- });
+ const petIndex = findIndex(
+ keys(content.dropEggs),
+ animal => !user.items.pets[`${animal}-${achievement.color}`] || user.items.pets[`${animal}-${achievement.color}`] <= 0,
+ );
if (petIndex === -1) {
user.achievements[achievement.petAchievement] = true;
if (user.addNotification) {
@@ -66,4 +73,4 @@ module.exports = function hatch (user, req = {}) {
user.items,
i18n.t('messageHatched', req.language),
];
-};
+}
diff --git a/website/common/script/ops/index.js b/website/common/script/ops/index.js
index f9407fad67..f3a773a8a0 100644
--- a/website/common/script/ops/index.js
+++ b/website/common/script/ops/index.js
@@ -32,7 +32,7 @@ import scoreTask from './scoreTask';
import markPmsRead from './markPMSRead';
import * as pinnedGearUtils from './pinnedGearUtils';
-module.exports = {
+export default {
sleep,
revive,
reset,
diff --git a/website/common/script/ops/markPMSRead.js b/website/common/script/ops/markPMSRead.js
index ad9beab9b5..a5fc3d1a6e 100644
--- a/website/common/script/ops/markPMSRead.js
+++ b/website/common/script/ops/markPMSRead.js
@@ -1,10 +1,10 @@
import i18n from '../i18n';
-module.exports = function markPmsRead (user) {
+export default function markPmsRead (user) {
user.inbox.newMessages = 0;
return [
user.inbox.newMessages,
i18n.t('pmsMarkedRead'),
];
-};
+}
diff --git a/website/common/script/ops/openMysteryItem.js b/website/common/script/ops/openMysteryItem.js
index b2cf4ea561..0ab7926c40 100644
--- a/website/common/script/ops/openMysteryItem.js
+++ b/website/common/script/ops/openMysteryItem.js
@@ -1,20 +1,18 @@
+import cloneDeep from 'lodash/cloneDeep';
import content from '../content/index';
import i18n from '../i18n';
import {
BadRequest,
} from '../libs/errors';
-import cloneDeep from 'lodash/cloneDeep';
function markNotificationAsRead (user) {
- const index = user.notifications.findIndex(notification => {
- return notification && notification.type === 'NEW_MYSTERY_ITEMS';
- });
+ const index = user.notifications.findIndex(notification => notification && notification.type === 'NEW_MYSTERY_ITEMS');
if (index !== -1) user.notifications.splice(index, 1);
}
-module.exports = function openMysteryItem (user, req = {}, analytics) {
- const mysteryItems = user.purchased.plan.mysteryItems;
+export default function openMysteryItem (user, req = {}, analytics) {
+ const { mysteryItems } = user.purchased.plan;
let item = mysteryItems.shift();
if (!item) {
@@ -47,4 +45,4 @@ module.exports = function openMysteryItem (user, req = {}, analytics) {
item,
i18n.t('mysteryItemOpened', req.language),
];
-};
+}
diff --git a/website/common/script/ops/pinnedGearUtils.js b/website/common/script/ops/pinnedGearUtils.js
index 23dd66a9c2..1150fb6a2f 100644
--- a/website/common/script/ops/pinnedGearUtils.js
+++ b/website/common/script/ops/pinnedGearUtils.js
@@ -1,17 +1,16 @@
-import content from '../content/index';
-import getItemInfo from '../libs/getItemInfo';
-import { BadRequest } from '../libs/errors';
-import i18n from '../i18n';
-import isPinned from '../libs/isPinned';
-import getItemByPathAndType from '../libs/getItemByPathAndType';
-import getOfficialPinnedItems from '../libs/getOfficialPinnedItems';
-
import each from 'lodash/each';
import sortBy from 'lodash/sortBy';
import lodashFind from 'lodash/find';
import reduce from 'lodash/reduce';
+import content from '../content/index';
+import getItemInfo from '../libs/getItemInfo';
+import { BadRequest } from '../libs/errors';
+import i18n from '../i18n';
+import getItemByPathAndType from '../libs/getItemByPathAndType';
+import getOfficialPinnedItems from '../libs/getOfficialPinnedItems';
-let sortOrder = reduce(content.gearTypes, (accumulator, val, key) => {
+
+const sortOrder = reduce(content.gearTypes, (accumulator, val, key) => {
accumulator[val] = key;
return accumulator;
}, {});
@@ -22,35 +21,34 @@ let sortOrder = reduce(content.gearTypes, (accumulator, val, key) => {
* @param String path
*/
function pathExistsInArray (array, path) {
- return array.findIndex(item => {
- return item.path === path;
- });
+ return array.findIndex(item => item.path === path);
}
function checkForNullEntries (array) {
return array.filter(e => Boolean(e));
}
-function checkPinnedAreasForNullEntries (user) {
+export function checkPinnedAreasForNullEntries (user) {
user.pinnedItems = checkForNullEntries(user.pinnedItems);
user.unpinnedItems = checkForNullEntries(user.unpinnedItems);
}
-function selectGearToPin (user) {
- let changes = [];
+export function selectGearToPin (user) {
+ const changes = [];
- each(content.gearTypes, (type) => {
- let found = lodashFind(content.gear.tree[type][user.stats.class], (item) => {
- return !user.items.gear.owned[item.key];
- });
+ each(content.gearTypes, type => {
+ const found = lodashFind(
+ content.gear.tree[type][user.stats.class],
+ item => !user.items.gear.owned[item.key],
+ );
if (found) changes.push(found);
});
- return sortBy(changes, (change) => sortOrder[change.type]);
+ return sortBy(changes, change => sortOrder[change.type]);
}
-function addPinnedGear (user, type, path) {
+export function addPinnedGear (user, type, path) {
const foundIndex = pathExistsInArray(user.pinnedItems, path);
if (foundIndex === -1 && type && path) {
@@ -61,17 +59,16 @@ function addPinnedGear (user, type, path) {
}
}
-function addPinnedGearByClass (user) {
- let newPinnedItems = selectGearToPin(user);
-
- for (let item of newPinnedItems) {
- let itemInfo = getItemInfo(user, 'marketGear', item);
+export function addPinnedGearByClass (user) {
+ const newPinnedItems = selectGearToPin(user);
+ for (const item of newPinnedItems) {
+ const itemInfo = getItemInfo(user, 'marketGear', item);
addPinnedGear(user, itemInfo.pinType, itemInfo.path);
}
}
-function removeItemByPath (user, path) {
+export function removeItemByPath (user, path) {
const foundIndex = pathExistsInArray(user.pinnedItems, path);
if (foundIndex >= 0) {
@@ -82,17 +79,16 @@ function removeItemByPath (user, path) {
return false;
}
-function removePinnedGearByClass (user) {
- let currentPinnedItems = selectGearToPin(user);
-
- for (let item of currentPinnedItems) {
- let itemInfo = getItemInfo(user, 'marketGear', item);
+export function removePinnedGearByClass (user) {
+ const currentPinnedItems = selectGearToPin(user);
+ for (const item of currentPinnedItems) {
+ const itemInfo = getItemInfo(user, 'marketGear', item);
removeItemByPath(user, itemInfo.path);
}
}
-function removePinnedGearAddPossibleNewOnes (user, itemPath, newItemKey) {
+export function removePinnedGearAddPossibleNewOnes (user, itemPath, newItemKey) {
removeItemByPath(user, itemPath);
// an item of the users current "new" gear was bought
@@ -105,14 +101,15 @@ function removePinnedGearAddPossibleNewOnes (user, itemPath, newItemKey) {
addPinnedGearByClass(user);
// update the version, so that vue can refresh the seasonal shop
- user._v++;
+ user._v += 1;
}
/**
- * removes all pinned gear that the user already owns (like class starter gear which has been pinned before)
+ * removes all pinned gear that the user already owns
+ *(like class starter gear which has been pinned before)
* @param user
*/
-function removePinnedItemsByOwnedGear (user) {
+export function removePinnedItemsByOwnedGear (user) {
each(user.items.gear.owned, (bool, key) => {
if (bool) {
removeItemByPath(user, `gear.flat.${key}`);
@@ -125,20 +122,20 @@ const PATHS_WITHOUT_ITEM = ['special.gems', 'special.rebirth_orb', 'special.fort
/**
* @returns {boolean} TRUE added the item / FALSE removed it
*/
-function togglePinnedItem (user, {item, type, path}, req = {}) {
+export function togglePinnedItem (user, { item, type, path }, req = {}) {
let arrayToChange;
- let officialPinnedItems = getOfficialPinnedItems(user);
+ const officialPinnedItems = getOfficialPinnedItems(user);
if (!path) {
// If path isn't passed it means an item was passed
- path = getItemInfo(user, type, item, officialPinnedItems, req.language).path;
+ path = getItemInfo(user, type, item, officialPinnedItems, req.language).path; // eslint-disable-line no-param-reassign, max-len
} else {
- item = getItemByPathAndType(type, path);
+ item = getItemByPathAndType(type, path); // eslint-disable-line no-param-reassign
if (!item && PATHS_WITHOUT_ITEM.indexOf(path) === -1) {
// path not exists in our content structure
- throw new BadRequest(i18n.t('wrongItemPath', {path}, req.language));
+ throw new BadRequest(i18n.t('wrongItemPath', { path }, req.language));
}
// check if item exists & valid to be pinned
@@ -173,21 +170,9 @@ function togglePinnedItem (user, {item, type, path}, req = {}) {
if (foundIndex >= 0) {
arrayToChange.splice(foundIndex, 1);
return isOfficialPinned;
- } else {
- arrayToChange.push({path, type});
- return !isOfficialPinned;
}
+ arrayToChange.push({ path, type });
+ return !isOfficialPinned;
}
-module.exports = {
- addPinnedGearByClass,
- addPinnedGear,
- removePinnedGearByClass,
- removePinnedGearAddPossibleNewOnes,
- removePinnedItemsByOwnedGear,
- togglePinnedItem,
- removeItemByPath,
- selectGearToPin,
- checkPinnedAreasForNullEntries,
- isPinned,
-};
+export { default as isPinned } from '../libs/isPinned';
diff --git a/website/common/script/ops/readCard.js b/website/common/script/ops/readCard.js
index a651238af1..b0097aab9f 100644
--- a/website/common/script/ops/readCard.js
+++ b/website/common/script/ops/readCard.js
@@ -11,19 +11,21 @@ import content from '../content/index';
function markNotificationAsRead (user, cardType) {
const indexToRemove = user.notifications.findIndex(notification => {
if (
- notification &&
- notification.type === 'CARD_RECEIVED' &&
- notification.data &&
- notification.data.card === cardType
+ notification
+ && notification.type === 'CARD_RECEIVED'
+ && notification.data
+ && notification.data.card === cardType
) return true;
+
+ return false;
});
if (indexToRemove !== -1) user.notifications.splice(indexToRemove, 1);
}
-module.exports = function readCard (user, req = {}) {
- let cardType = get(req.params, 'cardType');
+export default function readCard (user, req = {}) {
+ const cardType = get(req.params, 'cardType');
if (!cardType) {
throw new BadRequest(i18n.t('cardTypeRequired', req.language));
@@ -40,6 +42,6 @@ module.exports = function readCard (user, req = {}) {
return [
{ specialItems: user.items.special, cardReceived: user.flags.cardReceived },
- i18n.t('readCard', {cardType}, req.language),
+ i18n.t('readCard', { cardType }, req.language),
];
-};
+}
diff --git a/website/common/script/ops/rebirth.js b/website/common/script/ops/rebirth.js
index 02207c4ac4..4d3c57ce23 100644
--- a/website/common/script/ops/rebirth.js
+++ b/website/common/script/ops/rebirth.js
@@ -1,5 +1,5 @@
-import i18n from '../i18n';
import each from 'lodash/each';
+import i18n from '../i18n';
import { capByLevel } from '../statHelpers';
import { MAX_LEVEL } from '../constants';
import {
@@ -11,14 +11,14 @@ import isFreeRebirth from '../libs/isFreeRebirth';
const USERSTATSLIST = ['per', 'int', 'con', 'str', 'points', 'gp', 'exp', 'mp'];
-module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
+export default function rebirth (user, tasks = [], req = {}, analytics) {
const notFree = !isFreeRebirth(user);
if (user.balance < 1.5 && notFree) {
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
}
- let analyticsData = {
+ const analyticsData = {
uuid: user._id,
category: 'behavior',
};
@@ -37,9 +37,9 @@ module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
analytics.track('Rebirth', analyticsData);
}
- let lvl = capByLevel(user.stats.lvl);
+ const lvl = capByLevel(user.stats.lvl);
- each(tasks, function resetTasks (task) {
+ each(tasks, task => {
if (!task.challenge || !task.challenge.id || task.challenge.broken) {
if (task.type !== 'reward') {
task.value = 0;
@@ -56,7 +56,7 @@ module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
removePinnedGearByClass(user);
- let stats = user.stats;
+ const { stats } = user;
stats.buffs = {};
stats.hp = 50;
stats.lvl = 1;
@@ -64,7 +64,7 @@ module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
user.preferences.automaticAllocation = false;
- each(USERSTATSLIST, function resetStats (value) {
+ each(USERSTATSLIST, value => {
stats[value] = 0;
});
@@ -86,7 +86,7 @@ module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
});
}
- let flags = user.flags;
+ const { flags } = user;
flags.itemsEnabled = false;
flags.dropsEnabled = false;
flags.classSelected = false;
@@ -97,7 +97,7 @@ module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
user.achievements.rebirths = 1;
user.achievements.rebirthLevel = lvl;
} else if (lvl > user.achievements.rebirthLevel || lvl === MAX_LEVEL) {
- user.achievements.rebirths++;
+ user.achievements.rebirths += 1;
user.achievements.rebirthLevel = lvl;
}
@@ -110,7 +110,7 @@ module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
user.stats.buffs = {};
return [
- {user, tasks},
+ { user, tasks },
i18n.t('rebirthComplete'),
];
-};
+}
diff --git a/website/common/script/ops/releaseBoth.js b/website/common/script/ops/releaseBoth.js
index 75aa65abd7..80a7c81241 100644
--- a/website/common/script/ops/releaseBoth.js
+++ b/website/common/script/ops/releaseBoth.js
@@ -1,20 +1,21 @@
+import pick from 'lodash/pick';
import content from '../content/index';
-import {beastMasterProgress, mountMasterProgress} from '../count';
+import { beastMasterProgress, mountMasterProgress } from '../count';
import i18n from '../i18n';
import {
NotAuthorized,
} from '../libs/errors';
import splitWhitespace from '../libs/splitWhitespace';
-import pick from 'lodash/pick';
-
-module.exports = function releaseBoth (user, req = {}) {
- let animal;
+export default function releaseBoth (user, req = {}) {
if (!user.achievements.triadBingo) {
throw new NotAuthorized(i18n.t('notEnoughPetsMounts', req.language));
}
- if (beastMasterProgress(user.items.pets) !== 90 || mountMasterProgress(user.items.mounts) !== 90) {
+ if (
+ beastMasterProgress(user.items.pets) !== 90
+ || mountMasterProgress(user.items.mounts) !== 90
+ ) {
throw new NotAuthorized(i18n.t('notEnoughPetsMounts', req.language));
}
@@ -37,19 +38,19 @@ module.exports = function releaseBoth (user, req = {}) {
// user.balance -= 1.5;
// }
- let mountInfo = content.mountInfo[user.items.currentMount];
+ const mountInfo = content.mountInfo[user.items.currentMount];
if (mountInfo && mountInfo.type === 'drop') {
user.items.currentMount = '';
}
- let petInfo = content.petInfo[user.items.currentPet];
+ const petInfo = content.petInfo[user.items.currentPet];
if (petInfo && petInfo.type === 'drop') {
user.items.currentPet = '';
}
- for (animal in content.pets) {
+ for (const animal of Object.keys(content.pets)) {
if (user.items.pets[animal] === -1) {
giveTriadBingo = false;
} else if (!user.items.pets[animal]) {
@@ -62,6 +63,7 @@ module.exports = function releaseBoth (user, req = {}) {
user.items.pets[animal] = 0;
user.items.mounts[animal] = null;
}
+
if (user.markModified) {
user.markModified('items.pets');
user.markModified('items.mounts');
@@ -71,25 +73,25 @@ module.exports = function releaseBoth (user, req = {}) {
if (!user.achievements.beastMasterCount) {
user.achievements.beastMasterCount = 0;
}
- user.achievements.beastMasterCount++;
+ user.achievements.beastMasterCount += 1;
}
if (giveMountMasterAchievement) {
if (!user.achievements.mountMasterCount) {
user.achievements.mountMasterCount = 0;
}
- user.achievements.mountMasterCount++;
+ user.achievements.mountMasterCount += 1;
}
if (giveTriadBingo) {
if (!user.achievements.triadBingoCount) {
user.achievements.triadBingoCount = 0;
}
- user.achievements.triadBingoCount++;
+ user.achievements.triadBingoCount += 1;
}
return [
pick(user, splitWhitespace('achievements items balance')),
i18n.t('mountsAndPetsReleased'),
];
-};
+}
diff --git a/website/common/script/ops/releaseMounts.js b/website/common/script/ops/releaseMounts.js
index adb9d96dfd..b41e50d861 100644
--- a/website/common/script/ops/releaseMounts.js
+++ b/website/common/script/ops/releaseMounts.js
@@ -1,11 +1,11 @@
import content from '../content/index';
-import {mountMasterProgress} from '../count';
+import { mountMasterProgress } from '../count';
import i18n from '../i18n';
import {
NotAuthorized,
} from '../libs/errors';
-module.exports = function releaseMounts (user, req = {}, analytics) {
+export default function releaseMounts (user, req = {}, analytics) {
if (user.balance < 1) {
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
}
@@ -18,25 +18,26 @@ module.exports = function releaseMounts (user, req = {}, analytics) {
let giveMountMasterAchievement = true;
- let mountInfo = content.mountInfo[user.items.currentMount];
+ const mountInfo = content.mountInfo[user.items.currentMount];
if (mountInfo && mountInfo.type === 'drop') {
user.items.currentMount = '';
}
- for (let mount in content.pets) {
+ for (const mount of Object.keys(content.pets)) {
if (user.items.mounts[mount] === null || user.items.mounts[mount] === undefined) {
giveMountMasterAchievement = false;
}
user.items.mounts[mount] = null;
}
+
if (user.markModified) user.markModified('items.mounts');
if (giveMountMasterAchievement) {
if (!user.achievements.mountMasterCount) {
user.achievements.mountMasterCount = 0;
}
- user.achievements.mountMasterCount++;
+ user.achievements.mountMasterCount += 1;
}
if (analytics) {
@@ -53,4 +54,4 @@ module.exports = function releaseMounts (user, req = {}, analytics) {
user.items.mounts,
i18n.t('mountsReleased'),
];
-};
+}
diff --git a/website/common/script/ops/releasePets.js b/website/common/script/ops/releasePets.js
index 0764fddb62..df7596a1a3 100644
--- a/website/common/script/ops/releasePets.js
+++ b/website/common/script/ops/releasePets.js
@@ -1,11 +1,11 @@
import content from '../content/index';
-import {beastMasterProgress} from '../count';
+import { beastMasterProgress } from '../count';
import i18n from '../i18n';
import {
NotAuthorized,
} from '../libs/errors';
-module.exports = function releasePets (user, req = {}, analytics) {
+export default function releasePets (user, req = {}, analytics) {
if (user.balance < 1) {
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
}
@@ -18,25 +18,26 @@ module.exports = function releasePets (user, req = {}, analytics) {
let giveBeastMasterAchievement = true;
- let petInfo = content.petInfo[user.items.currentPet];
+ const petInfo = content.petInfo[user.items.currentPet];
if (petInfo && petInfo.type === 'drop') {
user.items.currentPet = '';
}
- for (let pet in content.pets) {
+ for (const pet of Object.keys(content.pets)) {
if (!user.items.pets[pet]) {
giveBeastMasterAchievement = false;
}
user.items.pets[pet] = 0;
}
+
if (user.markModified) user.markModified('items.pets');
if (giveBeastMasterAchievement) {
if (!user.achievements.beastMasterCount) {
user.achievements.beastMasterCount = 0;
}
- user.achievements.beastMasterCount++;
+ user.achievements.beastMasterCount += 1;
}
if (analytics) {
@@ -53,4 +54,4 @@ module.exports = function releasePets (user, req = {}, analytics) {
user.items.pets,
i18n.t('petsReleased'),
];
-};
+}
diff --git a/website/common/script/ops/reroll.js b/website/common/script/ops/reroll.js
index 9f8da0c839..faf89ba68a 100644
--- a/website/common/script/ops/reroll.js
+++ b/website/common/script/ops/reroll.js
@@ -1,18 +1,18 @@
-import i18n from '../i18n';
import each from 'lodash/each';
+import i18n from '../i18n';
import {
NotAuthorized,
} from '../libs/errors';
-module.exports = function reroll (user, tasks = [], req = {}, analytics) {
+export default function reroll (user, tasks = [], req = {}, analytics) {
if (user.balance < 1) {
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
}
- user.balance--;
+ user.balance -= 1;
user.stats.hp = 50;
- each(tasks, function resetTaskValues (task) {
+ each(tasks, task => {
if (!task.challenge || !task.challenge.id || task.challenge.broken) {
if (task.type !== 'reward') {
task.value = 0;
@@ -31,7 +31,7 @@ module.exports = function reroll (user, tasks = [], req = {}, analytics) {
}
return [
- {user, tasks},
+ { user, tasks },
i18n.t('fortifyComplete'),
];
-};
+}
diff --git a/website/common/script/ops/reset.js b/website/common/script/ops/reset.js
index 4108d08e9e..1964afb0fd 100644
--- a/website/common/script/ops/reset.js
+++ b/website/common/script/ops/reset.js
@@ -1,20 +1,20 @@
import resetGear from '../fns/resetGear';
import i18n from '../i18n';
-module.exports = function reset (user, tasks = []) {
+export default function reset (user, tasks = []) {
user.stats.hp = 50;
user.stats.lvl = 1;
user.stats.gp = 0;
user.stats.exp = 0;
- let tasksToRemove = [];
+ const tasksToRemove = [];
tasks.forEach(task => {
- let isNotChallengeTask = !task.challenge || !task.challenge.id || task.challenge.broken;
- let isNotGroupTask = !task.group || !task.group.id || task.group.broken;
+ const isNotChallengeTask = !task.challenge || !task.challenge.id || task.challenge.broken;
+ const isNotGroupTask = !task.group || !task.group.id || task.group.broken;
if (isNotChallengeTask && isNotGroupTask) {
tasksToRemove.push(task._id);
- let i = user.tasksOrder[`${task.type}s`].indexOf(task._id);
+ const i = user.tasksOrder[`${task.type}s`].indexOf(task._id);
if (i !== -1) user.tasksOrder[`${task.type}s`].splice(i, 1);
}
});
@@ -24,7 +24,7 @@ module.exports = function reset (user, tasks = []) {
user.preferences.automaticAllocation = false;
return [
- {user, tasksToRemove},
+ { user, tasksToRemove },
i18n.t('resetComplete'),
];
-};
+}
diff --git a/website/common/script/ops/revive.js b/website/common/script/ops/revive.js
index 14ad3d1ddd..e8ce46010b 100644
--- a/website/common/script/ops/revive.js
+++ b/website/common/script/ops/revive.js
@@ -1,8 +1,8 @@
-import content from '../content/index';
-import i18n from '../i18n';
import merge from 'lodash/merge';
import reduce from 'lodash/reduce';
import each from 'lodash/each';
+import i18n from '../i18n';
+import content from '../content/index';
import {
NotAuthorized,
} from '../libs/errors';
@@ -12,7 +12,7 @@ import predictableRandom from '../fns/predictableRandom';
import { removePinnedGearByClass, addPinnedGearByClass, addPinnedGear } from './pinnedGearUtils';
import getItemInfo from '../libs/getItemInfo';
-module.exports = function revive (user, req = {}, analytics) {
+export default function revive (user, req = {}, analytics) {
if (user.stats.hp > 0) {
throw new NotAuthorized(i18n.t('cannotRevive', req.language));
}
@@ -24,10 +24,10 @@ module.exports = function revive (user, req = {}, analytics) {
});
if (user.stats.lvl > 1) {
- user.stats.lvl--;
+ user.stats.lvl -= 1;
}
- let lostStat = randomVal(reduce(['str', 'con', 'per', 'int'], function findRandomStat (m, k) {
+ const lostStat = randomVal(reduce(['str', 'con', 'per', 'int'], (m, k) => {
if (user.stats[k]) {
m[k] = k;
}
@@ -37,10 +37,10 @@ module.exports = function revive (user, req = {}, analytics) {
});
if (lostStat) {
- user.stats[lostStat]--;
+ user.stats[lostStat] -= 1;
}
- let base = user.items.gear.owned;
+ const base = user.items.gear.owned;
let gearOwned;
if (typeof base.toObject === 'function') {
@@ -49,39 +49,42 @@ module.exports = function revive (user, req = {}, analytics) {
gearOwned = user.items.gear.owned;
}
- let losableItems = {};
- let userClass = user.stats.class;
+ const losableItems = {};
+ const userClass = user.stats.class;
- each(gearOwned, function findLosableItems (value, key) {
+ each(gearOwned, (value, key) => {
let itm;
if (value) {
itm = content.gear.flat[key];
if (itm) {
- let itemHasValueOrWarrior0 = itm.value > 0 || key === 'weapon_warrior_0';
+ const itemHasValueOrWarrior0 = itm.value > 0 || key === 'weapon_warrior_0';
- let itemClassEqualsUserClass = itm.klass === userClass;
+ const itemClassEqualsUserClass = itm.klass === userClass;
- let itemClassSpecial = itm.klass === 'special';
- let itemNotSpecialOrUserClassIsSpecial = !itm.specialClass || itm.specialClass === userClass;
- let itemIsSpecial = itemNotSpecialOrUserClassIsSpecial && itemClassSpecial;
+ const itemClassSpecial = itm.klass === 'special';
+ const itemNotSpecialOrUserClassIsSpecial = !itm.specialClass
+ || itm.specialClass === userClass;
+ const itemIsSpecial = itemNotSpecialOrUserClassIsSpecial && itemClassSpecial;
- let itemIsArmoire = itm.klass === 'armoire';
+ const itemIsArmoire = itm.klass === 'armoire';
- if (itemHasValueOrWarrior0 && (itemClassEqualsUserClass || itemIsSpecial || itemIsArmoire)) {
+ if (
+ itemHasValueOrWarrior0
+ && (itemClassEqualsUserClass || itemIsSpecial || itemIsArmoire)
+ ) {
losableItems[key] = key;
- return losableItems[key];
}
}
}
});
- let lostItem = randomVal(losableItems, {
+ const lostItem = randomVal(losableItems, {
predictableRandom: predictableRandom(user),
});
let message = '';
- let item = content.gear.flat[lostItem];
+ const item = content.gear.flat[lostItem];
if (item) {
removePinnedGearByClass(user);
@@ -91,18 +94,18 @@ module.exports = function revive (user, req = {}, analytics) {
addPinnedGearByClass(user);
- let itemInfo = getItemInfo(user, 'marketGear', item);
+ const itemInfo = getItemInfo(user, 'marketGear', item);
addPinnedGear(user, itemInfo.pinType, itemInfo.path);
if (user.items.gear.equipped[item.type] === lostItem) {
- user.items.gear.equipped[item.type] = `${item.type}_base_0`;
+ user.items.gear.equipped[item.type] = `${item.type}_base_0`;
}
if (user.items.gear.costume[item.type] === lostItem) {
user.items.gear.costume[item.type] = `${item.type}_base_0`;
}
- message = i18n.t('messageLostItem', { itemText: item.text(req.language)}, req.language);
+ message = i18n.t('messageLostItem', { itemText: item.text(req.language) }, req.language);
}
if (analytics) {
@@ -119,4 +122,4 @@ module.exports = function revive (user, req = {}, analytics) {
user.items,
message,
];
-};
+}
diff --git a/website/common/script/ops/scoreTask.js b/website/common/script/ops/scoreTask.js
index abe6ccf0fc..bee17ba957 100644
--- a/website/common/script/ops/scoreTask.js
+++ b/website/common/script/ops/scoreTask.js
@@ -17,25 +17,28 @@ const CLOSE_ENOUGH = 0.00001;
function _getTaskValue (taskValue) {
if (taskValue < MIN_TASK_VALUE) {
return MIN_TASK_VALUE;
- } else if (taskValue > MAX_TASK_VALUE) {
+ } if (taskValue > MAX_TASK_VALUE) {
return MAX_TASK_VALUE;
- } else {
- return taskValue;
}
+ return taskValue;
}
// Calculates the next task.value based on direction
// Uses a capped inverse log y=.95^x, y>= -5
function _calculateDelta (task, direction, cron) {
// Min/max on task redness
- let currVal = _getTaskValue(task.value);
- let nextDelta = Math.pow(0.9747, currVal) * (direction === 'down' ? -1 : 1);
+ const currVal = _getTaskValue(task.value);
+ let nextDelta = (0.9747 ** currVal) * (direction === 'down' ? -1 : 1);
// Checklists
if (task.checklist && task.checklist.length > 0) {
// If the Daily, only dock them a portion based on their checklist completion
if (direction === 'down' && task.type === 'daily' && cron) {
- nextDelta *= 1 - reduce(task.checklist, (m, i) => m + (i.completed ? 1 : 0), 0) / task.checklist.length;
+ nextDelta *= 1 - reduce(
+ task.checklist,
+ (m, i) => m + (i.completed ? 1 : 0),
+ 0,
+ ) / task.checklist.length;
}
// If To-Do, point-match the TD per checklist item completed
@@ -52,15 +55,15 @@ function _calculateDelta (task, direction, cron) {
// First, calculate the value using the normal way for our first guess although
// it will be a bit off
function _calculateReverseDelta (task, direction) {
- let currVal = _getTaskValue(task.value);
- let testVal = currVal + Math.pow(0.9747, currVal) * (direction === 'down' ? -1 : 1);
+ const currVal = _getTaskValue(task.value);
+ let testVal = currVal + (0.9747 ** currVal) * (direction === 'down' ? -1 : 1);
// Now keep moving closer to the original value until we get "close enough"
// Check how close we are to the original value by computing the delta off our guess
// and looking at the difference between that and our current value.
while (true) { // eslint-disable-line no-constant-condition
- let calc = testVal + Math.pow(0.9747, testVal);
- let diff = currVal - calc;
+ const calc = testVal + (0.9747 ** testVal);
+ const diff = currVal - calc;
if (Math.abs(diff) < CLOSE_ENOUGH) break;
@@ -85,7 +88,7 @@ function _calculateReverseDelta (task, direction) {
}
function _gainMP (user, val) {
- val *= user._tmp.crit || 1;
+ val *= user._tmp.crit || 1; // eslint-disable-line no-param-reassign
user.stats.mp += val;
if (user.stats.mp >= statsComputed(user).maxMP) user.stats.mp = statsComputed(user).maxMP;
@@ -101,32 +104,33 @@ function _subtractPoints (user, task, stats, delta) {
let conBonus = 1 - statsComputed(user).con / 250;
if (conBonus < 0.1) conBonus = 0.1;
- let hpMod = delta * conBonus * task.priority * 2; // constant 2 multiplier for better results
+ const hpMod = delta * conBonus * task.priority * 2; // constant 2 multiplier for better results
stats.hp += Math.round(hpMod * 10) / 10; // round to 1dp
return stats.hp;
}
function _addPoints (user, task, stats, direction, delta) {
- let _crit = user._tmp.crit || 1;
+ const _crit = user._tmp.crit || 1;
// Exp Modifier
// ===== Intelligence =====
// TODO Increases Experience gain by .2% per point.
- let intBonus = 1 + statsComputed(user).int * 0.025;
+ const intBonus = 1 + statsComputed(user).int * 0.025;
stats.exp += Math.round(delta * intBonus * task.priority * _crit * 6);
// GP modifier
// ===== PERCEPTION =====
// TODO Increases Gold gained from tasks by .3% per point.
- let perBonus = 1 + statsComputed(user).per * 0.02;
- let gpMod = delta * task.priority * _crit * perBonus;
+ const perBonus = 1 + statsComputed(user).per * 0.02;
+ const gpMod = delta * task.priority * _crit * perBonus;
if (task.streak) {
- let currStreak = direction === 'down' ? task.streak - 1 : task.streak;
- let streakBonus = currStreak / 100 + 1; // eg, 1-day streak is 1.01, 2-day is 1.02, etc
- let afterStreak = gpMod * streakBonus;
+ const currStreak = direction === 'down' ? task.streak - 1 : task.streak;
+ const streakBonus = currStreak / 100 + 1; // eg, 1-day streak is 1.01, 2-day is 1.02, etc
+ const afterStreak = gpMod * streakBonus;
if (currStreak > 0 && gpMod > 0) {
- user._tmp.streakBonus = afterStreak - gpMod; // keep this on-hand for later, so we can notify streak-bonus
+ // keep this on-hand for later, so we can notify streak-bonus
+ user._tmp.streakBonus = afterStreak - gpMod;
}
stats.gp += afterStreak;
@@ -140,14 +144,14 @@ function _changeTaskValue (user, task, direction, times, cron) {
// ===== CRITICAL HITS =====
// allow critical hit only when checking off a task, not when unchecking it:
- let _crit = direction === 'up' ? crit.crit(user) : 1;
+ const _crit = direction === 'up' ? crit.crit(user) : 1;
// if there was a crit, alert the user via notification
if (_crit > 1) user._tmp.crit = _crit;
// If multiple days have passed, multiply times days missed
timesLodash(times, () => {
// Each iteration calculate the nextDelta, which is then accumulated in the total delta.
- let nextDelta = !cron && direction === 'down' ? _calculateReverseDelta(task, direction) : _calculateDelta(task, direction, cron);
+ const nextDelta = !cron && direction === 'down' ? _calculateReverseDelta(task, direction) : _calculateDelta(task, direction, cron);
if (task.type !== 'reward') {
if (user.preferences.automaticAllocation === true && user.preferences.allocationMode === 'taskbased' && !(task.type === 'todo' && direction === 'down')) {
@@ -156,7 +160,7 @@ function _changeTaskValue (user, task, direction, times, cron) {
if (direction === 'up') { // Make progress on quest based on STR
user.party.quest.progress.up = user.party.quest.progress.up || 0;
- let prevProgress = user.party.quest.progress.up;
+ const prevProgress = user.party.quest.progress.up;
if (task.type === 'todo' || task.type === 'daily') {
user.party.quest.progress.up += nextDelta * _crit * (1 + statsComputed(user).str / 200);
@@ -184,18 +188,24 @@ function _updateCounter (task, direction, times) {
}
}
-module.exports = function scoreTask (options = {}, req = {}) {
- let {user, task, direction, times = 1, cron = false} = options;
+export default function scoreTask (options = {}, req = {}) {
+ const {
+ user, task, direction, times = 1, cron = false,
+ } = options;
let delta = 0;
- let stats = {
+ const stats = {
gp: user.stats.gp,
hp: user.stats.hp,
exp: user.stats.exp,
};
- if (task.group && task.group.approval && task.group.approval.required && !task.group.approval.approved) return 0;
+ if (
+ task.group && task.group.approval && task.group.approval.required
+ && !task.group.approval.approved
+ ) return 0;
- // This is for setting one-time temporary flags, such as streakBonus or itemDropped. Useful for notifying
+ // This is for setting one-time temporary flags,
+ // such as streakBonus or itemDropped. Useful for notifying
// the API consumer, then cleared afterwards
user._tmp = {};
@@ -215,8 +225,8 @@ module.exports = function scoreTask (options = {}, req = {}) {
// Save history entry for habit
task.history = task.history || [];
- const timezoneOffset = user.preferences.timezoneOffset;
- const dayStart = user.preferences.dayStart;
+ const { timezoneOffset } = user.preferences;
+ const { dayStart } = user.preferences;
const historyLength = task.history.length;
const lastHistoryEntry = task.history[historyLength - 1];
@@ -229,13 +239,14 @@ module.exports = function scoreTask (options = {}, req = {}) {
}
if (
- lastHistoryEntryDate &&
- moment().zone(timezoneOffset).isSame(lastHistoryEntryDate, 'day')
+ lastHistoryEntryDate
+ && moment().zone(timezoneOffset).isSame(lastHistoryEntryDate, 'day')
) {
lastHistoryEntry.value = task.value;
lastHistoryEntry.date = Number(new Date());
- // @TODO remove this extra check after migration has run to set scoredUp and scoredDown in every task
+ // @TODO remove this extra check after migration
+ // has run to set scoredUp and scoredDown in every task
lastHistoryEntry.scoredUp = lastHistoryEntry.scoredUp || 0;
lastHistoryEntry.scoredDown = lastHistoryEntry.scoredDown || 0;
@@ -264,7 +275,8 @@ module.exports = function scoreTask (options = {}, req = {}) {
} else {
delta += _changeTaskValue(user, task, direction, times, cron);
if (direction === 'down') delta = _calculateDelta(task, direction, cron); // recalculate delta for unchecking so the gp and exp come out correctly
- _addPoints(user, task, stats, direction, delta); // obviously for delta>0, but also a trick to undo accidental checkboxes
+ // obviously for delta>0, but also a trick to undo accidental checkboxes
+ _addPoints(user, task, stats, direction, delta);
_gainMP(user, max([1, 0.01 * statsComputed(user).maxMP]) * (direction === 'down' ? -1 : 1));
if (direction === 'up') {
@@ -278,14 +290,16 @@ module.exports = function scoreTask (options = {}, req = {}) {
// Save history entry for daily
task.history = task.history || [];
- let historyEntry = {
+ const historyEntry = {
date: Number(new Date()),
value: task.value,
};
task.history.push(historyEntry);
} else if (direction === 'down') {
// Remove a streak achievement if streak was a multiple of 21 and the daily was undone
- if (task.streak !== 0 && task.streak % 21 === 0) user.achievements.streak = user.achievements.streak ? user.achievements.streak - 1 : 0;
+ if (task.streak !== 0 && task.streak % 21 === 0) {
+ user.achievements.streak = user.achievements.streak ? user.achievements.streak - 1 : 0;
+ }
task.streak -= 1;
task.completed = false;
@@ -312,7 +326,7 @@ module.exports = function scoreTask (options = {}, req = {}) {
_addPoints(user, task, stats, direction, delta);
// MP++ per checklist item in ToDo, bonus per CLI
- let multiplier = max([reduce(task.checklist, (m, i) => m + (i.completed ? 1 : 0), 1), 1]);
+ const multiplier = max([reduce(task.checklist, (m, i) => m + (i.completed ? 1 : 0), 1), 1]);
_gainMP(user, max([multiplier, 0.01 * statsComputed(user).maxMP * multiplier]) * (direction === 'down' ? -1 : 1));
}
} else if (task.type === 'reward') {
@@ -330,4 +344,4 @@ module.exports = function scoreTask (options = {}, req = {}) {
req.yesterDailyScored = task.yesterDailyScored;
updateStats(user, stats, req);
return [delta];
-};
+}
diff --git a/website/common/script/ops/sell.js b/website/common/script/ops/sell.js
index 69e132da37..23f14cd851 100644
--- a/website/common/script/ops/sell.js
+++ b/website/common/script/ops/sell.js
@@ -1,7 +1,7 @@
-import content from '../content/index';
-import i18n from '../i18n';
import get from 'lodash/get';
import pick from 'lodash/pick';
+import content from '../content/index';
+import i18n from '../i18n';
import splitWhitespace from '../libs/splitWhitespace';
import {
NotFound,
@@ -12,10 +12,10 @@ import {
// @TODO: 'special' type throws NotAuthorized error
const ACCEPTEDTYPES = ['eggs', 'hatchingPotions', 'food'];
-module.exports = function sell (user, req = {}) {
- let key = get(req.params, 'key');
- let type = get(req.params, 'type');
- let amount = get(req.query, 'amount', 1);
+export default function sell (user, req = {}) {
+ const key = get(req.params, 'key');
+ const type = get(req.params, 'type');
+ const amount = get(req.query, 'amount', 1);
if (amount < 0) {
throw new BadRequest(i18n.t('positiveAmountRequired', req.language));
@@ -30,17 +30,17 @@ module.exports = function sell (user, req = {}) {
}
if (ACCEPTEDTYPES.indexOf(type) === -1) {
- throw new NotAuthorized(i18n.t('typeNotSellable', {acceptedTypes: ACCEPTEDTYPES.join(', ')}, req.language));
+ throw new NotAuthorized(i18n.t('typeNotSellable', { acceptedTypes: ACCEPTEDTYPES.join(', ') }, req.language));
}
if (!user.items[type][key]) {
- throw new NotFound(i18n.t('userItemsKeyNotFound', {type}, req.language));
+ throw new NotFound(i18n.t('userItemsKeyNotFound', { type }, req.language));
}
- let currentAmount = user.items[type][key];
+ const currentAmount = user.items[type][key];
if (amount > currentAmount) {
- throw new NotFound(i18n.t('userItemsNotEnough', {type}, req.language));
+ throw new NotFound(i18n.t('userItemsNotEnough', { type }, req.language));
}
if (type === 'food' && key === 'Saddle') {
@@ -55,4 +55,4 @@ module.exports = function sell (user, req = {}) {
return [
pick(user, splitWhitespace('stats items')),
];
-};
+}
diff --git a/website/common/script/ops/sleep.js b/website/common/script/ops/sleep.js
index e80f766b0a..15e49c80a0 100644
--- a/website/common/script/ops/sleep.js
+++ b/website/common/script/ops/sleep.js
@@ -1,4 +1,4 @@
-module.exports = function sleep (user, req = {}, analytics) {
+export default function sleep (user, req = {}, analytics) {
user.preferences.sleep = !user.preferences.sleep;
if (analytics) {
@@ -11,4 +11,4 @@ module.exports = function sleep (user, req = {}, analytics) {
}
return [user.preferences.sleep];
-};
+}
diff --git a/website/common/script/ops/sortTag.js b/website/common/script/ops/sortTag.js
index afbb3d289a..11dffeae4c 100644
--- a/website/common/script/ops/sortTag.js
+++ b/website/common/script/ops/sortTag.js
@@ -1,14 +1,14 @@
-import { BadRequest } from '../libs/errors';
import get from 'lodash/get';
+import { BadRequest } from '../libs/errors';
// TODO used only in client, move there?
-module.exports = function sortTag (user, req = {}) {
- let to = get(req, 'query.to');
- let fromParam = get(req, 'query.from');
+export default function sortTag (user, req = {}) {
+ const to = get(req, 'query.to');
+ const fromParam = get(req, 'query.from');
- let invalidTo = !to && to !== 0;
- let invalidFrom = !fromParam && fromParam !== 0;
+ const invalidTo = !to && to !== 0;
+ const invalidFrom = !fromParam && fromParam !== 0;
if (invalidTo || invalidFrom) {
throw new BadRequest('?to=__&from=__ are required');
@@ -16,4 +16,4 @@ module.exports = function sortTag (user, req = {}) {
user.tags.splice(to, 0, user.tags.splice(fromParam, 1)[0]);
return user.tags;
-};
+}
diff --git a/website/common/script/ops/sortTask.js b/website/common/script/ops/sortTask.js
index 27740bb69f..0e461f5a88 100644
--- a/website/common/script/ops/sortTask.js
+++ b/website/common/script/ops/sortTask.js
@@ -1,23 +1,21 @@
+import get from 'lodash/get';
+import findIndex from 'lodash/findIndex';
import i18n from '../i18n';
import preenTodos from '../libs/preenTodos';
import {
NotFound,
BadRequest,
} from '../libs/errors';
-import get from 'lodash/get';
-import findIndex from 'lodash/findIndex';
// TODO used only in client, move there?
-module.exports = function sortTask (user, req = {}) {
- let id = get(req, 'params.id');
+export default function sortTask (user, req = {}) {
+ const id = get(req, 'params.id');
let to = get(req, 'query.to');
let fromParam = get(req, 'query.from');
- let taskType = get(req, 'params.taskType');
+ const taskType = get(req, 'params.taskType');
- let index = findIndex(user[`${taskType}s`], function findById (task) {
- return task._id === id;
- });
+ const index = findIndex(user[`${taskType}s`], task => task._id === id);
if (index === -1) {
throw new NotFound(i18n.t('messageTaskNotFound', req.language));
@@ -26,10 +24,10 @@ module.exports = function sortTask (user, req = {}) {
throw new BadRequest('?to=__&from=__ are required');
}
- let tasks = user[`${taskType}s`];
+ const tasks = user[`${taskType}s`];
if (taskType === 'todo') {
- let preenedTasks = preenTodos(tasks);
+ const preenedTasks = preenTodos(tasks);
if (to !== -1) {
to = tasks.indexOf(preenedTasks[to]);
@@ -38,7 +36,7 @@ module.exports = function sortTask (user, req = {}) {
fromParam = tasks.indexOf(preenedTasks[fromParam]);
}
- let movedTask = tasks.splice(fromParam, 1)[0];
+ const movedTask = tasks.splice(fromParam, 1)[0];
if (to === -1) {
tasks.push(movedTask);
@@ -47,4 +45,4 @@ module.exports = function sortTask (user, req = {}) {
}
return tasks;
-};
+}
diff --git a/website/common/script/ops/stats/allocate.js b/website/common/script/ops/stats/allocate.js
index 0db8c59732..21cea70608 100644
--- a/website/common/script/ops/stats/allocate.js
+++ b/website/common/script/ops/stats/allocate.js
@@ -10,11 +10,11 @@ import i18n from '../../i18n';
import errorMessage from '../../libs/errorMessage';
import hasClass from '../../libs/hasClass';
-module.exports = function allocate (user, req = {}) {
- let stat = get(req, 'query.stat', 'str');
+export default function allocate (user, req = {}) {
+ const stat = get(req, 'query.stat', 'str');
if (ATTRIBUTES.indexOf(stat) === -1) {
- throw new BadRequest(errorMessage('invalidAttribute', {attr: stat}));
+ throw new BadRequest(errorMessage('invalidAttribute', { attr: stat }));
}
if (!hasClass(user)) {
@@ -22,10 +22,10 @@ module.exports = function allocate (user, req = {}) {
}
if (user.stats.points > 0) {
- user.stats[stat]++;
- user.stats.points--;
+ user.stats[stat] += 1;
+ user.stats.points -= 1;
if (stat === 'int') {
- user.stats.mp++;
+ user.stats.mp += 1;
}
} else {
throw new NotAuthorized(i18n.t('notEnoughAttrPoints', req.language));
@@ -34,4 +34,4 @@ module.exports = function allocate (user, req = {}) {
return [
user.stats,
];
-};
+}
diff --git a/website/common/script/ops/stats/allocateBulk.js b/website/common/script/ops/stats/allocateBulk.js
index ad6e2aeedf..e532525d89 100644
--- a/website/common/script/ops/stats/allocateBulk.js
+++ b/website/common/script/ops/stats/allocateBulk.js
@@ -10,16 +10,14 @@ import i18n from '../../i18n';
import errorMessage from '../../libs/errorMessage';
import hasClass from '../../libs/hasClass';
-module.exports = function allocateBulk (user, req = {}) {
+export default function allocateBulk (user, req = {}) {
const stats = get(req, 'body.stats');
if (!stats) throw new BadRequest(errorMessage('statsObjectRequired'));
const statKeys = Object.keys(stats);
- const invalidStats = statKeys.filter(statKey => {
- return ATTRIBUTES.indexOf(statKey) === -1;
- });
+ const invalidStats = statKeys.filter(statKey => ATTRIBUTES.indexOf(statKey) === -1);
if (invalidStats.length > 0) {
- throw new BadRequest(errorMessage('invalidAttribute', {attr: invalidStats.join(',')}));
+ throw new BadRequest(errorMessage('invalidAttribute', { attr: invalidStats.join(',') }));
}
if (!hasClass(user)) {
@@ -31,14 +29,12 @@ module.exports = function allocateBulk (user, req = {}) {
}
const newStatValues = Object.values(stats);
- const totalPointsToAllocate = newStatValues.reduce((sum, value) => {
- return sum + value;
- }, 0);
+ const totalPointsToAllocate = newStatValues.reduce((sum, value) => sum + value, 0);
if (user.stats.points < totalPointsToAllocate) {
throw new NotAuthorized(i18n.t('notEnoughAttrPoints', req.language));
}
- for (let [stat, value] of Object.entries(stats)) {
+ for (const [stat, value] of Object.entries(stats)) {
user.stats[stat] += value;
user.stats.points -= value;
if (stat === 'int') user.stats.mp += value;
@@ -47,4 +43,4 @@ module.exports = function allocateBulk (user, req = {}) {
return [
user.stats,
];
-};
+}
diff --git a/website/common/script/ops/stats/allocateNow.js b/website/common/script/ops/stats/allocateNow.js
index 09b4ab2c82..2efaf33ade 100644
--- a/website/common/script/ops/stats/allocateNow.js
+++ b/website/common/script/ops/stats/allocateNow.js
@@ -1,11 +1,11 @@
import times from 'lodash/times';
import autoAllocate from '../../fns/autoAllocate';
-module.exports = function allocateNow (user) {
+export default function allocateNow (user) {
times(user.stats.points, () => autoAllocate(user));
user.stats.points = 0;
return [
user.stats,
];
-};
+}
diff --git a/website/common/script/ops/unlock.js b/website/common/script/ops/unlock.js
index 7adbac48de..48720322b0 100644
--- a/website/common/script/ops/unlock.js
+++ b/website/common/script/ops/unlock.js
@@ -1,8 +1,8 @@
-import i18n from '../i18n';
import get from 'lodash/get';
import each from 'lodash/each';
import pick from 'lodash/pick';
import setWith from 'lodash/setWith';
+import i18n from '../i18n';
import splitWhitespace from '../libs/splitWhitespace';
import {
NotAuthorized,
@@ -15,15 +15,15 @@ import content from '../content/index';
// If item is already purchased -> equip it
// Otherwise unlock it
-module.exports = function unlock (user, req = {}, analytics) {
- let path = get(req.query, 'path');
+export default function unlock (user, req = {}, analytics) {
+ const path = get(req.query, 'path');
if (!path) {
throw new BadRequest(i18n.t('pathRequired', req.language));
}
- let isFullSet = path.indexOf(',') !== -1;
- let isBackground = path.indexOf('background.') !== -1;
+ const isFullSet = path.indexOf(',') !== -1;
+ const isBackground = path.indexOf('background.') !== -1;
let cost;
if (isBackground && isFullSet) {
@@ -45,13 +45,14 @@ module.exports = function unlock (user, req = {}, analytics) {
each(setPaths, singlePath => {
if (get(user, `purchased.${singlePath}`) === true) {
- alreadyOwnedItems++;
+ alreadyOwnedItems += 1;
}
});
if (alreadyOwnedItems === setPaths.length) {
throw new NotAuthorized(i18n.t('alreadyUnlocked', req.language));
- // TODO write math formula to check if buying the full set is cheaper than the items individually
+ // TODO write math formula to check if buying
+ // the full set is cheaper than the items individually
// (item cost * number of remaining items) < setCost`
} /* else if (alreadyOwnedItems > 0) {
throw new NotAuthorized(i18n.t('alreadyUnlockedPart', req.language));
@@ -69,11 +70,11 @@ module.exports = function unlock (user, req = {}, analytics) {
}
if (isFullSet) {
- each(setPaths, function markItemsAsPurchased (pathPart) {
+ each(setPaths, pathPart => {
if (path.indexOf('gear.') !== -1) {
// Using Object so path[1] won't create an array but an object {path: {1: value}}
setWith(user, pathPart, true, Object);
- let itemName = pathPart.split('.').pop();
+ const itemName = pathPart.split('.').pop();
removeItemByPath(user, `gear.flat.${itemName}`);
if (user.markModified && path.indexOf('gear.owned') !== -1) user.markModified('items.gear.owned');
}
@@ -82,9 +83,9 @@ module.exports = function unlock (user, req = {}, analytics) {
setWith(user, `purchased.${pathPart}`, true, Object);
});
} else {
- let split = path.split('.');
+ const split = path.split('.');
let value = split.pop();
- let key = split.join('.');
+ const key = split.join('.');
if (alreadyOwns) { // eslint-disable-line no-lonely-if
if (key === 'background' && value === user.preferences.background) {
@@ -104,8 +105,8 @@ module.exports = function unlock (user, req = {}, analytics) {
// @TODO: Test and check test coverage
if (isBackground) {
- let backgroundContent = content.backgroundsFlat[value];
- let itemInfo = getItemInfo(user, 'background', backgroundContent);
+ const backgroundContent = content.backgroundsFlat[value];
+ const itemInfo = getItemInfo(user, 'background', backgroundContent);
removeItemByPath(user, itemInfo.path);
}
}
@@ -131,11 +132,11 @@ module.exports = function unlock (user, req = {}, analytics) {
}
}
- let response = [
+ const response = [
pick(user, splitWhitespace('purchased preferences items')),
];
if (!alreadyOwns) response.push(i18n.t('unlocked', req.language));
return response;
-};
+}
diff --git a/website/common/script/ops/updateTag.js b/website/common/script/ops/updateTag.js
index fcfadb1cc9..a939e24cc2 100644
--- a/website/common/script/ops/updateTag.js
+++ b/website/common/script/ops/updateTag.js
@@ -1,14 +1,14 @@
-import i18n from '../i18n';
import get from 'lodash/get';
import findIndex from 'lodash/findIndex';
+import i18n from '../i18n';
import { NotFound } from '../libs/errors';
// TODO used only in client, move there?
-module.exports = function updateTag (user, req = {}) {
- let tid = get(req, 'params.id');
+export default function updateTag (user, req = {}) {
+ const tid = get(req, 'params.id');
- let index = findIndex(user.tags, {
+ const index = findIndex(user.tags, {
id: tid,
});
@@ -18,4 +18,4 @@ module.exports = function updateTag (user, req = {}) {
user.tags[index].name = get(req, 'body.name');
return user.tags[index];
-};
+}
diff --git a/website/common/script/ops/updateTask.js b/website/common/script/ops/updateTask.js
index 379ac73caa..dcca31c529 100644
--- a/website/common/script/ops/updateTask.js
+++ b/website/common/script/ops/updateTask.js
@@ -2,8 +2,8 @@ import merge from 'lodash/merge';
import omit from 'lodash/omit';
// From server pass task.toObject() not the task document directly
-module.exports = function updateTask (task, req = {}) {
- let body = req.body || {};
+export default function updateTask (task, req = {}) {
+ const body = req.body || {};
// If reminders are updated -> replace the original ones
if (body.reminders) {
@@ -32,4 +32,4 @@ module.exports = function updateTask (task, req = {}) {
}
return [task];
-};
+}
diff --git a/website/common/script/statHelpers.js b/website/common/script/statHelpers.js
index b678f08ef1..ce44d18d33 100644
--- a/website/common/script/statHelpers.js
+++ b/website/common/script/statHelpers.js
@@ -11,9 +11,8 @@ import {
export function capByLevel (lvl) {
if (lvl > MAX_LEVEL) {
return MAX_LEVEL;
- } else {
- return lvl;
}
+ return lvl;
}
/*
@@ -25,16 +24,18 @@ export function capByLevel (lvl) {
export function toNextLevel (lvl) {
if (lvl < 5) {
return 25 * lvl;
- } else if (lvl === 5) {
+ } if (lvl === 5) {
return 150;
}
- return Math.round((Math.pow(lvl, 2) * 0.25 + 10 * lvl + 139.75) / 10) * 10;
+ return Math.round(((lvl ** 2) * 0.25 + 10 * lvl + 139.75) / 10) * 10;
}
/*
- A hyperbola function that creates diminishing returns, so you can't go to infinite (eg, with Exp gain).
+ A hyperbola function that creates diminishing returns,
+ so you can't go to infinite (eg, with Exp gain).
{max} The asymptote
- {bonus} All the numbers combined for your point bonus (eg, task.value * user.stats.int * critChance, etc)
+ {bonus} All the numbers combined for your point bonus
+ (eg, task.value * user.stats.int * critChance, etc)
{halfway} (optional) the point at which the graph starts bending
*/
diff --git a/website/raw_sprites/css/css.template.handlebars b/website/raw_sprites/css/css.template.handlebars
index 9c7c6b5ce4..1e30164ed6 100755
--- a/website/raw_sprites/css/css.template.handlebars
+++ b/website/raw_sprites/css/css.template.handlebars
@@ -1,13 +1,13 @@
{{#sprites}}
.{{name}} {
- background-image: url('~assets/images/sprites/{{{escaped_image}}}');
+ background-image: url('~@/assets/images/sprites/{{{escaped_image}}}');
background-position: {{px.offset_x}} {{px.offset_y}};
width: {{px.width}};
height: {{px.height}};
}
{{#if custom}}
.customize-option.{{name}} {
- background-image: url('~assets/images/sprites/{{{escaped_image}}}');
+ background-image: url('~@/assets/images/sprites/{{{escaped_image}}}');
background-position: {{custom.px.offsetX}} {{custom.px.offsetY}};
width: {{custom.px.width}};
height: {{custom.px.height}};
diff --git a/website/raw_sprites/spritesmith/achievements/achievement-monsterMagus2x.png b/website/raw_sprites/spritesmith/achievements/achievement-monsterMagus2x.png
new file mode 100644
index 0000000000..02a7c0d359
Binary files /dev/null and b/website/raw_sprites/spritesmith/achievements/achievement-monsterMagus2x.png differ
diff --git a/website/raw_sprites/spritesmith/achievements/achievement-undeadUndertaker2x.png b/website/raw_sprites/spritesmith/achievements/achievement-undeadUndertaker2x.png
new file mode 100644
index 0000000000..6ffcceeeea
Binary files /dev/null and b/website/raw_sprites/spritesmith/achievements/achievement-undeadUndertaker2x.png differ
diff --git a/website/raw_sprites/spritesmith/gear/events/mystery_201910/broad_armor_mystery_201910.png b/website/raw_sprites/spritesmith/gear/events/mystery_201910/broad_armor_mystery_201910.png
new file mode 100644
index 0000000000..2f0df1817b
Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/mystery_201910/broad_armor_mystery_201910.png differ
diff --git a/website/raw_sprites/spritesmith/gear/events/mystery_201910/head_mystery_201910.png b/website/raw_sprites/spritesmith/gear/events/mystery_201910/head_mystery_201910.png
new file mode 100644
index 0000000000..01952f38df
Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/mystery_201910/head_mystery_201910.png differ
diff --git a/website/raw_sprites/spritesmith/gear/events/mystery_201910/shop_armor_mystery_201910.png b/website/raw_sprites/spritesmith/gear/events/mystery_201910/shop_armor_mystery_201910.png
new file mode 100644
index 0000000000..04cd9a3ac7
Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/mystery_201910/shop_armor_mystery_201910.png differ
diff --git a/website/raw_sprites/spritesmith/gear/events/mystery_201910/shop_head_mystery_201910.png b/website/raw_sprites/spritesmith/gear/events/mystery_201910/shop_head_mystery_201910.png
new file mode 100644
index 0000000000..354db6b605
Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/mystery_201910/shop_head_mystery_201910.png differ
diff --git a/website/raw_sprites/spritesmith/gear/events/mystery_201910/shop_set_mystery_201910.png b/website/raw_sprites/spritesmith/gear/events/mystery_201910/shop_set_mystery_201910.png
new file mode 100644
index 0000000000..5c0f405974
Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/mystery_201910/shop_set_mystery_201910.png differ
diff --git a/website/raw_sprites/spritesmith/gear/events/mystery_201910/slim_armor_mystery_201910.png b/website/raw_sprites/spritesmith/gear/events/mystery_201910/slim_armor_mystery_201910.png
new file mode 100644
index 0000000000..5f2b7265d7
Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/mystery_201910/slim_armor_mystery_201910.png differ
diff --git a/website/raw_sprites/spritesmith_large/promo_fall_skins.png b/website/raw_sprites/spritesmith_large/promo_fall_skins.png
new file mode 100644
index 0000000000..718c858b4b
Binary files /dev/null and b/website/raw_sprites/spritesmith_large/promo_fall_skins.png differ
diff --git a/website/raw_sprites/spritesmith_large/promo_mystery_201909.png b/website/raw_sprites/spritesmith_large/promo_mystery_201909.png
deleted file mode 100644
index e5cfdfcc37..0000000000
Binary files a/website/raw_sprites/spritesmith_large/promo_mystery_201909.png and /dev/null differ
diff --git a/website/raw_sprites/spritesmith_large/promo_mystery_201910.png b/website/raw_sprites/spritesmith_large/promo_mystery_201910.png
new file mode 100644
index 0000000000..7832bac392
Binary files /dev/null and b/website/raw_sprites/spritesmith_large/promo_mystery_201910.png differ
diff --git a/website/raw_sprites/spritesmith_large/promo_witchy_familiars.png b/website/raw_sprites/spritesmith_large/promo_witchy_familiars.png
new file mode 100644
index 0000000000..c31d486f72
Binary files /dev/null and b/website/raw_sprites/spritesmith_large/promo_witchy_familiars.png differ
diff --git a/website/raw_sprites/spritesmith_large/promo_zombie_achievements.png b/website/raw_sprites/spritesmith_large/promo_zombie_achievements.png
new file mode 100644
index 0000000000..0ef72d7927
Binary files /dev/null and b/website/raw_sprites/spritesmith_large/promo_zombie_achievements.png differ
diff --git a/website/raw_sprites/spritesmith_large/scene_arts_crafts.png b/website/raw_sprites/spritesmith_large/scene_arts_crafts.png
new file mode 100644
index 0000000000..81ea5b011e
Binary files /dev/null and b/website/raw_sprites/spritesmith_large/scene_arts_crafts.png differ
diff --git a/website/raw_sprites/spritesmith_large/scene_quest_shop.png b/website/raw_sprites/spritesmith_large/scene_quest_shop.png
new file mode 100644
index 0000000000..a787976921
Binary files /dev/null and b/website/raw_sprites/spritesmith_large/scene_quest_shop.png differ
diff --git a/website/server/.eslintrc b/website/server/.eslintrc
deleted file mode 100644
index 7b3c05adf0..0000000000
--- a/website/server/.eslintrc
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "extends": [
- "habitrpg/server",
- "habitrpg/esnext"
- ]
-}
\ No newline at end of file
diff --git a/website/server/.eslintrc.js b/website/server/.eslintrc.js
new file mode 100644
index 0000000000..e745414cf9
--- /dev/null
+++ b/website/server/.eslintrc.js
@@ -0,0 +1,6 @@
+/* eslint-disable import/no-commonjs */
+module.exports = {
+ extends: [
+ "habitrpg/lib/node",
+ ]
+}
\ No newline at end of file
diff --git a/website/server/api-doc.js b/website/server/api-doc.js
index 14d136ef30..83b417afed 100644
--- a/website/server/api-doc.js
+++ b/website/server/api-doc.js
@@ -1,4 +1,3 @@
-'use strict';
// This file defines some globals for use in the API Doc comments
diff --git a/website/server/controllers/api-v3/auth.js b/website/server/controllers/api-v3/auth.js
index 9d5d2a4977..8113eb1c25 100644
--- a/website/server/controllers/api-v3/auth.js
+++ b/website/server/controllers/api-v3/auth.js
@@ -12,7 +12,6 @@ import {
} from '../../libs/errors';
import * as passwordUtils from '../../libs/password';
import { sendTxn as sendTxnEmail } from '../../libs/email';
-import { validatePasswordResetCodeAndFindUser, convertToBcrypt} from '../../libs/password';
import { encrypt } from '../../libs/encryption';
import {
loginRes,
@@ -20,25 +19,29 @@ import {
loginSocial,
registerLocal,
} from '../../libs/auth';
-import {verifyUsername} from '../../libs/user/validation';
+import { verifyUsername } from '../../libs/user/validation';
const BASE_URL = nconf.get('BASE_URL');
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
-let api = {};
+const api = {};
/**
* @api {post} /api/v3/user/auth/local/register Register
- * @apiDescription Register a new user with email, login name, and password or attach local auth to a social user
+ * @apiDescription Register a new user with email, login name, and password or
+ * attach local auth to a social user
* @apiName UserRegisterLocal
* @apiGroup User
*
- * @apiParam (Body) {String} username Login name of the new user. Must be 1-36 characters, containing only a-z, 0-9, hyphens (-), or underscores (_).
+ * @apiParam (Body) {String} username Login name of the new user.
+ * Must be 1-36 characters, containing only a-z, 0-9,
+ * hyphens (-), or underscores (_).
* @apiParam (Body) {String} email Email address of the new user
* @apiParam (Body) {String} password Password for the new user
* @apiParam (Body) {String} confirmPassword Password confirmation
*
- * @apiSuccess {Object} data The user object, if local auth was just attached to a social user then only user.auth.local
+ * @apiSuccess {Object} data The user object, if local auth was just
+ * attached to a social user then only user.auth.local
*/
api.registerLocal = {
method: 'POST',
@@ -61,8 +64,10 @@ api.registerLocal = {
* @apiParam (Body) {String} password The user's password
*
* @apiSuccess {String} data._id The user's unique identifier
- * @apiSuccess {String} data.apiToken The user's api token that must be used to authenticate requests.
- * @apiSuccess {Boolean} data.newUser Returns true if the user was just created (always false for local login).
+ * @apiSuccess {String} data.apiToken The user's api token
+ * that must be used to authenticate requests.
+ * @apiSuccess {Boolean} data.newUser Returns true if the user was just created
+ * (always false for local login).
*/
api.loginLocal = {
method: 'POST',
@@ -79,24 +84,24 @@ api.loginLocal = {
errorMessage: res.t('missingPassword'),
},
});
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
req.sanitizeBody('username').trim();
req.sanitizeBody('password').trim();
let login;
- let username = req.body.username;
- let password = req.body.password;
+ const { username } = req.body;
+ const { password } = req.body;
if (validator.isEmail(String(username))) {
- login = {'auth.local.email': username.toLowerCase()}; // Emails are stored lowercase
+ login = { 'auth.local.email': username.toLowerCase() }; // Emails are stored lowercase
} else {
- login = {'auth.local.username': username};
+ login = { 'auth.local.username': username };
}
// load the entire user because we may have to save it to convert the password to bcrypt
- let user = await User.findOne(login).exec();
+ const user = await User.findOne(login).exec();
// if user is using social login, then user will not have a hashed_password stored
if (!user || !user.auth.local.hashed_password) throw new NotAuthorized(res.t('invalidLoginCredentialsLong'));
@@ -125,7 +130,7 @@ api.loginLocal = {
headers: req.headers,
});
- return loginRes(user, ...arguments);
+ return loginRes(user, req, res);
},
};
@@ -137,7 +142,7 @@ api.loginSocial = {
})],
url: '/user/auth/social',
async handler (req, res) {
- return await loginSocial(req, res);
+ await loginSocial(req, res);
},
};
@@ -150,17 +155,17 @@ api.loginSocial = {
* @apiParam (Body) {String} username The new username
* @apiSuccess {String} data.username The new username
- **/
+ * */
api.updateUsername = {
method: 'PUT',
middlewares: [authWithHeaders()],
url: '/user/auth/update-username',
async handler (req, res) {
- const user = res.locals.user;
+ const { user } = res.locals;
req.checkBody({
username: {
- notEmpty: {errorMessage: res.t('missingUsername')},
+ notEmpty: { errorMessage: res.t('missingUsername') },
},
});
@@ -172,13 +177,13 @@ api.updateUsername = {
const issues = verifyUsername(newUsername, res);
if (issues.length > 0) throw new BadRequest(issues.join(' '));
- const password = req.body.password;
+ const { password } = req.body;
if (password !== undefined) {
- let isValidPassword = await passwordUtils.compare(user, password);
+ const isValidPassword = await passwordUtils.compare(user, password);
if (!isValidPassword) throw new NotAuthorized(res.t('wrongPassword'));
}
- const existingUser = await User.findOne({ 'auth.local.lowerCaseUsername': newUsername.toLowerCase() }, {auth: 1}).exec();
+ const existingUser = await User.findOne({ 'auth.local.lowerCaseUsername': newUsername.toLowerCase() }, { auth: 1 }).exec();
if (existingUser !== undefined && existingUser !== null && existingUser._id !== user._id) {
throw new BadRequest(res.t('usernameTaken'));
}
@@ -224,39 +229,39 @@ api.updateUsername = {
* @apiParam (Body) {String} confirmPassword New password confirmation
*
* @apiSuccess {Object} data An empty object
- **/
+ * */
api.updatePassword = {
method: 'PUT',
middlewares: [authWithHeaders()],
url: '/user/auth/update-password',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
if (!user.auth.local.hashed_password) throw new BadRequest(res.t('userHasNoLocalRegistration'));
req.checkBody({
password: {
- notEmpty: {errorMessage: res.t('missingPassword')},
+ notEmpty: { errorMessage: res.t('missingPassword') },
},
newPassword: {
- notEmpty: {errorMessage: res.t('missingNewPassword')},
+ notEmpty: { errorMessage: res.t('missingNewPassword') },
},
confirmPassword: {
- notEmpty: {errorMessage: res.t('missingNewPassword')},
+ notEmpty: { errorMessage: res.t('missingNewPassword') },
},
});
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) {
throw validationErrors;
}
- let oldPassword = req.body.password;
- let isValidPassword = await passwordUtils.compare(user, oldPassword);
+ const oldPassword = req.body.password;
+ const isValidPassword = await passwordUtils.compare(user, oldPassword);
if (!isValidPassword) throw new NotAuthorized(res.t('wrongPassword'));
- let newPassword = req.body.newPassword;
+ const { newPassword } = req.body;
if (newPassword !== req.body.confirmPassword) throw new NotAuthorized(res.t('passwordConfirmationMatch'));
// set new password and make sure it's using bcrypt for hashing
@@ -276,7 +281,7 @@ api.updatePassword = {
* @apiParam (Body) {String} email The email address of the user
*
* @apiSuccess {String} message The localized success message
- **/
+ * */
api.resetPassword = {
method: 'POST',
middlewares: [],
@@ -284,14 +289,14 @@ api.resetPassword = {
async handler (req, res) {
req.checkBody({
email: {
- notEmpty: {errorMessage: res.t('missingEmail')},
+ notEmpty: { errorMessage: res.t('missingEmail') },
},
});
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let email = req.body.email.toLowerCase();
- let user = await User.findOne({ 'auth.local.email': email }).exec();
+ const email = req.body.email.toLowerCase();
+ const user = await User.findOne({ 'auth.local.email': email }).exec();
if (user) {
// create an encrypted link to be used to reset the password
@@ -299,12 +304,12 @@ api.resetPassword = {
userId: user._id,
expiresAt: moment().add({ hours: 24 }),
}));
- let link = `${BASE_URL}/static/user/auth/local/reset-password-set-new-one?code=${passwordResetCode}`;
+ const link = `${BASE_URL}/static/user/auth/local/reset-password-set-new-one?code=${passwordResetCode}`;
user.auth.local.passwordResetCode = passwordResetCode;
sendTxnEmail(user, 'reset-password', [
- {name: 'PASSWORD_RESET_LINK', content: link},
+ { name: 'PASSWORD_RESET_LINK', content: link },
]);
await user.save();
@@ -330,23 +335,23 @@ api.updateEmail = {
middlewares: [authWithHeaders()],
url: '/user/auth/update-email',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
if (!user.auth.local.email) throw new BadRequest(res.t('userHasNoLocalRegistration'));
req.checkBody('newEmail', res.t('newEmailRequired')).notEmpty().isEmail();
req.checkBody('password', res.t('missingPassword')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let emailAlreadyInUse = await User.findOne({
+ const emailAlreadyInUse = await User.findOne({
'auth.local.email': req.body.newEmail.toLowerCase(),
- }).select({_id: 1}).lean().exec();
+ }).select({ _id: 1 }).lean().exec();
if (emailAlreadyInUse) throw new NotAuthorized(res.t('cannotFulfillReq', { techAssistanceEmail: TECH_ASSISTANCE_EMAIL }));
- let password = req.body.password;
- let isValidPassword = await passwordUtils.compare(user, password);
+ const { password } = req.body;
+ const isValidPassword = await passwordUtils.compare(user, password);
if (!isValidPassword) throw new NotAuthorized(res.t('wrongPassword'));
// if password is using old sha1 encryption, change it
@@ -377,25 +382,25 @@ api.resetPasswordSetNewOne = {
method: 'POST',
url: '/user/auth/reset-password-set-new-one',
async handler (req, res) {
- let user = await validatePasswordResetCodeAndFindUser(req.body.code);
- let isValidCode = Boolean(user);
+ const user = await passwordUtils.validatePasswordResetCodeAndFindUser(req.body.code);
+ const isValidCode = Boolean(user);
if (!isValidCode) throw new NotAuthorized(res.t('invalidPasswordResetCode'));
req.checkBody('newPassword', res.t('missingNewPassword')).notEmpty();
req.checkBody('confirmPassword', res.t('missingNewPassword')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let newPassword = req.body.newPassword;
- let confirmPassword = req.body.confirmPassword;
+ const { newPassword } = req.body;
+ const { confirmPassword } = req.body;
if (newPassword !== confirmPassword) {
throw new BadRequest(res.t('passwordConfirmationMatch'));
}
// set new password and make sure it's using bcrypt for hashing
- await convertToBcrypt(user, String(newPassword));
+ await passwordUtils.convertToBcrypt(user, String(newPassword));
user.auth.local.passwordResetCode = undefined; // Reset saved password reset code
await user.save();
@@ -405,7 +410,8 @@ api.resetPasswordSetNewOne = {
/**
* @api {delete} /api/v3/user/auth/social/:network Delete social authentication method
- * @apiDescription Remove a social authentication method (only facebook supported) from a user profile. The user must have local authentication enabled
+ * @apiDescription Remove a social authentication method (only facebook supported)
+ * from a user profile. The user must have local authentication enabled
* @apiName UserDeleteSocial
* @apiGroup User
*
@@ -416,20 +422,19 @@ api.deleteSocial = {
url: '/user/auth/social/:network',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let network = req.params.network;
- let isSupportedNetwork = common.constants.SUPPORTED_SOCIAL_NETWORKS.find(supportedNetwork => {
- return supportedNetwork.key === network;
- });
+ const { user } = res.locals;
+ const { network } = req.params;
+ const isSupportedNetwork = common.constants.SUPPORTED_SOCIAL_NETWORKS
+ .find(supportedNetwork => supportedNetwork.key === network);
if (!isSupportedNetwork) throw new BadRequest(res.t('unsupportedNetwork'));
if (!hasBackupAuth(user, network)) throw new NotAuthorized(res.t('cantDetachSocial'));
- let unset = {
+ const unset = {
[`auth.${network}`]: 1,
};
- await User.update({_id: user._id}, {$unset: unset}).exec();
+ await User.update({ _id: user._id }, { $unset: unset }).exec();
res.respond(200, {});
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/challenges.js b/website/server/controllers/api-v3/challenges.js
index f0a60396a9..236bf198c4 100644
--- a/website/server/controllers/api-v3/challenges.js
+++ b/website/server/controllers/api-v3/challenges.js
@@ -1,6 +1,6 @@
-import { authWithHeaders, authWithSession } from '../../middlewares/auth';
import _ from 'lodash';
import cloneDeep from 'lodash/cloneDeep';
+import { authWithHeaders, authWithSession } from '../../middlewares/auth';
import { model as Challenge } from '../../models/challenge';
import {
model as Group,
@@ -29,7 +29,7 @@ import {
} from '../../libs/challenges';
import apiError from '../../libs/apiError';
-let api = {};
+const api = {};
/**
* @apiDefine ChallengeLeader Challenge Leader
@@ -58,12 +58,14 @@ let api = {};
* @apiSuccess {UUID} challenge._id Same as `challenge.id`.
* @apiSuccess {String} challenge.prize Number of gems offered as prize to winner (can be 0).
* @apiSuccess {String} challenge.memberCount Number users participating in challenge.
- * @apiSuccess {Object} challenge.tasksOrder Object containing IDs of the challenge's tasks and rewards in their preferred sort order.
+ * @apiSuccess {Object} challenge.tasksOrder Object containing IDs of the challenge's
+ * tasks and rewards in their preferred sort order.
* @apiSuccess {Array} challenge.tasksOrder.rewards Array of `reward` task IDs.
* @apiSuccess {Array} challenge.tasksOrder.todos Array of `todo` task IDs.
* @apiSuccess {Array} challenge.tasksOrder.dailys Array of `daily` task IDs.
* @apiSuccess {Array} challenge.tasksOrder.habits Array of `habit` task IDs.
- * @apiSuccess {Boolean} challenge.official Boolean indicating if this is an official Habitica challenge.
+ * @apiSuccess {Boolean} challenge.official Boolean indicating if
+ * this is an official Habitica challenge.
*
*/
@@ -159,24 +161,32 @@ let api = {};
* @api {post} /api/v3/challenges Create a new challenge
* @apiName CreateChallenge
* @apiGroup Challenge
- * @apiDescription Creates a challenge. Cannot create associated tasks with this route. See CreateChallengeTasks.
+ * @apiDescription Creates a challenge. Cannot create associated
+ * tasks with this route. See CreateChallengeTasks.
*
* @apiParam (Body) {Object} challenge An object representing the challenge to be created
* @apiParam (Body) {UUID} challenge.group The id of the group to which the challenge belongs
* @apiParam (Body) {String} challenge.name The full name of the challenge
- * @apiParam (Body) {String} challenge.shortName A shortened name for the challenge, to be used as a tag
- * @apiParam (Body) {String} [challenge.summary] A short summary advertising the main purpose of the challenge; maximum 250 characters; if not supplied, challenge.name will be used
+ * @apiParam (Body) {String} challenge.shortName A shortened name for the challenge,
+ * to be used as a tag.
+ * @apiParam (Body) {String} [challenge.summary] A short summary advertising the main purpose
+ * of the challenge; maximum 250 characters;
+ * if not supplied, challenge.name will be used.
* @apiParam (Body) {String} [challenge.description] A detailed description of the challenge
- * @apiParam (Body) {Boolean} [official=false] Whether or not a challenge is an official Habitica challenge (requires admin)
- * @apiParam (Body) {Number} [challenge.prize=0] Number of gems offered as a prize to challenge winner
+ * @apiParam (Body) {Boolean} [official=false] Whether or not a challenge is an official
+ * Habitica challenge (requires admin).
+ * @apiParam (Body) {Number} [challenge.prize=0] Number of gems offered as
+ * a prize to challenge winner.
*
* @apiSuccess (201) {Object} challenge The newly created challenge.
* @apiUse SuccessfulChallengeRequest
*
* @apiUse ChallengeSuccessExample
*
- * @apiError (401) {NotAuthorized} CantAffordPrize User does not have enough gems to offer this prize.
- * @apiError (400) {BadRequest} ChallengeValidationFailed Invalid or missing parameter in challenge body.
+ * @apiError (401) {NotAuthorized} CantAffordPrize User does not have enough
+ gems to offer this prize.
+ * @apiError (400) {BadRequest} ChallengeValidationFailed Invalid or missing parameter
+ in challenge body.
*
* @apiUse GroupNotFound
* @apiUse UserNotFound
@@ -186,19 +196,19 @@ api.createChallenge = {
url: '/challenges',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkBody('group', apiError('groupIdRequired')).notEmpty();
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const {savedChal, group} = await createChallenge(user, req, res);
+ const { savedChal, group } = await createChallenge(user, req, res);
- let response = savedChal.toJSON();
+ const response = savedChal.toJSON();
response.leader = { // the leader is the authenticated user
_id: user._id,
- profile: {name: user.profile.name},
+ profile: { name: user.profile.name },
};
response.group = getChallengeGroupResponse(group);
@@ -235,18 +245,20 @@ api.joinChallenge = {
url: '/challenges/:challengeId/join',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec();
+ const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
if (challenge.isMember(user)) throw new NotAuthorized(res.t('userAlreadyInChallenge'));
- let group = await Group.getGroup({user, groupId: challenge.group, fields: basicGroupFields, optionalMembership: true});
+ const group = await Group.getGroup({
+ user, groupId: challenge.group, fields: basicGroupFields, optionalMembership: true,
+ });
if (!group || !challenge.canJoin(user, group)) throw new NotFound(res.t('challengeNotFound'));
challenge.memberCount += 1;
@@ -254,12 +266,12 @@ api.joinChallenge = {
addUserJoinChallengeNotification(user);
// Add all challenge's tasks to user's tasks and save the challenge
- let results = await Promise.all([challenge.syncToUser(user), challenge.save()]);
+ const results = await Promise.all([challenge.syncToUser(user), challenge.save()]);
- let response = results[1].toJSON();
+ const response = results[1].toJSON();
response.group = getChallengeGroupResponse(group);
- let chalLeader = await User.findById(response.leader).select(nameFields).exec();
- response.leader = chalLeader ? chalLeader.toJSON({minimize: true}) : null;
+ const chalLeader = await User.findById(response.leader).select(nameFields).exec();
+ response.leader = chalLeader ? chalLeader.toJSON({ minimize: true }) : null;
res.analytics.track('challenge join', {
uuid: user._id,
@@ -280,7 +292,9 @@ api.joinChallenge = {
* @apiName LeaveChallenge
* @apiGroup Challenge
* @apiParam (Path) {UUID} challengeId The challenge _id
- * @apiParam (Body) {String="remove-all","keep-all"} [keep="keep-all"] Whether or not to keep or remove the challenge's tasks
+ * @apiParam (Body) {String="remove-all","keep-all"} [keep="keep-all"] Whether or not to
+ * keep or remove the
+ * challenge's tasks.
*
* @apiSuccess {Object} data An empty object
*
@@ -292,15 +306,15 @@ api.leaveChallenge = {
url: '/challenges/:challengeId/leave',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let keep = req.body.keep === 'remove-all' ? 'remove-all' : 'keep-all';
+ const { user } = res.locals;
+ const keep = req.body.keep === 'remove-all' ? 'remove-all' : 'keep-all';
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec();
+ const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
if (!challenge.isMember(user)) throw new NotAuthorized(res.t('challengeMemberNotFound'));
@@ -326,9 +340,12 @@ api.leaveChallenge = {
* @api {get} /api/v3/challenges/user Get challenges for a user
* @apiName GetUserChallenges
* @apiGroup Challenge
- * @apiDescription Get challenges the user has access to. Includes public challenges, challenges belonging to the user's group, and challenges the user has already joined.
+ * @apiDescription Get challenges the user has access to. Includes public challenges,
+ * challenges belonging to the user's group, and challenges the user has already joined.
*
- * @apiSuccess {Object[]} challenges An array of challenges sorted with official challenges first, followed by the challenges in order from newest to oldest
+ * @apiSuccess {Object[]} challenges An array of challenges sorted with official
+ * challenges first, followed by the challenges
+ * in order from newest to oldest.
*
* @apiUse SuccessfulChallengeRequest
*
@@ -342,50 +359,50 @@ api.getUserChallenges = {
middlewares: [authWithHeaders()],
async handler (req, res) {
const CHALLENGES_PER_PAGE = 10;
- const page = req.query.page;
+ const { page } = req.query;
- const user = res.locals.user;
- let orOptions = [
- {_id: {$in: user.challenges}}, // Challenges where the user is participating
+ const { user } = res.locals;
+ const orOptions = [
+ { _id: { $in: user.challenges } }, // Challenges where the user is participating
];
- const owned = req.query.owned;
- if (!owned) {
- orOptions.push({leader: user._id});
+ const { owned } = req.query;
+ if (!owned) {
+ orOptions.push({ leader: user._id });
}
if (!req.query.member) {
orOptions.push({
- group: {$in: user.getGroups()},
+ group: { $in: user.getGroups() },
}); // Challenges in groups where I'm a member
}
- let query = {
- $and: [{$or: orOptions}],
+ const query = {
+ $and: [{ $or: orOptions }],
};
if (owned) {
if (owned === 'not_owned') {
- query.$and.push({leader: {$ne: user._id}});
+ query.$and.push({ leader: { $ne: user._id } });
}
if (owned === 'owned') {
- query.$and.push({leader: user._id});
+ query.$and.push({ leader: user._id });
}
}
if (req.query.search) {
- const searchOr = {$or: []};
+ const searchOr = { $or: [] };
const searchWords = _.escapeRegExp(req.query.search).split(' ').join('|');
const searchQuery = { $regex: new RegExp(`${searchWords}`, 'i') };
- searchOr.$or.push({name: searchQuery});
- searchOr.$or.push({description: searchQuery});
+ searchOr.$or.push({ name: searchQuery });
+ searchOr.$or.push({ description: searchQuery });
query.$and.push(searchOr);
}
if (req.query.categories) {
- let categorySlugs = req.query.categories.split(',');
- query.categories = { $elemMatch: { slug: {$in: categorySlugs} } };
+ const categorySlugs = req.query.categories.split(',');
+ query.categories = { $elemMatch: { slug: { $in: categorySlugs } } };
}
let mongoQuery = Challenge.find(query)
@@ -404,20 +421,20 @@ api.getUserChallenges = {
let resChals = challenges.map(challenge => challenge.toJSON());
- resChals = _.orderBy(resChals, [challenge => {
- return challenge.categories.map(category => category.slug).includes('habitica_official');
- }], ['desc']);
+ resChals = _.orderBy(resChals, [challenge => challenge.categories.map(category => category.slug).includes('habitica_official')], ['desc']);
// Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833
- await Promise.all(resChals.map((chal, index) => {
- return Promise.all([
- User.findById(chal.leader).select(`${nameFields} backer contributor`).exec(),
- Group.findById(chal.group).select(basicGroupFields).exec(),
- ]).then(populatedData => {
- resChals[index].leader = populatedData[0] ? populatedData[0].toJSON({minimize: true}) : null;
- resChals[index].group = populatedData[1] ? populatedData[1].toJSON({minimize: true}) : null;
- });
- }));
+ await Promise.all(resChals.map((chal, index) => Promise.all([
+ User.findById(chal.leader).select(`${nameFields} backer contributor`).exec(),
+ Group.findById(chal.group).select(basicGroupFields).exec(),
+ ]).then(populatedData => {
+ resChals[index].leader = populatedData[0]
+ ? populatedData[0].toJSON({ minimize: true })
+ : null;
+ resChals[index].group = populatedData[1]
+ ? populatedData[1].toJSON({ minimize: true })
+ : null;
+ })));
res.respond(200, resChals);
},
@@ -429,9 +446,11 @@ api.getUserChallenges = {
* @apiName GetGroupChallenges
* @apiGroup Challenge
*
- * @apiParam (Path) {UUID} groupId The group id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {UUID} groupId The group id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted)
*
- * @apiSuccess {Array} data An array of challenges sorted with official challenges first, followed by the challenges in order from newest to oldest
+ * @apiSuccess {Array} data An array of challenges sorted with official challenges first,
+ * followed by the challenges in order from newest to oldest.
*
* @apiUse SuccessfulChallengeRequest
* @apiUse ChallengeArrayExample
@@ -446,12 +465,12 @@ api.getGroupChallenges = {
userFieldsToInclude: ['party', 'guilds'], // Some fields are always loaded (see middlewares/auth)
})],
async handler (req, res) {
- let user = res.locals.user;
- let groupId = req.params.groupId;
+ const { user } = res.locals;
+ let { groupId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
if (groupId === 'party') groupId = user.party._id;
@@ -462,25 +481,28 @@ api.getGroupChallenges = {
const challenges = await Challenge.find({ group: groupId })
.sort('-createdAt')
- // .populate('leader', nameFields) // Only populate the leader as the group is implicit // see below why we're not using populate
+ // Only populate the leader as the group is implicit // see below why we're not using populate
+ // .populate('leader', nameFields)
.exec();
let resChals = challenges.map(challenge => challenge.toJSON());
- resChals = _.orderBy(resChals, [challenge => {
- return challenge.categories.map(category => category.slug).includes('habitica_official');
- }], ['desc']);
+ resChals = _.orderBy(
+ resChals,
+ [challenge => challenge.categories.map(category => category.slug).includes('habitica_official')],
+ ['desc'],
+ );
// Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833
- await Promise.all(resChals.map((chal, index) => {
- return User
- .findById(chal.leader)
- .select(nameFields)
- .exec()
- .then(populatedLeader => {
- resChals[index].leader = populatedLeader ? populatedLeader.toJSON({minimize: true}) : null;
- });
- }));
+ await Promise.all(resChals.map((chal, index) => User
+ .findById(chal.leader)
+ .select(nameFields)
+ .exec()
+ .then(populatedLeader => {
+ resChals[index].leader = populatedLeader
+ ? populatedLeader.toJSON({ minimize: true })
+ : null;
+ })));
res.respond(200, resChals);
},
@@ -506,27 +528,29 @@ api.getChallenge = {
async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let user = res.locals.user;
- let challengeId = req.params.challengeId;
+ const { user } = res.locals;
+ const { challengeId } = req.params;
// Don't populate the group as we'll fetch it manually later
// .populate('leader', nameFields)
- let challenge = await Challenge.findById(challengeId).exec();
+ const challenge = await Challenge.findById(challengeId).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
// Fetching basic group data
- let group = await Group.getGroup({user, groupId: challenge.group, fields: basicGroupFields, optionalMembership: true});
+ const group = await Group.getGroup({
+ user, groupId: challenge.group, fields: basicGroupFields, optionalMembership: true,
+ });
if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound'));
- let chalRes = challenge.toJSON();
- chalRes.group = group.toJSON({minimize: true});
+ const chalRes = challenge.toJSON();
+ chalRes.group = group.toJSON({ minimize: true });
// Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833
- let chalLeader = await User.findById(chalRes.leader).select(nameFields).exec();
- chalRes.leader = chalLeader ? chalLeader.toJSON({minimize: true}) : null;
+ const chalLeader = await User.findById(chalRes.leader).select(nameFields).exec();
+ chalRes.leader = chalLeader ? chalLeader.toJSON({ minimize: true }) : null;
res.respond(200, chalRes);
},
@@ -550,36 +574,41 @@ api.exportChallengeCsv = {
async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let user = res.locals.user;
- let challengeId = req.params.challengeId;
+ const { user } = res.locals;
+ const { challengeId } = req.params;
- let challenge = await Challenge.findById(challengeId).select('_id group leader tasksOrder').exec();
+ const challenge = await Challenge.findById(challengeId).select('_id group leader tasksOrder').exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
- let group = await Group.getGroup({user, groupId: challenge.group, fields: '_id type privacy', optionalMembership: true});
+ const group = await Group.getGroup({
+ user, groupId: challenge.group, fields: '_id type privacy', optionalMembership: true,
+ });
if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound'));
- // In v2 this used the aggregation framework to run some computation on MongoDB but then iterated through all
+ // In v2 this used the aggregation framework to run some
+ // computation on MongoDB but then iterated through all
// results on the server so the perf difference isn't that big (hopefully)
- let [members, tasks] = await Promise.all([
- User.find({challenges: challengeId})
+ const [members, tasks] = await Promise.all([
+ User.find({ challenges: challengeId })
.select(nameFields)
- .sort({_id: 1})
+ .sort({ _id: 1 })
.lean() // so we don't involve mongoose
.exec(),
Tasks.Task.find({
'challenge.id': challengeId,
- userId: {$exists: true},
- }).sort({userId: 1, text: 1})
+ userId: { $exists: true },
+ }).sort({ userId: 1, text: 1 })
.select('userId type text value notes streak')
- .lean().exec(),
+ .lean()
+ .exec(),
]);
- let resArray = members.map(member => [member._id, member.profile.name, member.auth.local.username]);
+ let resArray = members
+ .map(member => [member._id, member.profile.name, member.auth.local.username]);
let lastUserId;
let index = -1;
@@ -595,8 +624,8 @@ api.exportChallengeCsv = {
return;
}
while (task.userId !== lastUserId) {
- index++;
- lastUserId = resArray[index][0]; // resArray[index][0] is an user id
+ index += 1;
+ [lastUserId] = resArray[index]; // resArray[index][0] is an user id
}
const streak = task.streak || 0;
@@ -604,16 +633,18 @@ api.exportChallengeCsv = {
resArray[index].push(`${task.type}:${task.text}`, task.value, task.notes, streak);
});
- // The first row is going to be UUID name Task Value Notes repeated n times for the n challenge tasks
- let challengeTasks = _.reduce(challenge.tasksOrder.toObject(), (result, array) => {
- return result.concat(array);
- }, []).sort();
+ // The first row is going to be UUID name Task Value Notes
+ // repeated n times for the n challenge tasks
+ const challengeTasks = _.reduce(
+ challenge.tasksOrder.toObject(),
+ (result, array) => result.concat(array), [],
+ ).sort();
resArray.unshift(['UUID', 'Display Name', 'Username']);
_.times(challengeTasks.length, () => resArray[0].push('Task', 'Value', 'Notes', 'Streak'));
// Remove lines for users without tasks info
- resArray = resArray.filter((line) => {
+ resArray = resArray.filter(line => {
if (line.length === 2) { // only user data ([id, profile name]), no task data
return false;
}
@@ -626,7 +657,7 @@ api.exportChallengeCsv = {
'Content-disposition': `attachment; filename=${challengeId}.csv`,
});
- let csvRes = await csvStringify(resArray);
+ const csvRes = await csvStringify(resArray);
res.status(200).send(csvRes);
},
};
@@ -660,26 +691,28 @@ api.updateChallenge = {
async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let user = res.locals.user;
- let challengeId = req.params.challengeId;
+ const { user } = res.locals;
+ const { challengeId } = req.params;
- let challenge = await Challenge.findById(challengeId).exec();
+ const challenge = await Challenge.findById(challengeId).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
- let group = await Group.getGroup({user, groupId: challenge.group, fields: basicGroupFields, optionalMembership: true});
+ const group = await Group.getGroup({
+ user, groupId: challenge.group, fields: basicGroupFields, optionalMembership: true,
+ });
if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound'));
if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyLeaderUpdateChal'));
_.merge(challenge, Challenge.sanitizeUpdate(req.body));
- let savedChal = await challenge.save();
- let response = savedChal.toJSON();
+ const savedChal = await challenge.save();
+ const response = savedChal.toJSON();
response.group = getChallengeGroupResponse(group);
- let chalLeader = await User.findById(response.leader).select(nameFields).exec();
- response.leader = chalLeader ? chalLeader.toJSON({minimize: true}) : null;
+ const chalLeader = await User.findById(response.leader).select(nameFields).exec();
+ response.leader = chalLeader ? chalLeader.toJSON({ minimize: true }) : null;
res.respond(200, response);
},
};
@@ -700,19 +733,19 @@ api.deleteChallenge = {
url: '/challenges/:challengeId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let challenge = await Challenge.findOne({_id: req.params.challengeId}).exec();
+ const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyLeaderDeleteChal'));
// Close channel in background, some ops are run in the background without `await`ing
- await challenge.closeChal({broken: 'CHALLENGE_DELETED'});
+ await challenge.closeChal({ broken: 'CHALLENGE_DELETED' });
res.analytics.track('challenge delete', {
uuid: user._id,
@@ -745,23 +778,23 @@ api.selectChallengeWinner = {
url: '/challenges/:challengeId/selectWinner/:winnerId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
req.checkParams('winnerId', res.t('winnerIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let challenge = await Challenge.findOne({_id: req.params.challengeId}).exec();
+ const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyLeaderDeleteChal'));
- let winner = await User.findOne({_id: req.params.winnerId}).exec();
- if (!winner || winner.challenges.indexOf(challenge._id) === -1) throw new NotFound(res.t('winnerNotFound', {userId: req.params.winnerId}));
+ const winner = await User.findOne({ _id: req.params.winnerId }).exec();
+ if (!winner || winner.challenges.indexOf(challenge._id) === -1) throw new NotFound(res.t('winnerNotFound', { userId: req.params.winnerId }));
// Close channel in background, some ops are run in the background without `await`ing
- await challenge.closeChal({broken: 'CHALLENGE_CLOSED', winner});
+ await challenge.closeChal({ broken: 'CHALLENGE_CLOSED', winner });
res.analytics.track('challenge close', {
uuid: user._id,
@@ -794,26 +827,26 @@ api.cloneChallenge = {
url: '/challenges/:challengeId/clone',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const challengeToClone = await Challenge.findOne({_id: req.params.challengeId}).exec();
+ const challengeToClone = await Challenge.findOne({ _id: req.params.challengeId }).exec();
if (!challengeToClone) throw new NotFound(res.t('challengeNotFound'));
- const {savedChal} = await createChallenge(user, req, res);
+ const { savedChal } = await createChallenge(user, req, res);
const challengeTasks = await Tasks.Task.find({
'challenge.id': challengeToClone._id,
- userId: {$exists: false},
+ userId: { $exists: false },
}).exec();
const tasksToClone = challengeTasks.map(task => {
- let clonedTask = cloneDeep(task.toObject());
- let omittedTask = cleanUpTask(clonedTask);
+ const clonedTask = cloneDeep(task.toObject());
+ const omittedTask = cleanUpTask(clonedTask);
return omittedTask;
});
@@ -821,10 +854,10 @@ api.cloneChallenge = {
body: tasksToClone,
};
- const clonedTasks = await createTasks(taskRequest, res, {user, challenge: savedChal});
+ const clonedTasks = await createTasks(taskRequest, res, { user, challenge: savedChal });
- res.respond(200, {clonedTasks, clonedChallenge: savedChal});
+ res.respond(200, { clonedTasks, clonedChallenge: savedChal });
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/chat.js b/website/server/controllers/api-v3/chat.js
index e56337e76d..1a4466e0cb 100644
--- a/website/server/controllers/api-v3/chat.js
+++ b/website/server/controllers/api-v3/chat.js
@@ -1,3 +1,4 @@
+import nconf from 'nconf';
import { authWithHeaders } from '../../middlewares/auth';
import { model as Group } from '../../models/group';
import { model as User } from '../../models/user';
@@ -10,19 +11,17 @@ import {
} from '../../libs/errors';
import { removeFromArray } from '../../libs/collectionManipulators';
import { getUserInfo, getGroupUrl, sendTxn } from '../../libs/email';
-import slack from '../../libs/slack';
+import * as slack from '../../libs/slack';
import { chatReporterFactory } from '../../libs/chatReporting/chatReporterFactory';
-import { getAuthorEmailFromMessage} from '../../libs/chat';
-import nconf from 'nconf';
+import { getAuthorEmailFromMessage } from '../../libs/chat';
import bannedWords from '../../libs/bannedWords';
import guildsAllowingBannedWords from '../../libs/guildsAllowingBannedWords';
import { getMatchesByWordArray } from '../../libs/stringUtils';
import bannedSlurs from '../../libs/bannedSlurs';
import apiError from '../../libs/apiError';
+import { highlightMentions } from '../../libs/highlightMentions';
-const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) => {
- return { email, canSend: true };
-});
+const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map(email => ({ email, canSend: true }));
/**
* @apiDefine MessageNotFound
@@ -44,10 +43,10 @@ const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email)
* @apiError (400) {badRequest} messageIdRequired A message ID is required
*/
-let api = {};
+const api = {};
function textContainsBannedSlur (message) {
- let bannedSlursMatched = getMatchesByWordArray(message, bannedSlurs);
+ const bannedSlursMatched = getMatchesByWordArray(message, bannedSlurs);
return bannedSlursMatched.length > 0;
}
@@ -57,7 +56,8 @@ function textContainsBannedSlur (message) {
* @apiGroup Chat
* @apiDescription Fetches an array of messages from a group
*
- * @apiParam (Path) {String} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {String} groupId The group _id ('party' for the user party and
+ * 'habitrpg' for tavern are accepted).
*
* @apiSuccess {Array} data An array of chat messages
*
@@ -69,15 +69,15 @@ api.getChat = {
url: '/groups/:groupId/chat',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const groupId = req.params.groupId;
- let group = await Group.getGroup({user, groupId, fields: 'chat'});
+ const { groupId } = req.params;
+ const group = await Group.getGroup({ user, groupId, fields: 'chat' });
if (!group) throw new NotFound(res.t('groupNotFound'));
const groupChat = await Group.toJSONCleanChat(group, user);
@@ -90,62 +90,63 @@ function getBannedWordsFromText (message) {
}
-const mentionRegex = new RegExp('\\B@[-\\w]+', 'g');
/**
* @api {post} /api/v3/groups/:groupId/chat Post chat message to a group
* @apiName PostChat
* @apiGroup Chat
* @apiDescription Posts a chat message to a group
*
- * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted)
* @apiParam (Body) {String} message Message The message to post
- * @apiParam (Query) {UUID} previousMsg The previous chat message's UUID which will force a return of the full group chat
+ * @apiParam (Query) {UUID} previousMsg The previous chat message's UUID which will
+ * force a return of the full group chat.
*
* @apiUse GroupNotFound
* @apiUse GroupIdRequired
- * @apiError (400) {NotAuthorized} chatPriviledgesRevoked You cannot do that because your chat privileges have been revoked.
+ * @apiError (400) {NotAuthorized} chatPriviledgesRevoked You cannot do that because
+ * your chat privileges have been revoked.
*/
api.postChat = {
method: 'POST',
url: '/groups/:groupId/chat',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let groupId = req.params.groupId;
- let chatUpdated;
+ const { user } = res.locals;
+ const { groupId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
req.sanitize('message').trim();
req.checkBody('message', res.t('messageGroupChatBlankMessage')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let group = await Group.getGroup({user, groupId});
+ const group = await Group.getGroup({ user, groupId });
// Check message for banned slurs
if (textContainsBannedSlur(req.body.message)) {
- let message = req.body.message;
+ const { message } = req.body;
user.flags.chatRevoked = true;
await user.save();
// Email the mods
- let authorEmail = getUserInfo(user, ['email']).email;
- let groupUrl = getGroupUrl(group);
+ const authorEmail = getUserInfo(user, ['email']).email;
+ const groupUrl = getGroupUrl(group);
- let report = [
- {name: 'MESSAGE_TIME', content: (new Date()).toString()},
- {name: 'MESSAGE_TEXT', content: message},
+ const report = [
+ { name: 'MESSAGE_TIME', content: (new Date()).toString() },
+ { name: 'MESSAGE_TEXT', content: message },
- {name: 'AUTHOR_USERNAME', content: user.profile.name},
- {name: 'AUTHOR_UUID', content: user._id},
- {name: 'AUTHOR_EMAIL', content: authorEmail},
- {name: 'AUTHOR_MODAL_URL', content: `/profile/${user._id}`},
+ { name: 'AUTHOR_USERNAME', content: user.profile.name },
+ { name: 'AUTHOR_UUID', content: user._id },
+ { name: 'AUTHOR_EMAIL', content: authorEmail },
+ { name: 'AUTHOR_MODAL_URL', content: `/profile/${user._id}` },
- {name: 'GROUP_NAME', content: group.name},
- {name: 'GROUP_TYPE', content: group.type},
- {name: 'GROUP_ID', content: group._id},
- {name: 'GROUP_URL', content: groupUrl},
+ { name: 'GROUP_NAME', content: group.name },
+ { name: 'GROUP_TYPE', content: group.type },
+ { name: 'GROUP_ID', content: group._id },
+ { name: 'GROUP_URL', content: groupUrl },
];
sendTxn(FLAG_REPORT_EMAILS, 'slur-report-to-mods', report);
@@ -167,22 +168,26 @@ api.postChat = {
throw new NotAuthorized(res.t('chatPrivilegesRevoked'));
}
- // prevent banned words being posted, except in private guilds/parties and in certain public guilds with specific topics
+ // prevent banned words being posted, except in private guilds/parties
+ // and in certain public guilds with specific topics
if (group.privacy === 'public' && !guildsAllowingBannedWords[group._id]) {
- let matchedBadWords = getBannedWordsFromText(req.body.message);
+ const matchedBadWords = getBannedWordsFromText(req.body.message);
if (matchedBadWords.length > 0) {
- throw new BadRequest(res.t('bannedWordUsed', {swearWordsUsed: matchedBadWords.join(', ')}));
+ throw new BadRequest(res.t('bannedWordUsed', { swearWordsUsed: matchedBadWords.join(', ') }));
}
}
const chatRes = await Group.toJSONCleanChat(group, user);
const lastClientMsg = req.query.previousMsg;
- chatUpdated = lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg ? true : false;
+ const chatUpdated = !!(
+ lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg
+ );
if (group.checkChatSpam(user)) {
throw new NotAuthorized(res.t('messageGroupChatSpam'));
}
+ const [message, mentions, mentionedMembers] = await highlightMentions(req.body.message);
let client = req.headers['x-client'] || '3rd Party';
if (client) {
client = client.replace('habitica-', '');
@@ -191,25 +196,24 @@ api.postChat = {
let flagCount = 0;
if (group.privacy === 'public' && user.flags.chatShadowMuted) {
flagCount = common.constants.CHAT_FLAG_FROM_SHADOW_MUTE;
- let message = req.body.message;
// Email the mods
- let authorEmail = getUserInfo(user, ['email']).email;
- let groupUrl = getGroupUrl(group);
+ const authorEmail = getUserInfo(user, ['email']).email;
+ const groupUrl = getGroupUrl(group);
- let report = [
- {name: 'MESSAGE_TIME', content: (new Date()).toString()},
- {name: 'MESSAGE_TEXT', content: message},
+ const report = [
+ { name: 'MESSAGE_TIME', content: (new Date()).toString() },
+ { name: 'MESSAGE_TEXT', content: message },
- {name: 'AUTHOR_USERNAME', content: user.profile.name},
- {name: 'AUTHOR_UUID', content: user._id},
- {name: 'AUTHOR_EMAIL', content: authorEmail},
- {name: 'AUTHOR_MODAL_URL', content: `/profile/${user._id}`},
+ { name: 'AUTHOR_USERNAME', content: user.profile.name },
+ { name: 'AUTHOR_UUID', content: user._id },
+ { name: 'AUTHOR_EMAIL', content: authorEmail },
+ { name: 'AUTHOR_MODAL_URL', content: `/profile/${user._id}` },
- {name: 'GROUP_NAME', content: group.name},
- {name: 'GROUP_TYPE', content: group.type},
- {name: 'GROUP_ID', content: group._id},
- {name: 'GROUP_URL', content: groupUrl},
+ { name: 'GROUP_NAME', content: group.name },
+ { name: 'GROUP_TYPE', content: group.type },
+ { name: 'GROUP_ID', content: group._id },
+ { name: 'GROUP_URL', content: groupUrl },
];
sendTxn(FLAG_REPORT_EMAILS, 'shadow-muted-post-report-to-mods', report);
@@ -223,17 +227,27 @@ api.postChat = {
});
}
- const newChatMessage = group.sendChat({message: req.body.message, user, flagCount, metaData: null, client, translate: res.t});
- let toSave = [newChatMessage.save()];
+ const newChatMessage = group.sendChat({
+ message,
+ user,
+ flagCount,
+ metaData: null,
+ client,
+ translate: res.t,
+ mentions,
+ mentionedMembers,
+ });
+ const toSave = [newChatMessage.save()];
if (group.type === 'party') {
user.party.lastMessageSeen = newChatMessage.id;
toSave.push(user.save());
}
+
await Promise.all(toSave);
- let analyticsObject = {
+ const analyticsObject = {
uuid: user._id,
hitType: 'event',
category: 'behavior',
@@ -242,7 +256,6 @@ api.postChat = {
headers: req.headers,
};
- const mentions = req.body.message.match(mentionRegex);
if (mentions) {
analyticsObject.mentionsCount = mentions.length;
} else {
@@ -255,9 +268,9 @@ api.postChat = {
res.analytics.track('group chat', analyticsObject);
if (chatUpdated) {
- res.respond(200, {chat: chatRes.chat});
+ res.respond(200, { chat: chatRes.chat });
} else {
- res.respond(200, {message: newChatMessage});
+ res.respond(200, { message: newChatMessage });
}
},
};
@@ -268,7 +281,8 @@ api.postChat = {
* @apiGroup Chat
* @apiDescription Likes a chat message from a group
*
- * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted).
* @apiParam (Path) {UUID} chatId The chat message _id
*
* @apiSuccess {Object} data The liked chat message
@@ -284,19 +298,19 @@ api.likeChat = {
url: '/groups/:groupId/chat/:chatId/like',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let groupId = req.params.groupId;
+ const { user } = res.locals;
+ const { groupId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
req.checkParams('chatId', apiError('chatIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let group = await Group.getGroup({user, groupId});
+ const group = await Group.getGroup({ user, groupId });
if (!group) throw new NotFound(res.t('groupNotFound'));
- let message = await Chat.findOne({_id: req.params.chatId}).exec();
+ const message = await Chat.findOne({ _id: req.params.chatId }).exec();
if (!message) throw new NotFound(res.t('messageGroupChatNotFound'));
// @TODO correct this error type
if (message.uuid === user._id) throw new NotFound(res.t('messageGroupChatLikeOwnMessage'));
@@ -312,11 +326,14 @@ api.likeChat = {
/**
* @api {post} /api/v3/groups/:groupId/chat/:chatId/flag Flag a group chat message
- * @apiDescription A message will be hidden from chat if two or more users flag a message. It will be hidden immediately if a moderator flags the message. An email is sent to the moderators about every flagged message.
+ * @apiDescription A message will be hidden from chat if two or more users flag a message.
+ * It will be hidden immediately if a moderator flags the message.
+ * An email is sent to the moderators about every flagged message.
* @apiName FlagChat
* @apiGroup Chat
*
- * @apiParam (Path) {UUID} groupId The group id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {UUID} groupId The group id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted)
* @apiParam (Path) {UUID} chatId The chat message id
* @apiParam (Body) {String} [comment] explain why the message was flagged
*
@@ -334,8 +351,10 @@ api.likeChat = {
* @apiUse MessageNotFound
* @apiUse GroupIdRequired
* @apiUse ChatIdRequired
- * @apiError (404) {NotFound} AlreadyFlagged Chat messages cannot be flagged more than once by a user
- * @apiError (404) {NotFound} messageGroupChatFlagAlreadyReported The message has already been flagged
+ * @apiError (404) {NotFound} AlreadyFlagged Chat messages cannot be flagged
+ more than once by a user
+ * @apiError (404) {NotFound} messageGroupChatFlagAlreadyReported The message
+ has already been flagged.
*/
api.flagChat = {
method: 'POST',
@@ -350,12 +369,14 @@ api.flagChat = {
/**
* @api {post} /api/v3/groups/:groupId/chat/:chatId/clearflags Clear flags
- * @apiDescription Resets the flag count on a chat message. Retains the id of the user's that have flagged the message. (Only visible to moderators)
+ * @apiDescription Resets the flag count on a chat message.
+ * Retains the id of the user's that have flagged the message. (Only visible to moderators)
* @apiPermission Admin
* @apiName ClearFlags
* @apiGroup Chat
*
- * @apiParam (Path) {UUID} groupId The group id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {UUID} groupId The group id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted)
* @apiParam (Path) {UUID} chatId The chat message id
*
* @apiSuccess {Object} data An empty object
@@ -371,55 +392,55 @@ api.clearChatFlags = {
url: '/groups/:groupId/chat/:chatId/clearflags',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let groupId = req.params.groupId;
- let chatId = req.params.chatId;
+ const { user } = res.locals;
+ const { groupId } = req.params;
+ const { chatId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
req.checkParams('chatId', apiError('chatIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
if (!user.contributor.admin) {
throw new NotAuthorized(res.t('messageGroupChatAdminClearFlagCount'));
}
- let group = await Group.getGroup({
+ const group = await Group.getGroup({
user,
groupId,
optionalMembership: user.contributor.admin,
});
if (!group) throw new NotFound(res.t('groupNotFound'));
- let message = await Chat.findOne({_id: chatId}).exec();
+ const message = await Chat.findOne({ _id: chatId }).exec();
if (!message) throw new NotFound(res.t('messageGroupChatNotFound'));
message.flagCount = 0;
await message.save();
- let adminEmailContent = getUserInfo(user, ['email']).email;
- let authorEmail = getAuthorEmailFromMessage(message);
- let groupUrl = getGroupUrl(group);
+ const adminEmailContent = getUserInfo(user, ['email']).email;
+ const authorEmail = getAuthorEmailFromMessage(message);
+ const groupUrl = getGroupUrl(group);
sendTxn(FLAG_REPORT_EMAILS, 'unflag-report-to-mods', [
- {name: 'MESSAGE_TIME', content: (new Date(message.timestamp)).toString()},
- {name: 'MESSAGE_TEXT', content: message.text},
+ { name: 'MESSAGE_TIME', content: (new Date(message.timestamp)).toString() },
+ { name: 'MESSAGE_TEXT', content: message.text },
- {name: 'ADMIN_USERNAME', content: user.profile.name},
- {name: 'ADMIN_UUID', content: user._id},
- {name: 'ADMIN_EMAIL', content: adminEmailContent},
- {name: 'ADMIN_MODAL_URL', content: `/profile/${user._id}`},
+ { name: 'ADMIN_USERNAME', content: user.profile.name },
+ { name: 'ADMIN_UUID', content: user._id },
+ { name: 'ADMIN_EMAIL', content: adminEmailContent },
+ { name: 'ADMIN_MODAL_URL', content: `/profile/${user._id}` },
- {name: 'AUTHOR_USERNAME', content: message.user},
- {name: 'AUTHOR_UUID', content: message.uuid},
- {name: 'AUTHOR_EMAIL', content: authorEmail},
- {name: 'AUTHOR_MODAL_URL', content: `/profile/${message.uuid}`},
+ { name: 'AUTHOR_USERNAME', content: message.user },
+ { name: 'AUTHOR_UUID', content: message.uuid },
+ { name: 'AUTHOR_EMAIL', content: authorEmail },
+ { name: 'AUTHOR_MODAL_URL', content: `/profile/${message.uuid}` },
- {name: 'GROUP_NAME', content: group.name},
- {name: 'GROUP_TYPE', content: group.type},
- {name: 'GROUP_ID', content: group._id},
- {name: 'GROUP_URL', content: groupUrl},
+ { name: 'GROUP_NAME', content: group.name },
+ { name: 'GROUP_TYPE', content: group.type },
+ { name: 'GROUP_ID', content: group._id },
+ { name: 'GROUP_URL', content: groupUrl },
]);
res.respond(200, {});
@@ -431,7 +452,8 @@ api.clearChatFlags = {
* @apiName SeenChat
* @apiGroup Chat
*
- * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted)
*
* @apiSuccess {Object} data An empty object
* @apiUse GroupIdRequired
@@ -441,19 +463,20 @@ api.seenChat = {
url: '/groups/:groupId/chat/seen',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let groupId = req.params.groupId;
+ const { user } = res.locals;
+ const { groupId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- // Do not validate group existence, it doesn't really matter and make it works if the group gets deleted
+ // Do not validate group existence,
+ // it doesn't really matter and make it works if the group gets deleted
// let group = await Group.getGroup({user, groupId});
// if (!group) throw new NotFound(res.t('groupNotFound'));
- let update = {
+ const update = {
$unset: {},
$pull: {},
};
@@ -476,9 +499,9 @@ api.seenChat = {
// Update the user version field manually,
// it cannot be updated in the pre update hook
// See https://github.com/HabitRPG/habitica/pull/9321#issuecomment-354187666 for more info
- user._v++;
+ user._v += 1;
- await User.update({_id: user._id}, update).exec();
+ await User.update({ _id: user._id }, update).exec();
res.respond(200, {});
},
};
@@ -489,38 +512,43 @@ api.seenChat = {
* @apiGroup Chat
* @apiDescription Delete's a chat message from a group
*
- * @apiParam (Query) {UUID} previousMsg The last message's ID fetched by the client so that the whole chat will be returned only if new messages have been posted in the meantime
- * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Query) {UUID} previousMsg The last message's ID fetched by the
+ * client so that the whole chat will be returned only
+ * if new messages have been posted in the meantime.
+ * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted).
* @apiParam (Path) {UUID} chatId The chat message id
*
- * @apiSuccess data The updated chat array or an empty object if no message was posted after previousMsg
+ * @apiSuccess data The updated chat array or an empty object if no message was posted
+ * after previousMsg.
* @apiSuccess {Object} data An empty object when the previous message was deleted
*
* @apiUse GroupNotFound
* @apiUse MessageNotFound
* @apiUse GroupIdRequired
* @apiUse ChatIdRequired
- * @apiError (400) onlyCreatorOrAdminCanDeleteChat Only the creator of the message and admins can delete a chat message
+ * @apiError (400) onlyCreatorOrAdminCanDeleteChat Only the creator of the message and admins
+ can delete a chat message.
*/
api.deleteChat = {
method: 'DELETE',
url: '/groups/:groupId/chat/:chatId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let groupId = req.params.groupId;
- let chatId = req.params.chatId;
+ const { user } = res.locals;
+ const { groupId } = req.params;
+ const { chatId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
req.checkParams('chatId', apiError('chatIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let group = await Group.getGroup({user, groupId, fields: 'chat'});
+ const group = await Group.getGroup({ user, groupId, fields: 'chat' });
if (!group) throw new NotFound(res.t('groupNotFound'));
- let message = await Chat.findOne({_id: chatId}).exec();
+ const message = await Chat.findOne({ _id: chatId }).exec();
if (!message) throw new NotFound(res.t('messageGroupChatNotFound'));
if (user._id !== message.uuid && !user.contributor.admin) {
@@ -529,12 +557,14 @@ api.deleteChat = {
const chatRes = await Group.toJSONCleanChat(group, user);
const lastClientMsg = req.query.previousMsg;
- const chatUpdated = lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg ? true : false;
+ const chatUpdated = !!(
+ lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg
+ );
- await Chat.remove({_id: message._id}).exec();
+ await Chat.remove({ _id: message._id }).exec();
if (chatUpdated) {
- removeFromArray(chatRes.chat, {id: chatId});
+ removeFromArray(chatRes.chat, { id: chatId });
res.respond(200, chatRes.chat);
} else {
res.respond(200, {});
@@ -542,4 +572,4 @@ api.deleteChat = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/content.js b/website/server/controllers/api-v3/content.js
index ed1ede77e2..727a56fa13 100644
--- a/website/server/controllers/api-v3/content.js
+++ b/website/server/controllers/api-v3/content.js
@@ -1,10 +1,10 @@
-import common from '../../../common';
import _ from 'lodash';
-import { langCodes } from '../../libs/i18n';
import fsCallback from 'fs';
import path from 'path';
-import logger from '../../libs/logger';
import util from 'util';
+import logger from '../../libs/logger';
+import { langCodes } from '../../libs/i18n';
+import common from '../../../common';
// Transform fs methods that accept callbacks in ones that return promises
const fs = {
@@ -14,22 +14,26 @@ const fs = {
mkdir: util.promisify(fsCallback.mkdir).bind(fsCallback),
};
-let api = {};
+const api = {};
function walkContent (obj, lang) {
_.each(obj, (item, key, source) => {
- if (_.isPlainObject(item) || _.isArray(item)) return walkContent(item, lang);
- if (_.isFunction(item) && item.i18nLangFunc) source[key] = item(lang);
+ if (_.isPlainObject(item) || _.isArray(item)) {
+ walkContent(item, lang);
+ } else if (_.isFunction(item) && item.i18nLangFunc) {
+ source[key] = item(lang);
+ }
});
}
// After the getContent route is called the first time for a certain language
-// the response is saved on disk and subsequentially served directly from there to reduce computation.
+// the response is saved on disk and subsequentially served
+// directly from there to reduce computation.
// Example: if `cachedContentResponses.en` is true it means that the response is cached
-let cachedContentResponses = {};
+const cachedContentResponses = {};
// Language key set to true while the cache file is being written
-let cacheBeingWritten = {};
+const cacheBeingWritten = {};
_.each(langCodes, code => {
cachedContentResponses[code] = false;
@@ -43,19 +47,20 @@ async function saveContentToDisk (language, content) {
try {
cacheBeingWritten[language] = true;
- await fs.stat(CONTENT_CACHE_PATH); // check if the directory exists, if it doesn't an error is thrown
+ // check if the directory exists, if it doesn't an error is thrown
+ await fs.stat(CONTENT_CACHE_PATH);
await fs.writeFile(`${CONTENT_CACHE_PATH}${language}.json`, content, 'utf8');
cacheBeingWritten[language] = false;
cachedContentResponses[language] = true;
} catch (err) {
- if (err.code === 'ENOENT' && err.syscall === 'stat') { // the directory doesn't exists, create it and retry
+ // the directory doesn't exists, create it and retry
+ if (err.code === 'ENOENT' && err.syscall === 'stat') {
await fs.mkdir(CONTENT_CACHE_PATH);
- return saveContentToDisk(language, content);
+ saveContentToDisk(language, content);
} else {
cacheBeingWritten[language] = false;
logger.error(err);
- return;
}
}
}
@@ -66,7 +71,15 @@ async function saveContentToDisk (language, content) {
* @apiName ContentGet
* @apiGroup Content
*
- * @apiParam (Query) {String="bg","cs","da","de","en","en@pirate","en_GB","es","es_419","fr","he","hu","id","it","ja","nl","pl","pt","pt_BR","ro","ru","sk","sr","sv","uk","zh","zh_TW"} [language=en] Language code used for the items' strings. If the authenticated user makes the request, the content will return with the user's configured language.
+ * @apiParam (Query) {String="bg","cs","da","de",
+ * "en","en@pirate","en_GB",
+ * "es","es_419","fr","he","hu",
+ * "id","it","ja","nl","pl","pt","pt_BR",
+ * "ro","ru","sk","sr","sv",
+ * "uk","zh","zh_TW"} [language=en] Language code used for the items'
+ * strings. If the authenticated user makes
+ * the request, the content will return with
+ * the user's configured language.
*
* @apiSuccess {Object} data Various data about the content of Habitica. The content route
* contains many keys, but the data listed below are the recomended data to use.
@@ -79,8 +92,9 @@ async function saveContentToDisk (language, content) {
* @apiSuccess {Object} data.armoire Data about the armoire.
* @apiSuccess {Array} data.classes The available classes.
* @apiSuccess {Object} data.eggs All available eggs.
- * @apiSuccess {Object} data.timeTravelStable The animals available in the Time Traveler's stable, separated
- * into pets and mounts.
+ * @apiSuccess {Object} data.timeTravelStable The animals available
+ * in the Time Traveler's stable, separated
+ * into pets and mounts.
* @apiSuccess {Object} data.hatchingPotions All the hatching potions.
* @apiSuccess {Object} data.petInfo All the pets with extra info.
* @apiSuccess {Object} data.mountInfo All the mounts with extra info.
@@ -104,7 +118,7 @@ api.getContent = {
noLanguage: true,
async handler (req, res) {
let language = 'en';
- let proposedLang = req.query.language && req.query.language.toString();
+ const proposedLang = req.query.language && req.query.language.toString();
if (proposedLang in cachedContentResponses) {
language = proposedLang;
@@ -125,7 +139,7 @@ api.getContent = {
'Content-Type': 'application/json',
});
- let jsonResString = `{"success": true, "data": ${content}}`;
+ const jsonResString = `{"success": true, "data": ${content}}`;
res.status(200).send(jsonResString);
// save the file in background unless it's already cached or being written right now
@@ -135,4 +149,4 @@ api.getContent = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/coupon.js b/website/server/controllers/api-v3/coupon.js
index 7acc406a44..eba36b7b23 100644
--- a/website/server/controllers/api-v3/coupon.js
+++ b/website/server/controllers/api-v3/coupon.js
@@ -1,16 +1,16 @@
+import _ from 'lodash';
+import couponCode from 'coupon-code';
import csvStringify from '../../libs/csvStringify';
import {
authWithHeaders,
authWithSession,
} from '../../middlewares/auth';
import { ensureSudo } from '../../middlewares/ensureAccessRight';
-import _ from 'lodash';
import * as couponsLib from '../../libs/coupons';
-import couponCode from 'coupon-code';
import apiError from '../../libs/apiError';
import { model as Coupon } from '../../models/coupon';
-let api = {};
+const api = {};
/**
* @apiDefine Sudo Sudo Users
@@ -37,12 +37,10 @@ api.getCoupons = {
url: '/coupons',
middlewares: [authWithSession, ensureSudo],
async handler (req, res) {
- let coupons = await Coupon.find().sort('createdAt').lean().exec();
+ const coupons = await Coupon.find().sort('createdAt').lean().exec();
- let output = [['code', 'event', 'date', 'user']].concat(_.map(coupons, coupon => {
- return [coupon._id, coupon.event, coupon.createdAt, coupon.user];
- }));
- let csv = await csvStringify(output);
+ const output = [['code', 'event', 'date', 'user']].concat(_.map(coupons, coupon => [coupon._id, coupon.event, coupon.createdAt, coupon.user]));
+ const csv = await csvStringify(output);
res.set({
'Content-Type': 'text/csv',
@@ -58,12 +56,15 @@ api.getCoupons = {
* @apiGroup Coupon
* @apiPermission sudo
*
- * @apiParam (Path) {String=wondercon,google_6mo} event The event for which the coupon should be generated
+ * @apiParam (Path) {String=wondercon,google_6mo} event The event for which the coupon
+ * should be generated
* @apiParam (Query) {Number} count The number of coupon codes to generate
*
* @apiSuccess {Array} data Generated coupons
*
- * @apiError (400) {BadRequest} CouponValidationError The request was missing the count query parameter or used an invalid event.
+ * @apiError (400) {BadRequest} CouponValidationError The request was missing the
+ * count query parameter or used
+ * an invalid event.
*
*/
api.generateCoupons = {
@@ -74,10 +75,10 @@ api.generateCoupons = {
req.checkParams('event', apiError('eventRequired')).notEmpty();
req.checkQuery('count', apiError('countRequired')).notEmpty().isNumeric();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let coupons = await Coupon.generate(req.params.event, req.query.count);
+ const coupons = await Coupon.generate(req.params.event, req.query.count);
res.respond(200, coupons);
},
};
@@ -98,7 +99,7 @@ api.enterCouponCode = {
url: '/coupons/enter/:code',
middlewares: [authWithHeaders()],
async handler (req, res) {
- const user = res.locals.user;
+ const { user } = res.locals;
await couponsLib.enterCode(req, res, user);
const userToJSON = await user.toJSONWithInbox();
res.respond(200, userToJSON);
@@ -123,18 +124,18 @@ api.validateCoupon = {
async handler (req, res) {
req.checkParams('code', res.t('couponCodeRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
let valid = false;
- let code = couponCode.validate(req.params.code);
+ const code = couponCode.validate(req.params.code);
if (code) {
- let coupon = await Coupon.findOne({_id: code}).exec();
- valid = coupon ? true : false;
+ const coupon = await Coupon.findOne({ _id: code }).exec();
+ valid = !!coupon;
}
- res.respond(200, {valid});
+ res.respond(200, { valid });
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/cron.js b/website/server/controllers/api-v3/cron.js
index 32ed99039a..0016650bcf 100644
--- a/website/server/controllers/api-v3/cron.js
+++ b/website/server/controllers/api-v3/cron.js
@@ -1,7 +1,7 @@
import { authWithHeaders } from '../../middlewares/auth';
import cron from '../../middlewares/cron';
-let api = {};
+const api = {};
/**
* @api {post} /api/v3/cron Runs cron
@@ -19,4 +19,4 @@ api.cron = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/debug.js b/website/server/controllers/api-v3/debug.js
index eb2cd31260..9ed4e1a84f 100644
--- a/website/server/controllers/api-v3/debug.js
+++ b/website/server/controllers/api-v3/debug.js
@@ -1,12 +1,15 @@
+import _ from 'lodash';
import { authWithHeaders } from '../../middlewares/auth';
import ensureDevelpmentMode from '../../middlewares/ensureDevelpmentMode';
import { BadRequest } from '../../libs/errors';
-import { content } from '../../../common';
-import _ from 'lodash';
+import common from '../../../common';
+
+const { content } = common;
/**
* @apiDefine Development Development
- * These routes only exist while Habitica is in development mode. (Such as running a local instance on your computer)
+ * These routes only exist while Habitica is in development mode.
+ * (Such as running a local instance on your computer).
*/
/**
@@ -14,7 +17,7 @@ import _ from 'lodash';
* This route only exists when developing Habitica in non-production environment.
*/
-let api = {};
+const api = {};
/**
* @api {post} /api/v3/debug/add-ten-gems Add ten gems to the current user
@@ -29,7 +32,7 @@ api.addTenGems = {
url: '/debug/add-ten-gems',
middlewares: [ensureDevelpmentMode, authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
user.balance += 2.5;
@@ -52,7 +55,7 @@ api.addHourglass = {
url: '/debug/add-hourglass',
middlewares: [ensureDevelpmentMode, authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
user.purchased.plan.consecutive.trinkets += 1;
@@ -75,8 +78,8 @@ api.setCron = {
url: '/debug/set-cron',
middlewares: [ensureDevelpmentMode, authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let cron = req.body.lastCron;
+ const { user } = res.locals;
+ const cron = req.body.lastCron;
user.lastCron = cron;
@@ -99,7 +102,7 @@ api.makeAdmin = {
url: '/debug/make-admin',
middlewares: [ensureDevelpmentMode, authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
user.contributor.admin = true;
@@ -130,8 +133,8 @@ api.modifyInventory = {
url: '/debug/modify-inventory',
middlewares: [ensureDevelpmentMode, authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let { gear } = req.body;
+ const { user } = res.locals;
+ const { gear } = req.body;
if (gear) {
user.items.gear.owned = gear;
@@ -146,7 +149,7 @@ api.modifyInventory = {
'hatchingPotions',
'food',
'quests',
- ].forEach((type) => {
+ ].forEach(type => {
if (req.body[type]) {
user.items[type] = req.body[type];
user.markModified(`items.${type}`);
@@ -172,9 +175,9 @@ api.questProgress = {
url: '/debug/quest-progress',
middlewares: [ensureDevelpmentMode, authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let key = _.get(user, 'party.quest.key');
- let quest = content.quests[key];
+ const { user } = res.locals;
+ const key = _.get(user, 'party.quest.key');
+ const quest = content.quests[key];
if (!quest) {
throw new BadRequest('User is not on a valid quest.');
@@ -198,4 +201,4 @@ api.questProgress = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/groups.js b/website/server/controllers/api-v3/groups.js
index 41e1884ae5..dbfaac3ba2 100644
--- a/website/server/controllers/api-v3/groups.js
+++ b/website/server/controllers/api-v3/groups.js
@@ -1,6 +1,6 @@
-import { authWithHeaders } from '../../middlewares/auth';
import _ from 'lodash';
import nconf from 'nconf';
+import { authWithHeaders } from '../../middlewares/auth';
import {
model as Group,
basicFields as basicGroupFields,
@@ -25,8 +25,8 @@ import common from '../../../common';
import payments from '../../libs/payments/payments';
import stripePayments from '../../libs/payments/stripe';
import amzLib from '../../libs/payments/amazon';
-import shared from '../../../common';
import apiError from '../../libs/apiError';
+import { model as UserNotification } from '../../models/userNotification';
const MAX_EMAIL_INVITES_BY_USER = 200;
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
@@ -53,7 +53,8 @@ const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
/**
* @apiDefine messageGroupRequiresInvite
- * @apiError (400) {NotAuthorized} messageGroupRequiresInvite Group requires an invitation to join (e.g. private group, party)
+ * @apiError (400) {NotAuthorized} messageGroupRequiresInvite Group requires an invitation
+ * to join (e.g. private group, party).
*/
/**
@@ -61,7 +62,7 @@ const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
* The group leader can use this route.
*/
-let api = {};
+const api = {};
/**
* @api {post} /api/v3/groups Create group
@@ -82,7 +83,8 @@ let api = {};
* @apiError (401) {NotAuthorized} messageInsufficientGems User does not have enough gems (4)
* @apiError (401) {NotAuthorized} partyMustbePrivate Party must have privacy set to private
* @apiError (401) {NotAuthorized} messageGroupAlreadyInParty
- * @apiError (401) {NotAuthorized} chatPrivilegesRevoked You cannot do this because your chat privileges have been removed...
+ * @apiError (401) {NotAuthorized} chatPrivilegesRevoked You cannot do this because your chat
+ privileges have been removed...
*
* @apiSuccess (201) {Object} data The created group (See /website/server/models/group.js)
*
@@ -112,8 +114,8 @@ api.createGroup = {
url: '/groups',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let group = new Group(Group.sanitize(req.body));
+ const { user } = res.locals;
+ const group = new Group(Group.sanitize(req.body));
group.leader = user._id;
if (group.type === 'guild') {
@@ -122,7 +124,7 @@ api.createGroup = {
group.balance = 1;
- user.balance--;
+ user.balance -= 1;
user.guilds.push(group._id);
if (!user.achievements.joinedGuild) {
user.achievements.joinedGuild = true;
@@ -135,19 +137,20 @@ api.createGroup = {
user.party._id = group._id;
}
- let results = await Promise.all([user.save(), group.save()]);
- let savedGroup = results[1];
+ const results = await Promise.all([user.save(), group.save()]);
+ const savedGroup = results[1];
// Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833
- // await Q.ninvoke(savedGroup, 'populate', ['leader', nameFields]); // doc.populate doesn't return a promise
- let response = savedGroup.toJSON();
+ // await Q.ninvoke(savedGroup, 'populate', ['leader', nameFields]);
+ // doc.populate doesn't return a promise
+ const response = savedGroup.toJSON();
// the leader is the authenticated user
response.leader = {
_id: user._id,
- profile: {name: user.profile.name},
+ profile: { name: user.profile.name },
};
- let analyticsObject = {
+ const analyticsObject = {
uuid: user._id,
hitType: 'event',
category: 'behavior',
@@ -179,12 +182,12 @@ api.createGroupPlan = {
url: '/groups/create-plan',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let group = new Group(Group.sanitize(req.body.groupToCreate));
+ const { user } = res.locals;
+ const group = new Group(Group.sanitize(req.body.groupToCreate));
req.checkBody('paymentType', res.t('paymentTypeRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
// @TODO: Change message
@@ -192,11 +195,11 @@ api.createGroupPlan = {
group.leader = user._id;
user.guilds.push(group._id);
- let results = await Promise.all([user.save(), group.save()]);
- let savedGroup = results[1];
+ const results = await Promise.all([user.save(), group.save()]);
+ const savedGroup = results[1];
// Analytics
- let analyticsObject = {
+ const analyticsObject = {
uuid: user._id,
hitType: 'event',
category: 'behavior',
@@ -208,13 +211,13 @@ api.createGroupPlan = {
res.analytics.track('join group', analyticsObject);
if (req.body.paymentType === 'Stripe') {
- let token = req.body.id;
- let gift = req.query.gift ? JSON.parse(req.query.gift) : undefined;
- let sub = req.query.sub ? shared.content.subscriptionBlocks[req.query.sub] : false;
- let groupId = savedGroup._id;
- let email = req.body.email;
- let headers = req.headers;
- let coupon = req.query.coupon;
+ const token = req.body.id;
+ const gift = req.query.gift ? JSON.parse(req.query.gift) : undefined;
+ const sub = req.query.sub ? common.content.subscriptionBlocks[req.query.sub] : false;
+ const groupId = savedGroup._id;
+ const { email } = req.body;
+ const { headers } = req;
+ const { coupon } = req.query;
await stripePayments.checkout({
token,
@@ -227,11 +230,13 @@ api.createGroupPlan = {
coupon,
});
} else if (req.body.paymentType === 'Amazon') {
- let billingAgreementId = req.body.billingAgreementId;
- let sub = req.body.subscription ? shared.content.subscriptionBlocks[req.body.subscription] : false;
- let coupon = req.body.coupon;
- let groupId = savedGroup._id;
- let headers = req.headers;
+ const { billingAgreementId } = req.body;
+ const sub = req.body.subscription
+ ? common.content.subscriptionBlocks[req.body.subscription]
+ : false;
+ const { coupon } = req.body;
+ const groupId = savedGroup._id;
+ const { headers } = req;
await amzLib.subscribe({
billingAgreementId,
@@ -244,12 +249,13 @@ api.createGroupPlan = {
}
// Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833
- // await Q.ninvoke(savedGroup, 'populate', ['leader', nameFields]); // doc.populate doesn't return a promise
- let response = savedGroup.toJSON();
+ // await Q.ninvoke(savedGroup, 'populate', ['leader', nameFields]);
+ // doc.populate doesn't return a promise
+ const response = savedGroup.toJSON();
// the leader is the authenticated user
response.leader = {
_id: user._id,
- profile: {name: user.profile.name},
+ profile: { name: user.profile.name },
};
res.respond(201, response); // do not remove chat flags data as we've just created the group
@@ -261,9 +267,16 @@ api.createGroupPlan = {
* @apiName GetGroups
* @apiGroup Group
*
- * @apiParam (Query) {String} type The type of groups to retrieve. Must be a query string representing a list of values like 'tavern,party'. Possible values are party, guilds, privateGuilds, publicGuilds, tavern
- * @apiParam (Query) {String="true","false"} [paginate] Public guilds support pagination. When true guilds are returned in groups of 30
- * @apiParam (Query) {Number} [page] When pagination is enabled for public guilds this parameter can be used to specify the page number (the initial page is number 0 and not required)
+ * @apiParam (Query) {String} type The type of groups to retrieve.
+ * Must be a query string representing a list of values
+ * like 'tavern,party'. Possible values are party, guilds,
+ * privateGuilds, publicGuilds, tavern.
+ * @apiParam (Query) {String="true","false"} [paginate] Public guilds support pagination.
+ * When true guilds are returned in
+ * groups of 30.
+ * @apiParam (Query) {Number} [page] When pagination is enabled for public guilds this
+ parameter can be used to specify the page number
+ (the initial page is number 0 and not required).
*
* @apiParamExample {json} Private Guilds, Tavern:
* {
@@ -271,7 +284,8 @@ api.createGroupPlan = {
* }
*
* @apiError (400) {BadRequest} groupTypesRequired Group types are required
- * @apiError (400) {BadRequest} guildsPaginateBooleanString Paginate query parameter must be a boolean (true or false)
+ * @apiError (400) {BadRequest} guildsPaginateBooleanString Paginate query parameter
+ * must be a boolean (true or false).
* @apiError (400) {BadRequest} queryPageInteger Page query parameter must be a positive integer
* @apiError (400) {BadRequest} guildsOnlyPaginate Only public guilds support pagination
*
@@ -288,30 +302,30 @@ api.getGroups = {
url: '/groups',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkQuery('type', res.t('groupTypesRequired')).notEmpty();
// pagination options, can only be used with public guilds
req.checkQuery('paginate').optional().isIn(['true', 'false'], apiError('guildsPaginateBooleanString'));
- req.checkQuery('page').optional().isInt({min: 0}, apiError('queryPageInteger'));
+ req.checkQuery('page').optional().isInt({ min: 0 }, apiError('queryPageInteger'));
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let types = req.query.type.split(',');
+ const types = req.query.type.split(',');
- let paginate = req.query.paginate === 'true' ? true : false;
+ const paginate = req.query.paginate === 'true';
if (paginate && !_.includes(types, 'publicGuilds')) {
throw new BadRequest(apiError('guildsOnlyPaginate'));
}
- let groupFields = basicGroupFields.concat(' description memberCount balance');
- let sort = '-memberCount';
+ const groupFields = basicGroupFields.concat(' description memberCount balance');
+ const sort = '-memberCount';
- let filters = {};
+ const filters = {};
if (req.query.categories) {
- let categorySlugs = req.query.categories.split(',');
- filters.categories = { $elemMatch: { slug: {$in: categorySlugs} } };
+ const categorySlugs = req.query.categories.split(',');
+ filters.categories = { $elemMatch: { slug: { $in: categorySlugs } } };
}
if (req.query.minMemberCount) {
@@ -337,13 +351,18 @@ api.getGroups = {
filters.$or = [];
const searchWords = _.escapeRegExp(req.query.search).split(' ').join('|');
const searchQuery = { $regex: new RegExp(`${searchWords}`, 'i') };
- filters.$or.push({name: searchQuery});
- filters.$or.push({description: searchQuery});
+ filters.$or.push({ name: searchQuery });
+ filters.$or.push({ description: searchQuery });
}
- let results = await Group.getGroups({
- user, types, groupFields, sort,
- paginate, page: req.query.page, filters,
+ const results = await Group.getGroups({
+ user,
+ types,
+ groupFields,
+ sort,
+ paginate,
+ page: req.query.page,
+ filters,
});
res.respond(200, results);
},
@@ -354,7 +373,8 @@ api.getGroups = {
* @apiName GetGroup
* @apiGroup Group
*
- * @apiParam (Path) {String} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {String} groupId The group _id ('party' for the user party
+ * and 'habitrpg' for tavern are accepted)
*
* @apiParamExample {String} Tavern:
* /api/v3/groups/habitrpg
@@ -379,28 +399,28 @@ api.getGroup = {
userFieldsToInclude: ['party', 'guilds', 'contributor'],
})],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let groupId = req.params.groupId;
- let group = await Group.getGroup({user, groupId, populateLeader: false});
+ const { groupId } = req.params;
+ const group = await Group.getGroup({ user, groupId, populateLeader: false });
if (!group) {
throw new NotFound(res.t('groupNotFound'));
}
- let groupJson = await Group.toJSONCleanChat(group, user);
+ const groupJson = await Group.toJSONCleanChat(group, user);
if (groupJson.leader === user._id) {
groupJson.purchased.plan = group.purchased.plan.toObject();
}
// Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833
- let leader = await User.findById(groupJson.leader).select(nameFields).exec();
- if (leader) groupJson.leader = leader.toJSON({minimize: true});
+ const leader = await User.findById(groupJson.leader).select(nameFields).exec();
+ if (leader) groupJson.leader = leader.toJSON({ minimize: true });
res.respond(200, groupJson);
},
@@ -411,12 +431,14 @@ api.getGroup = {
* @apiName UpdateGroup
* @apiGroup Group
*
- * @apiParam (Path) {String} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {String} groupId The group _id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted).
*
* @apiParamExample {String} Tavern:
* /api/v3/groups/habitrpg
*
- * @apiError (400) {NotAuthorized} messageGroupOnlyLeaderCanUpdate Only the group's leader can update the party
+ * @apiError (400) {NotAuthorized} messageGroupOnlyLeaderCanUpdate Only the group's leader
+ * can update the party.
*
* @apiSuccess {Object} data The updated group (See /website/server/models/group.js)
*
@@ -437,14 +459,14 @@ api.updateGroup = {
url: '/groups/:groupId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let optionalMembership = Boolean(user.contributor.admin);
- let group = await Group.getGroup({user, groupId: req.params.groupId, optionalMembership});
+ const optionalMembership = Boolean(user.contributor.admin);
+ const group = await Group.getGroup({ user, groupId: req.params.groupId, optionalMembership });
if (!group) throw new NotFound(res.t('groupNotFound'));
@@ -455,17 +477,17 @@ api.updateGroup = {
_.assign(group, _.merge(group.toObject(), Group.sanitizeUpdate(req.body)));
- let savedGroup = await group.save();
- let response = await Group.toJSONCleanChat(savedGroup, user);
+ const savedGroup = await group.save();
+ const response = await Group.toJSONCleanChat(savedGroup, user);
// If the leader changed fetch new data, otherwise use authenticated user
if (response.leader !== user._id) {
- let rawLeader = await User.findById(response.leader).select(nameFields).exec();
- response.leader = rawLeader.toJSON({minimize: true});
+ const rawLeader = await User.findById(response.leader).select(nameFields).exec();
+ response.leader = rawLeader.toJSON({ minimize: true });
} else {
response.leader = {
_id: user._id,
- profile: {name: user.profile.name},
+ profile: { name: user.profile.name },
};
}
res.respond(200, response);
@@ -477,7 +499,8 @@ api.updateGroup = {
* @apiName JoinGroup
* @apiGroup Group
*
- * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted).
*
* @apiParamExample {String} Tavern:
* /api/v3/groups/habitrpg/join
@@ -500,30 +523,32 @@ api.joinGroup = {
url: '/groups/:groupId/join',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
let inviter;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
// Works even if the user is not yet a member of the group
- let group = await Group.getGroup({user, groupId: req.params.groupId, optionalMembership: true}); // Do not fetch chat and work even if the user is not yet a member of the group
+ // Do not fetch chat and work even if the user is not yet a member of the group
+ const group = await Group
+ .getGroup({ user, groupId: req.params.groupId, optionalMembership: true });
if (!group) throw new NotFound(res.t('groupNotFound'));
let isUserInvited = false;
if (group.type === 'party') {
// Check if was invited to party
- let inviterParty = _.find(user.invitations.parties, {id: group._id});
+ const inviterParty = _.find(user.invitations.parties, { id: group._id });
if (inviterParty) {
inviter = inviterParty.inviter;
// If user was in a different party (when partying solo you can be invited to a new party)
// make them leave that party before doing anything
if (user.party._id) {
- let userPreviousParty = await Group.getGroup({user, groupId: user.party._id});
+ const userPreviousParty = await Group.getGroup({ user, groupId: user.party._id });
if (userPreviousParty.memberCount === 1 && user.party.quest.key) {
throw new NotAuthorized(res.t('messageCannotLeaveWhileQuesting'));
@@ -549,18 +574,19 @@ api.joinGroup = {
isUserInvited = true;
}
} else if (group.type === 'guild') {
- let hasInvitation = removeFromArray(user.invitations.guilds, { id: group._id });
+ const hasInvitation = removeFromArray(user.invitations.guilds, { id: group._id });
if (hasInvitation) {
isUserInvited = true;
inviter = hasInvitation.inviter;
} else {
- isUserInvited = group.privacy === 'private' ? false : true;
+ isUserInvited = group.privacy !== 'private';
}
}
if (isUserInvited && group.type === 'guild') {
- if (user.guilds.indexOf(group._id) !== -1) { // if user is already a member (party is checked previously)
+ // if user is already a member (party is checked previously)
+ if (user.guilds.indexOf(group._id) !== -1) {
throw new NotAuthorized(res.t('youAreAlreadyInGroup'));
}
user.guilds.push(group._id); // Add group to user's guilds
@@ -572,7 +598,9 @@ api.joinGroup = {
if (!isUserInvited) throw new NotAuthorized(res.t('messageGroupRequiresInvite'));
// @TODO: Review the need for this and if still needed, don't base this on memberCount
- if (!group.hasNotCancelled() && group.memberCount === 0) group.leader = user._id; // If new user is only member -> set as leader
+ if (!group.hasNotCancelled() && group.memberCount === 0) {
+ group.leader = user._id; // If new user is only member -> set as leader
+ }
group.memberCount += 1;
@@ -581,7 +609,7 @@ api.joinGroup = {
if (inviter) {
inviter = await User.findById(inviter).exec();
- let data = {
+ const data = {
headerText: common.i18n.t('invitationAcceptedHeader', inviter.preferences.language),
bodyText: common.i18n.t('invitationAcceptedBody', {
groupName: group.name,
@@ -595,7 +623,7 @@ api.joinGroup = {
if (!inviter.items.quests.basilist) {
inviter.items.quests.basilist = 0;
}
- inviter.items.quests.basilist++;
+ inviter.items.quests.basilist += 1;
inviter.markModified('items.quests');
}
promises.push(inviter.save());
@@ -603,33 +631,68 @@ api.joinGroup = {
if (group.type === 'party' && inviter) {
if (group.memberCount > 1) {
- promises.push(User.update({
- $or: [{'party._id': group._id}, {_id: user._id}],
- 'achievements.partyUp': {$ne: true},
- }, {$set: {'achievements.partyUp': true}}, {multi: true}).exec());
+ const notification = new UserNotification({ type: 'ACHIEVEMENT_PARTY_UP' });
+
+ promises.push(User.update(
+ {
+ $or: [{ 'party._id': group._id }, { _id: user._id }],
+ 'achievements.partyUp': { $ne: true },
+ },
+ {
+ $set: { 'achievements.partyUp': true },
+ $push: { notifications: notification.toObject() },
+ },
+ { multi: true },
+ ).exec());
+
+ if (inviter) {
+ if (inviter.achievements.partyUp !== true) {
+ // Since the notification list of the inviter is already
+ // updated in this save we need to add the notification here
+ inviter.addNotification('ACHIEVEMENT_PARTY_UP');
+ }
+ }
}
+
if (group.memberCount > 3) {
- promises.push(User.update({
- $or: [{'party._id': group._id}, {_id: user._id}],
- 'achievements.partyOn': {$ne: true},
- }, {$set: {'achievements.partyOn': true}}, {multi: true}).exec());
+ const notification = new UserNotification({ type: 'ACHIEVEMENT_PARTY_ON' });
+
+ promises.push(User.update(
+ {
+ $or: [{ 'party._id': group._id }, { _id: user._id }],
+ 'achievements.partyOn': { $ne: true },
+ },
+ {
+ $set: { 'achievements.partyOn': true },
+ $push: { notifications: notification.toObject() },
+ },
+ { multi: true },
+ ).exec());
+
+ if (inviter) {
+ if (inviter.achievements.partyOn !== true) {
+ // Since the notification list of the inviter is already
+ // updated in this save we need to add the notification here
+ inviter.addNotification('ACHIEVEMENT_PARTY_ON');
+ }
+ }
}
}
promises = await Promise.all(promises);
- if (group.hasNotCancelled()) {
+ if (group.hasNotCancelled()) {
await payments.addSubToGroupUser(user, group);
await group.updateGroupPlan();
}
- let response = await Group.toJSONCleanChat(promises[0], user);
- let leader = await User.findById(response.leader).select(nameFields).exec();
+ const response = await Group.toJSONCleanChat(promises[0], user);
+ const leader = await User.findById(response.leader).select(nameFields).exec();
if (leader) {
- response.leader = leader.toJSON({minimize: true});
+ response.leader = leader.toJSON({ minimize: true });
}
- let analyticsObject = {
+ const analyticsObject = {
uuid: user._id,
hitType: 'event',
category: 'behavior',
@@ -654,7 +717,8 @@ api.joinGroup = {
* @apiName RejectGroupInvite
* @apiGroup Group
*
- * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted).
*
* @apiParamExample {String} party:
* /api/v3/groups/party/reject-invite
@@ -669,23 +733,25 @@ api.rejectGroupInvite = {
url: '/groups/:groupId/reject-invite',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let groupId = req.params.groupId;
+ const { groupId } = req.params;
let isUserInvited = false;
- let hasPartyInvitation = removeFromArray(user.invitations.parties, { id: groupId });
+ const hasPartyInvitation = removeFromArray(user.invitations.parties, { id: groupId });
if (hasPartyInvitation) {
- user.invitations.party = user.invitations.parties.length > 0 ? user.invitations.parties[user.invitations.parties.length - 1] : {};
+ user.invitations.party = user.invitations.parties.length > 0
+ ? user.invitations.parties[user.invitations.parties.length - 1]
+ : {};
user.markModified('invitations.party');
isUserInvited = true;
} else {
- let hasInvitation = removeFromArray(user.invitations.guilds, { id: groupId });
+ const hasInvitation = removeFromArray(user.invitations.guilds, { id: groupId });
if (hasInvitation) {
isUserInvited = true;
@@ -720,9 +786,16 @@ function _removeMessagesFromMember (member, groupId) {
* @apiName LeaveGroup
* @apiGroup Group
*
- * @apiParam (Path) {String} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
- * @apiParam (Query) {String="remove-all","keep-all"} keep=keep-all Whether or not to keep challenge tasks belonging to the group being left.
- * @apiParam (Body) {String="remain-in-challenges","leave-challenges"} [keepChallenges=leave-challenges] Whether or not to remain in the challenges of the group being left.
+ * @apiParam (Path) {String} groupId The group _id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted).
+ * @apiParam (Query) {String="remove-all","keep-all"} keep=keep-all Whether or not to keep
+ * challenge tasks belonging to
+ * the group being left.
+ * @apiParam (Body) {String="remain-in-challenges"
+ * ,"leave-challenges"} [keepChallenges=leave-challenges] Whether or not
+ * to remain in the
+ * challenges of the
+ * group being left.
*
* @apiParamExample {json} Leave Party:
* /api/v3/groups/party/leave
@@ -731,8 +804,11 @@ function _removeMessagesFromMember (member, groupId) {
* }
*
* @apiError (400) {BadRequest} keepOrRemoveAll "keep" parameter is not "remove-all" or "keep-all"
- * @apiError (400) {NotAuthorized} questLeaderCannotLeaveGroup User could not leave party because they are the owner of a quest currently running
- * @apiError (400) {NotAuthorized} cannotLeaveWhileActiveQuest User could not leave party due to being in a quest
+ * @apiError (400) {NotAuthorized} questLeaderCannotLeaveGroup User could not leave party because
+ * they are the owner of a quest
+ * currently running.
+ * @apiError (400) {NotAuthorized} cannotLeaveWhileActiveQuest User could not leave party due to
+ * being in a quest.
*
* @apiSuccess {Object} data An empty object
*
@@ -744,17 +820,19 @@ api.leaveGroup = {
url: '/groups/:groupId/leave',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
// When removing the user from challenges, should we keep the tasks?
req.checkQuery('keep', apiError('keepOrRemoveAll')).optional().isIn(['keep-all', 'remove-all']);
req.checkBody('keepChallenges', apiError('groupRemainOrLeaveChallenges')).optional().isIn(['remain-in-challenges', 'leave-challenges']);
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let groupId = req.params.groupId;
- let group = await Group.getGroup({user, groupId, fields: '-chat', requireMembership: true});
+ const { groupId } = req.params;
+ const group = await Group.getGroup({
+ user, groupId, fields: '-chat', requireMembership: true,
+ });
if (!group) {
throw new NotFound(res.t('groupNotFound'));
}
@@ -765,7 +843,10 @@ api.leaveGroup = {
throw new NotAuthorized(res.t('questLeaderCannotLeaveGroup'));
}
- if (group.quest && group.quest.active && group.quest.members && group.quest.members[user._id]) {
+ if (
+ group.quest && group.quest.active
+ && group.quest.members && group.quest.members[user._id]
+ ) {
throw new NotAuthorized(res.t('cannotLeaveWhileActiveQuest'));
}
}
@@ -775,11 +856,11 @@ api.leaveGroup = {
await user.save();
if (group.type !== 'party') {
- let guildIndex = user.guilds.indexOf(group._id);
+ const guildIndex = user.guilds.indexOf(group._id);
if (guildIndex >= 0) user.guilds.splice(guildIndex, 1);
}
- let isMemberOfGroupPlan = await user.isMemberOfGroupPlan();
+ const isMemberOfGroupPlan = await user.isMemberOfGroupPlan();
if (!isMemberOfGroupPlan) {
await payments.cancelGroupSubscriptionForUser(user, group);
}
@@ -792,12 +873,12 @@ api.leaveGroup = {
// Send an email to the removed user with an optional message from the leader
function _sendMessageToRemoved (group, removedUser, message, isInGroup) {
if (removedUser.preferences.emailNotifications.kickedGroup !== false) {
- let subject = isInGroup ? `kicked-from-${group.type}` : `${group.type}-invite-rescinded`;
+ const subject = isInGroup ? `kicked-from-${group.type}` : `${group.type}-invite-rescinded`;
sendTxnEmail(removedUser, subject, [
- {name: 'GROUP_NAME', content: group.name},
- {name: 'MESSAGE', content: message},
- {name: 'GUILDS_LINK', content: '/groups/discovery'},
- {name: 'PARTY_WANTED_GUILD', content: '/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601'},
+ { name: 'GROUP_NAME', content: group.name },
+ { name: 'MESSAGE', content: message },
+ { name: 'GUILDS_LINK', content: '/groups/discovery' },
+ { name: 'PARTY_WANTED_GUILD', content: '/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601' },
]);
}
}
@@ -807,7 +888,8 @@ function _sendMessageToRemoved (group, removedUser, message, isInGroup) {
* @apiName RemoveGroupMember
* @apiGroup Group
*
- * @apiParam (Path) {String} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {String} groupId The group _id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted).
* @apiParam (Path) {UUID} memberId The _id of the member to remove
* @apiParam (Query) {String} message Query parameter - The message to send to the removed members
*
@@ -815,7 +897,8 @@ function _sendMessageToRemoved (group, removedUser, message, isInGroup) {
* /api/v3/groups/party/removeMember/[User's ID]?message=Bye
*
* @apiError (400) {BadRequest} userIdrequired "memberId" cannot be empty or not a UUID
- * @apiError (400) {NotAuthorized} onlyLeaderCanRemoveMember Only the group leader can remove members
+ * @apiError (400) {NotAuthorized} onlyLeaderCanRemoveMember Only the group
+ leader can remove members.
* @apiError (400) {NotAuthorized} memberCannotRemoveYourself Group leader cannot remove themselves
* @apiError (404) {NotFound} groupMemberNotFound Group member was not found
*
@@ -831,19 +914,21 @@ api.removeGroupMember = {
url: '/groups/:groupId/removeMember/:memberId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
req.checkParams('memberId', res.t('userIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let optionalMembership = Boolean(user.contributor.admin);
- let group = await Group.getGroup({user, groupId: req.params.groupId, optionalMembership, fields: '-chat'}); // Do not fetch chat
+ const optionalMembership = Boolean(user.contributor.admin);
+ const group = await Group.getGroup({
+ user, groupId: req.params.groupId, optionalMembership, fields: '-chat',
+ }); // Do not fetch chat
if (!group) throw new NotFound(res.t('groupNotFound'));
- let uuid = req.params.memberId;
+ const uuid = req.params.memberId;
if (group.leader !== user._id && group.type === 'party') throw new NotAuthorized(res.t('onlyLeaderCanRemoveMember'));
if (group.leader !== user._id && !user.contributor.admin) throw new NotAuthorized(res.t('onlyLeaderCanRemoveMember'));
@@ -852,7 +937,7 @@ api.removeGroupMember = {
if (user._id === uuid) throw new NotAuthorized(res.t('memberCannotRemoveYourself'));
- let member = await User.findOne({_id: uuid}).exec();
+ const member = await User.findOne({ _id: uuid }).exec();
// We're removing the user from a guild or a party? is the user invited only?
let isInGroup;
@@ -863,9 +948,9 @@ api.removeGroupMember = {
}
let isInvited;
- if (_.find(member.invitations.parties, {id: group._id})) {
+ if (_.find(member.invitations.parties, { id: group._id })) {
isInvited = 'party';
- } else if (_.findIndex(member.invitations.guilds, {id: group._id}) !== -1) {
+ } else if (_.findIndex(member.invitations.guilds, { id: group._id }) !== -1) {
isInvited = 'guild';
}
@@ -900,14 +985,16 @@ api.removeGroupMember = {
}
if (isInvited === 'party') {
removeFromArray(member.invitations.parties, { id: group._id });
- member.invitations.party = member.invitations.parties.length > 0 ? member.invitations.parties[member.invitations.parties.length - 1] : {};
+ member.invitations.party = member.invitations.parties.length > 0
+ ? member.invitations.parties[member.invitations.parties.length - 1]
+ : {};
member.markModified('invitations.party');
}
} else {
throw new NotFound(res.t('groupMemberNotFound'));
}
- let message = req.query.message || req.body.message;
+ const message = req.query.message || req.body.message;
_sendMessageToRemoved(group, member, message, isInGroup);
await Promise.all([
@@ -915,7 +1002,7 @@ api.removeGroupMember = {
group.save(),
]);
- if (isInGroup && group.hasNotCancelled()) {
+ if (isInGroup && group.hasNotCancelled()) {
await group.updateGroupPlan(true);
await payments.cancelGroupSubscriptionForUser(member, group, true);
}
@@ -928,11 +1015,14 @@ api.removeGroupMember = {
* @api {post} /api/v3/groups/:groupId/invite Invite users to a group
* @apiName InviteToGroup
* @apiGroup Group
- * @apiDescription You can provide both `emails` and `uuids`, or just one. You must provide at least one.
+ * @apiDescription You can provide both `emails` and `uuids`, or just one.
+ * You must provide at least one.
*
- * @apiParam (Path) {String} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {String} groupId The group _id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted)
*
- * @apiParam (Body) {Object[]} [emails] An array of objects, each representing one email address to invite
+ * @apiParam (Body) {Object[]} [emails] An array of objects, each representing one
+ * email address to invite.
* @apiParam (Body) {String} emails.email The email address of the user being invited.
* @apiParam (Body) {String} [emails.name] The name of the user being invited.
* @apiParam (Body) {Array} [uuids] An array of uuids to invite
@@ -958,8 +1048,10 @@ api.removeGroupMember = {
* }
*
* @apiSuccess {Array} data The invites
- * @apiSuccess {Object} data[0] If the invitation was a User ID, you'll receive back an object. You'll receive one Object for each succesful User ID invite.
- * @apiSuccess {String} data[1] If the invitation was an email, you'll receive back the email. You'll receive one String for each successful email invite.
+ * @apiSuccess {Object} data[0] If the invitation was a User ID, you'll receive back an object.
+ * You'll receive one Object for each succesful User ID invite.
+ * @apiSuccess {String} data[1] If the invitation was an email, you'll receive back the email.
+ * You'll receive one String for each successful email invite.
*
* @apiSuccessExample {json} Successful Response with Emails
* {
@@ -986,20 +1078,30 @@ api.removeGroupMember = {
*
* @apiUse GroupBodyInvalid
*
- * @apiError (400) {BadRequest} NoEmailProvided An email address was not provided in the `emails` body
- * param `Array`.
- * @apiError (400) {BadRequest} UuidOrEmailOnly The `emails` and `uuids` params were both missing and/or a
- * key other than `emails` or `uuids` was provided in the body param.
- * @apiError (400) {BadRequest} CannotInviteSelf User ID or email of invitee matches that of the inviter.
+ * @apiError (400) {BadRequest} NoEmailProvided An email address was not provided
+ * in the `emails` body param `Array`.
+ * @apiError (400) {BadRequest} UuidOrEmailOnly The `emails` and `uuids` params
+ * were both missing and/or a.
+ * key other than `emails` or `uuids` was provided
+ * in the body param.
+ * @apiError (400) {BadRequest} CannotInviteSelf User ID or email of invitee matches
+ * that of the inviter.
* @apiError (400) {BadRequest} MustBeArray The `uuids` or `emails` body param was not an array.
- * @apiError (400) {BadRequest} TooManyInvites A max of 100 invites (combined emails and User IDs) can
- * be sent out at a time.
+ * @apiError (400) {BadRequest} TooManyInvites A max of 100 invites (combined
+ * emails and User IDs) can
+ * be sent out at a time.
* @apiError (400) {BadRequest} ExceedsMembersLimit A max of 30 members can join a party.
*
- * @apiError (401) {NotAuthorized} UserAlreadyInvited The user has already been invited to the group.
+ * @apiError (401) {NotAuthorized} UserAlreadyInvited The user has already
+ * been invited to the group.
* @apiError (401) {NotAuthorized} UserAlreadyInGroup The user is already a member of the group.
- * @apiError (401) {NotAuthorized} CannotInviteWhenMuted You cannot invite anyone to a guild or party because your chat privileges have been revoked.
- * @apiError (401) {NotAuthorized} NotAuthorizedToSendMessageToThisUser You can't send a message to this player because they have chosen to block messages.
+ * @apiError (401) {NotAuthorized} CannotInviteWhenMuted You cannot invite anyone
+ * to a guild or party because your
+ * chat privileges have been revoked.
+ * @apiError (401) {NotAuthorized} NotAuthorizedToSendMessageToThisUser You can't send a
+ * message to this player
+ * because they have chosen to
+ * block messages.
*
* @apiUse GroupNotFound
* @apiUse UserNotFound
@@ -1010,7 +1112,7 @@ api.inviteToGroup = {
url: '/groups/:groupId/invite',
middlewares: [authWithHeaders()],
async handler (req, res) {
- const user = res.locals.user;
+ const { user } = res.locals;
if (user.flags.chatRevoked) throw new NotAuthorized(res.t('chatPrivilegesRevoked'));
@@ -1021,7 +1123,7 @@ api.inviteToGroup = {
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const group = await Group.getGroup({user, groupId: req.params.groupId, fields: '-chat'});
+ const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: '-chat' });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.purchased && group.purchased.plan.customerId && user._id !== group.leader) throw new NotAuthorized(res.t('onlyGroupLeaderCanInviteToGroupPlan'));
@@ -1041,13 +1143,13 @@ api.inviteToGroup = {
const results = [];
if (uuids) {
- const uuidInvites = uuids.map((uuid) => inviteByUUID(uuid, group, user, req, res));
+ const uuidInvites = uuids.map(uuid => inviteByUUID(uuid, group, user, req, res));
const uuidResults = await Promise.all(uuidInvites);
results.push(...uuidResults);
}
if (emails) {
- const emailInvites = emails.map((invite) => inviteByEmail(invite, group, user, req, res));
+ const emailInvites = emails.map(invite => inviteByEmail(invite, group, user, req, res));
user.invitesSent += emails.length;
await user.save();
const emailResults = await Promise.all(emailInvites);
@@ -1055,12 +1157,13 @@ api.inviteToGroup = {
}
if (usernames) {
- const usernameInvites = usernames.map((username) => inviteByUserName(username, group, user, req, res));
+ const usernameInvites = usernames
+ .map(username => inviteByUserName(username, group, user, req, res));
const usernameResults = await Promise.all(usernameInvites);
results.push(...usernameResults);
}
- let analyticsObject = {
+ const analyticsObject = {
uuid: user._id,
hitType: 'event',
category: 'behavior',
@@ -1079,7 +1182,8 @@ api.inviteToGroup = {
* @apiName AddGroupManager
* @apiGroup Group
*
- * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted).
*
* @apiParamExample {String} party:
* /api/v3/groups/party/add-manager
@@ -1096,23 +1200,23 @@ api.addGroupManager = {
url: '/groups/:groupId/add-manager',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let managerId = req.body.managerId;
+ const { user } = res.locals;
+ const { managerId } = req.body;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
req.checkBody('managerId', apiError('managerIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let newManager = await User.findById(managerId, 'guilds party').exec();
- let groupFields = basicGroupFields.concat(' managers');
- let group = await Group.getGroup({user, groupId: req.params.groupId, fields: groupFields});
+ const newManager = await User.findById(managerId, 'guilds party').exec();
+ const groupFields = basicGroupFields.concat(' managers');
+ const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: groupFields });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.leader !== user._id) throw new NotAuthorized(res.t('messageGroupOnlyLeaderCanUpdate'));
- let isMember = group.isMember(newManager);
+ const isMember = group.isMember(newManager);
if (!isMember) throw new NotAuthorized(res.t('userMustBeMember'));
group.managers[managerId] = true;
@@ -1128,7 +1232,8 @@ api.addGroupManager = {
* @apiName RemoveGroupManager
* @apiGroup Group
*
- * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg' for tavern are accepted)
+ * @apiParam (Path) {UUID} groupId The group _id ('party' for the user party and 'habitrpg'
+ * for tavern are accepted).
*
* @apiParamExample {String} party:
* /api/v3/groups/party/add-manager
@@ -1145,17 +1250,17 @@ api.removeGroupManager = {
url: '/groups/:groupId/remove-manager',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let managerId = req.body.managerId;
+ const { user } = res.locals;
+ const { managerId } = req.body;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
req.checkBody('managerId', apiError('managerIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let groupFields = basicGroupFields.concat(' managers');
- let group = await Group.getGroup({user, groupId: req.params.groupId, fields: groupFields});
+ const groupFields = basicGroupFields.concat(' managers');
+ const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: groupFields });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.leader !== user._id) throw new NotAuthorized(res.t('messageGroupOnlyLeaderCanUpdate'));
@@ -1166,8 +1271,8 @@ api.removeGroupManager = {
group.markModified('managers');
await group.save();
- let manager = await User.findById(managerId, 'notifications').exec();
- let newNotifications = manager.notifications.filter((notification) => {
+ const manager = await User.findById(managerId, 'notifications').exec();
+ const newNotifications = manager.notifications.filter(notification => {
const isGroupTaskNotification = notification && notification.type && notification.type.indexOf('GROUP_TASK_') === 0;
return !isGroupTaskNotification;
@@ -1198,23 +1303,21 @@ api.getGroupPlans = {
url: '/group-plans',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
const userGroups = user.getGroups();
const groups = await Group
.find({
- _id: {$in: userGroups},
+ _id: { $in: userGroups },
})
.select('leaderOnly leader purchased name managers')
.exec();
- let groupPlans = groups.filter(group => {
- return group.isSubscribed();
- });
+ const groupPlans = groups.filter(group => group.isSubscribed());
res.respond(200, groupPlans);
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/hall.js b/website/server/controllers/api-v3/hall.js
index 621433b76f..2874cd9b35 100644
--- a/website/server/controllers/api-v3/hall.js
+++ b/website/server/controllers/api-v3/hall.js
@@ -1,19 +1,19 @@
+import _ from 'lodash';
+import validator from 'validator';
import { authWithHeaders } from '../../middlewares/auth';
import { ensureAdmin } from '../../middlewares/ensureAccessRight';
import { model as User } from '../../models/user';
import {
NotFound,
} from '../../libs/errors';
-import _ from 'lodash';
import apiError from '../../libs/apiError';
-import validator from 'validator';
import {
validateItemPath,
castItemVal,
} from '../../libs/items/utils';
-let api = {};
+const api = {};
/**
* @api {get} /api/v3/hall/patrons Get all patrons
@@ -69,17 +69,17 @@ api.getPatrons = {
url: '/hall/patrons',
middlewares: [authWithHeaders()],
async handler (req, res) {
- req.checkQuery('page').optional().isInt({min: 0}, apiError('queryPageInteger'));
+ req.checkQuery('page').optional().isInt({ min: 0 }, apiError('queryPageInteger'));
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let page = req.query.page ? Number(req.query.page) : 0;
+ const page = req.query.page ? Number(req.query.page) : 0;
const perPage = 50;
- let patrons = await User
+ const patrons = await User
.find({
- 'backer.tier': {$gt: 0},
+ 'backer.tier': { $gt: 0 },
})
.select('contributor backer profile.name')
.sort('-backer.tier')
@@ -129,9 +129,9 @@ api.getHeroes = {
url: '/hall/heroes',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let heroes = await User
+ const heroes = await User
.find({
- 'contributor.level': {$gt: 0},
+ 'contributor.level': { $gt: 0 },
})
.select('contributor backer profile.name')
.sort('-contributor.level')
@@ -168,19 +168,18 @@ api.getHero = {
url: '/hall/heroes/:heroId',
middlewares: [authWithHeaders(), ensureAdmin],
async handler (req, res) {
- let validationErrors;
req.checkParams('heroId', res.t('heroIdRequired')).notEmpty();
- validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const heroId = req.params.heroId;
+ const { heroId } = req.params;
let query;
if (validator.isUUID(heroId)) {
- query = {_id: heroId};
+ query = { _id: heroId };
} else {
- query = {'auth.local.lowerCaseUsername': heroId.toLowerCase()};
+ query = { 'auth.local.lowerCaseUsername': heroId.toLowerCase() };
}
const hero = await User
@@ -188,8 +187,8 @@ api.getHero = {
.select(heroAdminFields)
.exec();
- if (!hero) throw new NotFound(res.t('userWithIDNotFound', {userId: heroId}));
- let heroRes = hero.toJSON({minimize: true});
+ if (!hero) throw new NotFound(res.t('userWithIDNotFound', { userId: heroId }));
+ const heroRes = hero.toJSON({ minimize: true });
// supply to the possible absence of hero.contributor
// if we didn't pass minimize: true it would have returned all fields as empty
if (!heroRes.contributor) heroRes.contributor = {};
@@ -198,7 +197,9 @@ api.getHero = {
};
// e.g., tier 5 gives 4 gems. Tier 8 = moderator. Tier 9 = staff
-const gemsPerTier = {1: 3, 2: 3, 3: 3, 4: 4, 5: 4, 6: 4, 7: 4, 8: 0, 9: 0};
+const gemsPerTier = {
+ 1: 3, 2: 3, 3: 3, 4: 4, 5: 4, 6: 4, 7: 4, 8: 0, 9: 0,
+};
/**
* @api {put} /api/v3/hall/heroes/:heroId Update any user ("hero")
@@ -207,7 +208,9 @@ const gemsPerTier = {1: 3, 2: 3, 3: 3, 4: 4, 5: 4, 6: 4, 7: 4, 8: 0, 9: 0};
* @apiGroup Hall
* @apiPermission Admin
*
- * @apiDescription Update user's gem balance, contributions & contribution tier and admin status. Grant items, block / unblock user's account and revoke / unrevoke chat privileges.
+ * @apiDescription Update user's gem balance, contributions & contribution tier
+ * and admin status. Grant items, block / unblock user's account
+ * and revoke / unrevoke chat privileges.
*
* @apiExample Example Body:
* {
@@ -240,36 +243,40 @@ api.updateHero = {
url: '/hall/heroes/:heroId',
middlewares: [authWithHeaders(), ensureAdmin],
async handler (req, res) {
- let heroId = req.params.heroId;
- let updateData = req.body;
+ const { heroId } = req.params;
+ const updateData = req.body;
req.checkParams('heroId', res.t('heroIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let hero = await User.findById(heroId).exec();
- if (!hero) throw new NotFound(res.t('userWithIDNotFound', {userId: heroId}));
+ const hero = await User.findById(heroId).exec();
+ if (!hero) throw new NotFound(res.t('userWithIDNotFound', { userId: heroId }));
if (updateData.balance) hero.balance = updateData.balance;
// give them gems if they got an higher level
- let newTier = updateData.contributor && updateData.contributor.level; // tier = level in this context
- let oldTier = hero.contributor && hero.contributor.level || 0;
+ // tier = level in this context
+ let newTier = updateData.contributor && updateData.contributor.level;
+
+ const oldTier = (hero.contributor && hero.contributor.level) || 0;
if (newTier > oldTier) {
hero.flags.contributor = true;
let tierDiff = newTier - oldTier; // can be 2+ tier increases at once
while (tierDiff) {
hero.balance += gemsPerTier[newTier] / 4; // balance is in $
- tierDiff--;
- newTier--; // give them gems for the next tier down if they weren't aready that tier
+ tierDiff -= 1;
+ newTier -= 1; // give them gems for the next tier down if they weren't aready that tier
}
hero.addNotification('NEW_CONTRIBUTOR_LEVEL');
}
if (updateData.contributor) _.assign(hero.contributor, updateData.contributor);
- if (updateData.purchased && updateData.purchased.ads) hero.purchased.ads = updateData.purchased.ads;
+ if (updateData.purchased && updateData.purchased.ads) {
+ hero.purchased.ads = updateData.purchased.ads;
+ }
// give them the Dragon Hydra pet if they're above level 6
if (hero.contributor.level >= 6) {
@@ -277,7 +284,8 @@ api.updateHero = {
hero.markModified('items.pets');
}
if (updateData.itemPath && updateData.itemVal && validateItemPath(updateData.itemPath)) {
- _.set(hero, updateData.itemPath, castItemVal(updateData.itemPath, updateData.itemVal)); // Sanitization at 5c30944 (deemed unnecessary)
+ // Sanitization at 5c30944 (deemed unnecessary)
+ _.set(hero, updateData.itemPath, castItemVal(updateData.itemPath, updateData.itemVal));
}
if (updateData.auth && updateData.auth.blocked === true) {
@@ -288,12 +296,16 @@ api.updateHero = {
hero.auth.blocked = false;
}
- if (updateData.flags && _.isBoolean(updateData.flags.chatRevoked)) hero.flags.chatRevoked = updateData.flags.chatRevoked;
- if (updateData.flags && _.isBoolean(updateData.flags.chatShadowMuted)) hero.flags.chatShadowMuted = updateData.flags.chatShadowMuted;
+ if (updateData.flags && _.isBoolean(updateData.flags.chatRevoked)) {
+ hero.flags.chatRevoked = updateData.flags.chatRevoked;
+ }
+ if (updateData.flags && _.isBoolean(updateData.flags.chatShadowMuted)) {
+ hero.flags.chatShadowMuted = updateData.flags.chatShadowMuted;
+ }
- let savedHero = await hero.save();
- let heroJSON = savedHero.toJSON();
- let responseHero = {_id: heroJSON._id}; // only respond with important fields
+ const savedHero = await hero.save();
+ const heroJSON = savedHero.toJSON();
+ const responseHero = { _id: heroJSON._id }; // only respond with important fields
heroAdminFields.split(' ').forEach(field => {
_.set(responseHero, field, _.get(heroJSON, field));
});
@@ -302,4 +314,4 @@ api.updateHero = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/i18n.js b/website/server/controllers/api-v3/i18n.js
index de6cfddebb..092521f216 100644
--- a/website/server/controllers/api-v3/i18n.js
+++ b/website/server/controllers/api-v3/i18n.js
@@ -1,9 +1,9 @@
+import _ from 'lodash';
import {
translations,
momentLangs,
availableLanguages,
} from '../../libs/i18n';
-import _ from 'lodash';
const api = {};
@@ -22,9 +22,10 @@ function geti18nBrowserScript (language) {
}
/**
- * @api {get} /api/v3/i18n/browser-script Returns a JS script to make all the i18n strings available in the browser
- * under window.i18n.strings
- * @apiDescription Does not require authentication.
+ * @api {get} /api/v3/i18n/browser-script Returns the i18n JS script.
+ * @apiDescription Returns the i18n JS script to make
+ * all the i18n strings available in the browser under window.i18n.strings.
+ * Does not require authentication.
* @apiName i18nBrowserScriptGet
* @apiGroup i18n
*/
@@ -32,7 +33,7 @@ api.geti18nBrowserScript = {
method: 'GET',
url: '/i18n/browser-script',
async handler (req, res) {
- const language = _.find(availableLanguages, {code: req.language});
+ const language = _.find(availableLanguages, { code: req.language });
res.set({
'Content-Type': 'application/javascript',
@@ -43,4 +44,4 @@ api.geti18nBrowserScript = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/iap.js b/website/server/controllers/api-v3/iap.js
index a626817c82..6512bf9dff 100644
--- a/website/server/controllers/api-v3/iap.js
+++ b/website/server/controllers/api-v3/iap.js
@@ -1,4 +1,6 @@
// NOTE: this file is only used because the mobile apps expect IAP routes
// to be found at /api/v3/iap instead of /iap.
-module.exports = require('../top-level/payments/iap');
+import iap from '../top-level/payments/iap';
+
+export default iap;
diff --git a/website/server/controllers/api-v3/inbox.js b/website/server/controllers/api-v3/inbox.js
index b806931a8d..0702fd0979 100644
--- a/website/server/controllers/api-v3/inbox.js
+++ b/website/server/controllers/api-v3/inbox.js
@@ -1,7 +1,7 @@
import { authWithHeaders } from '../../middlewares/auth';
import * as inboxLib from '../../libs/inbox';
-let api = {};
+const api = {};
/* NOTE most inbox routes are either in the user or members controller */
@@ -21,9 +21,9 @@ api.getInboxMessages = {
url: '/inbox/messages',
middlewares: [authWithHeaders()],
async handler (req, res) {
- const user = res.locals.user;
- const page = req.query.page;
- const conversation = req.query.conversation;
+ const { user } = res.locals;
+ const { page } = req.query;
+ const { conversation } = req.query;
const userInbox = await inboxLib.getUserInbox(user, {
page, conversation,
@@ -33,4 +33,4 @@ api.getInboxMessages = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/members.js b/website/server/controllers/api-v3/members.js
index 3623477205..6d16734273 100644
--- a/website/server/controllers/api-v3/members.js
+++ b/website/server/controllers/api-v3/members.js
@@ -19,10 +19,13 @@ import {
sendTxn as sendTxnEmail,
} from '../../libs/email';
import { sendNotification as sendPushNotification } from '../../libs/pushNotifications';
-import { achievements } from '../../../../website/common/';
-import {sentMessage} from '../../libs/inbox';
+import common from '../../../common';
+import { sentMessage } from '../../libs/inbox';
+import { highlightMentions } from '../../libs/highlightMentions';
-let api = {};
+const { achievements } = common;
+
+const api = {};
/**
* @api {get} /api/v3/members/:memberId Get a member profile
@@ -38,7 +41,8 @@ let api = {};
* @apiSuccess {Object} data.profile Includes name
* @apiSuccess {Object} data.preferences Includes info about appearance and public prefs
* @apiSuccess {Object} data.party Includes basic info about current party and quests
- * @apiSuccess {Object} data.items Basic inventory information includes quests, food, potions, eggs, gear, special items
+ * @apiSuccess {Object} data.items Basic inventory information includes quests,
+ * food, potions, eggs, gear, special items
* @apiSuccess {Object} data.achievements Lists current achievements
* @apiSuccess {Object} data.auth Includes latest timestamps
*
@@ -98,22 +102,22 @@ api.getMember = {
async handler (req, res) {
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let memberId = req.params.memberId;
+ const { memberId } = req.params;
- let member = await User
+ const member = await User
.findById(memberId)
.select(memberFields)
.exec();
- if (!member) throw new NotFound(res.t('userWithIDNotFound', {userId: memberId}));
+ if (!member) throw new NotFound(res.t('userWithIDNotFound', { userId: memberId }));
if (!member.flags.verifiedUsername) member.auth.local.username = null;
// manually call toJSON with minimize: true so empty paths aren't returned
- let memberToJSON = member.toJSON({minimize: true});
+ const memberToJSON = member.toJSON({ minimize: true });
User.addComputedStatsToJSONObj(memberToJSON.stats, member);
res.respond(200, memberToJSON);
@@ -127,21 +131,21 @@ api.getMemberByUsername = {
async handler (req, res) {
req.checkParams('username', res.t('invalidReqParams')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
let username = req.params.username.toLowerCase();
if (username[0] === '@') username = username.slice(1, username.length);
- let member = await User
- .findOne({'auth.local.lowerCaseUsername': username, 'flags.verifiedUsername': true})
+ const member = await User
+ .findOne({ 'auth.local.lowerCaseUsername': username, 'flags.verifiedUsername': true })
.select(memberFields)
.exec();
if (!member) throw new NotFound(res.t('userNotFound'));
// manually call toJSON with minimize: true so empty paths aren't returned
- let memberToJSON = member.toJSON({minimize: true});
+ const memberToJSON = member.toJSON({ minimize: true });
User.addComputedStatsToJSONObj(memberToJSON.stats, member);
res.respond(200, memberToJSON);
@@ -152,7 +156,8 @@ api.getMemberByUsername = {
* @api {get} /api/v3/members/:memberId/achievements Get member achievements object
* @apiName GetMemberAchievements
* @apiGroup Member
- * @apiDescription Get a list of achievements of the requested member, grouped by basic / seasonal / special.
+ * @apiDescription Get a list of achievements
+ * of the requested member, grouped by basic / seasonal / special.
*
* @apiParam (Path) {UUID} memberId The member's id
*
@@ -168,9 +173,12 @@ api.getMemberByUsername = {
* @apiSuccess {String} data.*.achievements.title The localized title string
* @apiSuccess {String} data.*.achievements.text The localized description string
* @apiSuccess {Boolean} data.*.achievements.earned Whether the user has earned the achievement
- * @apiSuccess {Number} data.*.achievements.index The unique index assigned to the achievement (only for sorting purposes)
- * @apiSuccess {Anything} data.*.achievements.value The value related to the achievement (if applicable)
- * @apiSuccess {Number} data.*.achievements.optionalCount The count related to the achievement (if applicable)
+ * @apiSuccess {Number} data.*.achievements.index The unique index assigned
+ * to the achievement (only for sorting purposes).
+ * @apiSuccess {Anything} data.*.achievements.value The value related to the achievement
+ * (if applicable)
+ * @apiSuccess {Number} data.*.achievements.optionalCount The count related to the achievement
+ * (if applicable)
*
* @apiSuccessExample {json} Successful Response
* {
@@ -188,7 +196,9 @@ api.getMemberByUsername = {
* },
* perfect: {
* title: "5 Perfect Days",
- * text: "Completed all active Dailies on 5 days. With this achievement you get a +level/2 buff to all attributes for the next day. Levels greater than 100 don't have any additional effects on buffs.",
+ * text: "Completed all active Dailies on 5 days. With this achievement
+ * you get a +level/2 buff to all attributes for the next day.
+ * Levels greater than 100 don't have any additional effects on buffs.",
* icon: "achievement-perfect",
* earned: true,
* value: 5,
@@ -216,7 +226,8 @@ api.getMemberByUsername = {
* achievements: {
* habitSurveys: {
* title: "Helped Habitica Grow",
- * text: "Helped Habitica grow on 0 occasions, either by filling out a survey or helping with a major testing effort. Thank you!",
+ * text: "Helped Habitica grow on 0 occasions, either by filling out
+ * a survey or helping with a major testing effort. Thank you!",
* icon: "achievement-tree",
* earned: false,
* value: 0,
@@ -227,8 +238,10 @@ api.getMemberByUsername = {
* }
* }
*
- * @apiError (400) {BadRequest} MemberIdRequired The `id` param is required and must be a valid `UUID`
- * @apiError (404) {NotFound} UserWithIdNotFound The `id` param did not belong to an existing member
+ * @apiError (400) {BadRequest} MemberIdRequired The `id` param is required
+ * and must be a valid `UUID`.
+ * @apiError (404) {NotFound} UserWithIdNotFound The `id` param did not
+ * belong to an existing member.
*/
api.getMemberAchievements = {
method: 'GET',
@@ -237,19 +250,19 @@ api.getMemberAchievements = {
async handler (req, res) {
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let memberId = req.params.memberId;
+ const { memberId } = req.params;
- let member = await User
+ const member = await User
.findById(memberId)
.select(memberFields)
.exec();
- if (!member) throw new NotFound(res.t('userWithIDNotFound', {userId: memberId}));
+ if (!member) throw new NotFound(res.t('userWithIDNotFound', { userId: memberId }));
- let achievsObject = achievements.getAchievementsForProfile(member, req.language);
+ const achievsObject = achievements.getAchievementsForProfile(member, req.language);
res.respond(200, achievsObject);
},
@@ -257,7 +270,8 @@ api.getMemberAchievements = {
// Return a request handler for getMembersForGroup / getInvitesForGroup / getMembersForChallenge
-// @TODO: This violates the Liskov substitution principle. We should create factory functions. See Webhooks for a good example
+// @TODO: This violates the Liskov substitution principle.
+// We should create factory functions. See Webhooks for a good example
function _getMembersForItem (type) {
// check for allowed `type`
if (['group-members', 'group-invites', 'challenge-members'].indexOf(type) === -1) {
@@ -272,13 +286,13 @@ function _getMembersForItem (type) {
}
req.checkQuery('lastId').optional().notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let groupId = req.params.groupId;
- let challengeId = req.params.challengeId;
- let lastId = req.query.lastId;
- let user = res.locals.user;
+ const { groupId } = req.params;
+ const { challengeId } = req.params;
+ const { lastId } = req.query;
+ const { user } = res.locals;
let challenge;
let group;
@@ -286,7 +300,8 @@ function _getMembersForItem (type) {
challenge = await Challenge.findById(challengeId).select('_id type leader group').exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
- // optionalMembership is set to true because even if you're not member of the group you may be able to access the challenge
+ // optionalMembership is set to true because even
+ // if you're not member of the group you may be able to access the challenge
// for example if you've been booted from it, are the leader or a site admin
group = await Group.getGroup({
user,
@@ -297,13 +312,14 @@ function _getMembersForItem (type) {
if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound'));
} else {
- group = await Group.getGroup({user, groupId, fields: '_id type'});
+ group = await Group.getGroup({ user, groupId, fields: '_id type' });
if (!group) throw new NotFound(res.t('groupNotFound'));
}
- let query = {};
+ const query = {};
let fields = nameFields;
- let addComputedStats = false; // add computes stats to the member info when items and stats are available
+ // add computes stats to the member info when items and stats are available
+ let addComputedStats = false;
if (type === 'challenge-members') {
query.challenges = challenge._id;
@@ -314,7 +330,7 @@ function _getMembersForItem (type) {
}
if (req.query.search) {
- query['profile.name'] = {$regex: req.query.search};
+ query['profile.name'] = { $regex: req.query.search };
}
} else if (type === 'group-members') {
if (group.type === 'guild') {
@@ -347,7 +363,8 @@ function _getMembersForItem (type) {
}
} else {
query['invitations.party.id'] = group._id; // group._id and not groupId because groupId could be === 'party'
- // @TODO invitations are now stored like this: `'invitations.parties': []` Probably need a database index for it.
+ // @TODO invitations are now stored like this: `'invitations.parties': []`
+ // Probably need a database index for it.
if (req.query.includeAllPublicFields === 'true') {
fields = memberFields;
addComputedStats = true;
@@ -355,7 +372,7 @@ function _getMembersForItem (type) {
}
}
- if (lastId) query._id = {$gt: lastId};
+ if (lastId) query._id = { $gt: lastId };
let limit = 30;
@@ -364,9 +381,9 @@ function _getMembersForItem (type) {
limit = 0; // no limit
}
- let members = await User
+ const members = await User
.find(query)
- .sort({_id: 1})
+ .sort({ _id: 1 })
.limit(limit)
.select(fields)
.lean()
@@ -380,13 +397,21 @@ function _getMembersForItem (type) {
/**
* @api {get} /api/v3/groups/:groupId/members Get members for a group
- * @apiDescription With a limit of 30 member per request. To get all members run requests against this routes (updating the lastId query parameter) until you get less than 30 results.
+ * @apiDescription With a limit of 30 member per request.
+ * To get all members run requests against this routes (updating the lastId query parameter)
+ * until you get less than 30 results.
* @apiName GetMembersForGroup
* @apiGroup Member
*
* @apiParam (Path) {UUID} groupId The group id
- * @apiParam (Query) {UUID} lastId Query parameter to specify the last member returned in a previous request to this route and get the next batch of results
- * @apiParam (Query) {Boolean} includeAllPublicFields Query parameter available only when fetching a party. If === `true` then all public fields for members will be returned (like when making a request for a single member)
+ * @apiParam (Query) {UUID} lastId Query parameter to specify the last member
+ * returned in a previous request to this route and
+ * get the next batch of results.
+ * @apiParam (Query) {Boolean} includeAllPublicFields Query parameter available
+ * only when fetching a party. If === `true`
+ * then all public fields for members
+ * will be returned (like when making a request
+ * for a single member).
*
* @apiSuccess {Array} data An array of members, sorted by _id
*
@@ -416,12 +441,16 @@ api.getMembersForGroup = {
/**
* @api {get} /api/v3/groups/:groupId/invites Get invites for a group
- * @apiDescription With a limit of 30 member per request. To get all invites run requests against this routes (updating the lastId query parameter) until you get less than 30 results.
+ * @apiDescription With a limit of 30 member per request. To get all invites run
+ * requests against this routes (updating the lastId query parameter)
+ * until you get less than 30 results.
* @apiName GetInvitesForGroup
* @apiGroup Member
*
* @apiParam (Path) {UUID} groupId The group id
- * @apiParam (Query) {UUID} lastId Query parameter to specify the last invite returned in a previous request to this route and get the next batch of results
+ * @apiParam (Query) {UUID} lastId Query parameter to specify the last invite
+ * returned in a previous request to this route and
+ * get the next batch of results.
*
* @apiSuccess {array} data An array of invites, sorted by _id
*
@@ -453,16 +482,21 @@ api.getInvitesForGroup = {
/**
* @api {get} /api/v3/challenges/:challengeId/members Get members for a challenge
* @apiDescription With a limit of 30 member per request.
- * To get all members run requests against this routes (updating the lastId query parameter) until you get less than 30 results.
- * BETA You can also use ?includeAllMembers=true. This option is currently in BETA and may be removed in future.
+ * To get all members run requests against this routes (updating the lastId query parameter)
+ * until you get less than 30 results.
+ * BETA You can also use ?includeAllMembers=true. This option is currently in BETA
+ * and may be removed in future.
* Its use is discouraged and its performaces are not optimized especially for large challenges.
*
* @apiName GetMembersForChallenge
* @apiGroup Member
*
* @apiParam (Path) {UUID} challengeId The challenge id
- * @apiParam (Query) {UUID} lastId Query parameter to specify the last member returned in a previous request to this route and get the next batch of results
- * @apiParam (Query) {String} includeAllMembers BETA Query parameter - If 'true' all challenge members are returned
+ * @apiParam (Query) {UUID} lastId Query parameter to specify the last member returned
+ * in a previous request to this route and
+ * get the next batch of results.
+ * @apiParam (Query) {String} includeAllMembers BETA Query parameter - If 'true' all
+ * challenge members are returned.
* @apiSuccess {Array} data An array of members, sorted by _id
*
@@ -484,7 +518,8 @@ api.getMembersForChallenge = {
* @apiParam (Path) {UUID} challengeId The challenge _id
* @apiParam (Path) {UUID} memberId The member _id
*
- * @apiSuccess {Object} data Return an object with member _id, profile.name and a tasks object with the challenge tasks for the member
+ * @apiSuccess {Object} data Return an object with member _id, profile.name
+ * and a tasks object with the challenge tasks for the member.
*
* @apiSuccessExample {json} Success-Response:
* {
@@ -539,26 +574,29 @@ api.getChallengeMemberProgress = {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let user = res.locals.user;
- let challengeId = req.params.challengeId;
- let memberId = req.params.memberId;
+ const { user } = res.locals;
+ const { challengeId } = req.params;
+ const { memberId } = req.params;
- let member = await User.findById(memberId).select(`${nameFields} challenges`).exec();
- if (!member) throw new NotFound(res.t('userWithIDNotFound', {userId: memberId}));
+ const member = await User.findById(memberId).select(`${nameFields} challenges`).exec();
+ if (!member) throw new NotFound(res.t('userWithIDNotFound', { userId: memberId }));
- let challenge = await Challenge.findById(challengeId).exec();
+ const challenge = await Challenge.findById(challengeId).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
- // optionalMembership is set to true because even if you're not member of the group you may be able to access the challenge
+ // optionalMembership is set to true because even if you're
+ // not member of the group you may be able to access the challenge
// for example if you've been booted from it, are the leader or a site admin
- let group = await Group.getGroup({user, groupId: challenge.group, fields: '_id type privacy', optionalMembership: true});
+ const group = await Group.getGroup({
+ user, groupId: challenge.group, fields: '_id type privacy', optionalMembership: true,
+ });
if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound'));
if (!challenge.isMember(member)) throw new NotFound(res.t('challengeMemberNotFound'));
- let chalTasks = await Tasks.Task.find({
+ const chalTasks = await Tasks.Task.find({
userId: memberId,
'challenge.id': challengeId,
})
@@ -566,26 +604,32 @@ api.getChallengeMemberProgress = {
.exec();
// manually call toJSON with minimize: true so empty paths aren't returned
- let response = member.toJSON({minimize: true});
+ const response = member.toJSON({ minimize: true });
delete response.challenges;
response.tasks = chalTasks.map(chalTask => {
chalTask.checklist = []; // Clear checklists as they are private
- return chalTask.toJSON({minimize: true});
+ return chalTask.toJSON({ minimize: true });
});
res.respond(200, response);
},
};
/**
- * @api {get} /api/v3/members/:toUserId/objections/:interaction Get any objections that would occur if the given interaction was attempted - BETA
+ * @api {get} /api/v3/members/:toUserId/objections/:interaction Get objections to interaction
+ * @apiDescription Get any objections that would occur
+ * if the given interaction was attempted - BETA.
+ *
* @apiVersion 3.0.0
* @apiName GetObjectionsToInteraction
* @apiGroup Member
*
* @apiParam (Path) {UUID} toUserId The user to interact with
- * @apiParam (Path) {String="send-private-message","transfer-gems"} interaction Name of the interaction to query
+ * @apiParam (Path) {String="send-private-message","transfer-gems"} interaction Name of the
+ * interaction
+ * to query.
*
- * @apiSuccess {Array} data Return an array of objections, if the interaction would be blocked; otherwise an empty array
+ * @apiSuccess {Array} data Return an array of objections,
+ * if the interaction would be blocked; otherwise an empty array.
*/
api.getObjectionsToInteraction = {
method: 'GET',
@@ -595,15 +639,15 @@ api.getObjectionsToInteraction = {
req.checkParams('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID();
req.checkParams('interaction', res.t('interactionRequired')).notEmpty().isIn(KNOWN_INTERACTIONS);
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let sender = res.locals.user;
- let receiver = await User.findById(req.params.toUserId).exec();
- if (!receiver) throw new NotFound(res.t('userWithIDNotFound', {userId: req.params.toUserId}));
+ const sender = res.locals.user;
+ const receiver = await User.findById(req.params.toUserId).exec();
+ if (!receiver) throw new NotFound(res.t('userWithIDNotFound', { userId: req.params.toUserId }));
- let interaction = req.params.interaction;
- let response = sender.getObjectionsToInteraction(interaction, receiver);
+ const { interaction } = req.params;
+ const response = sender.getObjectionsToInteraction(interaction, receiver);
res.respond(200, response.map(res.t));
},
@@ -633,7 +677,7 @@ api.sendPrivateMessage = {
if (validationErrors) throw validationErrors;
const sender = res.locals.user;
- const message = req.body.message;
+ const message = (await highlightMentions(req.body.message))[0];
const receiver = await User.findById(req.body.toUserId).exec();
if (!receiver) throw new NotFound(res.t('userNotFound'));
@@ -644,7 +688,7 @@ api.sendPrivateMessage = {
const messageSent = await sentMessage(sender, receiver, message, res.t);
- res.respond(200, {message: messageSent});
+ res.respond(200, { message: messageSent });
},
};
@@ -669,18 +713,18 @@ api.transferGems = {
req.checkBody('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID();
req.checkBody('gemAmount', res.t('gemAmountRequired')).notEmpty().isInt();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let sender = res.locals.user;
- let receiver = await User.findById(req.body.toUserId).exec();
+ const sender = res.locals.user;
+ const receiver = await User.findById(req.body.toUserId).exec();
if (!receiver) throw new NotFound(res.t('userNotFound'));
- let objections = sender.getObjectionsToInteraction('transfer-gems', receiver);
+ const objections = sender.getObjectionsToInteraction('transfer-gems', receiver);
if (objections.length > 0) throw new NotAuthorized(res.t(objections[0]));
- let gemAmount = req.body.gemAmount;
- let amount = gemAmount / 4;
+ const { gemAmount } = req.body;
+ const amount = gemAmount / 4;
if (amount <= 0 || sender.balance < amount) {
throw new NotAuthorized(res.t('badAmountOfGemsToSend'));
@@ -689,13 +733,13 @@ api.transferGems = {
receiver.balance += amount;
sender.balance -= amount;
// @TODO necessary? Also saved when sending the inbox message
- let promises = [receiver.save(), sender.save()];
+ const promises = [receiver.save(), sender.save()];
await Promise.all(promises);
// generate the message in both languages, so both users can understand it
- let receiverLang = receiver.preferences.language;
- let senderLang = sender.preferences.language;
- let [receiverMsg, senderMsg] = [receiverLang, senderLang].map((lang) => {
+ const receiverLang = receiver.preferences.language;
+ const senderLang = sender.preferences.language;
+ const [receiverMsg, senderMsg] = [receiverLang, senderLang].map(lang => {
let messageContent = res.t('privateMessageGiftGemsMessage', {
receiverName: receiver.profile.name,
senderName: sender.profile.name,
@@ -714,21 +758,21 @@ api.transferGems = {
receiverMsg,
});
- let byUsername = getUserInfo(sender, ['name']).name;
+ const byUsername = getUserInfo(sender, ['name']).name;
if (receiver.preferences.emailNotifications.giftedGems !== false) {
sendTxnEmail(receiver, 'gifted-gems', [
- {name: 'GIFTER', content: byUsername},
- {name: 'X_GEMS_GIFTED', content: gemAmount},
+ { name: 'GIFTER', content: byUsername },
+ { name: 'X_GEMS_GIFTED', content: gemAmount },
]);
}
if (receiver.preferences.pushNotifications.giftedGems !== false) {
sendPushNotification(receiver,
{
title: res.t('giftedGems', receiverLang),
- message: res.t('giftedGemsInfo', {amount: gemAmount, name: byUsername}, receiverLang),
+ message: res.t('giftedGemsInfo', { amount: gemAmount, name: byUsername }, receiverLang),
identifier: 'giftedGems',
- payload: {replyTo: sender._id},
+ payload: { replyTo: sender._id },
});
}
@@ -737,4 +781,4 @@ api.transferGems = {
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/modelsPaths.js b/website/server/controllers/api-v3/modelsPaths.js
index 93b8641b10..5358d44f8c 100644
--- a/website/server/controllers/api-v3/modelsPaths.js
+++ b/website/server/controllers/api-v3/modelsPaths.js
@@ -1,9 +1,9 @@
import mongoose from 'mongoose';
-let api = {};
+const api = {};
-let tasksModels = ['habit', 'daily', 'todo', 'reward'];
-let allModels = ['user', 'tag', 'challenge', 'group'].concat(tasksModels);
+const tasksModels = ['habit', 'daily', 'todo', 'reward'];
+const allModels = ['user', 'tag', 'challenge', 'group'].concat(tasksModels);
/**
* @api {get} /api/v3/models/:model/paths Get all paths for the specified model
@@ -11,12 +11,14 @@ let allModels = ['user', 'tag', 'challenge', 'group'].concat(tasksModels);
* @apiName GetUserModelPaths
* @apiGroup Meta
*
- * @apiParam (Path) {String="user","group","challenge","tag","habit","daily","todo","reward"} model The name of the model
+ * @apiParam (Path) {String="user","group","challenge","tag","habit",
+ "daily","todo","reward"} model The name of the model
*
* @apiExample {curl} Tag
* curl https://habitica.com/api/v3/models/tag/paths
*
- * @apiSuccess {Object} data A key-value object made of fieldPath: fieldType (like {'field.nested': Boolean})
+ * @apiSuccess {Object} data A key-value object made of fieldPath: fieldType
+ (like {'field.nested': Boolean})
*
* @apiSuccessExample {json} Tag
* {
@@ -36,10 +38,10 @@ api.getModelPaths = {
async handler (req, res) {
req.checkParams('model', res.t('modelNotFound')).notEmpty().isIn(allModels);
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let model = req.params.model;
+ let { model } = req.params;
// tasks models are lowercase, the others have the first letter uppercase (User, Group)
if (tasksModels.indexOf(model) === -1) {
model = model.charAt(0).toUpperCase() + model.slice(1);
@@ -51,4 +53,4 @@ api.getModelPaths = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/news.js b/website/server/controllers/api-v3/news.js
index 51f7441054..595410109d 100644
--- a/website/server/controllers/api-v3/news.js
+++ b/website/server/controllers/api-v3/news.js
@@ -1,9 +1,10 @@
import { authWithHeaders } from '../../middlewares/auth';
-let api = {};
+const api = {};
-// @TODO export this const, cannot export it from here because only routes are exported from controllers
-const LAST_ANNOUNCEMENT_TITLE = 'SPOOKY SPARKLES AND COSTUME CHALLENGE!';
+// @TODO export this const, cannot export it from here because only routes are exported from
+// controllers
+const LAST_ANNOUNCEMENT_TITLE = 'OCTOBER SUBSCRIBER ITEMS AND BLOG POSTS!';
const worldDmg = { // @TODO
bailey: false,
};
@@ -30,21 +31,43 @@ api.getNews = {
${res.t('newStuff')}
-
10/3/2019 - ${LAST_ANNOUNCEMENT_TITLE}
+
10/24/2019 - ${LAST_ANNOUNCEMENT_TITLE}
-
-
Spooky Sparkles in the Seasonal Shop
-
There's a new Gold-purchasable item in the Seasonal Shop: Spooky Sparkles! Buy some and then cast it on your friends. I wonder what it will do?
-
If you have Spooky Sparkles cast on you, you will receive the "Alarming Friends" badge! Don't worry, any mysterious effects will wear off the next day.... or you can cancel them early by buying an Opaque Potion!
-
While you're at it, be sure to check out all the other items in the Seasonal Shop! There are lots of equipment items from the previous Fall Festivals. The Seasonal Shop will only be open until October 31st, so stock up now.
-
by Lemoness and SabreCat
-
-
Costume Challenge
-
The Community Costume Challenge has begun! Between now and October 31st, dress up as your avatar in real life and post a photo on social media to get the coveted Costume Challenge badge! Read the full rules on the Challenge page.
The October Subscriber Item has been revealed: the Cryptic Flame Item Set! You only
+ have until October 31 to receive the item set when
+ you subscribe. If you're already an active subscriber, reload the site and then head
+ to Inventory > Items to claim your gear!
+
Subscribers also receive the ability to buy Gems for Gold -- the longer you subscribe,
+ the more Gems you can buy per month! There are other perks as well, such as longer
+ access to uncompressed data and a cute Jackalope pet. Best of all, subscriptions let us
+ keep Habitica running. Thank you very much for your support -- it means a lot to us.
by Beffymaroo
+
+
Use Case Spotlight: Habitica Events!
+
This month's Use Case
+ Spotlight is about Using Habitica Events for Motivation! It features a number of
+ great suggestions submitted by Habiticans in the
+ Use Case Spotlights
+ Guild. We hope it helps any of you who might be looking for new ways to
+ incentivize yourselves.
+
Plus, we're collecting user submissions for the next spotlight! How do you gamify your
+ tasks? We’ll be featuring player-submitted examples in Use Case Spotlights on the
+ Habitica Blog next month, so post your suggestions in the Use Case Spotlight Guild now.
+ We look forward to learning more about how you use Habitica to improve your life and get
+ things done!
+
by shanaqui
+
Guild Spotlight: More New and Notable Guilds!
+
There's a new Guild Spotlight on the blog
+ that highlights yet another selection of the upcoming Guilds in Habitica dedicated to a
+ variety of topics! Check it out now to find some of Habitica's best new communities.
+
by shanaqui
+
`,
});
@@ -65,13 +88,11 @@ api.tellMeLaterNews = {
middlewares: [authWithHeaders()],
url: '/news/tell-me-later',
async handler (req, res) {
- const user = res.locals.user;
+ const { user } = res.locals;
user.flags.newStuff = false;
- const existingNotificationIndex = user.notifications.findIndex(n => {
- return n && n.type === 'NEW_STUFF';
- });
+ const existingNotificationIndex = user.notifications.findIndex(n => n && n.type === 'NEW_STUFF');
if (existingNotificationIndex !== -1) user.notifications.splice(existingNotificationIndex, 1);
user.addNotification('NEW_STUFF', { title: LAST_ANNOUNCEMENT_TITLE }, true); // seen by default
@@ -80,4 +101,4 @@ api.tellMeLaterNews = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/notifications.js b/website/server/controllers/api-v3/notifications.js
index e656063529..16a0410511 100644
--- a/website/server/controllers/api-v3/notifications.js
+++ b/website/server/controllers/api-v3/notifications.js
@@ -9,7 +9,7 @@ import {
model as UserNotification,
} from '../../models/userNotification';
-let api = {};
+const api = {};
/**
* @api {post} /api/v3/notifications/:notificationId/read Mark one notification as read
@@ -25,16 +25,14 @@ api.readNotification = {
url: '/notifications/:notificationId/read',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('notificationId', res.t('notificationIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const index = user.notifications.findIndex(n => {
- return n && n.id === req.params.notificationId;
- });
+ const index = user.notifications.findIndex(n => n && n.id === req.params.notificationId);
if (index === -1) {
throw new NotificationNotFound(req.language);
@@ -45,7 +43,7 @@ api.readNotification = {
// Update the user version field manually,
// it cannot be updated in the pre update hook
// See https://github.com/HabitRPG/habitica/pull/9321#issuecomment-354187666 for more info
- user._v++;
+ user._v += 1;
await user.update({
$pull: { notifications: { id: req.params.notificationId } },
@@ -67,18 +65,16 @@ api.readNotifications = {
url: '/notifications/read',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkBody('notificationIds', res.t('notificationsRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let notificationsIds = req.body.notificationIds;
- for (let notificationId of notificationsIds) {
- const index = user.notifications.findIndex(n => {
- return n && n.id === notificationId;
- });
+ const notificationsIds = req.body.notificationIds;
+ for (const notificationId of notificationsIds) {
+ const index = user.notifications.findIndex(n => n && n.id === notificationId);
if (index === -1) {
throw new NotificationNotFound(req.language);
@@ -94,7 +90,7 @@ api.readNotifications = {
// Update the user version field manually,
// it cannot be updated in the pre update hook
// See https://github.com/HabitRPG/habitica/pull/9321#issuecomment-354187666 for more info
- user._v++;
+ user._v += 1;
res.respond(200, UserNotification.convertNotificationsToSafeJson(user.notifications));
},
@@ -102,7 +98,9 @@ api.readNotifications = {
/**
* @api {post} /api/v3/notifications/:notificationId/see Mark one notification as seen
- * @apiDescription Mark a notification as seen. Different from marking them as read in that the notification isn't removed but the `seen` field is set to `true`
+ * @apiDescription Mark a notification as seen.
+ * Different from marking them as read in that the notification isn't
+ * removed but the `seen` field is set to `true`.
* @apiName SeeNotification
* @apiGroup Notification
*
@@ -115,18 +113,16 @@ api.seeNotification = {
url: '/notifications/:notificationId/see',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('notificationId', res.t('notificationIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const notificationId = req.params.notificationId;
+ const { notificationId } = req.params;
- const notification = user.notifications.find(n => {
- return n && n.id === notificationId;
- });
+ const notification = user.notifications.find(n => n && n.id === notificationId);
if (!notification) {
throw new NotificationNotFound(req.language);
@@ -146,7 +142,7 @@ api.seeNotification = {
// Update the user version field manually,
// it cannot be updated in the pre update hook
// See https://github.com/HabitRPG/habitica/pull/9321#issuecomment-354187666 for more info
- user._v++;
+ user._v += 1;
res.respond(200, notification);
},
@@ -164,19 +160,17 @@ api.seeNotifications = {
url: '/notifications/see',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkBody('notificationIds', res.t('notificationsRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let notificationsIds = req.body.notificationIds;
+ const notificationsIds = req.body.notificationIds;
- for (let notificationId of notificationsIds) {
- const notification = user.notifications.find(n => {
- return n && n.id === notificationId;
- });
+ for (const notificationId of notificationsIds) {
+ const notification = user.notifications.find(n => n && n.id === notificationId);
if (!notification) {
throw new NotificationNotFound(req.language);
@@ -191,4 +185,4 @@ api.seeNotifications = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/pushNotifications.js b/website/server/controllers/api-v3/pushNotifications.js
index 14330e4e6b..83768ca48a 100644
--- a/website/server/controllers/api-v3/pushNotifications.js
+++ b/website/server/controllers/api-v3/pushNotifications.js
@@ -4,7 +4,7 @@ import {
} from '../../libs/errors';
import { model as PushDevice } from '../../models/pushDevice';
-let api = {};
+const api = {};
/**
* @apiIgnore
@@ -23,7 +23,7 @@ api.addPushDevice = {
url: '/user/push-devices',
middlewares: [authWithHeaders()],
async handler (req, res) {
- const user = res.locals.user;
+ const { user } = res.locals;
req.checkBody('regId', res.t('regIdRequired')).notEmpty();
req.checkBody('type', res.t('typeRequired')).notEmpty().isIn(['ios', 'android']);
@@ -31,7 +31,7 @@ api.addPushDevice = {
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const pushDevices = user.pushDevices;
+ const { pushDevices } = user;
const item = {
regId: req.body.regId,
@@ -73,27 +73,25 @@ api.removePushDevice = {
url: '/user/push-devices/:regId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- const user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('regId', res.t('regIdRequired')).notEmpty();
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const regId = req.params.regId;
+ const { regId } = req.params;
- const pushDevices = user.pushDevices;
+ const { pushDevices } = user;
- const indexOfPushDevice = pushDevices.findIndex((element) => {
- return element.regId === regId;
- });
+ const indexOfPushDevice = pushDevices.findIndex(element => element.regId === regId);
if (indexOfPushDevice === -1) {
throw new NotFound(res.t('pushDeviceNotFound'));
}
// Concurrency safe update
- const pullQuery = { $pull: { pushDevices: { $elemMatch: { regId } } } };
+ const pullQuery = { $pull: { pushDevices: { regId } } };
await user.update(pullQuery).exec();
// Update the response
@@ -103,4 +101,4 @@ api.removePushDevice = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/quests.js b/website/server/controllers/api-v3/quests.js
index f43b5f7f6b..5b4c0322cb 100644
--- a/website/server/controllers/api-v3/quests.js
+++ b/website/server/controllers/api-v3/quests.js
@@ -1,6 +1,6 @@
import _ from 'lodash';
import { authWithHeaders } from '../../middlewares/auth';
-import analytics from '../../libs/analyticsService';
+import * as analytics from '../../libs/analyticsService';
import {
model as Group,
basicFields as basicGroupFields,
@@ -21,7 +21,7 @@ import apiError from '../../libs/apiError';
const questScrolls = common.content.quests;
-function canStartQuestAutomatically (group) {
+function canStartQuestAutomatically (group) {
// If all members are either true (accepted) or false (rejected) return true
// If any member is null/undefined (undecided) return false
return _.every(group.quest.members, _.isBoolean);
@@ -37,7 +37,7 @@ function canStartQuestAutomatically (group) {
* The quest leader can use this route.
*/
-let api = {};
+const api = {};
/**
* @api {post} /api/v3/groups/:groupId/quests/invite/:questKey Invite users to a quest
@@ -57,16 +57,16 @@ api.inviteToQuest = {
url: '/groups/:groupId/quests/invite/:questKey',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let questKey = req.params.questKey;
- let quest = questScrolls[questKey];
+ const { user } = res.locals;
+ const { questKey } = req.params;
+ const quest = questScrolls[questKey];
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let group = await Group.getGroup({user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat')});
+ const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat') });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported'));
@@ -75,9 +75,9 @@ api.inviteToQuest = {
if (user.stats.lvl < quest.lvl) throw new NotAuthorized(res.t('questLevelTooHigh', { level: quest.lvl }));
if (group.quest.key) throw new NotAuthorized(res.t('questAlreadyUnderway'));
- let members = await User.find({
+ const members = await User.find({
'party._id': group._id,
- _id: {$ne: user._id},
+ _id: { $ne: user._id },
})
.select('auth.facebook auth.google auth.local preferences.emailNotifications preferences.pushNotifications preferences.language profile.name pushDevices')
.exec();
@@ -93,15 +93,15 @@ api.inviteToQuest = {
await User.update({
'party._id': group._id,
- _id: {$ne: user._id},
+ _id: { $ne: user._id },
}, {
$set: {
'party.quest.RSVPNeeded': true,
'party.quest.key': questKey,
},
- }, {multi: true}).exec();
+ }, { multi: true }).exec();
- _.each(members, (member) => {
+ _.each(members, member => {
group.quest.members[member._id] = null;
});
@@ -109,7 +109,7 @@ api.inviteToQuest = {
await group.startQuest(user);
}
- let [savedGroup] = await Promise.all([
+ const [savedGroup] = await Promise.all([
group.save(),
user.save(),
]);
@@ -117,8 +117,8 @@ api.inviteToQuest = {
res.respond(200, savedGroup.quest);
// send out invites
- let inviterVars = getUserInfo(user, ['name', 'email']);
- let membersToEmail = members.filter(member => {
+ const inviterVars = getUserInfo(user, ['name', 'email']);
+ const membersToEmail = members.filter(member => {
// send push notifications while filtering members before sending emails
if (member.preferences.pushNotifications.invitedQuest !== false) {
sendPushNotification(
@@ -128,16 +128,16 @@ api.inviteToQuest = {
message: res.t('questInvitationNotificationInfo', member.preferences.language),
identifier: 'questInvitation',
category: 'questInvitation',
- }
+ },
);
}
return member.preferences.emailNotifications.invitedQuest !== false;
});
sendTxnEmail(membersToEmail, `invite-${quest.boss ? 'boss' : 'collection'}-quest`, [
- {name: 'QUEST_NAME', content: quest.text()},
- {name: 'INVITER', content: inviterVars.name},
- {name: 'PARTY_URL', content: '/party'},
+ { name: 'QUEST_NAME', content: quest.text() },
+ { name: 'INVITER', content: inviterVars.name },
+ { name: 'PARTY_URL', content: '/party' },
]);
// track that the inviting user has accepted the quest
@@ -170,14 +170,14 @@ api.acceptQuest = {
url: '/groups/:groupId/quests/accept',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let group = await Group.getGroup({user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat')});
+ const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat') });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported'));
@@ -195,7 +195,7 @@ api.acceptQuest = {
await group.startQuest(user);
}
- let savedGroup = await group.save();
+ const savedGroup = await group.save();
res.respond(200, savedGroup.quest);
@@ -229,14 +229,14 @@ api.rejectQuest = {
url: '/groups/:groupId/quests/reject',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let group = await Group.getGroup({user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat')});
+ const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat') });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported'));
if (!group.quest.key) throw new NotFound(res.t('questInvitationDoesNotExist'));
@@ -255,7 +255,7 @@ api.rejectQuest = {
await group.startQuest(user);
}
- let savedGroup = await group.save();
+ const savedGroup = await group.save();
res.respond(200, savedGroup.quest);
@@ -292,26 +292,28 @@ api.forceStart = {
url: '/groups/:groupId/quests/force-start',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let group = await Group.getGroup({user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat')});
+ const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat') });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported'));
if (!group.quest.key) throw new NotFound(res.t('questNotPending'));
if (group.quest.active) throw new NotAuthorized(res.t('questAlreadyUnderway'));
- if (!(user._id === group.quest.leader || user._id === group.leader)) throw new NotAuthorized(res.t('questOrGroupLeaderOnlyStartQuest'));
+ if (!(user._id === group.quest.leader || user._id === group.leader)) {
+ throw new NotAuthorized(res.t('questOrGroupLeaderOnlyStartQuest'));
+ }
group.markModified('quest');
await group.startQuest(user);
- let [savedGroup] = await Promise.all([
+ const [savedGroup] = await Promise.all([
group.save(),
user.save(),
]);
@@ -352,24 +354,27 @@ api.cancelQuest = {
async handler (req, res) {
// Cancel a quest BEFORE it has begun (i.e., in the invitation stage)
// Quest scroll has not yet left quest owner's inventory so no need to return it.
- // Do not wipe quest progress for members because they'll want it to be applied to the next quest that's started.
- let user = res.locals.user;
- let groupId = req.params.groupId;
+ // Do not wipe quest progress for members because they'll
+ // want it to be applied to the next quest that's started.
+ const { user } = res.locals;
+ const { groupId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let group = await Group.getGroup({user, groupId, fields: basicGroupFields.concat(' quest')});
+ const group = await Group.getGroup({ user, groupId, fields: basicGroupFields.concat(' quest') });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported'));
if (!group.quest.key) throw new NotFound(res.t('questInvitationDoesNotExist'));
- if (user._id !== group.leader && group.quest.leader !== user._id) throw new NotAuthorized(res.t('onlyLeaderCancelQuest'));
+ if (user._id !== group.leader && group.quest.leader !== user._id) {
+ throw new NotAuthorized(res.t('onlyLeaderCancelQuest'));
+ }
if (group.quest.active) throw new NotAuthorized(res.t('cantCancelActiveQuest'));
- let questName = questScrolls[group.quest.key].text('en');
+ const questName = questScrolls[group.quest.key].text('en');
const newChatMessage = group.sendChat({
message: `\`${user.profile.name} cancelled the party quest ${questName}.\``,
info: {
@@ -382,13 +387,13 @@ api.cancelQuest = {
group.quest = Group.cleanGroupQuest();
group.markModified('quest');
- let [savedGroup] = await Promise.all([
+ const [savedGroup] = await Promise.all([
group.save(),
newChatMessage.save(),
User.update(
- {'party._id': groupId},
+ { 'party._id': groupId },
Group.cleanQuestParty(),
- {multi: true}
+ { multi: true },
).exec(),
]);
@@ -417,24 +422,24 @@ api.abortQuest = {
middlewares: [authWithHeaders()],
async handler (req, res) {
// Abort a quest AFTER it has begun
- let user = res.locals.user;
- let groupId = req.params.groupId;
+ const { user } = res.locals;
+ const { groupId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let group = await Group.getGroup({user, groupId, fields: basicGroupFields.concat(' quest chat')});
+ const group = await Group.getGroup({ user, groupId, fields: basicGroupFields.concat(' quest chat') });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported'));
if (!group.quest.active) throw new NotFound(res.t('noActiveQuestToAbort'));
if (user._id !== group.leader && user._id !== group.quest.leader) throw new NotAuthorized(res.t('onlyLeaderAbortQuest'));
- let questName = questScrolls[group.quest.key].text('en');
+ const questName = questScrolls[group.quest.key].text('en');
const newChatMessage = group.sendChat({
- message: `\`${common.i18n.t('chatQuestAborted', {username: user.profile.name, questName}, 'en')}\``,
+ message: `\`${common.i18n.t('chatQuestAborted', { username: user.profile.name, questName }, 'en')}\``,
info: {
type: 'quest_abort',
user: user.profile.name,
@@ -443,12 +448,12 @@ api.abortQuest = {
});
await newChatMessage.save();
- let memberUpdates = User.update({
+ const memberUpdates = User.update({
'party._id': groupId,
}, Group.cleanQuestParty(),
- {multi: true}).exec();
+ { multi: true }).exec();
- let questLeaderUpdate = User.update({
+ const questLeaderUpdate = User.update({
_id: group.quest.leader,
}, {
$inc: {
@@ -459,7 +464,7 @@ api.abortQuest = {
group.quest = Group.cleanGroupQuest();
group.markModified('quest');
- let [groupSaved] = await Promise.all([group.save(), memberUpdates, questLeaderUpdate]);
+ const [groupSaved] = await Promise.all([group.save(), memberUpdates, questLeaderUpdate]);
res.respond(200, groupSaved.quest);
},
@@ -482,15 +487,15 @@ api.leaveQuest = {
url: '/groups/:groupId/quests/leave',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let groupId = req.params.groupId;
+ const { user } = res.locals;
+ const { groupId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let group = await Group.getGroup({user, groupId, fields: basicGroupFields.concat(' quest')});
+ const group = await Group.getGroup({ user, groupId, fields: basicGroupFields.concat(' quest') });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported'));
@@ -504,7 +509,7 @@ api.leaveQuest = {
user.party.quest = Group.cleanQuestUser(user.party.quest.progress);
user.markModified('party.quest');
- let [savedGroup] = await Promise.all([
+ const [savedGroup] = await Promise.all([
group.save(),
user.save(),
]);
@@ -513,4 +518,4 @@ api.leaveQuest = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/shops.js b/website/server/controllers/api-v3/shops.js
index 32c46bcd9d..f94129cb1f 100644
--- a/website/server/controllers/api-v3/shops.js
+++ b/website/server/controllers/api-v3/shops.js
@@ -1,7 +1,9 @@
import { authWithHeaders } from '../../middlewares/auth';
-import { shops } from '../../../common/';
+import common from '../../../common';
-let api = {};
+const { shops } = common;
+
+const api = {};
/**
* @apiIgnore
@@ -17,9 +19,9 @@ api.getMarketItems = {
url: '/shops/market',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
- let resObject = shops.getMarketShop(user, req.language);
+ const resObject = shops.getMarketShop(user, req.language);
res.respond(200, resObject);
},
@@ -38,9 +40,9 @@ api.getMarketGear = {
url: '/shops/market-gear',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
- let resObject = {
+ const resObject = {
categories: shops.getMarketGearCategories(user, req.language),
};
@@ -62,9 +64,9 @@ api.getQuestShopItems = {
url: '/shops/quests',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
- let resObject = shops.getQuestShop(user, req.language);
+ const resObject = shops.getQuestShop(user, req.language);
res.respond(200, resObject);
},
@@ -84,9 +86,9 @@ api.getTimeTravelerShopItems = {
url: '/shops/time-travelers',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
- let resObject = shops.getTimeTravelersShop(user, req.language);
+ const resObject = shops.getTimeTravelersShop(user, req.language);
res.respond(200, resObject);
},
@@ -106,9 +108,9 @@ api.getSeasonalShopItems = {
url: '/shops/seasonal',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
- let resObject = shops.getSeasonalShop(user, req.language);
+ const resObject = shops.getSeasonalShop(user, req.language);
res.respond(200, resObject);
},
@@ -128,9 +130,9 @@ api.getBackgroundShopItems = {
url: '/shops/backgrounds',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
- let resObject = {
+ const resObject = {
identifier: 'backgroundShop',
text: res.t('backgroundShop'),
notes: res.t('backgroundShopText'),
@@ -142,4 +144,4 @@ api.getBackgroundShopItems = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/status.js b/website/server/controllers/api-v3/status.js
index baba426ba7..c957388d59 100644
--- a/website/server/controllers/api-v3/status.js
+++ b/website/server/controllers/api-v3/status.js
@@ -1,4 +1,4 @@
-let api = {};
+const api = {};
/**
* @api {get} /api/v3/status Get Habitica's API status
@@ -22,4 +22,4 @@ api.getStatus = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/tags.js b/website/server/controllers/api-v3/tags.js
index 4d90311257..6c2ab2e268 100644
--- a/website/server/controllers/api-v3/tags.js
+++ b/website/server/controllers/api-v3/tags.js
@@ -1,11 +1,11 @@
+import _ from 'lodash';
+import find from 'lodash/find';
import { authWithHeaders } from '../../middlewares/auth';
import { model as Tag } from '../../models/tag';
import * as Tasks from '../../models/task';
import {
NotFound,
} from '../../libs/errors';
-import _ from 'lodash';
-import find from 'lodash/find';
/**
* @apiDefine TagNotFound
@@ -14,11 +14,13 @@ import find from 'lodash/find';
/**
* @apiDefine InvalidUUID
- * @apiError (400) {BadRequest} InvalidRequestParameters "tagId" must be a valid UUID corresponding to a tag belonging to the user.
+ * @apiError (400) {BadRequest} InvalidRequestParameters "tagId" must be a valid UUID
+ * corresponding to a tag
+ * belonging to the user.
*/
-let api = {};
+const api = {};
/**
* @api {post} /api/v3/tags Create a new tag
@@ -33,20 +35,21 @@ let api = {};
* @apiSuccess (201) {Object} data The newly created tag
*
* @apiSuccessExample {json} Example return:
- * {"success":true,"data":{"name":"practicetag","id":"8bc0afbf-ab8e-49a4-982d-67a40557ed1a"},"notifications":[]}
+ * {"success":true,"data":{"name":"practicetag","id":"8bc0afbf-ab8e-49a4-982d-67a40557ed1a"},
+ * "notifications":[]}
*/
api.createTag = {
method: 'POST',
url: '/tags',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
user.tags.push(Tag.sanitize(req.body));
- let savedUser = await user.save();
+ const savedUser = await user.save();
- let l = savedUser.tags.length;
- let tag = savedUser.tags[l - 1];
+ const l = savedUser.tags.length;
+ const tag = savedUser.tags[l - 1];
res.respond(201, tag);
},
};
@@ -59,14 +62,17 @@ api.createTag = {
* @apiSuccess {Array} data An array of tags
*
* @apiSuccessExample {json} Example return:
- * {"success":true,"data":[{"name":"Work","id":"3d5d324d-a042-4d5f-872e-0553e228553e"},{"name":"apitester","challenge":"true","id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},{"name":"practicetag","id":"8bc0afbf-ab8e-49a4-982d-67a40557ed1a"}],"notifications":[]}
+ * {"success":true,"data":[{"name":"Work",
+ * "id":"3d5d324d-a042-4d5f-872e-0553e228553e"},
+ * {"name":"apitester","challenge":"true","id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},
+ * {"name":"practicetag","id":"8bc0afbf-ab8e-49a4-982d-67a40557ed1a"}],"notifications":[]}
*/
api.getTags = {
method: 'GET',
url: '/tags',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
res.respond(200, user.tags);
},
};
@@ -81,7 +87,8 @@ api.getTags = {
* @apiSuccess {Object} data The tag object
*
* @apiSuccessExample {json} Example return:
- * {"success":true,"data":{"name":"practicetag","id":"8bc0afbf-ab8e-49a4-982d-67a40557ed1a"},"notifications":[]}
+ * {"success":true,"data":{"name":"practicetag",
+ * "id":"8bc0afbf-ab8e-49a4-982d-67a40557ed1a"},"notifications":[]}
*
* @apiUse TagNotFound
* @apiUSe InvalidUUID
@@ -91,14 +98,14 @@ api.getTag = {
url: '/tags/:tagId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let tag = _.find(user.tags, {id: req.params.tagId});
+ const tag = _.find(user.tags, { id: req.params.tagId });
if (!tag) throw new NotFound(res.t('tagNotFound'));
res.respond(200, tag);
},
@@ -118,7 +125,8 @@ api.getTag = {
* @apiSuccess {Object} data The updated tag
*
* @apiSuccessExample {json} Example result:
- * {"success":true,"data":{"name":"practice-tag","id":"8bc0afbf-ab8e-49a4-982d-67a40557ed1a"},"notifications":[]}
+ * {"success":true,"data":{"name":"practice-tag",
+ * "id":"8bc0afbf-ab8e-49a4-982d-67a40557ed1a"},"notifications":[]}
*
* @apiUse TagNotFound
* @apiUSe InvalidUUID
@@ -128,22 +136,22 @@ api.updateTag = {
url: '/tags/:tagId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID();
- let tagId = req.params.tagId;
+ const { tagId } = req.params;
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let tag = _.find(user.tags, {id: tagId});
+ const tag = _.find(user.tags, { id: tagId });
if (!tag) throw new NotFound(res.t('tagNotFound'));
_.merge(tag, Tag.sanitize(req.body));
- let savedUser = await user.save();
- res.respond(200, _.find(savedUser.tags, {id: tagId}));
+ const savedUser = await user.save();
+ res.respond(200, _.find(savedUser.tags, { id: tagId }));
},
};
@@ -170,17 +178,15 @@ api.reorderTags = {
url: '/reorder-tags',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkBody('to', res.t('toRequired')).notEmpty();
req.checkBody('tagId', res.t('tagIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let tagIndex = _.findIndex(user.tags, function findTag (tag) {
- return tag.id === req.body.tagId;
- });
+ const tagIndex = _.findIndex(user.tags, tag => tag.id === req.body.tagId);
if (tagIndex === -1) throw new NotFound(res.t('tagNotFound'));
const removedItem = user.tags.splice(tagIndex, 1)[0];
@@ -212,16 +218,14 @@ api.deleteTag = {
url: '/tags/:tagId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let tagFound = find(user.tags, (tag) => {
- return tag.id === req.params.tagId;
- });
+ const tagFound = find(user.tags, tag => tag.id === req.params.tagId);
if (!tagFound) throw new NotFound(res.t('tagNotFound'));
await user.update({
@@ -231,7 +235,7 @@ api.deleteTag = {
// Update the user version field manually,
// it cannot be updated in the pre update hook
// See https://github.com/HabitRPG/habitica/pull/9321#issuecomment-354187666 for more info
- user._v++;
+ user._v += 1;
// Remove from all the tasks TODO test
await Tasks.Task.update({
@@ -240,10 +244,10 @@ api.deleteTag = {
$pull: {
tags: tagFound.id,
},
- }, {multi: true}).exec();
+ }, { multi: true }).exec();
res.respond(200, {});
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/tasks.js b/website/server/controllers/api-v3/tasks.js
index 0eb220767f..f9f48ab5ad 100644
--- a/website/server/controllers/api-v3/tasks.js
+++ b/website/server/controllers/api-v3/tasks.js
@@ -1,3 +1,5 @@
+import _ from 'lodash';
+import moment from 'moment';
import { authWithHeaders } from '../../middlewares/auth';
import {
taskActivityWebhook,
@@ -21,15 +23,13 @@ import {
setNextDue,
} from '../../libs/taskManager';
import common from '../../../common';
-import _ from 'lodash';
import logger from '../../libs/logger';
-import moment from 'moment';
import apiError from '../../libs/apiError';
function canNotEditTasks (group, user, assignedUserId) {
- let isNotGroupLeader = group.leader !== user._id;
- let isManager = Boolean(group.managers[user._id]);
- let userIsAssigningToSelf = Boolean(assignedUserId && user._id === assignedUserId);
+ const isNotGroupLeader = group.leader !== user._id;
+ const isManager = Boolean(group.managers[user._id]);
+ const userIsAssigningToSelf = Boolean(assignedUserId && user._id === assignedUserId);
return isNotGroupLeader && !isManager && !userIsAssigningToSelf;
}
@@ -48,32 +48,57 @@ function canNotEditTasks (group, user, assignedUserId) {
* @apiError (401) {NotAuthorized} There is no account that uses those credentials.
*/
-let api = {};
-let requiredGroupFields = '_id leader tasksOrder name';
+const api = {};
+const requiredGroupFields = '_id leader tasksOrder name';
/**
* @api {post} /api/v3/tasks/user Create a new task belonging to the user
- * @apiDescription Can be passed an object to create a single task or an array of objects to create multiple tasks.
+ * @apiDescription Can be passed an object to create a single task or an array of objects
+ * to create multiple tasks.
* @apiName CreateUserTasks
* @apiGroup Task
*
* @apiParam (Body) {String} text The text to be displayed for the task
- * @apiParam (Body) {String="habit","daily","todo","reward"} type Task type, options are: "habit", "daily", "todo", "reward".
+ * @apiParam (Body) {String="habit","daily","todo","reward"} type Task type, options are: "habit",
+ * "daily", "todo", "reward".
* @apiParam (Body) {String[]} [tags] Array of UUIDs of tags
* @apiParam (Body) {String} [alias] Alias to assign to task
- * @apiParam (Body) {String="str","int","per","con"} [attribute] User's attribute to use, options are: "str", "int", "per", "con"
+ * @apiParam (Body) {String="str","int","per","con"} [attribute] User's attribute to use,
+ * options are: "str", "int",
+ * "per", "con"
* @apiParam (Body) {Boolean} [collapseChecklist=false] Determines if a checklist will be displayed
* @apiParam (Body) {String} [notes] Extra notes
* @apiParam (Body) {String} [date] Due date to be shown in task list. Only valid for type "todo."
- * @apiParam (Body) {Number="0.1","1","1.5","2"} [priority=1] Difficulty, options are 0.1, 1, 1.5, 2; eqivalent of Trivial, Easy, Medium, Hard.
- * @apiParam (Body) {String[]} [reminders] Array of reminders, each an object that must include: a UUID, startDate and time. For example {"id":"ed427623-9a69-4aac-9852-13deb9c190c3","startDate":"1/16/17","time":"1/16/17" }
- * @apiParam (Body) {String="weekly","daily"} [frequency=weekly] Value "weekly" enables "On days of the week", value "daily" enables "EveryX Days". Only valid for type "daily".
- * @apiParam (Body) {String} [repeat=true] List of objects for days of the week, Days that are true will be repeated upon. Only valid for type "daily". Any days not specified will be marked as true. Days are: su, m, t, w, th, f, s. Value of frequency must be "weekly". For example, to skip repeats on Mon and Fri: "repeat":{"f":false,"m":false}
- * @apiParam (Body) {Number} [everyX=1] Value of frequency must be "daily", the number of days until this daily task is available again.
- * @apiParam (Body) {Number} [streak=0] Number of days that the task has consecutively been checked off. Only valid for type "daily"
- * @apiParam (Body) {Date} [startDate] Date when the task will first become available. Only valid for type "daily"
- * @apiParam (Body) {Boolean} [up=true] Only valid for type "habit" If true, enables the "+" under "Directions/Action" for "Good habits"
- * @apiParam (Body) {Boolean} [down=true] Only valid for type "habit" If true, enables the "-" under "Directions/Action" for "Bad habits"
+ * @apiParam (Body) {Number="0.1","1","1.5","2"} [priority=1] Difficulty, options are 0.1, 1,
+ * 1.5, 2; eqivalent of Trivial,
+ * Easy, Medium, Hard.
+ * @apiParam (Body) {String[]} [reminders] Array of reminders, each an object that must
+ * include: a UUID, startDate and time.
+ * For example {"id":"ed427623-9a69-4aac-9852-13deb9c190c3",
+ * "startDate":"1/16/17","time":"1/16/17" }
+ * @apiParam (Body) {String="weekly","daily"} [frequency=weekly] Value "weekly" enables
+ * "On days of the week", value
+ * "daily" enables "EveryX Days".
+ * Only valid for type "daily".
+ * @apiParam (Body) {String} [repeat=true] List of objects for days of the week,
+ * Days that are true will be repeated upon.
+ * Only valid for type "daily". Any days not specified
+ * will be marked as true. Days are: su, m, t, w, th,
+ * f, s. Value of frequency must be "weekly".
+ * For example, to skip repeats on Mon and
+ * Fri: "repeat":{"f":false,"m":false}
+ * @apiParam (Body) {Number} [everyX=1] Value of frequency must be "daily",
+ * the number of days until this daily
+ * task is available again.
+ * @apiParam (Body) {Number} [streak=0] Number of days that the task has consecutively
+ * been checked off. Only valid for type "daily"
+ * @apiParam (Body) {Date} [startDate] Date when the task will first become available.
+ * Only valid for type "daily"
+ * @apiParam (Body) {Boolean} [up=true] Only valid for type "habit"
+ * If true, enables the "+" under "Directions/Action"
+ * for "Good habits"-
+ * @apiParam (Body) {Boolean} [down=true] Only valid for type "habit" If true, enables
+ * the "-" under "Directions/Action" for "Bad habits"
* @apiParam (Body) {Number} [value=0] Only valid for type "reward." The cost in gold of the reward
*
* @apiParamExample {json} Request-Example:
@@ -135,10 +160,14 @@ let requiredGroupFields = '_id leader tasksOrder name';
* }
*
* @apiError (404) {NotFound} ChecklistNotFound The specified checklist item could not be found.
- * @apiError (400) {BadRequest} MustBeType Task type must be one of "habit", "daily", "todo", "reward".
+ * @apiError (400) {BadRequest} MustBeType Task type must be one of "habit", "daily",
+ * "todo", "reward".
* @apiError (400) {BadRequest} Text-ValidationFailed Path 'text' is required.
- * @apiError (400) {BadRequest} Alias-ValidationFailed Task short names can only contain alphanumeric characters, underscores and dashes.
- * @apiError (400) {BadRequest} Value-ValidationFailed `x` is not a valid enum value for path `(body param)`.
+ * @apiError (400) {BadRequest} Alias-ValidationFailed Task short names can only
+ * contain alphanumeric characters,
+ * underscores and dashes.
+ * @apiError (400) {BadRequest} Value-ValidationFailed `x` is not a valid enum value
+ * for path `(body param)`.
* @apiError (401) {NotAuthorized} There is no account that uses those credentials.
*
* @apiErrorExample {json} Error-Response:
@@ -160,12 +189,12 @@ api.createUserTasks = {
url: '/tasks/user',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let tasks = await createTasks(req, res, {user});
+ const { user } = res.locals;
+ const tasks = await createTasks(req, res, { user });
res.respond(201, tasks.length === 1 ? tasks[0] : tasks);
- tasks.forEach((task) => {
+ tasks.forEach(task => {
// Track when new users (first 7 days) create tasks
if (moment().diff(user.auth.timestamps.created, 'days') < 7) {
res.analytics.track('task create', {
@@ -187,28 +216,52 @@ api.createUserTasks = {
/**
* @api {post} /api/v3/tasks/challenge/:challengeId Create a new task belonging to a challenge
- * @apiDescription Can be passed an object to create a single task or an array of objects to create multiple tasks.
+ * @apiDescription Can be passed an object to create a single task or an
+ * array of objects to create multiple tasks.
* @apiName CreateChallengeTasks
* @apiGroup Task
*
* @apiParam (Path) {UUID} challengeId The id of the challenge the new task(s) will belong to
*
* @apiParam (Body) {String} text The text to be displayed for the task
- * @apiParam (Body) {String="habit","daily","todo","reward"} type Task type, options are: "habit", "daily", "todo", "reward".
+ * @apiParam (Body) {String="habit","daily","todo","reward"} type Task type, options are: "habit",
+ * "daily", "todo", "reward".
* @apiParam (Body) {String} [alias] Alias to assign to task
- * @apiParam (Body) {String="str","int","per","con"} [attribute] User's attribute to use, options are: "str", "int", "per", "con"
+ * @apiParam (Body) {String="str","int","per","con"} [attribute] User's attribute to use,
+ * options are: "str",
+ * "int", "per", "con".
* @apiParam (Body) {Boolean} [collapseChecklist=false] Determines if a checklist will be displayed
* @apiParam (Body) {String} [notes] Extra notes
* @apiParam (Body) {String} [date] Due date to be shown in task list. Only valid for type "todo."
- * @apiParam (Body) {Number="0.1","1","1.5","2"} [priority=1] Difficulty, options are 0.1, 1, 1.5, 2; eqivalent of Trivial, Easy, Medium, Hard.
- * @apiParam (Body) {String[]} [reminders] Array of reminders, each an object that must include: a UUID, startDate and time. For example {"id":"ed427623-9a69-4aac-9852-13deb9c190c3","startDate":"1/16/17","time":"1/16/17" }
- * @apiParam (Body) {String="weekly","daily"} [frequency=weekly] Value "weekly" enables "On days of the week", value "daily" enables "EveryX Days". Only valid for type "daily".
- * @apiParam (Body) {String} [repeat=true] List of objects for days of the week, Days that are true will be repeated upon. Only valid for type "daily". Any days not specified will be marked as true. Days are: su, m, t, w, th, f, s. Value of frequency must be "weekly". For example, to skip repeats on Mon and Fri: "repeat":{"f":false,"m":false}
- * @apiParam (Body) {Number} [everyX=1] Value of frequency must be "daily", the number of days until this daily task is available again.
- * @apiParam (Body) {Number} [streak=0] Number of days that the task has consecutively been checked off. Only valid for type "daily"
- * @apiParam (Body) {Date} [startDate] Date when the task will first become available. Only valid for type "daily"
- * @apiParam (Body) {Boolean} [up=true] Only valid for type "habit" If true, enables the "+" under "Directions/Action" for "Good habits"
- * @apiParam (Body) {Boolean} [down=true] Only valid for type "habit" If true, enables the "-" under "Directions/Action" for "Bad habits"
+ * @apiParam (Body) {Number="0.1","1","1.5","2"} [priority=1] Difficulty, options are 0.1, 1,
+ * 1.5, 2; eqivalent of Trivial,
+ * Easy, Medium, Hard.
+ * @apiParam (Body) {String[]} [reminders] Array of reminders, each an object that must
+ * include: a UUID, startDate and time.
+ * For example {"id":"ed427623-9a69-4aac-9852-13deb9c190c3",
+ * "startDate":"1/16/17","time":"1/16/17" }
+ * @apiParam (Body) {String="weekly","daily"} [frequency=weekly] Value "weekly" enables
+ * "On days of the week", value
+ * "daily" enables "EveryX Days".
+ * Only valid for type "daily".
+ * @apiParam (Body) {String} [repeat=true] List of objects for days of the week,
+ * Days that are true will be repeated upon.
+ * Only valid for type "daily". Any days not
+ * specified will be marked as true. Days are:
+ * su, m, t, w, th, f, s. Value of frequency must
+ * be "weekly". For example, to skip repeats on
+ * Mon and Fri: "repeat":{"f":false,"m":false}
+ * @apiParam (Body) {Number} [everyX=1] Value of frequency must be "daily", the number
+ * of days until this daily task is available again.
+ * @apiParam (Body) {Number} [streak=0] Number of days that the task has consecutively
+ * been checked off. Only valid for type "daily"
+ * @apiParam (Body) {Date} [startDate] Date when the task will first become available.
+ * Only valid for type "daily"
+ * @apiParam (Body) {Boolean} [up=true] Only valid for type "habit" If true,
+ * enables the "+" under "Directions/Action"
+ * for "Good habits"
+ * @apiParam (Body) {Boolean} [down=true] Only valid for type "habit" If true, enables
+ * the "-" under "Directions/Action" for "Bad habits"
* @apiParam (Body) {Number} [value=0] Only valid for type "reward." The cost in gold of the reward
*
* @apiParamExample {json} Request-Example:
@@ -217,14 +270,25 @@ api.createUserTasks = {
* @apiSuccess (201) data An object if a single task was created, otherwise an array of tasks
*
* @apiSuccessExample {json} Example return:
- * {"success":true,"data":{"text":"Test API Params","type":"todo","notes":"","tags":[],"value":0,"priority":1,"attribute":"str","challenge":{"id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],"approval":{"required":false,"approved":false,"requested":false}},"reminders":[],"_id":"4a29874c-0308-417b-a909-2a7d262b49f6","createdAt":"2017-01-13T21:23:05.949Z","updatedAt":"2017-01-13T21:23:05.949Z","checklist":[],"collapseChecklist":false,"completed":false,"id":"4a29874c-0308-417b-a909-2a7d262b49f6"},"notifications":[]}
+ * {"success":true,"data":{"text":"Test API Params","type":"todo","notes":"",
+ * "tags":[],"value":0,"priority":1,"attribute":"str",
+ * "challenge":{"id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},
+ * "group":{"assignedUsers":[],"approval":{"required":false,"approved":false,
+ * "requested":false}},"reminders":[],"_id":"4a29874c-0308-417b-a909-2a7d262b49f6",
+ * "createdAt":"2017-01-13T21:23:05.949Z","updatedAt":"2017-01-13T21:23:05.949Z",
+ * "checklist":[],"collapseChecklist":false,"completed":false,
+ * "id":"4a29874c-0308-417b-a909-2a7d262b49f6"},"notifications":[]}
*
* @apiError (404) {NotFound} ChecklistNotFound The specified checklist item could not be found.
* @apiUse ChallengeNotFound
- * @apiError (400) {BadRequest} MustBeType Task type must be one of "habit", "daily", "todo", "reward".
+ * @apiError (400) {BadRequest} MustBeType Task type must be one of "habit",
+ * "daily", "todo", "reward".
* @apiError (400) {BadRequest} Text-ValidationFailed Path 'text' is required.
- * @apiError (400) {BadRequest} Alias-ValidationFailed Task short names can only contain alphanumeric characters, underscores and dashes.
- * @apiError (400) {BadRequest} Value-ValidationFailed `x` is not a valid enum value for path `(body param)`.
+ * @apiError (400) {BadRequest} Alias-ValidationFailed Task short names can only contain
+ * alphanumeric characters, underscores
+ * and dashes.
+ * @apiError (400) {BadRequest} Value-ValidationFailed `x` is not a valid enum value
+ * for path `(body param)`.
* @apiError (401) {NotAuthorized} There is no account that uses those credentials.
*/
api.createChallengeTasks = {
@@ -234,26 +298,26 @@ api.createChallengeTasks = {
async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
- let reqValidationErrors = req.validationErrors();
+ const reqValidationErrors = req.validationErrors();
if (reqValidationErrors) throw reqValidationErrors;
- let user = res.locals.user;
- let challengeId = req.params.challengeId;
+ const { user } = res.locals;
+ const { challengeId } = req.params;
- let challenge = await Challenge.findOne({_id: challengeId}).exec();
+ const challenge = await Challenge.findOne({ _id: challengeId }).exec();
// If the challenge does not exist, or if it exists but user is not the leader -> throw error
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks'));
- let tasks = await createTasks(req, res, {user, challenge});
+ const tasks = await createTasks(req, res, { user, challenge });
res.respond(201, tasks.length === 1 ? tasks[0] : tasks);
// If adding tasks to a challenge -> sync users
if (challenge) challenge.addTasks(tasks);
- tasks.forEach((task) => {
+ tasks.forEach(task => {
res.analytics.track('task create', {
uuid: user._id,
hitType: 'event',
@@ -270,15 +334,39 @@ api.createChallengeTasks = {
* @apiName GetUserTasks
* @apiGroup Task
*
- * @apiParam (Query) {String="habits","dailys","todos","rewards","completedTodos"} type Optional query parameter to return just a type of tasks. By default all types will be returned except completed todos that must be requested separately. The "completedTodos" type returns only the 30 most recently completed.
- * @apiParam (Query) [dueDate] type Optional date to use for computing the nextDue field for each returned task.
+ * @apiParam (Query) {String="habits","dailys",
+ * "todos","rewards","completedTodos"} type Optional query parameter to return
+ * just a type of tasks. By default all
+ * types will be returned except
+ * completed todos that must be
+ * requested separately.
+ * The "completedTodos" type returns
+ * only the 30 most recently completed.
+ * @apiParam (Query) [dueDate] type Optional date to use for computing the nextDue field
+ * for each returned task.
*
* @apiSuccess {Array} data An array of tasks
*
* @apiSuccessExample
- * {"success":true,"data":[{"_id":"8a9d461b-f5eb-4a16-97d3-c03380c422a3","userId":"b0413351-405f-416f-8787-947ec1c85199","text":"15 minute break","type":"reward","notes":"","tags":[],"value":10,"priority":1,"attribute":"str","challenge":{},"group":{"assignedUsers":[],"approval":{"required":false,"approved":false,"requested":false}},"reminders":[],"createdAt":"2017-01-07T17:52:09.121Z","updatedAt":"2017-01-11T14:25:32.504Z","id":"8a9d461b-f5eb-4a16-97d3-c03380c422a3"},,{"_id":"84c2e874-a8c9-4673-bd31-d97a1a42e9a3","userId":"b0413351-405f-416f-8787-947ec1c85199","alias":"prac31","text":"Practice Task 31","type":"daily","notes":"","tags":[],"value":1,"priority":1,"attribute":"str","challenge":{},"group":{"assignedUsers":[],"approval":{"required":false,"approved":false,"requested":false}},"reminders":[{"time":"2017-01-13T16:21:00.074Z","startDate":"2017-01-13T16:20:00.074Z","id":"b8b549c4-8d56-4e49-9b38-b4dcde9763b9"}],"createdAt":"2017-01-13T16:34:06.632Z","updatedAt":"2017-01-13T16:49:35.762Z","checklist":[],"collapseChecklist":false,"completed":true,"history":[],"streak":1,"repeat":{"su":false,"s":false,"f":true,"th":true,"w":true,"t":true,"m":true},"startDate":"2017-01-13T00:00:00.000Z","everyX":1,"frequency":"weekly","id":"84c2e874-a8c9-4673-bd31-d97a1a42e9a3"}],"notifications":[]}
+ * {"success":true,"data":[{"_id":"8a9d461b-f5eb-4a16-97d3-c03380c422a3",
+ * "userId":"b0413351-405f-416f-8787-947ec1c85199","text":"15 minute break",
+ * "type":"reward","notes":"","tags":[],"value":10,"priority":1,"attribute":"str",
+ * "challenge":{},"group":{"assignedUsers":[],"approval":{"required":false,"approved":false,
+ * "requested":false}},"reminders":[],"createdAt":"2017-01-07T17:52:09.121Z",
+ * "updatedAt":"2017-01-11T14:25:32.504Z","id":"8a9d461b-f5eb-4a16-97d3-c03380c422a3"},
+ * ,{"_id":"84c2e874-a8c9-4673-bd31-d97a1a42e9a3","userId":"b0413351-405f-416f-8787-947ec1c85199",
+ * "alias":"prac31","text":"Practice Task 31","type":"daily","notes":"","tags":[],"value":1,
+ * "priority":1,"attribute":"str","challenge":{},"group":{"assignedUsers":[],
+ * "approval":{"required":false,"approved":false,"requested":false}},
+ * "reminders":[{"time":"2017-01-13T16:21:00.074Z","startDate":"2017-01-13T16:20:00.074Z",
+ * "id":"b8b549c4-8d56-4e49-9b38-b4dcde9763b9"}],"createdAt":"2017-01-13T16:34:06.632Z",
+ * "updatedAt":"2017-01-13T16:49:35.762Z","checklist":[],"collapseChecklist":false,
+ * "completed":true,"history":[],"streak":1,"repeat":{"su":false,"s":false,"f":true,
+ * "th":true,"w":true,"t":true,"m":true},"startDate":"2017-01-13T00:00:00.000Z",
+ * "everyX":1,"frequency":"weekly","id":"84c2e874-a8c9-4673-bd31-d97a1a42e9a3"}],"notifications":[]}
*
- * @apiError (BadRequest) Invalid_request_parameters Error returned if the type URL param was not correct.
+ * @apiError (BadRequest) Invalid_request_parameters Error returned if the
+ * type URL param was not correct.
* @apiError (401) {NotAuthorized} There is no account that uses those credentials.
*/
api.getUserTasks = {
@@ -289,15 +377,15 @@ api.getUserTasks = {
userFieldsToInclude: ['tasksOrder'],
})],
async handler (req, res) {
- let types = Tasks.tasksTypes.map(type => `${type}s`);
+ const types = Tasks.tasksTypes.map(type => `${type}s`);
types.push('completedTodos', '_allCompletedTodos'); // _allCompletedTodos is currently in BETA and is likely to be removed in future
req.checkQuery('type', res.t('invalidTasksTypeExtra')).optional().isIn(types);
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const user = res.locals.user;
- const dueDate = req.query.dueDate;
+ const { user } = res.locals;
+ const { dueDate } = req.query;
const tasks = await getTasks(req, res, { user, dueDate });
return res.respond(200, tasks);
@@ -310,7 +398,8 @@ api.getUserTasks = {
* @apiGroup Task
*
* @apiParam (Path) {UUID} challengeId The id of the challenge from which to retrieve the tasks
- * @apiParam (Query) {String="habits","dailys","todos","rewards"} [type] Query parameter to return just a type of tasks
+ * @apiParam (Query) {String="habits","dailys","todos","rewards"} [type] Query parameter to return
+ * just a type of tasks.
*
* @apiExample {curl} Example use:
* curl -i https://habitica.com/api/v3/tasks/challenge/f23c12f2-5830-4f15-9c36-e17fd729a812
@@ -318,7 +407,23 @@ api.getUserTasks = {
* @apiSuccess {Array} data An array of tasks
*
* @apiSuccessExample
- * {"success":true,"data":[{"_id":"5f12bfba-da30-4733-ad01-9c42f9817975","text":"API Trial","type":"habit","notes":"","tags":[],"value":27.70767809690112,"priority":1.5,"attribute":"str","challenge":{"id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],"approval":{"required":false,"approved":false,"requested":false}},"reminders":[],"createdAt":"2017-01-12T19:03:33.485Z","updatedAt":"2017-01-13T17:45:52.442Z","history":[{"date":1484257319183,"value":18.53316748293123},{"date":1484329552441,"value":27.70767809690112}],"down":false,"up":true,"id":"5f12bfba-da30-4733-ad01-9c42f9817975"},{"_id":"54a81d23-529c-4daa-a6f7-c5c6e7e84936","text":"Challenge TODO","type":"todo","notes":"","tags":[],"value":2,"priority":2,"attribute":"str","challenge":{"id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],"approval":{"required":false,"approved":false,"requested":false}},"reminders":[],"createdAt":"2017-01-12T19:07:10.310Z","updatedAt":"2017-01-13T20:24:51.070Z","checklist":[],"collapseChecklist":false,"completed":false,"id":"54a81d23-529c-4daa-a6f7-c5c6e7e84936"}],"notifications":[]}
+ * {"success":true,"data":[{"_id":"5f12bfba-da30-4733-ad01-9c42f9817975",
+ * "text":"API Trial","type":"habit","notes":"","tags":[],"value":27.70767809690112,
+ * "priority":1.5,"attribute":"str","challenge":{"id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},
+ * "group":{"assignedUsers":[],"approval":{"required":false,"approved":false,
+ * "requested":false}},"reminders":[],"createdAt":"2017-01-12T19:03:33.485Z",
+ * "updatedAt":"2017-01-13T17:45:52.442Z","history":
+ * [{"date":1484257319183,"value":18.53316748293123},
+ * {"date":1484329552441,"value":27.70767809690112}],
+ * "down":false,"up":true,"id":"5f12bfba-da30-4733-ad01-9c42f9817975"},
+ * {"_id":"54a81d23-529c-4daa-a6f7-c5c6e7e84936","text":"Challenge TODO","type":"todo",
+ * "notes":"","tags":[],"value":2,"priority":2,"attribute":"str",
+ * "challenge":{"id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},
+ * "group":{"assignedUsers":[],"approval":{"required":false,"approved":false,
+ * "requested":false}},"reminders":[],"createdAt":"2017-01-12T19:07:10.310Z",
+ * "updatedAt":"2017-01-13T20:24:51.070Z","checklist":[],
+ * "collapseChecklist":false,"completed":false,"id":"54a81d23-529c-4daa-a6f7-c5c6e7e84936"}],
+ * "notifications":[]}
*
* @apiUse ChallengeNotFound
*/
@@ -328,21 +433,21 @@ api.getChallengeTasks = {
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
- let types = Tasks.tasksTypes.map(type => `${type}s`);
+ const types = Tasks.tasksTypes.map(type => `${type}s`);
req.checkQuery('type', res.t('invalidTasksType')).optional().isIn(types);
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let user = res.locals.user;
- let challengeId = req.params.challengeId;
+ const { user } = res.locals;
+ const { challengeId } = req.params;
- let challenge = await Challenge.findOne({
+ const challenge = await Challenge.findOne({
_id: challengeId,
}).select('group leader tasksOrder').exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
- let group = await Group.getGroup({
+ const group = await Group.getGroup({
user,
groupId: challenge.group,
fields: '_id type privacy',
@@ -350,7 +455,7 @@ api.getChallengeTasks = {
});
if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound'));
- let tasks = await getTasks(req, res, {user, challenge});
+ const tasks = await getTasks(req, res, { user, challenge });
return res.respond(200, tasks);
},
};
@@ -368,7 +473,20 @@ api.getChallengeTasks = {
* @apiSuccess {Object} data The task object
*
* @apiSuccessExample {json} Example returned object
- * {"success":true,"data":{"_id":"2b774d70-ec8b-41c1-8967-eb6b13d962ba","userId":"b0413351-405f-416f-8787-947ec1c85199","text":"API Trial","alias":"apiTrial","type":"habit","notes":"","tags":[],"value":11.996661122825959,"priority":1.5,"attribute":"str","challenge":{"taskId":"5f12bfba-da30-4733-ad01-9c42f9817975","id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],"approval":{"required":false,"approved":false,"requested":false}},"reminders":[],"createdAt":"2017-01-12T19:03:33.495Z","updatedAt":"2017-01-13T20:52:02.927Z","history":[{"value":1,"date":1484248053486},{"value":1.9747,"date":1484252965224},{"value":2.9253562257358428,"date":1484252966902},{"value":3.853133245658556,"date":1484257191129},{"value":4.759112700885761,"date":1484257318911},{"value":5.6443010177121415,"date":1484257319164},{"value":3.752384470969301,"date":1484311429292},{"value":4.660705953838478,"date":1484311575632},{"value":5.54812929062314,"date":1484315395369},{"value":6.415599723011605,"date":1484329050485},{"value":7.263999553295137,"date":1484329050885},{"value":8.094153625212375,"date":1484329051509},{"value":8.906834219714574,"date":1484329088943},{"value":9.70276543915464,"date":1484329089547},{"value":10.482627142836241,"date":1484329089835},{"value":11.24705848799571,"date":1484329095500},{"value":11.996661122825959,"date":1484329552423}],"down":false,"up":true,"id":"2b774d70-ec8b-41c1-8967-eb6b13d962ba"},"notifications":[]}
+ * {"success":true,"data":{"_id":"2b774d70-ec8b-41c1-8967-eb6b13d962ba",
+ * "userId":"b0413351-405f-416f-8787-947ec1c85199","text":"API Trial",
+ * "alias":"apiTrial","type":"habit","notes":"","tags":[],"value":11.996661122825959,
+ * "priority":1.5,"attribute":"str","challenge":{"taskId":"5f12bfba-da30-4733-ad01-9c42f9817975",
+ * "id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],
+ * "approval":{"required":false,"approved":false,"requested":false}},"reminders":[],
+ * "createdAt":"2017-01-12T19:03:33.495Z","updatedAt":"2017-01-13T20:52:02.927Z",
+ * "history":[{"value":1,"date":1484248053486},{"value":1.9747,"date":1484252965224},
+ * {"value":2.9253562257358428,"date":1484252966902},
+ * {"value":6.415599723011605,"date":1484329050485},
+ * {"value":10.482627142836241,"date":1484329089835},
+ * {"value":11.24705848799571,"date":1484329095500},
+ * {"value":11.996661122825959,"date":1484329552423}],"down":false,
+ * "up":true,"id":"2b774d70-ec8b-41c1-8967-eb6b13d962ba"},"notifications":[]}
*
* @apiUse TaskNotFound
*/
@@ -377,18 +495,29 @@ api.getTask = {
url: '/tasks/:taskId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
+ const { user } = res.locals;
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
if (!task) {
throw new NotFound(res.t('taskNotFound'));
- } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights
- let challenge = await Challenge.find({_id: task.challenge.id}).select('leader').exec();
- if (!challenge || (user.challenges.indexOf(task.challenge.id) === -1 && challenge.leader !== user._id && !user.contributor.admin)) { // eslint-disable-line no-extra-parens
+
+ // If the task belongs to a challenge make sure the user has rights
+ } else if (task.challenge.id && !task.userId) {
+ const challenge = await Challenge.find({ _id: task.challenge.id }).select('leader').exec();
+ if (
+ !challenge
+ || (
+ user.challenges.indexOf(task.challenge.id) === -1
+ && challenge.leader !== user._id
+ && !user.contributor.admin
+ )
+ ) { // eslint-disable-line no-extra-parens
throw new NotFound(res.t('taskNotFound'));
}
- } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one
+
+ // If the task is owned by a user make it's the current one
+ } else if (task.userId !== user._id) {
throw new NotFound(res.t('taskNotFound'));
}
@@ -404,19 +533,37 @@ api.getTask = {
* @apiParam (Path) {String} taskId The task _id or alias
*
* @apiParam (Body) {String} [text] The text to be displayed for the task
- * @apiParam (Body) {String="str","int","per","con"} [attribute] User's attribute to use, options are: "str", "int", "per", "con"
+ * @apiParam (Body) {String="str","int","per","con"} [attribute] User's attribute to use,
+ * options are: "str", "int",
+ * "per", "con".
* @apiParam (Body) {Boolean} [collapseChecklist=false] Determines if a checklist will be displayed
* @apiParam (Body) {String} [notes] Extra notes
* @apiParam (Body) {String} [date] Due date to be shown in task list. Only valid for type "todo."
- * @apiParam (Body) {Number="0.1","1","1.5","2"} [priority=1] Difficulty, options are 0.1, 1, 1.5, 2; eqivalent of Trivial, Easy, Medium, Hard.
- * @apiParam (Body) {String[]} [reminders] Array of reminders, each an object that must include: a UUID, startDate and time.
- * @apiParam (Body) {String="weekly","daily"} [frequency=weekly] Value "weekly" enables "On days of the week", value "daily" enables "EveryX Days". Only valid for type "daily".
- * @apiParam (Body) {String} [repeat=true] List of objects for days of the week, Days that are true will be repeated upon. Only valid for type "daily". Any days not specified will be marked as true. Days are: su, m, t, w, th, f, s. Value of frequency must be "weekly". For example, to skip repeats on Mon and Fri: "repeat":{"f":false,"m":false}
- * @apiParam (Body) {Number} [everyX=1] Value of frequency must be "daily", the number of days until this daily task is available again.
- * @apiParam (Body) {Number} [streak=0] Number of days that the task has consecutively been checked off. Only valid for type "daily"
- * @apiParam (Body) {Date} [startDate] Date when the task will first become available. Only valid for type "daily"
- * @apiParam (Body) {Boolean} [up=true] Only valid for type "habit" If true, enables the "+" under "Directions/Action" for "Good habits"
- * @apiParam (Body) {Boolean} [down=true] Only valid for type "habit" If true, enables the "-" under "Directions/Action" for "Bad habits"
+ * @apiParam (Body) {Number="0.1","1","1.5","2"} [priority=1] Difficulty, options are 0.1, 1,
+ * 1.5, 2; eqivalent of Trivial,
+ * Easy, Medium, Hard.
+ * @apiParam (Body) {String[]} [reminders] Array of reminders, each an object that must include:
+ * a UUID, startDate and time.
+ * @apiParam (Body) {String="weekly","daily"} [frequency=weekly] Value "weekly" enables "On days
+ * of the week", value "daily"
+ * enables "EveryX Days".
+ * Only valid for type "daily".
+ * @apiParam (Body) {String} [repeat=true] List of objects for days of the week, Days that
+ * are true will be repeated upon. Only valid for type
+ * "daily". Any days not specified will be marked as true.
+ * Days are: su, m, t, w, th, f, s. Value of frequency must
+ * be "weekly". For example, to skip repeats on Mon and Fri:
+ * "repeat":{"f":false,"m":false}
+ * @apiParam (Body) {Number} [everyX=1] Value of frequency must be "daily", the number
+ * of days until this daily task is available again.
+ * @apiParam (Body) {Number} [streak=0] Number of days that the task has consecutively
+ * been checked off. Only valid for type "daily",
+ * @apiParam (Body) {Date} [startDate] Date when the task will first become available.
+ * Only valid for type "daily".
+ * @apiParam (Body) {Boolean} [up=true] Only valid for type "habit" If true, enables
+ * the "+" under "Directions/Action" for "Good habits".
+ * @apiParam (Body) {Boolean} [down=true] Only valid for type "habit" If true, enables the
+ * "-" under "Directions/Action" for "Bad habits".
* @apiParam (Body) {Number} [value=0] Only valid for type "reward." The cost in gold of the reward
*
* @apiParamExample {json} Request-Example:
@@ -431,37 +578,42 @@ api.updateTask = {
url: '/tasks/:taskId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
let challenge;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
let group;
if (!task) {
throw new NotFound(res.t('taskNotFound'));
} else if (task.group.id && !task.userId) {
// @TODO: Abstract this access snippet
- let fields = requiredGroupFields.concat(' managers');
- group = await Group.getGroup({user, groupId: task.group.id, fields});
+ const fields = requiredGroupFields.concat(' managers');
+ group = await Group.getGroup({ user, groupId: task.group.id, fields });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
- } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights
- challenge = await Challenge.findOne({_id: task.challenge.id}).exec();
+
+ // If the task belongs to a challenge make sure the user has rights
+ } else if (task.challenge.id && !task.userId) {
+ challenge = await Challenge.findOne({ _id: task.challenge.id }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks'));
- } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one
+
+ // If the task is owned by a user make it's the current one
+ } else if (task.userId !== user._id) {
throw new NotFound(res.t('taskNotFound'));
}
- let oldCheckList = task.checklist;
- // we have to convert task to an object because otherwise things don't get merged correctly. Bad for performances?
- let [updatedTaskObj] = common.ops.updateTask(task.toObject(), req);
+ const oldCheckList = task.checklist;
+ // we have to convert task to an object because otherwise things
+ // don't get merged correctly. Bad for performances?
+ const [updatedTaskObj] = common.ops.updateTask(task.toObject(), req);
// Sanitize differently user tasks linked to a challenge
let sanitizedObj;
@@ -476,7 +628,8 @@ api.updateTask = {
_.assign(task, sanitizedObj);
// console.log(task.modifiedPaths(), task.toObject().repeat === tep)
- // repeat is always among modifiedPaths because mongoose changes the other of the keys when using .toObject()
+ // repeat is always among modifiedPaths because mongoose changes
+ // the other of the keys when using .toObject()
// see https://github.com/Automattic/mongoose/issues/2749
task.group.approval.required = false;
@@ -488,18 +641,16 @@ api.updateTask = {
}
setNextDue(task, user);
- let savedTask = await task.save();
+ const savedTask = await task.save();
if (group && task.group.id && task.group.assignedUsers.length > 0) {
- let updateCheckListItems = _.remove(sanitizedObj.checklist, function getCheckListsToUpdate (checklist) {
- let indexOld = _.findIndex(oldCheckList, function findIndex (check) {
- return check.id === checklist.id;
- });
+ const updateCheckListItems = _.remove(sanitizedObj.checklist, checklist => {
+ const indexOld = _.findIndex(oldCheckList, check => check.id === checklist.id);
if (indexOld !== -1) return checklist.text !== oldCheckList[indexOld].text;
return false; // Only return changes. Adding and remove are handled differently
});
- await group.updateTask(savedTask, {updateCheckListItems});
+ await group.updateTask(savedTask, { updateCheckListItems });
}
res.respond(200, savedTask);
@@ -533,10 +684,23 @@ api.updateTask = {
* @apiSuccess {Number} data.delta The delta
*
* @apiSuccessExample {json} Example result:
- * {"success":true,"data":{"delta":0.9746999906450404,"_tmp":{},"hp":49.06645205596985,"mp":37.2008917491047,"exp":101.93810026267543,"gp":77.09694176716997,"lvl":19,"class":"rogue","points":0,"str":5,"con":3,"int":3,"per":8,"buffs":{"str":9,"int":9,"per":9,"con":9,"stealth":0,"streaks":false,"snowball":false,"spookySparkles":false,"shinySeed":false,"seafoam":false},"training":{"int":0,"per":0,"str":0,"con":0}},"notifications":[]}
+ * {"success":true,"data":{"delta":0.9746999906450404,"_tmp":{},"hp":49.06645205596985,
+ * "mp":37.2008917491047,"exp":101.93810026267543,"gp":77.09694176716997,
+ * "lvl":19,"class":"rogue","points":0,"str":5,"con":3,"int":3,"per":8,
+ * "buffs":{"str":9,"int":9,"per":9,"con":9,"stealth":0,"streaks":false,
+ * "snowball":false,"spookySparkles":false,"shinySeed":false,"seafoam":false},
+ * "training":{"int":0,"per":0,"str":0,"con":0}},"notifications":[]}
*
* @apiSuccessExample {json} Example result with item drop:
- * {"success":true,"data":{"delta":1.0259567046270648,"_tmp":{"quest":{"progressDelta":1.2362778290756147,"collection":1},"drop":{"target":"Zombie","canDrop":true,"value":1,"key":"RottenMeat","type":"Food","dialog":"You've found Rotten Meat! Feed this to a pet and it may grow into a sturdy steed."}},"hp":50,"mp":66.2390716654227,"exp":143.93810026267545,"gp":135.12889840462591,"lvl":20,"class":"rogue","points":0,"str":6,"con":3,"int":3,"per":8,"buffs":{"str":10,"int":10,"per":10,"con":10,"stealth":0,"streaks":false,"snowball":false,"spookySparkles":false,"shinySeed":false,"seafoam":false},"training":{"int":0,"per":0,"str":0,"con":0}},"notifications":[]}
+ * {"success":true,"data":{"delta":1.0259567046270648,
+ * "_tmp":{"quest":{"progressDelta":1.2362778290756147,"collection":1},
+ * "drop":{"target":"Zombie","canDrop":true,"value":1,"key":"RottenMeat","type":"Food",
+ * "dialog":"You've found Rotten Meat! Feed this to a pet and it may grow into a sturdy steed."}},
+ * "hp":50,"mp":66.2390716654227,"exp":143.93810026267545,"gp":135.12889840462591,
+ * "lvl":20,"class":"rogue","points":0,"str":6,"con":3,"int":3,"per":8,
+ * "buffs":{"str":10,"int":10,"per":10,"con":10,"stealth":0,"streaks":false,
+ * "snowball":false,"spookySparkles":false,"shinySeed":false,"seafoam":false},
+ * "training":{"int":0,"per":0,"str":0,"con":0}},"notifications":[]}
*
* @apiUse TaskNotFound
*/
@@ -550,11 +714,11 @@ api.scoreTask = {
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const user = res.locals.user;
- const {taskId} = req.params;
+ const { user } = res.locals;
+ const { taskId } = req.params;
- const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, {userId: user._id});
- const direction = req.params.direction;
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
+ const { direction } = req.params;
if (!task) throw new NotFound(res.t('taskNotFound'));
@@ -567,10 +731,10 @@ api.scoreTask = {
}
if (task.group.approval.required && !task.group.approval.approved) {
- let fields = requiredGroupFields.concat(' managers');
- let group = await Group.getGroup({user, groupId: task.group.id, fields});
+ const fields = requiredGroupFields.concat(' managers');
+ const group = await Group.getGroup({ user, groupId: task.group.id, fields });
- let managerIds = Object.keys(group.managers);
+ const managerIds = Object.keys(group.managers);
managerIds.push(group.leader);
if (managerIds.indexOf(user._id) !== -1) {
@@ -585,18 +749,20 @@ api.scoreTask = {
task.group.approval.requested = true;
task.group.approval.requestedDate = new Date();
- let managers = await User.find({_id: managerIds}, 'notifications preferences').exec(); // Use this method so we can get access to notifications
+ const managers = await User.find({ _id: managerIds }, 'notifications preferences').exec(); // Use this method so we can get access to notifications
- // @TODO: we can use the User.pushNotification function because we need to ensure notifications are translated
- let managerPromises = [];
- managers.forEach((manager) => {
+ // @TODO: we can use the User.pushNotification function because
+ // we need to ensure notifications are translated
+ const managerPromises = [];
+ managers.forEach(manager => {
manager.addNotification('GROUP_TASK_APPROVAL', {
message: res.t('userHasRequestedTaskApproval', {
user: user.profile.name,
taskName: task.text,
}, manager.preferences.language),
groupId: group._id,
- taskId: task._id, // user task id, used to match the notification when the task is approved
+ // user task id, used to match the notification when the task is approved
+ taskId: task._id,
userId: user._id,
groupTaskId: task.group.taskId, // the original task id
direction,
@@ -611,11 +777,12 @@ api.scoreTask = {
}
}
- let wasCompleted = task.completed;
+ const wasCompleted = task.completed;
- let [delta] = common.ops.scoreTask({task, user, direction}, req);
- // Drop system (don't run on the client, as it would only be discarded since ops are sent to the API, not the results)
- if (direction === 'up') common.fns.randomDrop(user, {task, delta}, req, res.analytics);
+ const [delta] = common.ops.scoreTask({ task, user, direction }, req);
+ // Drop system (don't run on the client,
+ // as it would only be discarded since ops are sent to the API, not the results)
+ if (direction === 'up') common.fns.randomDrop(user, { task, delta }, req, res.analytics);
// If a todo was completed or uncompleted move it in or out of the user.tasksOrder.todos list
// TODO move to common code?
@@ -628,7 +795,11 @@ api.scoreTask = {
$pull: { 'tasksOrder.todos': task._id },
}).exec();
// user.tasksOrder.todos.pull(task._id);
- } else if (wasCompleted && !task.completed && user.tasksOrder.todos.indexOf(task._id) === -1) {
+ } else if (
+ wasCompleted
+ && !task.completed
+ && user.tasksOrder.todos.indexOf(task._id) === -1
+ ) {
taskOrderPromise = user.update({
$push: { 'tasksOrder.todos': task._id },
}).exec();
@@ -638,7 +809,7 @@ api.scoreTask = {
setNextDue(task, user);
- let promises = [
+ const promises = [
user.save(),
task.save(),
];
@@ -651,7 +822,9 @@ api.scoreTask = {
}).exec();
if (groupTask) {
- const groupDelta = groupTask.group.assignedUsers ? delta / groupTask.group.assignedUsers.length : delta;
+ const groupDelta = groupTask.group.assignedUsers
+ ? delta / groupTask.group.assignedUsers.length
+ : delta;
await groupTask.scoreChallengeTask(groupDelta, direction);
}
} catch (e) {
@@ -661,12 +834,12 @@ api.scoreTask = {
// Save results and handle request
if (taskOrderPromise) promises.push(taskOrderPromise);
- let results = await Promise.all(promises);
+ const results = await Promise.all(promises);
- let savedUser = results[0];
+ const savedUser = results[0];
- let userStats = savedUser.stats.toJSON();
- let resJsonData = _.assign({delta, _tmp: user._tmp}, userStats);
+ const userStats = savedUser.stats.toJSON();
+ const resJsonData = _.assign({ delta, _tmp: user._tmp }, userStats);
res.respond(200, resJsonData);
taskScoredWebhook.send(user, {
@@ -677,7 +850,8 @@ api.scoreTask = {
});
if (task.challenge && task.challenge.id && task.challenge.taskId && !task.challenge.broken && task.type !== 'reward') {
- // Wrapping everything in a try/catch block because if an error occurs using `await` it MUST NOT bubble up because the request has already been handled
+ // Wrapping everything in a try/catch block because if an error occurs
+ // using `await` it MUST NOT bubble up because the request has already been handled
try {
const chalTask = await Tasks.Task.findOne({
_id: task.challenge.taskId,
@@ -707,17 +881,22 @@ api.scoreTask = {
/**
* @api {post} /api/v3/tasks/:taskId/move/to/:position Move a task to a new position
- * @apiDescription Note: completed To-Dos are not sortable, do not appear in user.tasksOrder.todos, and are ordered by date of completion.
+ * @apiDescription Note: completed To-Dos are not sortable,
+ * do not appear in user.tasksOrder.todos, and are ordered by date of completion.
* @apiName MoveTask
* @apiGroup Task
*
* @apiParam (Path) {String} taskId The task _id or alias
- * @apiParam (Path) {Number} position Where to move the task. 0 = top of the list. -1 = bottom of the list. (-1 means push to bottom). First position is 0
+ * @apiParam (Path) {Number} position Where to move the task. 0 = top of the list.
+ é -1 = bottom of the list.
+ é (-1 means push to bottom). First position is 0
*
* @apiSuccess {Array} data The new tasks order for the specific type that the taskID belongs to.
*
* @apiSuccessExample {json}
- * {"success":true,"data":["8d7e237a-b259-46ee-b431-33621256bb0b","2b774d70-ec8b-41c1-8967-eb6b13d962ba","f03d4a2b-9c36-4f33-9b5f-bae0aed23a49"],"notifications":[]}
+ * {"success":true,"data":["8d7e237a-b259-46ee-b431-33621256bb0b",
+ * "2b774d70-ec8b-41c1-8967-eb6b13d962ba","f03d4a2b-9c36-4f33-9b5f-bae0aed23a49"],
+ * "notifications":[]}
*
* @apiUse TaskNotFound
*/
@@ -729,25 +908,25 @@ api.moveTask = {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let user = res.locals.user;
- let taskId = req.params.taskId;
- let to = Number(req.params.position);
+ const { user } = res.locals;
+ const { taskId } = req.params;
+ const to = Number(req.params.position);
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
if (!task) throw new NotFound(res.t('taskNotFound'));
if (task.type === 'todo' && task.completed) throw new BadRequest(res.t('cantMoveCompletedTodo'));
// In memory updates
- let order = user.tasksOrder[`${task.type}s`];
+ const order = user.tasksOrder[`${task.type}s`];
moveTask(order, task._id, to);
// Server updates
// Cannot send $pull and $push on same field in one single op
- let pullQuery = { $pull: {} };
+ const pullQuery = { $pull: {} };
pullQuery.$pull[`tasksOrder.${task.type}s`] = task.id;
await user.update(pullQuery).exec();
@@ -755,7 +934,7 @@ api.moveTask = {
let position = to;
if (to === -1) position = [`tasksOrder.${task.type}s`].length - 1;
- let updateQuery = { $push: {} };
+ const updateQuery = { $push: {} };
updateQuery.$push[`tasksOrder.${task.type}s`] = {
$each: [task._id],
$position: position,
@@ -765,7 +944,7 @@ api.moveTask = {
// Update the user version field manually,
// it cannot be updated in the pre update hook
// See https://github.com/HabitRPG/habitica/pull/9321#issuecomment-354187666 for more info
- user._v++;
+ user._v += 1;
res.respond(200, order);
},
@@ -786,7 +965,16 @@ api.moveTask = {
* @apiSuccess {Object} data The updated task
*
* @apiSuccessExample {json} Example return:
- * {"success":true,"data":{"_id":"84f02d6a-7b43-4818-a35c-d3336cec4880","userId":"b0413351-405f-416f-8787-947ec1c85199","text":"Test API Params","alias":"test-api-params","type":"todo","notes":"","tags":[],"value":0,"priority":2,"attribute":"int","challenge":{"taskId":"4a29874c-0308-417b-a909-2a7d262b49f6","id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],"approval":{"required":false,"approved":false,"requested":false}},"reminders":[],"createdAt":"2017-01-13T21:23:05.949Z","updatedAt":"2017-01-14T03:38:07.406Z","checklist":[{"id":"afe4079d-dff1-47d9-9b06-5d76c69ddb12","text":"Do this subtask","completed":false}],"collapseChecklist":false,"completed":false,"id":"84f02d6a-7b43-4818-a35c-d3336cec4880"},"notifications":[]}
+ * {"success":true,"data":{"_id":"84f02d6a-7b43-4818-a35c-d3336cec4880",
+ * "userId":"b0413351-405f-416f-8787-947ec1c85199","text":"Test API Params",
+ * "alias":"test-api-params","type":"todo","notes":"","tags":[],"value":0,
+ * "priority":2,"attribute":"int","challenge":{"taskId":"4a29874c-0308-417b-a909-2a7d262b49f6",
+ * "id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],
+ * "approval":{"required":false,"approved":false,"requested":false}},"reminders":[],
+ * "createdAt":"2017-01-13T21:23:05.949Z","updatedAt":"2017-01-14T03:38:07.406Z",
+ * "checklist":[{"id":"afe4079d-dff1-47d9-9b06-5d76c69ddb12","text":"Do this subtask",
+ * "completed":false}],"collapseChecklist":false,"completed":false,
+ * "id":"84f02d6a-7b43-4818-a35c-d3336cec4880"},"notifications":[]}
*
* @apiUse TaskNotFound
*/
@@ -795,44 +983,48 @@ api.addChecklistItem = {
url: '/tasks/:taskId/checklist',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
let challenge;
let group;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
if (!task) {
throw new NotFound(res.t('taskNotFound'));
} else if (task.group.id && !task.userId) {
- let fields = requiredGroupFields.concat(' managers');
- group = await Group.getGroup({user, groupId: task.group.id, fields});
+ const fields = requiredGroupFields.concat(' managers');
+ group = await Group.getGroup({ user, groupId: task.group.id, fields });
if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
- } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights
- challenge = await Challenge.findOne({_id: task.challenge.id}).exec();
+
+ // If the task belongs to a challenge make sure the user has rights
+ } else if (task.challenge.id && !task.userId) {
+ challenge = await Challenge.findOne({ _id: task.challenge.id }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks'));
- } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one
+
+ // If the task is owned by a user make it's the current one
+ } else if (task.userId !== user._id) {
throw new NotFound(res.t('taskNotFound'));
}
if (task.type !== 'daily' && task.type !== 'todo') throw new BadRequest(res.t('checklistOnlyDailyTodo'));
- let newCheckListItem = Tasks.Task.sanitizeChecklist(req.body);
+ const newCheckListItem = Tasks.Task.sanitizeChecklist(req.body);
task.checklist.push(newCheckListItem);
- let savedTask = await task.save();
+ const savedTask = await task.save();
newCheckListItem.id = savedTask.checklist[savedTask.checklist.length - 1].id;
res.respond(200, savedTask);
if (challenge) challenge.updateTask(savedTask);
if (group && task.group.id && task.group.assignedUsers.length > 0) {
- await group.updateTask(savedTask, {newCheckListItem});
+ await group.updateTask(savedTask, { newCheckListItem });
}
},
};
@@ -855,25 +1047,25 @@ api.scoreCheckListItem = {
url: '/tasks/:taskId/checklist/:itemId/score',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
if (!task) throw new NotFound(res.t('taskNotFound'));
if (task.type !== 'daily' && task.type !== 'todo') throw new BadRequest(res.t('checklistOnlyDailyTodo'));
- let item = _.find(task.checklist, {id: req.params.itemId});
+ const item = _.find(task.checklist, { id: req.params.itemId });
if (!item) throw new NotFound(res.t('checklistItemNotFound'));
item.completed = !item.completed;
- let savedTask = await task.save();
+ const savedTask = await task.save();
res.respond(200, savedTask);
@@ -909,40 +1101,44 @@ api.updateChecklistItem = {
url: '/tasks/:taskId/checklist/:itemId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
let challenge;
let group;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
if (!task) {
throw new NotFound(res.t('taskNotFound'));
} else if (task.group.id && !task.userId) {
- let fields = requiredGroupFields.concat(' managers');
- group = await Group.getGroup({user, groupId: task.group.id, fields});
+ const fields = requiredGroupFields.concat(' managers');
+ group = await Group.getGroup({ user, groupId: task.group.id, fields });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
- } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights
- challenge = await Challenge.findOne({_id: task.challenge.id}).exec();
+
+ // If the task belongs to a challenge make sure the user has rights
+ } else if (task.challenge.id && !task.userId) {
+ challenge = await Challenge.findOne({ _id: task.challenge.id }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks'));
- } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one
+
+ // If the task is owned by a user make it's the current one
+ } else if (task.userId !== user._id) {
throw new NotFound(res.t('taskNotFound'));
}
if (task.type !== 'daily' && task.type !== 'todo') throw new BadRequest(res.t('checklistOnlyDailyTodo'));
- let item = _.find(task.checklist, {id: req.params.itemId});
+ const item = _.find(task.checklist, { id: req.params.itemId });
if (!item) throw new NotFound(res.t('checklistItemNotFound'));
_.merge(item, Tasks.Task.sanitizeChecklist(req.body));
- let savedTask = await task.save();
+ const savedTask = await task.save();
res.respond(200, savedTask);
if (challenge) challenge.updateTask(savedTask);
@@ -963,7 +1159,15 @@ api.updateChecklistItem = {
* @apiSuccess {Object} data The updated task
*
* @apiSuccessExample {json} Example return:
- * {"success":true,"data":{"_id":"84f02d6a-7b43-4818-a35c-d3336cec4880","userId":"b0413351-405f-416f-8787-947ec1c85199","text":"Test API Params","alias":"test-api-params","type":"todo","notes":"","tags":[],"value":-1,"priority":2,"attribute":"int","challenge":{"taskId":"4a29874c-0308-417b-a909-2a7d262b49f6","id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],"approval":{"required":false,"approved":false,"requested":false}},"reminders":[],"createdAt":"2017-01-13T21:23:05.949Z","updatedAt":"2017-01-14T19:35:41.881Z","checklist":[],"collapseChecklist":false,"completed":false,"id":"84f02d6a-7b43-4818-a35c-d3336cec4880"},"notifications":[]}
+ * {"success":true,"data":{"_id":"84f02d6a-7b43-4818-a35c-d3336cec4880",
+ * "userId":"b0413351-405f-416f-8787-947ec1c85199","text":"Test API Params",
+ * "alias":"test-api-params","type":"todo","notes":"","tags":[],"value":-1,
+ * "priority":2,"attribute":"int","challenge":{"taskId":"4a29874c-0308-417b-a909-2a7d262b49f6",
+ * "id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],
+ * "approval":{"required":false,"approved":false,"requested":false}},"reminders":[],
+ * "createdAt":"2017-01-13T21:23:05.949Z","updatedAt":"2017-01-14T19:35:41.881Z",
+ * "checklist":[],"collapseChecklist":false,"completed":false,
+ * "id":"84f02d6a-7b43-4818-a35c-d3336cec4880"},"notifications":[]}
*
* @apiUse TaskNotFound
* @apiUse ChallengeNotFound
@@ -974,43 +1178,47 @@ api.removeChecklistItem = {
url: '/tasks/:taskId/checklist/:itemId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
let challenge;
let group;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
if (!task) {
throw new NotFound(res.t('taskNotFound'));
} else if (task.group.id && !task.userId) {
- let fields = requiredGroupFields.concat(' managers');
- group = await Group.getGroup({user, groupId: task.group.id, fields});
+ const fields = requiredGroupFields.concat(' managers');
+ group = await Group.getGroup({ user, groupId: task.group.id, fields });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
- } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights
- challenge = await Challenge.findOne({_id: task.challenge.id}).exec();
+
+ // If the task belongs to a challenge make sure the user has rights
+ } else if (task.challenge.id && !task.userId) {
+ challenge = await Challenge.findOne({ _id: task.challenge.id }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks'));
- } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one
+
+ // If the task is owned by a user make it's the current one
+ } else if (task.userId !== user._id) {
throw new NotFound(res.t('taskNotFound'));
}
if (task.type !== 'daily' && task.type !== 'todo') throw new BadRequest(res.t('checklistOnlyDailyTodo'));
- let hasItem = removeFromArray(task.checklist, { id: req.params.itemId });
+ const hasItem = removeFromArray(task.checklist, { id: req.params.itemId });
if (!hasItem) throw new NotFound(res.t('checklistItemNotFound'));
- let savedTask = await task.save();
+ const savedTask = await task.save();
res.respond(200, savedTask);
if (challenge) challenge.updateTask(savedTask);
if (group && task.group.id && task.group.assignedUsers.length > 0) {
- await group.updateTask(savedTask, {removedCheckListItemId: req.params.itemId});
+ await group.updateTask(savedTask, { removedCheckListItemId: req.params.itemId });
}
},
};
@@ -1026,10 +1234,21 @@ api.removeChecklistItem = {
* @apiSuccess {Object} data The updated task
*
* @apiSuccessExample {json} Example return:
- * {"success":true,"data":{"_id":"84f02d6a-7b43-4818-a35c-d3336cec4880","userId":"b0413351-405f-416f-8787-947ec1c85199","text":"Test API Params","alias":"test-api-params","type":"todo","notes":"","tags":["3d5d324d-a042-4d5f-872e-0553e228553e"],"value":-1,"priority":2,"attribute":"int","challenge":{"taskId":"4a29874c-0308-417b-a909-2a7d262b49f6","id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],"approval":{"required":false,"approved":false,"requested":false}},"reminders":[],"createdAt":"2017-01-13T21:23:05.949Z","updatedAt":"2017-01-14T19:41:29.466Z","checklist":[],"collapseChecklist":false,"completed":false,"id":"84f02d6a-7b43-4818-a35c-d3336cec4880"},"notifications":[]}
+ * {"success":true,"data":{"_id":"84f02d6a-7b43-4818-a35c-d3336cec4880",
+ * "userId":"b0413351-405f-416f-8787-947ec1c85199","text":"Test API Params",
+ * "alias":"test-api-params","type":"todo","notes":"",
+ * "tags":["3d5d324d-a042-4d5f-872e-0553e228553e"],"value":-1,"priority":2,"attribute":"int",
+ * "challenge":{"taskId":"4a29874c-0308-417b-a909-2a7d262b49f6",
+ * "id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],
+ * "approval":{"required":false,"approved":false,"requested":false}},"reminders":[],
+ * "createdAt":"2017-01-13T21:23:05.949Z","updatedAt":"2017-01-14T19:41:29.466Z",
+ * "checklist":[],"collapseChecklist":false,"completed":false,
+ * "id":"84f02d6a-7b43-4818-a35c-d3336cec4880"},"notifications":[]}
*
* @apiUse TaskNotFound
- * @apiError (400) {BadRequest} Invalid-request-parameters "tagId" must be a valid UUID corresponding to a tag belonging to the user.
+ * @apiError (400) {BadRequest} Invalid-request-parameters "tagId" must be a valid UUID
+ * corresponding to a tag belonging
+ * to the user.
* @apiError (400) {BadRequest} TagExists The task is already tagged with given tag.
*/
api.addTagToTask = {
@@ -1037,27 +1256,27 @@ api.addTagToTask = {
url: '/tasks/:taskId/tags/:tagId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
- let userTags = user.tags.map(tag => tag.id);
+ const userTags = user.tags.map(tag => tag.id);
req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID().isIn(userTags);
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
if (!task) throw new NotFound(res.t('taskNotFound'));
- let tagId = req.params.tagId;
+ const { tagId } = req.params;
- let alreadyTagged = task.tags.indexOf(tagId) !== -1;
+ const alreadyTagged = task.tags.indexOf(tagId) !== -1;
if (alreadyTagged) throw new BadRequest(res.t('alreadyTagged'));
task.tags.push(tagId);
- let savedTask = await task.save();
+ const savedTask = await task.save();
res.respond(200, savedTask);
},
};
@@ -1076,7 +1295,15 @@ api.addTagToTask = {
* @apiSuccess {Object} data The updated task
*
* @apiSuccessExample {json} Example return:
- * {"success":true,"data":{"_id":"84f02d6a-7b43-4818-a35c-d3336cec4880","userId":"b0413351-405f-416f-8787-947ec1c85199","text":"Test API Params","alias":"test-api-params","type":"todo","notes":"","tags":[],"value":-1,"priority":2,"attribute":"int","challenge":{"taskId":"4a29874c-0308-417b-a909-2a7d262b49f6","id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],"approval":{"required":false,"approved":false,"requested":false}},"reminders":[],"createdAt":"2017-01-13T21:23:05.949Z","updatedAt":"2017-01-14T20:02:18.206Z","checklist":[],"collapseChecklist":false,"completed":false,"id":"84f02d6a-7b43-4818-a35c-d3336cec4880"},"notifications":[]}
+ * {"success":true,"data":{"_id":"84f02d6a-7b43-4818-a35c-d3336cec4880",
+ * "userId":"b0413351-405f-416f-8787-947ec1c85199","text":"Test API Params",
+ * "alias":"test-api-params","type":"todo","notes":"","tags":[],"value":-1,"priority":2,
+ * "attribute":"int","challenge":{"taskId":"4a29874c-0308-417b-a909-2a7d262b49f6",
+ * "id":"f23c12f2-5830-4f15-9c36-e17fd729a812"},"group":{"assignedUsers":[],
+ * "approval":{"required":false,"approved":false,"requested":false}},"reminders":[],
+ * "createdAt":"2017-01-13T21:23:05.949Z","updatedAt":"2017-01-14T20:02:18.206Z","checklist":[],
+ * "collapseChecklist":false,"completed":false,"id":"84f02d6a-7b43-4818-a35c-d3336cec4880"},
+ * "notifications":[]}
*
* @apiUse TaskNotFound
* @apiUse TagNotFound
@@ -1086,23 +1313,23 @@ api.removeTagFromTask = {
url: '/tasks/:taskId/tags/:tagId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
if (!task) throw new NotFound(res.t('taskNotFound'));
- let hasTag = removeFromArray(task.tags, req.params.tagId);
+ const hasTag = removeFromArray(task.tags, req.params.tagId);
if (!hasTag) throw new NotFound(res.t('tagNotFound'));
- let savedTask = await task.save();
+ const savedTask = await task.save();
res.respond(200, savedTask);
},
};
@@ -1113,7 +1340,9 @@ api.removeTagFromTask = {
* @apiGroup Task
*
* @apiParam (Path) {UUID} challengeId The challenge _id
- * @apiParam (Query) {String='keep-all','remove-all'} keep Specifies if tasks should be kept(keep-all) or removed(remove-all) after the unlink
+ * @apiParam (Query) {String='keep-all','remove-all'} keep Specifies if tasks
+ * should be kept(keep-all) or
+ * removed(remove-all) after the unlink.
*
* @apiExample {curl}
* curl -X "POST" https://habitica.com/api/v3/tasks/unlink-all/f23c12f2-5830-4f15-9c36-e17fd729a812?keep=remove-all
@@ -1134,21 +1363,19 @@ api.unlinkAllTasks = {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
req.checkQuery('keep', apiError('keepOrRemoveAll')).notEmpty().isIn(['keep-all', 'remove-all']);
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let user = res.locals.user;
- let keep = req.query.keep;
- let challengeId = req.params.challengeId;
+ const { user } = res.locals;
+ const { keep } = req.query;
+ const { challengeId } = req.params;
- let tasks = await Tasks.Task.find({
+ const tasks = await Tasks.Task.find({
'challenge.id': challengeId,
userId: user._id,
}).exec();
- let validTasks = tasks.every(task => {
- return task.challenge.broken;
- });
+ const validTasks = tasks.every(task => task.challenge.broken);
if (!validTasks) throw new BadRequest(res.t('cantOnlyUnlinkChalTask'));
@@ -1158,7 +1385,7 @@ api.unlinkAllTasks = {
return task.save();
}));
} else { // remove
- let toSave = [];
+ const toSave = [];
tasks.forEach(task => {
if (task.type !== 'todo' || !task.completed) { // eslint-disable-line no-lonely-if
@@ -1183,7 +1410,8 @@ api.unlinkAllTasks = {
* @apiGroup Task
*
* @apiParam (Path) {String} taskId The task _id or alias
- * @apiParam (Query) {String='keep','remove'} keep Specifies if the task should be kept(keep) or removed(remove)
+ * @apiParam (Query) {String='keep','remove'} keep Specifies if the task should
+ * be kept(keep) or removed(remove).
*
* @apiExample {curl} Example call:
* curl -X "POST" https://habitica.com/api/v3/tasks/unlink-one/ee882e1d-ebd1-4716-88f2-4f9e47d947a8?keep=keep
@@ -1201,14 +1429,14 @@ api.unlinkOneTask = {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
req.checkQuery('keep', apiError('keepOrRemove')).notEmpty().isIn(['keep', 'remove']);
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let user = res.locals.user;
- let keep = req.query.keep;
- let taskId = req.params.taskId;
+ const { user } = res.locals;
+ const { keep } = req.query;
+ const { taskId } = req.params;
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
if (!task) throw new NotFound(res.t('taskNotFound'));
if (!task.challenge.id) throw new BadRequest(res.t('cantOnlyUnlinkChalTask'));
@@ -1248,7 +1476,7 @@ api.clearCompletedTodos = {
url: '/tasks/clearCompletedTodos',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
// Clear completed todos
// Do not delete completed todos from challenges or groups, unless the task is broken
@@ -1259,14 +1487,14 @@ api.clearCompletedTodos = {
$and: [ // exclude challenge and group tasks
{
$or: [
- {'challenge.id': {$exists: false}},
- {'challenge.broken': {$exists: true}},
+ { 'challenge.id': { $exists: false } },
+ { 'challenge.broken': { $exists: true } },
],
},
{
$or: [
- {'group.id': {$exists: false}},
- {'group.broken': {$exists: true}},
+ { 'group.id': { $exists: false } },
+ { 'group.broken': { $exists: true } },
],
},
],
@@ -1291,7 +1519,8 @@ api.clearCompletedTodos = {
* @apiUse TaskNotFound
* @apiError (401) {NotAuthorized} Challenge A task belonging to a challenge can't be deleted.
* @apiError (401) {NotAuthorized} Group Can't delete group tasks that are assigned to you
- * @apiError (401) {NotAuthorized} ChallengeLeader Tasks belonging to a challenge can only be edited by the leader.
+ * @apiError (401) {NotAuthorized} ChallengeLeader Tasks belonging to a challenge
+ * can only be edited by the leader.
* @apiError (401) {NotAuthorized} GroupLeader Not authorized to manage tasks!
*/
api.deleteTask = {
@@ -1299,44 +1528,52 @@ api.deleteTask = {
url: '/tasks/:taskId',
middlewares: [authWithHeaders()],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
let challenge;
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
if (!task) {
throw new NotFound(res.t('taskNotFound'));
} else if (task.group.id && !task.userId) {
// @TODO: Abstract this access snippet
- let fields = requiredGroupFields.concat(' managers');
- let group = await Group.getGroup({user, groupId: task.group.id, fields});
+ const fields = requiredGroupFields.concat(' managers');
+ const group = await Group.getGroup({ user, groupId: task.group.id, fields });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
await group.removeTask(task);
- } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights
- challenge = await Challenge.findOne({_id: task.challenge.id}).exec();
+
+ // If the task belongs to a challenge make sure the user has rights
+ } else if (task.challenge.id && !task.userId) {
+ challenge = await Challenge.findOne({ _id: task.challenge.id }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks'));
- } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one
+
+ // If the task is owned by a user make it's the current one
+ } else if (task.userId !== user._id) {
throw new NotFound(res.t('taskNotFound'));
} else if (task.userId && task.challenge.id && !task.challenge.broken) {
throw new NotAuthorized(res.t('cantDeleteChallengeTasks'));
- } else if (task.group.id && task.group.assignedUsers.indexOf(user._id) !== -1 && !task.group.broken) {
+ } else if (
+ task.group.id
+ && task.group.assignedUsers.indexOf(user._id) !== -1
+ && !task.group.broken
+ ) {
throw new NotAuthorized(res.t('cantDeleteAssignedGroupTasks'));
}
if (task.type !== 'todo' || !task.completed) {
removeFromArray((challenge || user).tasksOrder[`${task.type}s`], taskId);
- let pullQuery = {$pull: {}};
+ const pullQuery = { $pull: {} };
pullQuery.$pull[`tasksOrder.${task.type}s`] = task._id;
- let taskOrderUpdate = (challenge || user).update(pullQuery).exec();
+ const taskOrderUpdate = (challenge || user).update(pullQuery).exec();
// Update the user version field manually,
// it cannot be updated in the pre update hook
// See https://github.com/HabitRPG/habitica/pull/9321#issuecomment-354187666 for more info
- if (!challenge) user._v++;
+ if (!challenge) user._v += 1;
await Promise.all([taskOrderUpdate, task.remove()]);
} else {
@@ -1356,4 +1593,4 @@ api.deleteTask = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/tasks/groups.js b/website/server/controllers/api-v3/tasks/groups.js
index 27fcc62db4..1045860c42 100644
--- a/website/server/controllers/api-v3/tasks/groups.js
+++ b/website/server/controllers/api-v3/tasks/groups.js
@@ -15,23 +15,25 @@ import {
import { handleSharedCompletion } from '../../../libs/groupTasks';
import apiError from '../../../libs/apiError';
-let requiredGroupFields = '_id leader tasksOrder name';
+const requiredGroupFields = '_id leader tasksOrder name';
// @TODO: abstract to task lib
-let types = Tasks.tasksTypes.map(type => `${type}s`);
-types.push('completedTodos', '_allCompletedTodos'); // _allCompletedTodos is currently in BETA and is likely to be removed in future
+const types = Tasks.tasksTypes.map(type => `${type}s`);
+// _allCompletedTodos is currently in BETA and is likely to be removed in future
+types.push('completedTodos', '_allCompletedTodos');
function canNotEditTasks (group, user, assignedUserId) {
- let isNotGroupLeader = group.leader !== user._id;
- let isManager = Boolean(group.managers[user._id]);
- let userIsAssigningToSelf = Boolean(assignedUserId && user._id === assignedUserId);
+ const isNotGroupLeader = group.leader !== user._id;
+ const isManager = Boolean(group.managers[user._id]);
+ const userIsAssigningToSelf = Boolean(assignedUserId && user._id === assignedUserId);
return isNotGroupLeader && !isManager && !userIsAssigningToSelf;
}
-let api = {};
+const api = {};
/**
* @api {post} /api/v3/tasks/group/:groupId Create a new task belonging to a group
- * @apiDescription Can be passed an object to create a single task or an array of objects to create multiple tasks.
+ * @apiDescription Can be passed an object to create a single task or
+ * an array of objects to create multiple tasks.
* @apiName CreateGroupTasks
* @apiGroup Task
*
@@ -46,22 +48,22 @@ api.createGroupTasks = {
async handler (req, res) {
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty().isUUID();
- let reqValidationErrors = req.validationErrors();
+ const reqValidationErrors = req.validationErrors();
if (reqValidationErrors) throw reqValidationErrors;
- let user = res.locals.user;
+ const { user } = res.locals;
- let fields = requiredGroupFields.concat(' managers');
- let group = await Group.getGroup({user, groupId: req.params.groupId, fields});
+ const fields = requiredGroupFields.concat(' managers');
+ const group = await Group.getGroup({ user, groupId: req.params.groupId, fields });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
- let tasks = await createTasks(req, res, {user, group});
+ const tasks = await createTasks(req, res, { user, group });
res.respond(201, tasks.length === 1 ? tasks[0] : tasks);
- tasks.forEach((task) => {
+ tasks.forEach(task => {
res.analytics.track('task create', {
uuid: user._id,
hitType: 'event',
@@ -79,7 +81,8 @@ api.createGroupTasks = {
* @apiGroup Task
*
* @apiParam (Path) {UUID} groupId The id of the group from which to retrieve the tasks
- * @apiParam (Query) {string="habits","dailys","todos","rewards"} [type] Query parameter to return just a type of tasks
+ * @apiParam (Query) {string="habits","dailys","todos","rewards"} [type] Query parameter to
+ * return just a type of tasks
*
* @apiSuccess {Array} data An array of tasks
*/
@@ -91,28 +94,34 @@ api.getGroupTasks = {
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty().isUUID();
req.checkQuery('type', res.t('invalidTasksType')).optional().isIn(types);
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let user = res.locals.user;
+ const { user } = res.locals;
- let group = await Group.getGroup({user, groupId: req.params.groupId, fields: requiredGroupFields});
+ const group = await Group.getGroup({
+ user,
+ groupId: req.params.groupId,
+ fields: requiredGroupFields,
+ });
if (!group) throw new NotFound(res.t('groupNotFound'));
- let tasks = await getTasks(req, res, {user, group});
+ const tasks = await getTasks(req, res, { user, group });
res.respond(200, tasks);
},
};
/**
- * @api {post} /api/v3/group/:groupId/tasks/:taskId/move/to/:position Move a group task to a specified position
+ * @api {post} /api/v3/group/:groupId/tasks/:taskId/move/to/:position Move a group task to
+ * a specified position
* @apiDescription Moves a group task to a specified position
* @apiVersion 3.0.0
* @apiName GroupMoveTask
* @apiGroup Task
*
* @apiParam (Path) {String} taskId The task _id
- * @apiParam (Path) {Number} position Where to move the task (-1 means push to bottom). First position is 0
+ * @apiParam (Path) {Number} position Where to move the task (-1 means push to bottom).
+ * First position is 0
*
* @apiSuccess {Array} data The new tasks order (group.tasksOrder.{task.type}s)
*/
@@ -124,17 +133,17 @@ api.groupMoveTask = {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric();
- let reqValidationErrors = req.validationErrors();
+ const reqValidationErrors = req.validationErrors();
if (reqValidationErrors) throw reqValidationErrors;
- let user = res.locals.user;
+ const { user } = res.locals;
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findOne({
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findOne({
_id: taskId,
}).exec();
- let to = Number(req.params.position);
+ const to = Number(req.params.position);
if (!task) {
throw new NotFound(res.t('taskNotFound'));
@@ -142,12 +151,16 @@ api.groupMoveTask = {
if (task.type === 'todo' && task.completed) throw new BadRequest(res.t('cantMoveCompletedTodo'));
- let group = await Group.getGroup({user, groupId: task.group.id, fields: requiredGroupFields});
+ const group = await Group.getGroup({
+ user,
+ groupId: task.group.id,
+ fields: requiredGroupFields,
+ });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (group.leader !== user._id) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
- let order = group.tasksOrder[`${task.type}s`];
+ const order = group.tasksOrder[`${task.type}s`];
moveTask(order, task._id, to);
@@ -175,15 +188,15 @@ api.assignTask = {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
req.checkParams('assignedUserId', res.t('userIdRequired')).notEmpty().isUUID();
- let reqValidationErrors = req.validationErrors();
+ const reqValidationErrors = req.validationErrors();
if (reqValidationErrors) throw reqValidationErrors;
- let user = res.locals.user;
- let assignedUserId = req.params.assignedUserId;
- let assignedUser = await User.findById(assignedUserId).exec();
+ const { user } = res.locals;
+ const { assignedUserId } = req.params;
+ const assignedUser = await User.findById(assignedUserId).exec();
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
if (!task) {
throw new NotFound(res.t('taskNotFound'));
@@ -193,24 +206,24 @@ api.assignTask = {
throw new NotAuthorized(res.t('onlyGroupTasksCanBeAssigned'));
}
- let groupFields = `${requiredGroupFields} chat managers`;
- let group = await Group.getGroup({user, groupId: task.group.id, fields: groupFields});
+ const groupFields = `${requiredGroupFields} chat managers`;
+ const group = await Group.getGroup({ user, groupId: task.group.id, fields: groupFields });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (canNotEditTasks(group, user, assignedUserId)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
- let promises = [];
+ const promises = [];
const taskText = task.text;
const userName = user.profile.name;
if (user._id === assignedUserId) {
const managerIds = Object.keys(group.managers);
managerIds.push(group.leader);
- const managers = await User.find({_id: managerIds}, 'notifications preferences').exec();
- managers.forEach((manager) => {
+ const managers = await User.find({ _id: managerIds }, 'notifications preferences').exec();
+ managers.forEach(manager => {
if (manager._id === user._id) return;
manager.addNotification('GROUP_TASK_CLAIMED', {
- message: res.t('taskClaimed', {userName, taskText}, manager.preferences.language),
+ message: res.t('taskClaimed', { userName, taskText }, manager.preferences.language),
groupId: group._id,
taskId: task._id,
});
@@ -218,7 +231,7 @@ api.assignTask = {
});
} else {
assignedUser.addNotification('GROUP_TASK_ASSIGNED', {
- message: res.t('youHaveBeenAssignedTask', {managerName: userName, taskText}),
+ message: res.t('youHaveBeenAssignedTask', { managerName: userName, taskText }),
taskId: task._id,
});
}
@@ -250,15 +263,15 @@ api.unassignTask = {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
req.checkParams('assignedUserId', res.t('userIdRequired')).notEmpty().isUUID();
- let reqValidationErrors = req.validationErrors();
+ const reqValidationErrors = req.validationErrors();
if (reqValidationErrors) throw reqValidationErrors;
- let user = res.locals.user;
- let assignedUserId = req.params.assignedUserId;
- let assignedUser = await User.findById(assignedUserId).exec();
+ const { user } = res.locals;
+ const { assignedUserId } = req.params;
+ const assignedUser = await User.findById(assignedUserId).exec();
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
if (!task) {
throw new NotFound(res.t('taskNotFound'));
@@ -268,17 +281,15 @@ api.unassignTask = {
throw new NotAuthorized(res.t('onlyGroupTasksCanBeAssigned'));
}
- let fields = requiredGroupFields.concat(' managers');
- let group = await Group.getGroup({user, groupId: task.group.id, fields});
+ const fields = requiredGroupFields.concat(' managers');
+ const group = await Group.getGroup({ user, groupId: task.group.id, fields });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (canNotEditTasks(group, user, assignedUserId)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
await group.unlinkTask(task, assignedUser);
- let notificationIndex = assignedUser.notifications.findIndex(function findNotification (notification) {
- return notification && notification.data && notification.type === 'GROUP_TASK_ASSIGNED' && notification.data.taskId === task._id;
- });
+ const notificationIndex = assignedUser.notifications.findIndex(notification => notification && notification.data && notification.type === 'GROUP_TASK_ASSIGNED' && notification.data.taskId === task._id);
if (notificationIndex !== -1) {
assignedUser.notifications.splice(notificationIndex, 1);
@@ -309,15 +320,15 @@ api.approveTask = {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
req.checkParams('userId', res.t('userIdRequired')).notEmpty().isUUID();
- let reqValidationErrors = req.validationErrors();
+ const reqValidationErrors = req.validationErrors();
if (reqValidationErrors) throw reqValidationErrors;
- let user = res.locals.user;
- let assignedUserId = req.params.userId;
- let assignedUser = await User.findById(assignedUserId).exec();
+ const { user } = res.locals;
+ const assignedUserId = req.params.userId;
+ const assignedUser = await User.findById(assignedUserId).exec();
- let taskId = req.params.taskId;
- let task = await Tasks.Task.findOne({
+ const { taskId } = req.params;
+ const task = await Tasks.Task.findOne({
'group.taskId': taskId,
userId: assignedUserId,
}).exec();
@@ -326,8 +337,8 @@ api.approveTask = {
throw new NotFound(res.t('taskNotFound'));
}
- let fields = requiredGroupFields.concat(' managers');
- let group = await Group.getGroup({user, groupId: task.group.id, fields});
+ const fields = requiredGroupFields.concat(' managers');
+ const group = await Group.getGroup({ user, groupId: task.group.id, fields });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
@@ -343,24 +354,20 @@ api.approveTask = {
// Get Managers
const managerIds = Object.keys(group.managers);
managerIds.push(group.leader);
- const managers = await User.find({_id: managerIds}, 'notifications').exec(); // Use this method so we can get access to notifications
+ const managers = await User.find({ _id: managerIds }, 'notifications').exec(); // Use this method so we can get access to notifications
// Get task direction
const firstManagerNotifications = managers[0].notifications;
- const firstNotificationIndex = firstManagerNotifications.findIndex((notification) => {
- return notification && notification.data && notification.data.taskId === task._id && notification.type === 'GROUP_TASK_APPROVAL';
- });
+ const firstNotificationIndex = firstManagerNotifications.findIndex(notification => notification && notification.data && notification.data.taskId === task._id && notification.type === 'GROUP_TASK_APPROVAL');
let direction = 'up';
if (firstManagerNotifications[firstNotificationIndex]) {
direction = firstManagerNotifications[firstNotificationIndex].direction;
}
// Remove old notifications
- let approvalPromises = [];
- managers.forEach((manager) => {
- let notificationIndex = manager.notifications.findIndex(function findNotification (notification) {
- return notification && notification.data && notification.data.taskId === task._id && notification.type === 'GROUP_TASK_APPROVAL';
- });
+ const approvalPromises = [];
+ managers.forEach(manager => {
+ const notificationIndex = manager.notifications.findIndex(notification => notification && notification.data && notification.data.taskId === task._id && notification.type === 'GROUP_TASK_APPROVAL');
if (notificationIndex !== -1) {
manager.notifications.splice(notificationIndex, 1);
@@ -370,12 +377,12 @@ api.approveTask = {
// Add new notifications to user
assignedUser.addNotification('GROUP_TASK_APPROVED', {
- message: res.t('yourTaskHasBeenApproved', {taskText: task.text}),
+ message: res.t('yourTaskHasBeenApproved', { taskText: task.text }),
groupId: group._id,
});
assignedUser.addNotification('SCORED_TASK', {
- message: res.t('yourTaskHasBeenApproved', {taskText: task.text}),
+ message: res.t('yourTaskHasBeenApproved', { taskText: task.text }),
scoreTask: task,
direction,
});
@@ -410,13 +417,13 @@ api.taskNeedsWork = {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
req.checkParams('userId', res.t('userIdRequired')).notEmpty().isUUID();
- let reqValidationErrors = req.validationErrors();
+ const reqValidationErrors = req.validationErrors();
if (reqValidationErrors) throw reqValidationErrors;
- let user = res.locals.user;
+ const { user } = res.locals;
- let assignedUserId = req.params.userId;
- let taskId = req.params.taskId;
+ const assignedUserId = req.params.userId;
+ const { taskId } = req.params;
const [assignedUser, task] = await Promise.all([
User.findById(assignedUserId).exec(),
@@ -430,8 +437,8 @@ api.taskNeedsWork = {
throw new NotFound(res.t('taskNotFound'));
}
- let fields = requiredGroupFields.concat(' managers');
- let group = await Group.getGroup({user, groupId: task.group.id, fields});
+ const fields = requiredGroupFields.concat(' managers');
+ const group = await Group.getGroup({ user, groupId: task.group.id, fields });
if (!group) throw new NotFound(res.t('groupNotFound'));
if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks'));
@@ -443,15 +450,13 @@ api.taskNeedsWork = {
// Get Managers
const managerIds = Object.keys(group.managers);
managerIds.push(group.leader);
- const managers = await User.find({_id: managerIds}, 'notifications').exec(); // Use this method so we can get access to notifications
+ const managers = await User.find({ _id: managerIds }, 'notifications').exec(); // Use this method so we can get access to notifications
const promises = [];
// Remove old notifications
- managers.forEach((manager) => {
- let notificationIndex = manager.notifications.findIndex(function findNotification (notification) {
- return notification && notification.data && notification.data.taskId === task._id && notification.type === 'GROUP_TASK_APPROVAL';
- });
+ managers.forEach(manager => {
+ const notificationIndex = manager.notifications.findIndex(notification => notification && notification.data && notification.data.taskId === task._id && notification.type === 'GROUP_TASK_APPROVAL');
if (notificationIndex !== -1) {
manager.notifications.splice(notificationIndex, 1);
@@ -465,7 +470,7 @@ api.taskNeedsWork = {
const taskText = task.text;
const managerName = user.profile.name;
- const message = res.t('taskNeedsWork', {taskText, managerName}, assignedUser.preferences.language);
+ const message = res.t('taskNeedsWork', { taskText, managerName }, assignedUser.preferences.language);
assignedUser.addNotification('GROUP_TASK_NEEDS_WORK', {
message,
@@ -506,14 +511,14 @@ api.getGroupApprovals = {
async handler (req, res) {
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let user = res.locals.user;
- let groupId = req.params.groupId;
+ const { user } = res.locals;
+ const { groupId } = req.params;
- let fields = requiredGroupFields.concat(' managers');
- let group = await Group.getGroup({user, groupId, fields});
+ const fields = requiredGroupFields.concat(' managers');
+ const group = await Group.getGroup({ user, groupId, fields });
if (!group) throw new NotFound(res.t('groupNotFound'));
let approvals;
@@ -541,4 +546,4 @@ api.getGroupApprovals = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/user.js b/website/server/controllers/api-v3/user.js
index c1b721650e..1594e4fd7c 100644
--- a/website/server/controllers/api-v3/user.js
+++ b/website/server/controllers/api-v3/user.js
@@ -1,3 +1,6 @@
+import _ from 'lodash';
+import nconf from 'nconf';
+import get from 'lodash/get';
import { authWithHeaders } from '../../middlewares/auth';
import common from '../../../common';
import {
@@ -9,7 +12,6 @@ import {
model as Group,
} from '../../models/group';
import * as Tasks from '../../models/task';
-import _ from 'lodash';
import * as passwordUtils from '../../libs/password';
import {
userActivityWebhook,
@@ -20,8 +22,6 @@ import {
} from '../../libs/email';
import * as inboxLib from '../../libs/inbox';
import * as userLib from '../../libs/user';
-import nconf from 'nconf';
-import get from 'lodash/get';
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
const DELETE_CONFIRMATION = 'DELETE';
@@ -31,7 +31,7 @@ const DELETE_CONFIRMATION = 'DELETE';
* @apiError (404) {NotFound} UserNotFound The specified user could not be found.
*/
-let api = {};
+const api = {};
/* NOTE this route has also an API v4 version */
@@ -40,7 +40,8 @@ let api = {};
* @apiName UserGet
* @apiGroup User
*
- * @apiDescription The user profile contains data related to the authenticated user including (but not limited to);
+ * @apiDescription The user profile contains data related to the authenticated
+ * user including (but not limited to);
* Achievements
* Authentications (including types and timestamps)
* Challenges
@@ -61,7 +62,9 @@ let api = {};
* Tags
* TasksOrder (list of all ids for dailys, habits, rewards and todos)
*
- * @apiParam (Query) {String} [userFields] A list of comma separated user fields to be returned instead of the entire document. Notifications are always returned.
+ * @apiParam (Query) {String} [userFields] A list of comma separated user fields to
+ * be returned instead of the entire document.
+ * Notifications are always returned.
*
* @apiExample {curl} Example use:
* curl -i https://habitica.com/api/v3/user?userFields=achievements,items.mounts
@@ -88,7 +91,8 @@ api.getUser = {
};
/**
- * @api {get} /api/v3/user/inventory/buy Get the gear items available for purchase for the authenticated user
+ * @api {get} /api/v3/user/inventory/buy Get the gear items available for purchase
+ * for the authenticated user
* @apiName UserGetBuyList
* @apiGroup User
*
@@ -118,12 +122,15 @@ api.getBuyList = {
middlewares: [authWithHeaders()],
url: '/user/inventory/buy',
async handler (req, res) {
- let list = _.cloneDeep(common.updateStore(res.locals.user));
+ const list = _.cloneDeep(common.updateStore(res.locals.user));
// return text and notes strings
_.each(list, item => {
_.each(item, (itemPropVal, itemPropKey) => {
- if (_.isFunction(itemPropVal) && itemPropVal.i18nLangFunc) item[itemPropKey] = itemPropVal(req.language);
+ if (
+ _.isFunction(itemPropVal)
+ && itemPropVal.i18nLangFunc
+ ) item[itemPropKey] = itemPropVal(req.language);
});
});
@@ -143,7 +150,9 @@ api.getBuyList = {
* {
* "key":"weapon_armoire_battleAxe",
* "text":"Battle Axe",
- * "notes":"This fine iron axe is well-suited to battling your fiercest foes or your most difficult tasks. Increases Intelligence by 6 and Constitution by 8. Enchanted Armoire: Independent Item.",
+ * "notes":"This fine iron axe is well-suited to battling your fiercest
+ * foes or your most difficult tasks. Increases Intelligence by 6 and
+ * Constitution by 8. Enchanted Armoire: Independent Item.",
* "value":1,
* "type":"weapon",
* "locked":false,
@@ -161,12 +170,15 @@ api.getInAppRewardsList = {
middlewares: [authWithHeaders()],
url: '/user/in-app-rewards',
async handler (req, res) {
- let list = common.inAppRewards(res.locals.user);
+ const list = common.inAppRewards(res.locals.user);
// return text and notes strings
_.each(list, item => {
_.each(item, (itemPropVal, itemPropKey) => {
- if (_.isFunction(itemPropVal) && itemPropVal.i18nLangFunc) item[itemPropKey] = itemPropVal(req.language);
+ if (
+ _.isFunction(itemPropVal)
+ && itemPropVal.i18nLangFunc
+ ) item[itemPropKey] = itemPropVal(req.language);
});
});
@@ -195,7 +207,8 @@ api.getInAppRewardsList = {
*
* @apiSuccess {Object} data The updated user object, the result is identical to the get user call
*
- * @apiError (401) {NotAuthorized} messageUserOperationProtected Returned if the change is not allowed.
+ * @apiError (401) {NotAuthorized} messageUserOperationProtected Returned if the change
+ * is not allowed.
*
* @apiErrorExample {json} Error-Response:
* {
@@ -252,34 +265,32 @@ api.deleteUser = {
middlewares: [authWithHeaders()],
url: '/user',
async handler (req, res) {
- let user = res.locals.user;
- let plan = user.purchased.plan;
+ const { user } = res.locals;
+ const { plan } = user.purchased;
- let password = req.body.password;
+ const { password } = req.body;
if (!password) throw new BadRequest(res.t('missingPassword'));
if (user.auth.local.hashed_password && user.auth.local.email) {
- let isValidPassword = await passwordUtils.compare(user, password);
+ const isValidPassword = await passwordUtils.compare(user, password);
if (!isValidPassword) throw new NotAuthorized(res.t('wrongPassword'));
} else if ((user.auth.facebook.id || user.auth.google.id) && password !== DELETE_CONFIRMATION) {
- throw new NotAuthorized(res.t('incorrectDeletePhrase', {magicWord: 'DELETE'}));
+ throw new NotAuthorized(res.t('incorrectDeletePhrase', { magicWord: 'DELETE' }));
}
- let feedback = req.body.feedback;
+ const { feedback } = req.body;
if (feedback && feedback.length > 10000) throw new BadRequest(`Account deletion feedback is limited to 10,000 characters. For lengthy feedback, email ${TECH_ASSISTANCE_EMAIL}.`);
if (plan && plan.customerId && !plan.dateTerminated) {
throw new NotAuthorized(res.t('cannotDeleteActiveAccount'));
}
- let types = ['party', 'guilds'];
- let groupFields = basicGroupFields.concat(' leader memberCount purchased');
+ const types = ['party', 'guilds'];
+ const groupFields = basicGroupFields.concat(' leader memberCount purchased');
- let groupsUserIsMemberOf = await Group.getGroups({user, types, groupFields});
+ const groupsUserIsMemberOf = await Group.getGroups({ user, types, groupFields });
- let groupLeavePromises = groupsUserIsMemberOf.map((group) => {
- return group.leave(user, 'remove-all');
- });
+ const groupLeavePromises = groupsUserIsMemberOf.map(group => group.leave(user, 'remove-all'));
await Promise.all(groupLeavePromises);
@@ -290,13 +301,13 @@ api.deleteUser = {
await user.remove();
if (feedback) {
- sendTxn({email: TECH_ASSISTANCE_EMAIL}, 'admin-feedback', [
- {name: 'PROFILE_NAME', content: user.profile.name},
- {name: 'USERNAME', content: user.auth.local.username},
- {name: 'UUID', content: user._id},
- {name: 'EMAIL', content: getUserInfo(user, ['email']).email},
- {name: 'FEEDBACK_SOURCE', content: 'from deletion form'},
- {name: 'FEEDBACK', content: feedback},
+ sendTxn({ email: TECH_ASSISTANCE_EMAIL }, 'admin-feedback', [
+ { name: 'PROFILE_NAME', content: user.profile.name },
+ { name: 'USERNAME', content: user.auth.local.username },
+ { name: 'UUID', content: user._id },
+ { name: 'EMAIL', content: getUserInfo(user, ['email']).email },
+ { name: 'FEEDBACK_SOURCE', content: 'from deletion form' },
+ { name: 'FEEDBACK', content: feedback },
]);
}
@@ -333,13 +344,13 @@ function _cleanChecklist (task) {
*
* @apiSuccess {Object} data.user
* @apiSuccess {Object} data.tasks
- **/
+ * */
api.getUserAnonymized = {
method: 'GET',
middlewares: [authWithHeaders()],
url: '/user/anonymized',
async handler (req, res) {
- let user = await res.locals.user.toJSONWithInbox();
+ const user = await res.locals.user.toJSONWithInbox();
user.stats.toNextLevel = common.tnl(user.stats.lvl);
user.stats.maxHealth = common.maxHealth;
user.stats.maxMP = common.statsComputed(res.locals.user).maxMP;
@@ -361,25 +372,25 @@ api.getUserAnonymized = {
delete user.achievements.challenges;
delete user.notifications;
- _.forEach(user.inbox.messages, (msg) => {
+ _.forEach(user.inbox.messages, msg => {
msg.text = 'inbox message text';
});
- _.forEach(user.tags, (tag) => {
+ _.forEach(user.tags, tag => {
tag.name = 'tag';
tag.challenge = 'challenge';
});
- let query = {
+ const query = {
userId: user._id,
$or: [
{ type: 'todo', completed: false },
{ type: { $in: ['habit', 'daily', 'reward'] } },
],
};
- let tasks = await Tasks.Task.find(query).exec();
+ const tasks = await Tasks.Task.find(query).exec();
- _.forEach(tasks, (task) => {
+ _.forEach(tasks, task => {
task.text = 'task text';
task.notes = 'task notes';
if (task.type === 'todo' || task.type === 'daily') {
@@ -411,8 +422,8 @@ api.sleep = {
middlewares: [authWithHeaders()],
url: '/user/sleep',
async handler (req, res) {
- let user = res.locals.user;
- let sleepRes = common.ops.sleep(user, req, res.analytics);
+ const { user } = res.locals;
+ const sleepRes = common.ops.sleep(user, req, res.analytics);
await user.save();
res.respond(200, ...sleepRes);
},
@@ -455,11 +466,10 @@ api.buy = {
middlewares: [authWithHeaders()],
url: '/user/buy/:key',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
- let buyRes;
// @TODO: Remove this when mobile passes type in body
- let type = req.params.key;
+ const type = req.params.key;
if (buySpecialKeys.indexOf(type) !== -1) {
req.type = 'special';
} else if (buyKnownKeys.indexOf(type) === -1) {
@@ -472,7 +482,7 @@ api.buy = {
let quantity = 1;
if (req.body.quantity) quantity = req.body.quantity;
req.quantity = quantity;
- buyRes = common.ops.buy(user, req, res.analytics);
+ const buyRes = common.ops.buy(user, req, res.analytics);
await user.save();
res.respond(200, ...buyRes);
@@ -519,8 +529,8 @@ api.buyGear = {
middlewares: [authWithHeaders()],
url: '/user/buy-gear/:key',
async handler (req, res) {
- let user = res.locals.user;
- let buyGearRes = common.ops.buy(user, req, res.analytics);
+ const { user } = res.locals;
+ const buyGearRes = common.ops.buy(user, req, res.analytics);
await user.save();
res.respond(200, ...buyGearRes);
},
@@ -559,10 +569,10 @@ api.buyArmoire = {
middlewares: [authWithHeaders()],
url: '/user/buy-armoire',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.type = 'armoire';
req.params.key = 'armoire';
- let buyArmoireResponse = common.ops.buy(user, req, res.analytics);
+ const buyArmoireResponse = common.ops.buy(user, req, res.analytics);
await user.save();
res.respond(200, ...buyArmoireResponse);
},
@@ -599,10 +609,10 @@ api.buyHealthPotion = {
middlewares: [authWithHeaders()],
url: '/user/buy-health-potion',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.type = 'potion';
req.params.key = 'potion';
- let buyHealthPotionResponse = common.ops.buy(user, req, res.analytics);
+ const buyHealthPotionResponse = common.ops.buy(user, req, res.analytics);
await user.save();
res.respond(200, ...buyHealthPotionResponse);
},
@@ -641,9 +651,9 @@ api.buyMysterySet = {
middlewares: [authWithHeaders()],
url: '/user/buy-mystery-set/:key',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.type = 'mystery';
- let buyMysterySetRes = common.ops.buy(user, req, res.analytics);
+ const buyMysterySetRes = common.ops.buy(user, req, res.analytics);
await user.save();
res.respond(200, ...buyMysterySetRes);
},
@@ -684,9 +694,9 @@ api.buyQuest = {
middlewares: [authWithHeaders()],
url: '/user/buy-quest/:key',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.type = 'quest';
- let buyQuestRes = common.ops.buy(user, req, res.analytics);
+ const buyQuestRes = common.ops.buy(user, req, res.analytics);
await user.save();
res.respond(200, ...buyQuestRes);
},
@@ -694,11 +704,13 @@ api.buyQuest = {
/**
* @api {post} /api/v3/user/buy-special-spell/:key Buy special "spell" item
- * @apiDescription Includes gift cards (e.g., birthday card), and avatar Transformation Items and their antidotes (e.g., Snowball item and Salt reward).
+ * @apiDescription Includes gift cards (e.g., birthday card), and avatar Transformation
+ * Items and their antidotes (e.g., Snowball item and Salt reward).
* @apiName UserBuySpecialSpell
* @apiGroup User
*
- * @apiParam (Path) {String} key The special item to buy. Must be one of the keys from "content.special", such as birthday, snowball, salt.
+ * @apiParam (Path) {String} key The special item to buy. Must be one of the keys
+ * from "content.special", such as birthday, snowball, salt.
*
* @apiSuccess {Object} data.stats User's current stats
* @apiSuccess {Object} data.items User's current inventory
@@ -724,9 +736,9 @@ api.buySpecialSpell = {
middlewares: [authWithHeaders()],
url: '/user/buy-special-spell/:key',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.type = 'special';
- let buySpecialSpellRes = common.ops.buy(user, req);
+ const buySpecialSpellRes = common.ops.buy(user, req);
await user.save();
res.respond(200, ...buySpecialSpellRes);
},
@@ -757,19 +769,21 @@ api.buySpecialSpell = {
* @apiError {NotFound} messageInvalidEggPotionCombo Cannot use that combination of egg and potion.
*
* @apiErrorExample {json} Already have that pet.
- * {"success":false,"error":"NotAuthorized","message":"You already have that pet. Try hatching a different combination
+ * {"success":false,"error":"NotAuthorized","message":"You already have that pet.
+ * Try hatching a different combination"}
* @apiErrorExample {json} Either potion or egg (or both) not in inventory
* {"success":false,"error":"NotFound","message":"You're missing either that egg or that potion"}
* @apiErrorExample {json} Cannot use that combination
- * {"success":false,"error":"NotAuthorized","message":"You can't hatch Quest Pet Eggs with Magic Hatching Potions! Try a different egg."}
+ * {"success":false,"error":"NotAuthorized","message":"You can't hatch Quest
+ * Pet Eggs with Magic Hatching Potions! Try a different egg."}
*/
api.hatch = {
method: 'POST',
middlewares: [authWithHeaders()],
url: '/user/hatch/:egg/:hatchingPotion',
async handler (req, res) {
- let user = res.locals.user;
- let hatchRes = common.ops.hatch(user, req);
+ const { user } = res.locals;
+ const hatchRes = common.ops.hatch(user, req);
await user.save();
@@ -791,7 +805,8 @@ api.hatch = {
* @apiName UserEquip
* @apiGroup User
*
- * @apiParam (Path) {String="mount","pet","costume","equipped"} type The type of item to equip or unequip
+ * @apiParam (Path) {String="mount","pet","costume","equipped"} type The type of item
+ * to equip or unequip.
* @apiParam (Path) {String} key The item to equip or unequip
*
* @apiParamExample {URL} Example-URL
@@ -807,7 +822,8 @@ api.hatch = {
* "message": "Training Sword unequipped."
* }
*
- * @apiError {NotFound} notOwned Item is not in inventory, item doesn't exist, or item is of the wrong type.
+ * @apiError {NotFound} notOwned Item is not in inventory, item doesn't
+ * exist, or item is of the wrong type.
*
* @apiErrorExample {json} Item not owned or doesn't exist.
* {"success":false,"error":"NotFound","message":"You do not own this item."}
@@ -820,8 +836,8 @@ api.equip = {
middlewares: [authWithHeaders()],
url: '/user/equip/:type/:key',
async handler (req, res) {
- let user = res.locals.user;
- let equipRes = common.ops.equip(user, req);
+ const { user } = res.locals;
+ const equipRes = common.ops.equip(user, req);
await user.save();
res.respond(200, ...equipRes);
},
@@ -842,11 +858,13 @@ api.equip = {
* @apiSuccess {String} message Success message
*
* @apiSuccessExample {json}
- * {"success":true,"data":10,"message":"Shade Armadillo really likes the Chocolate!","notifications":[]}
+ * {"success":true,"data":10,"message":"Shade Armadillo
+ * really likes the Chocolate!","notifications":[]}
*
* @apiError {NotFound} PetNotOwned :pet not found in user.items.pets
* @apiError {BedRequest} InvalidPet Invalid pet name supplied.
- * @apiError {NotFound} FoodNotOwned :food not found in user.items.food Note: also sent if food name is invalid.
+ * @apiError {NotFound} FoodNotOwned :food not found in user.items.food
+ * Note: also sent if food name is invalid.
*
*
*/
@@ -855,8 +873,8 @@ api.feed = {
middlewares: [authWithHeaders()],
url: '/user/feed/:pet/:food',
async handler (req, res) {
- let user = res.locals.user;
- let feedRes = common.ops.feed(user, req);
+ const { user } = res.locals;
+ const feedRes = common.ops.feed(user, req);
await user.save();
@@ -877,7 +895,10 @@ api.feed = {
/**
* @api {post} /api/v3/user/change-class Change class
- * @apiDescription User must be at least level 10. If ?class is defined and user.flags.classSelected is false it'll change the class. If user.preferences.disableClasses it'll enable classes, otherwise it sets user.flags.classSelected to false (costs 3 gems)
+ * @apiDescription User must be at least level 10. If ?class is
+ * defined and user.flags.classSelected is false it'll change the class.
+ * If user.preferences.disableClasses it'll enable classes, otherwise it
+ * sets user.flags.classSelected to false (costs 3 gems).
* @apiName UserChangeClass
* @apiGroup User
*
@@ -888,7 +909,8 @@ api.feed = {
* @apiSuccess {Object} data.preferences user.preferences
* @apiSuccess {Object} data.items user.items
*
- * @apiError {NotAuthorized} Gems Not enough gems, if class was already selected and gems needed to be paid.
+ * @apiError {NotAuthorized} Gems Not enough gems, if class was already
+ * selected and gems needed to be paid.
* @apiError {NotAuthorized} Level To change class you must be at least level 10.
*
* @apiErrorExample {json}
@@ -899,8 +921,8 @@ api.changeClass = {
middlewares: [authWithHeaders()],
url: '/user/change-class',
async handler (req, res) {
- let user = res.locals.user;
- let changeClassRes = common.ops.changeClass(user, req, res.analytics);
+ const { user } = res.locals;
+ const changeClassRes = common.ops.changeClass(user, req, res.analytics);
await user.save();
res.respond(200, ...changeClassRes);
},
@@ -920,8 +942,8 @@ api.disableClasses = {
middlewares: [authWithHeaders()],
url: '/user/disable-classes',
async handler (req, res) {
- let user = res.locals.user;
- let disableClassesRes = common.ops.disableClasses(user, req);
+ const { user } = res.locals;
+ const disableClassesRes = common.ops.disableClasses(user, req);
await user.save();
res.respond(200, ...disableClassesRes);
},
@@ -932,27 +954,30 @@ api.disableClasses = {
* @apiName UserPurchase
* @apiGroup User
*
- * @apiParam (Path) {String="gems","eggs","hatchingPotions","premiumHatchingPotions",food","quests","gear"} type Type of item to purchase.
+ * @apiParam (Path) {String="gems","eggs","hatchingPotions","premiumHatchingPotions"
+ ,food","quests","gear"} type Type of item to purchase.
* @apiParam (Path) {String} key Item's key (use "gem" for purchasing gems)
*
* @apiSuccess {Object} data.items user.items
* @apiSuccess {Number} data.balance user.balance
* @apiSuccess {String} message Success message
*
- * @apiError {NotAuthorized} NotAvailable Item is not available to be purchased (not unlocked for the user).
+ * @apiError {NotAuthorized} NotAvailable Item is not available to be purchased
+ * (not unlocked for the user).
* @apiError {NotAuthorized} Gems Not enough gems
* @apiError {NotFound} Key Key not found for Content type.
* @apiError {NotFound} Type Type invalid.
*
* @apiErrorExample {json}
- * {"success":false,"error":"NotAuthorized","message":"This item is not currently available for purchase."}
+ * {"success":false,"error":"NotAuthorized","message":
+ * "This item is not currently available for purchase."}
*/
api.purchase = {
method: 'POST',
middlewares: [authWithHeaders()],
url: '/user/purchase/:type/:key',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
const type = get(req.params, 'type');
const key = get(req.params, 'key');
@@ -969,7 +994,7 @@ api.purchase = {
if (req.body.quantity) quantity = req.body.quantity;
req.quantity = quantity;
- let purchaseRes = common.ops.buy(user, req, res.analytics);
+ const purchaseRes = common.ops.buy(user, req, res.analytics);
await user.save();
res.respond(200, ...purchaseRes);
},
@@ -983,7 +1008,9 @@ api.purchase = {
* @apiParam (Path) {String="pets","mounts"} type The type of item to purchase
* @apiParam (Path) {String} key Ex: {Phoenix-Base}. The key for the mount/pet
*
- * @apiParam (Body) {Integer} [quantity=1] Count of items to buy. Defaults to 1 and is ignored for items where quantity is irrelevant.
+ * @apiParam (Body) {Integer} [quantity=1] Count of items to buy.
+ * Defaults to 1 and is ignored
+ * for items where quantity is irrelevant.
*
* @apiSuccess {Object} data.items user.items
* @apiSuccess {Object} data.purchasedPlanConsecutive user.purchased.plan.consecutive
@@ -1002,10 +1029,15 @@ api.userPurchaseHourglass = {
middlewares: [authWithHeaders()],
url: '/user/purchase-hourglass/:type/:key',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
const quantity = req.body.quantity || 1;
if (quantity < 1 || !Number.isInteger(quantity)) throw new BadRequest(res.t('invalidQuantity'), req.language);
- let purchaseHourglassRes = common.ops.buy(user, req, res.analytics, {quantity, hourglass: true});
+ const purchaseHourglassRes = common.ops.buy(
+ user,
+ req,
+ res.analytics,
+ { quantity, hourglass: true },
+ );
await user.save();
res.respond(200, ...purchaseHourglassRes);
},
@@ -1016,7 +1048,8 @@ api.userPurchaseHourglass = {
* @apiName UserReadCard
* @apiGroup User
*
- * @apiParam (Path) {String} cardType Type of card to read (e.g. - birthday, greeting, nye, thankyou, valentine)
+ * @apiParam (Path) {String} cardType Type of card to read (e.g. - birthday,
+ * greeting, nye, thankyou, valentine).
*
* @apiSuccess {Object} data.specialItems user.items.special
* @apiSuccess {Boolean} data.cardReceived user.flags.cardReceived
@@ -1056,8 +1089,8 @@ api.readCard = {
middlewares: [authWithHeaders()],
url: '/user/read-card/:cardType',
async handler (req, res) {
- let user = res.locals.user;
- let readCardRes = common.ops.readCard(user, req);
+ const { user } = res.locals;
+ const readCardRes = common.ops.readCard(user, req);
await user.save();
res.respond(200, ...readCardRes);
},
@@ -1098,8 +1131,8 @@ api.userOpenMysteryItem = {
middlewares: [authWithHeaders()],
url: '/user/open-mystery-item',
async handler (req, res) {
- let user = res.locals.user;
- let openMysteryItemRes = common.ops.openMysteryItem(user, req, res.analytics);
+ const { user } = res.locals;
+ const openMysteryItemRes = common.ops.openMysteryItem(user, req, res.analytics);
await user.save();
res.respond(200, ...openMysteryItemRes);
},
@@ -1130,8 +1163,8 @@ api.userReleasePets = {
middlewares: [authWithHeaders()],
url: '/user/release-pets',
async handler (req, res) {
- let user = res.locals.user;
- let releasePetsRes = common.ops.releasePets(user, req, res.analytics);
+ const { user } = res.locals;
+ const releasePetsRes = common.ops.releasePets(user, req, res.analytics);
await user.save();
res.respond(200, ...releasePetsRes);
},
@@ -1179,8 +1212,8 @@ api.userReleaseBoth = {
middlewares: [authWithHeaders()],
url: '/user/release-both',
async handler (req, res) {
- let user = res.locals.user;
- let releaseBothRes = common.ops.releaseBoth(user, req, res.analytics);
+ const { user } = res.locals;
+ const releaseBothRes = common.ops.releaseBoth(user, req, res.analytics);
await user.save();
res.respond(200, ...releaseBothRes);
},
@@ -1215,8 +1248,8 @@ api.userReleaseMounts = {
middlewares: [authWithHeaders()],
url: '/user/release-mounts',
async handler (req, res) {
- let user = res.locals.user;
- let releaseMountsRes = common.ops.releaseMounts(user, req, res.analytics);
+ const { user } = res.locals;
+ const releaseMountsRes = common.ops.releaseMounts(user, req, res.analytics);
await user.save();
res.respond(200, ...releaseMountsRes);
},
@@ -1234,19 +1267,22 @@ api.userReleaseMounts = {
* @apiSuccess {Object} data.stats
* @apiSuccess {Object} data.items
*
- * @apiError {NotFound} InvalidKey Key not found for user.items eggs (either the key does not exist or the user has none in inventory)
+ * @apiError {NotFound} InvalidKey Key not found for user.items eggs
+ * (either the key does not exist or the
+ * user has none in inventory).
* @apiError {NotAuthorized} InvalidType Type is not a valid type.
*
* @apiErrorExample {json}
- * {"success":false,"error":"NotAuthorized","message":"Type is not sellable. Must be one of the following eggs, hatchingPotions, food"}
+ * {"success":false,"error":"NotAuthorized","message":"Type is not sellable.
+ * Must be one of the following eggs, hatchingPotions, food"}
*/
api.userSell = {
method: 'POST',
middlewares: [authWithHeaders()],
url: '/user/sell/:type/:key',
async handler (req, res) {
- let user = res.locals.user;
- let sellRes = common.ops.sell(user, req);
+ const { user } = res.locals;
+ const sellRes = common.ops.sell(user, req);
await user.save();
res.respond(200, ...sellRes);
},
@@ -1288,8 +1324,8 @@ api.userUnlock = {
middlewares: [authWithHeaders()],
url: '/user/unlock',
async handler (req, res) {
- let user = res.locals.user;
- let unlockRes = common.ops.unlock(user, req, res.analytics);
+ const { user } = res.locals;
+ const unlockRes = common.ops.unlock(user, req, res.analytics);
await user.save();
res.respond(200, ...unlockRes);
},
@@ -1314,8 +1350,8 @@ api.userRevive = {
middlewares: [authWithHeaders()],
url: '/user/revive',
async handler (req, res) {
- let user = res.locals.user;
- let reviveRes = common.ops.revive(user, req, res.analytics);
+ const { user } = res.locals;
+ const reviveRes = common.ops.revive(user, req, res.analytics);
await user.save();
res.respond(200, ...reviveRes);
},
@@ -1380,8 +1416,8 @@ api.blockUser = {
middlewares: [authWithHeaders()],
url: '/user/block/:uuid',
async handler (req, res) {
- let user = res.locals.user;
- let blockUserRes = common.ops.blockUser(user, req);
+ const { user } = res.locals;
+ const blockUserRes = common.ops.blockUser(user, req);
await user.save();
res.respond(200, ...blockUserRes);
},
@@ -1422,11 +1458,11 @@ api.deleteMessage = {
middlewares: [authWithHeaders()],
url: '/user/messages/:id',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
await inboxLib.deleteMessage(user, req.params.id);
- res.respond(200, ...[await inboxLib.getUserInbox(user, {asArray: false})]);
+ res.respond(200, ...[await inboxLib.getUserInbox(user, { asArray: false })]);
},
};
@@ -1447,7 +1483,7 @@ api.clearMessages = {
middlewares: [authWithHeaders()],
url: '/user/messages',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
await inboxLib.clearPMs(user);
@@ -1471,8 +1507,8 @@ api.markPmsRead = {
middlewares: [authWithHeaders()],
url: '/user/mark-pms-read',
async handler (req, res) {
- let user = res.locals.user;
- let markPmsResponse = common.ops.markPmsRead(user);
+ const { user } = res.locals;
+ const markPmsResponse = common.ops.markPmsRead(user);
await user.save();
res.respond(200, markPmsResponse);
},
@@ -1544,12 +1580,14 @@ api.userReset = {
};
/**
- * @api {post} /api/v3/user/custom-day-start Set preferences.dayStart (Custom Day Start time) for user
+ * @api {post} /api/v3/user/custom-day-start Set preferences.dayStart
+ * (Custom Day Start time) for user.
* @apiName setCustomDayStart
* @apiGroup User
*
*
- * @apiParam (Body) {number} [dayStart=0] The hour number 0-23 for day to begin. If body is not included, will default to 0.
+ * @apiParam (Body) {number} [dayStart=0] The hour number 0-23 for day to begin.
+ * If body is not included, will default to 0.
*
* @apiParamExample {json} Request-Example:
* {"dayStart":2}
@@ -1563,15 +1601,17 @@ api.userReset = {
* @apiError {BadRequest} Validation Value provided is not a number, or is outside the range of 0-23
*
* @apiErrorExample {json}
- * {"success":false,"error":"BadRequest","message":"User validation failed","errors":[{"message":"Path `preferences.dayStart` (25) is more than maximum allowed value (23).","path":"preferences.dayStart","value":25}]}
+ * {"success":false,"error":"BadRequest","message":"User validation failed",
+ * "errors":[{"message":"Path `preferences.dayStart` (25) is more than maximum allowed value (23)."
+ * ,"path":"preferences.dayStart","value":25}]}
*/
api.setCustomDayStart = {
method: 'POST',
middlewares: [authWithHeaders()],
url: '/user/custom-day-start',
async handler (req, res) {
- let user = res.locals.user;
- let dayStart = req.body.dayStart;
+ const { user } = res.locals;
+ const { dayStart } = req.body;
user.preferences.dayStart = dayStart;
user.lastCron = new Date();
@@ -1608,15 +1648,15 @@ api.togglePinnedItem = {
middlewares: [authWithHeaders()],
url: '/user/toggle-pinned-item/:type/:path',
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
const path = get(req.params, 'path');
const type = get(req.params, 'type');
- common.ops.pinnedGearUtils.togglePinnedItem(user, {type, path}, req);
+ common.ops.pinnedGearUtils.togglePinnedItem(user, { type, path }, req);
await user.save();
- let userJson = user.toJSON();
+ const userJson = user.toJSON();
res.respond(200, {
pinnedItems: userJson.pinnedItems,
@@ -1626,17 +1666,21 @@ api.togglePinnedItem = {
};
/**
- * @api {post} /api/v3/user/move-pinned-item/:type/:path/move/to/:position Move a pinned item in the rewards column to a new position after being sorted
+ * @api {post} /api/v3/user/move-pinned-item/:type/:path/move/to/:position Move a pinned
+ * item in the rewards column to a new position after being sorted
* @apiName MovePinnedItem
* @apiGroup User
*
* @apiParam (Path) {String} path The unique item path used for pinning
- * @apiParam (Path) {Number} position Where to move the task. 0 = top of the list. -1 = bottom of the list. (-1 means push to bottom). First position is 0
+ * @apiParam (Path) {Number} position Where to move the task. 0 = top of the list.
+ * -1 = bottom of the list.
+ * (-1 means push to bottom). First position is 0.
*
* @apiSuccess {Array} data The new pinned items order.
*
* @apiSuccessExample {json}
- * {"success":true,"data":{"path":"quests.mayhemMistiflying3","type":"quests","_id": "5a32d357232feb3bc94c2bdf"},"notifications":[]}
+ * {"success":true,"data":{"path":"quests.mayhemMistiflying3","type":"quests",
+ * "_id": "5a32d357232feb3bc94c2bdf"},"notifications":[]}
*
* @apiUse TaskNotFound
*/
@@ -1648,28 +1692,28 @@ api.movePinnedItem = {
req.checkParams('path', res.t('taskIdRequired')).notEmpty();
req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let user = res.locals.user;
- let path = req.params.path;
- let position = Number(req.params.position);
+ const { user } = res.locals;
+ const { path } = req.params;
+ const position = Number(req.params.position);
// If something has been added or removed from the inAppRewards, we need
// to reset pinnedItemsOrder to have the correct length. Since inAppRewards
// Uses the current pinnedItemsOrder to return these in the right order,
// the new reset array will be in the right order before we do the swap
- let currentPinnedItems = common.inAppRewards(user);
+ const currentPinnedItems = common.inAppRewards(user);
if (user.pinnedItemsOrder.length !== currentPinnedItems.length) {
user.pinnedItemsOrder = currentPinnedItems.map(item => item.path);
}
// Adjust the order
- let currentIndex = user.pinnedItemsOrder.findIndex(item => item === path);
- let currentPinnedItemPath = user.pinnedItemsOrder[currentIndex];
+ const currentIndex = user.pinnedItemsOrder.findIndex(item => item === path);
+ const currentPinnedItemPath = user.pinnedItemsOrder[currentIndex];
if (currentIndex === -1) {
- throw new BadRequest(res.t('wrongItemPath', {path}, req.language));
+ throw new BadRequest(res.t('wrongItemPath', { path }, req.language));
}
// Remove the one we will move
@@ -1683,10 +1727,10 @@ api.movePinnedItem = {
}
await user.save();
- let userJson = user.toJSON();
+ const userJson = user.toJSON();
res.respond(200, userJson.pinnedItemsOrder);
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/user/spells.js b/website/server/controllers/api-v3/user/spells.js
index 8740458427..736fdc114f 100644
--- a/website/server/controllers/api-v3/user/spells.js
+++ b/website/server/controllers/api-v3/user/spells.js
@@ -3,7 +3,7 @@ import {
castSpell,
} from '../../../libs/spells';
-let api = {};
+const api = {};
/* NOTE this route has also an API v4 version */
@@ -13,8 +13,12 @@ let api = {};
* @apiGroup User
*
- * @apiParam (Path) {String=fireball, mpheal, earth, frost, smash, defensiveStance, valorousPresence, intimidate, pickPocket, backStab, toolsOfTrade, stealth, heal, protectAura, brightness, healAll} spellId The skill to cast.
- * @apiParam (Query) {UUID} targetId Query parameter, necessary if the spell is cast on a party member or task. Not used if the spell is case on the user or the user's current party.
+ * @apiParam (Path) {String=fireball, mpheal, earth, frost, smash, defensiveStance,
+ * valorousPresence, intimidate, pickPocket, backStab, toolsOfTrade,
+ * stealth, heal, protectAura, brightness, healAll} spellId The skill to cast.
+ * @apiParam (Query) {UUID} targetId Query parameter, necessary if the spell is
+ * cast on a party member or task. Not used if the spell
+ * is casted on the user or the user's current party.
* @apiParamExample {json} Query example:
* Cast "Pickpocket" on a task:
* https://habitica.com/api/v3/user/class/cast/pickPocket?targetId=fd427623...
@@ -22,7 +26,8 @@ let api = {};
* Cast "Tools of the Trade" on the party:
* https://habitica.com/api/v3/user/class/cast/toolsOfTrade
*
- * @apiSuccess data Will return the modified targets. For party members only the necessary fields will be populated. The user is always returned.
+ * @apiSuccess data Will return the modified targets. For party members only
+ * the necessary fields will be populated. The user is always returned.
*
* @apiDescription Skill Key to Name Mapping
* Mage
@@ -65,4 +70,4 @@ api.castSpell = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/user/stats.js b/website/server/controllers/api-v3/user/stats.js
index c3d3ed74e1..01a0eccacf 100644
--- a/website/server/controllers/api-v3/user/stats.js
+++ b/website/server/controllers/api-v3/user/stats.js
@@ -2,10 +2,11 @@
import common from '../../../../common';
import { authWithHeaders } from '../../../middlewares/auth';
-let api = {};
+const api = {};
/**
- * @api {post} /api/v3/user/allocate Allocate a single Stat Point (previously called Attribute Point)
+ * @api {post} /api/v3/user/allocate Allocate a single Stat Point
+ * (previously called Attribute Point)
* @apiName UserAllocate
* @apiGroup User
*
@@ -30,8 +31,8 @@ api.allocate = {
middlewares: [authWithHeaders()],
url: '/user/allocate',
async handler (req, res) {
- let user = res.locals.user;
- let allocateRes = common.ops.allocate(user, req);
+ const { user } = res.locals;
+ const allocateRes = common.ops.allocate(user, req);
await user.save();
res.respond(200, ...allocateRes);
},
@@ -70,8 +71,8 @@ api.allocateBulk = {
middlewares: [authWithHeaders()],
url: '/user/allocate-bulk',
async handler (req, res) {
- let user = res.locals.user;
- let allocateRes = common.ops.allocateBulk(user, req);
+ const { user } = res.locals;
+ const allocateRes = common.ops.allocateBulk(user, req);
await user.save();
res.respond(200, ...allocateRes);
},
@@ -79,7 +80,9 @@ api.allocateBulk = {
/**
* @api {post} /api/v3/user/allocate-now Allocate all Stat Points
- * @apiDescription Uses the user's chosen automatic allocation method, or if none, assigns all to STR. Note: will return success, even if there are 0 points to allocate.
+ * @apiDescription Uses the user's chosen automatic allocation method,
+ * or if none, assigns all to STR. Note: will return success,
+ * even if there are 0 points to allocate.
* @apiName UserAllocateNow
* @apiGroup User
*
@@ -127,11 +130,11 @@ api.allocateNow = {
middlewares: [authWithHeaders()],
url: '/user/allocate-now',
async handler (req, res) {
- let user = res.locals.user;
- let allocateNowRes = common.ops.allocateNow(user);
+ const { user } = res.locals;
+ const allocateNowRes = common.ops.allocateNow(user);
await user.save();
res.respond(200, ...allocateNowRes);
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/webhook.js b/website/server/controllers/api-v3/webhook.js
index 1ab37bf6a3..e85730a792 100644
--- a/website/server/controllers/api-v3/webhook.js
+++ b/website/server/controllers/api-v3/webhook.js
@@ -3,13 +3,15 @@ import { model as Webhook } from '../../models/webhook';
import { removeFromArray } from '../../libs/collectionManipulators';
import { NotFound, BadRequest } from '../../libs/errors';
-let api = {};
+const api = {};
/**
* @apiDefine Webhook Webhook
- * Webhooks fire when a particular action is performed, such as updating a task, or sending a message in a group.
+ * Webhooks fire when a particular action is performed, such as updating a task,
+ * or sending a message in a group.
*
- * Your user's configured webhooks are stored as an `Array` on the user object under the `webhooks` property.
+ * Your user's configured webhooks are stored as an `Array` on the user
+ * object under the `webhooks` property.
*/
/**
@@ -19,7 +21,8 @@ let api = {};
/**
* @apiDefine WebhookBodyInvalid
- * @apiError (400) {BadRequest} WebhookBodyInvalid A body parameter passed in the request did not pass validation.
+ * @apiError (400) {BadRequest} WebhookBodyInvalid A body parameter passed in the
+ * request did not pass validation.
*/
/**
@@ -31,8 +34,12 @@ let api = {};
* @apiParam (Body) {String} url The webhook's URL
* @apiParam (Body) {String} [label] A label to remind you what this webhook does
* @apiParam (Body) {Boolean} [enabled=true] If the webhook should be enabled
- * @apiParam (Body) {String="taskActivity","groupChatReceived","userActivity"} [type="taskActivity"] The webhook's type.
- * @apiParam (Body) {Object} [options] The webhook's options. Wil differ depending on type. Required for `groupChatReceived` type. If a webhook supports options, the default values are displayed in the examples below
+ * @apiParam (Body) {String="taskActivity","groupChatReceived",
+ "userActivity"} [type="taskActivity"] The webhook's type.
+ * @apiParam (Body) {Object} [options] The webhook's options. Wil differ depending on type.
+ * Required for `groupChatReceived` type.
+ * If a webhook supports options, the default values
+ * are displayed in the examples below
* @apiParamExample {json} Task Activity Example
* {
* "enabled": true, // default
@@ -76,10 +83,10 @@ api.addWebhook = {
middlewares: [authWithHeaders()],
url: '/user/webhook',
async handler (req, res) {
- let user = res.locals.user;
- let webhook = new Webhook(req.body);
+ const { user } = res.locals;
+ const webhook = new Webhook(req.body);
- let existingWebhook = user.webhooks.find(hook => hook.id === webhook.id);
+ const existingWebhook = user.webhooks.find(hook => hook.id === webhook.id);
if (existingWebhook) {
throw new BadRequest(res.t('webhookIdAlreadyTaken', { id: webhook.id }));
@@ -107,7 +114,7 @@ api.getWebhook = {
middlewares: [authWithHeaders()],
url: '/user/webhook',
async handler (req, res) {
- const user = res.locals.user;
+ const { user } = res.locals;
res.respond(200, user.webhooks);
},
@@ -117,14 +124,17 @@ api.getWebhook = {
* @api {put} /api/v3/user/webhook/:id Edit a webhook - BETA
* @apiName UserUpdateWebhook
* @apiGroup Webhook
- * @apiDescription Can change `url`, `enabled`, `type`, and `options` properties. Cannot change `id`.
+ * @apiDescription Can change `url`, `enabled`, `type`, and `options`
+ * properties. Cannot change `id`.
*
* @apiParam (Path) {UUID} id URL parameter - The id of the webhook to update
* @apiParam (Body) {String} [url] The webhook's URL
* @apiParam (Body) {String} [label] A label to remind you what this webhook does
* @apiParam (Body) {Boolean} [enabled] If the webhook should be enabled
* @apiParam (Body) {String="taskActivity","groupChatReceived"} [type] The webhook's type.
- * @apiParam (Body) {Object} [options] The webhook's options. Wil differ depending on type. The options are enumerated in the [add webhook examples](#api-Webhook-UserAddWebhook).
+ * @apiParam (Body) {Object} [options] The webhook's options. Wil differ depending on type.
+ * The options are enumerated in the
+ * [add webhook examples](#api-Webhook-UserAddWebhook).
* @apiParamExample {json} Update Enabled and Type Properties
* {
* "enabled": false,
@@ -154,13 +164,15 @@ api.updateWebhook = {
middlewares: [authWithHeaders()],
url: '/user/webhook/:id',
async handler (req, res) {
- let user = res.locals.user;
- let id = req.params.id;
- let webhook = user.webhooks.find(hook => hook.id === id);
- let { url, label, type, enabled, options } = req.body;
+ const { user } = res.locals;
+ const { id } = req.params;
+ const webhook = user.webhooks.find(hook => hook.id === id);
+ const {
+ url, label, type, enabled, options,
+ } = req.body;
if (!webhook) {
- throw new NotFound(res.t('noWebhookWithId', {id}));
+ throw new NotFound(res.t('noWebhookWithId', { id }));
}
if (url) {
@@ -205,13 +217,13 @@ api.deleteWebhook = {
middlewares: [authWithHeaders()],
url: '/user/webhook/:id',
async handler (req, res) {
- let user = res.locals.user;
- let id = req.params.id;
+ const { user } = res.locals;
+ const { id } = req.params;
- let webhook = user.webhooks.find(hook => hook.id === id);
+ const webhook = user.webhooks.find(hook => hook.id === id);
if (!webhook) {
- throw new NotFound(res.t('noWebhookWithId', {id}));
+ throw new NotFound(res.t('noWebhookWithId', { id }));
}
removeFromArray(user.webhooks, webhook);
@@ -222,4 +234,4 @@ api.deleteWebhook = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v3/world.js b/website/server/controllers/api-v3/world.js
index 1bc7a6ff5c..4015e54ae4 100644
--- a/website/server/controllers/api-v3/world.js
+++ b/website/server/controllers/api-v3/world.js
@@ -3,10 +3,10 @@ import {
TAVERN_ID as tavernId,
} from '../../models/group';
-let api = {};
+const api = {};
async function getWorldBoss () {
- let tavern = await Group
+ const tavern = await Group
.findById(tavernId)
.select('quest.progress quest.key quest.active quest.extra')
.exec();
@@ -23,7 +23,9 @@ async function getWorldBoss () {
* @apiGroup WorldState
*
* @apiSuccess {Object} data.worldBoss.active Boolean, true if world boss quest is underway
- * @apiSuccess {Object} data.worldBoss.extra.worldDmg Object with NPC names as Boolean properties, true if they are affected by Rage Strike
+ * @apiSuccess {Object} data.worldBoss.extra.worldDmg Object with NPC names
+ * as Boolean properties, true if they
+ * are affected by Rage Strike.
* @apiSuccess {Object} data.worldBoss.key String, Quest content key for the world boss
* @apiSuccess {Object} data.worldBoss.progress.hp Number, Current Health of the world boss
* @apiSuccess {Object} data.worldBoss.progress.rage Number, Current Rage of the world boss
@@ -34,7 +36,7 @@ api.getWorldState = {
method: 'GET',
url: '/world-state',
async handler (req, res) {
- let worldState = {};
+ const worldState = {};
worldState.worldBoss = await getWorldBoss();
worldState.npcImageSuffix = 'spring';
@@ -43,4 +45,4 @@ api.getWorldState = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v4/auth.js b/website/server/controllers/api-v4/auth.js
index 05f8b6dd9b..7ff213183c 100644
--- a/website/server/controllers/api-v4/auth.js
+++ b/website/server/controllers/api-v4/auth.js
@@ -3,7 +3,7 @@ import {
} from '../../middlewares/auth';
import * as authLib from '../../libs/auth';
import { model as User } from '../../models/user';
-import {verifyUsername} from '../../libs/user/validation';
+import { verifyUsername } from '../../libs/user/validation';
const api = {};
@@ -16,14 +16,14 @@ api.verifyUsername = {
async handler (req, res) {
req.checkBody({
username: {
- notEmpty: {errorMessage: res.t('missingUsername')},
+ notEmpty: { errorMessage: res.t('missingUsername') },
},
});
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const user = res.locals.user;
+ const { user } = res.locals;
const chosenUsername = req.body.username;
const issues = verifyUsername(chosenUsername, res);
@@ -31,10 +31,10 @@ api.verifyUsername = {
if (issues.length < 1) {
const existingUser = await User.findOne({
'auth.local.lowerCaseUsername': chosenUsername.toLowerCase(),
- }, {auth: 1}).exec();
+ }, { auth: 1 }).exec();
if (existingUser) {
- if (!user || existingUser._id !== user._id) issues.push(res.t('usernameTaken'));
+ if (!user || existingUser._id !== user._id) issues.push(res.t('usernameTaken'));
}
}
@@ -56,16 +56,20 @@ api.verifyUsername = {
/**
* @api {post} /api/v4/user/auth/local/register Register
- * @apiDescription Register a new user with email, login name, and password or attach local auth to a social user
+ * @apiDescription Register a new user with email, login name, and password
+ * or attach local auth to a social user
* @apiName UserRegisterLocal
* @apiGroup User
*
- * @apiParam (Body) {String} username Login name of the new user. Must be 1-36 characters, containing only a-z, 0-9, hyphens (-), or underscores (_).
+ * @apiParam (Body) {String} username Login name of the new user.
+ * Must be 1-36 characters, containing only
+ * a-z, 0-9, hyphens (-), or underscores (_).
* @apiParam (Body) {String} email Email address of the new user
* @apiParam (Body) {String} password Password for the new user
* @apiParam (Body) {String} confirmPassword Password confirmation
*
- * @apiSuccess {Object} data The user object, if local auth was just attached to a social user then only user.auth.local
+ * @apiSuccess {Object} data The user object, if local auth was just
+ * attached to a social user then only user.auth.local
*/
api.registerLocal = {
method: 'POST',
@@ -78,4 +82,4 @@ api.registerLocal = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v4/coupon.js b/website/server/controllers/api-v4/coupon.js
index dde0f8c8d0..819c0f407c 100644
--- a/website/server/controllers/api-v4/coupon.js
+++ b/website/server/controllers/api-v4/coupon.js
@@ -25,10 +25,10 @@ api.enterCouponCode = {
url: '/coupons/enter/:code',
middlewares: [authWithHeaders()],
async handler (req, res) {
- const user = res.locals.user;
+ const { user } = res.locals;
await couponsLib.enterCode(req, res, user);
res.respond(200, user);
},
};
-module.exports = api;
\ No newline at end of file
+export default api;
diff --git a/website/server/controllers/api-v4/inbox.js b/website/server/controllers/api-v4/inbox.js
index d37eb62e35..e6c9927c2a 100644
--- a/website/server/controllers/api-v4/inbox.js
+++ b/website/server/controllers/api-v4/inbox.js
@@ -37,8 +37,8 @@ api.deleteMessage = {
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- const messageId = req.params.messageId;
- const user = res.locals.user;
+ const { messageId } = req.params;
+ const { user } = res.locals;
const deleted = await inboxLib.deleteMessage(user, messageId);
if (!deleted) throw new NotFound(res.t('messageGroupChatNotFound'));
@@ -64,7 +64,7 @@ api.clearMessages = {
middlewares: [authWithHeaders()],
url: '/inbox/clear',
async handler (req, res) {
- const user = res.locals.user;
+ const { user } = res.locals;
await inboxLib.clearPMs(user);
@@ -99,7 +99,7 @@ api.conversations = {
middlewares: [authWithHeaders()],
url: '/inbox/conversations',
async handler (req, res) {
- const user = res.locals.user;
+ const { user } = res.locals;
const result = await inboxLib.listConversations(user);
@@ -111,7 +111,8 @@ api.conversations = {
* @api {get} /api/v4/inbox/paged-messages Get inbox messages for a user
* @apiName GetInboxMessages
* @apiGroup Inbox
- * @apiDescription Get inbox messages for a user. Entries already populated with the correct `sent` - information
+ * @apiDescription Get inbox messages for a user.
+ * Entries already populated with the correct `sent` - information
*
* @apiParam (Query) {Number} page Load the messages of the selected Page - 10 Messages per Page
* @apiParam (Query) {GUID} conversation Loads only the messages of a conversation
@@ -123,9 +124,9 @@ api.getInboxMessages = {
url: '/inbox/paged-messages',
middlewares: [authWithHeaders()],
async handler (req, res) {
- const user = res.locals.user;
- const page = req.query.page;
- const conversation = req.query.conversation;
+ const { user } = res.locals;
+ const { page } = req.query;
+ const { conversation } = req.query;
const userInbox = await inboxLib.getUserInbox(user, {
page, conversation, mapProps: true,
@@ -135,4 +136,4 @@ api.getInboxMessages = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v4/members.js b/website/server/controllers/api-v4/members.js
index 57a1b39ddd..bd31d6a0b4 100644
--- a/website/server/controllers/api-v4/members.js
+++ b/website/server/controllers/api-v4/members.js
@@ -1,11 +1,12 @@
import { authWithHeaders } from '../../middlewares/auth';
import { chatReporterFactory } from '../../libs/chatReporting/chatReporterFactory';
-let api = {};
+const api = {};
/**
* @api {post} /api/v4/members/flag-private-message/:messageId Flag a private message
- * @apiDescription An email and slack message are sent to the moderators about every flagged message.
+ * @apiDescription An email and slack message are sent
+ * to the moderators about every flagged message.
* @apiName FlagPrivateMessage
* @apiGroup Member
*
@@ -18,13 +19,17 @@ let api = {};
* @apiSuccess {Object} data.likes The likes of the message (always an empty object)
* @apiSuccess {Object} data.flags The flags of the message
* @apiSuccess {Number} data.flagCount The number of flags the message has
- * @apiSuccess {UUID} data.uuid The User ID of the author of the message, or of the recipient if `sent` is true
- * @apiSuccess {String} data.user The Display Name of the author of the message, or of the recipient if `sent` is true
- * @apiSuccess {String} data.username The Username of the author of the message, or of the recipient if `sent` is true
+ * @apiSuccess {UUID} data.uuid The User ID of the author of the message,
+ * or of the recipient if `sent` is true
+ * @apiSuccess {String} data.user The Display Name of the author of the message,
+ * or of the recipient if `sent` is true
+ * @apiSuccess {String} data.username The Username of the author of the message,
+ * or of the recipient if `sent` is true
*
* @apiUse MessageNotFound
* @apiUse MessageIdRequired
- * @apiError (400) {BadRequest} messageGroupChatFlagAlreadyReported You have already reported this message
+ * @apiError (400) {BadRequest} messageGroupChatFlagAlreadyReported You have already
+ * reported this message
*/
api.flagPrivateMessage = {
method: 'POST',
@@ -40,4 +45,4 @@ api.flagPrivateMessage = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v4/user.js b/website/server/controllers/api-v4/user.js
index 2474c31dc0..f7acd2d514 100644
--- a/website/server/controllers/api-v4/user.js
+++ b/website/server/controllers/api-v4/user.js
@@ -17,7 +17,8 @@ const api = {};
* @apiName UserGet
* @apiGroup User
*
- * @apiDescription The user profile contains data related to the authenticated user including (but not limited to);
+ * @apiDescription The user profile contains data related to the authenticated user
+ * including (but not limited to);
* Achievements
* Authentications (including types and timestamps)
* Challenges
@@ -38,7 +39,9 @@ const api = {};
* Tags
* TasksOrder (list of all ids for dailys, habits, rewards and todos)
*
- * @apiParam (Query) {String} [userFields] A list of comma separated user fields to be returned instead of the entire document. Notifications are always returned.
+ * @apiParam (Query) {String} [userFields] A list of comma separated user fields
+ * to be returned instead of the entire document.
+ * Notifications are always returned.
*
* @apiExample {curl} Example use:
* curl -i https://habitica.com/api/v3/user?userFields=achievements,items.mounts
@@ -85,7 +88,8 @@ api.getUser = {
*
* @apiSuccess {Object} data The updated user object, the result is identical to the get user call
*
- * @apiError (401) {NotAuthorized} messageUserOperationProtected Returned if the change is not allowed.
+ * @apiError (401) {NotAuthorized} messageUserOperationProtected Returned if the
+ * change is not allowed.
*
* @apiErrorExample {json} Error-Response:
* {
@@ -216,7 +220,7 @@ api.verifyDisplayName = {
async handler (req, res) {
req.checkBody({
displayName: {
- notEmpty: {errorMessage: res.t('messageMissingDisplayName')},
+ notEmpty: { errorMessage: res.t('messageMissingDisplayName') },
},
});
@@ -235,4 +239,4 @@ api.verifyDisplayName = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/api-v4/user/spells.js b/website/server/controllers/api-v4/user/spells.js
index b167a1aa0a..570e2ada81 100644
--- a/website/server/controllers/api-v4/user/spells.js
+++ b/website/server/controllers/api-v4/user/spells.js
@@ -3,7 +3,7 @@ import {
castSpell,
} from '../../../libs/spells';
-let api = {};
+const api = {};
/*
* NOTE most spells routes are still in the v3 controller
@@ -19,8 +19,13 @@ let api = {};
* @apiGroup User
*
- * @apiParam (Path) {String=fireball, mpheal, earth, frost, smash, defensiveStance, valorousPresence, intimidate, pickPocket, backStab, toolsOfTrade, stealth, heal, protectAura, brightness, healAll} spellId The skill to cast.
- * @apiParam (Query) {UUID} targetId Query parameter, necessary if the spell is cast on a party member or task. Not used if the spell is case on the user or the user's current party.
+ * @apiParam (Path) {String=fireball, mpheal, earth, frost, smash,
+ * defensiveStance, valorousPresence, intimidate, pickPocket,
+ * backStab, toolsOfTrade, stealth, heal, protectAura, brightness,
+ * healAll} spellId The skill to cast.
+ * @apiParam (Query) {UUID} targetId Query parameter, necessary if the spell
+ * is cast on a party member or task.
+ * Not used if the spell is case on the user or the user's current party.
* @apiParamExample {json} Query example:
* Cast "Pickpocket" on a task:
* https://habitica.com/api/v3/user/class/cast/pickPocket?targetId=fd427623...
@@ -28,7 +33,9 @@ let api = {};
* Cast "Tools of the Trade" on the party:
* https://habitica.com/api/v3/user/class/cast/toolsOfTrade
*
- * @apiSuccess data Will return the modified targets. For party members only the necessary fields will be populated. The user is always returned.
+ * @apiSuccess data Will return the modified targets.
+ * For party members only the necessary fields will be populated.
+ * The user is always returned.
*
* @apiDescription Skill Key to Name Mapping
* Mage
@@ -71,4 +78,4 @@ api.castSpell = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/top-level/auth.js b/website/server/controllers/top-level/auth.js
index f7fd76fe2b..ae8e08b87f 100644
--- a/website/server/controllers/top-level/auth.js
+++ b/website/server/controllers/top-level/auth.js
@@ -1,6 +1,6 @@
import { validatePasswordResetCodeAndFindUser } from '../../libs/password';
-let api = {};
+const api = {};
// Internal authentication routes
@@ -10,7 +10,7 @@ api.resetPasswordSetNewOne = {
url: '/static/user/auth/local/reset-password-set-new-one',
runCron: false,
async handler (req, res) {
- const code = req.query.code;
+ const { code } = req.query;
const user = await validatePasswordResetCodeAndFindUser(code);
const isValidCode = Boolean(user);
@@ -32,4 +32,4 @@ api.logout = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/top-level/dataexport.js b/website/server/controllers/top-level/dataexport.js
index 39333edead..4aead64047 100644
--- a/website/server/controllers/top-level/dataexport.js
+++ b/website/server/controllers/top-level/dataexport.js
@@ -1,18 +1,18 @@
-import { authWithSession } from '../../middlewares/auth';
-import { model as User } from '../../models/user';
-import * as inboxLib from '../../libs/inbox';
-import * as Tasks from '../../models/task';
-import {
- NotFound,
-} from '../../libs/errors';
import _ from 'lodash';
-import csvStringify from '../../libs/csvStringify';
import moment from 'moment';
import * as js2xml from 'js2xmlparser';
import Pageres from 'pageres';
import nconf from 'nconf';
import got from 'got';
import md from 'habitica-markdown';
+import csvStringify from '../../libs/csvStringify';
+import {
+ NotFound,
+} from '../../libs/errors';
+import * as Tasks from '../../models/task';
+import * as inboxLib from '../../libs/inbox';
+import { model as User } from '../../models/user';
+import { authWithSession } from '../../middlewares/auth';
import {
S3,
} from '../../libs/aws';
@@ -21,13 +21,14 @@ const S3_BUCKET = nconf.get('S3_BUCKET');
const BASE_URL = nconf.get('BASE_URL');
-let api = {};
+const api = {};
/**
* @apiDefine DataExport Data Export
* These routes allow you to download backups of your data.
*
- * **Note:** They are intented to be used on the website only and as such are part of the private API and may change at any time.
+ * **Note:** They are intented to be used on the website only and as such are part
+ * of the private API and may change at any time.
*/
/**
@@ -49,14 +50,14 @@ api.exportUserHistory = {
url: '/export/history.csv',
middlewares: [authWithSession],
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
- let tasks = await Tasks.Task.find({
+ const tasks = await Tasks.Task.find({
userId: user._id,
- type: {$in: ['habit', 'daily']},
+ type: { $in: ['habit', 'daily'] },
}).exec();
- let output = [
+ const output = [
['Task Name', 'Task ID', 'Task Type', 'Date', 'Value'],
];
@@ -77,7 +78,7 @@ api.exportUserHistory = {
'Content-disposition': 'attachment; filename=habitica-tasks-history.csv',
});
- let csvRes = await csvStringify(output);
+ const csvRes = await csvStringify(output);
res.status(200).send(csvRes);
},
};
@@ -85,7 +86,7 @@ api.exportUserHistory = {
// Convert user to json and attach tasks divided by type and inbox messages
// at user.tasks[`${taskType}s`] (user.tasks.{dailys/habits/...})
async function _getUserDataForExport (user, xmlMode = false) {
- let userData = user.toJSON();
+ const userData = user.toJSON();
userData.tasks = {};
userData.inbox.messages = {};
@@ -119,19 +120,15 @@ async function _getUserDataForExport (user, xmlMode = false) {
.value();
// _id gets parsed as an bytearray => which gets casted to a chararray => "weird chars"
- userData.unpinnedItems = userData.unpinnedItems.map(i => {
- return {
- path: i.path,
- type: i.type,
- };
- });
+ userData.unpinnedItems = userData.unpinnedItems.map(i => ({
+ path: i.path,
+ type: i.type,
+ }));
- userData.pinnedItems = userData.pinnedItems.map(i => {
- return {
- path: i.path,
- type: i.type,
- };
- });
+ userData.pinnedItems = userData.pinnedItems.map(i => ({
+ path: i.path,
+ type: i.type,
+ }));
}
return userData;
@@ -149,13 +146,13 @@ api.exportUserDataJson = {
url: '/export/userdata.json',
middlewares: [authWithSession],
async handler (req, res) {
- let userData = await _getUserDataForExport(res.locals.user);
+ const userData = await _getUserDataForExport(res.locals.user);
res.set({
'Content-Type': 'application/json',
'Content-disposition': 'attachment; filename=habitica-user-data.json',
});
- let jsonRes = JSON.stringify(userData);
+ const jsonRes = JSON.stringify(userData);
res.status(200).send(jsonRes);
},
@@ -173,7 +170,7 @@ api.exportUserDataXml = {
url: '/export/userdata.xml',
middlewares: [authWithSession],
async handler (req, res) {
- let userData = await _getUserDataForExport(res.locals.user, true);
+ const userData = await _getUserDataForExport(res.locals.user, true);
res.set({
'Content-Type': 'text/xml',
@@ -207,19 +204,19 @@ api.exportUserAvatarHtml = {
async handler (req, res) {
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let memberId = req.params.memberId;
- let member = await User
+ const { memberId } = req.params;
+ const member = await User
.findById(memberId)
.select('stats profile items achievements preferences backer contributor')
.exec();
- if (!member) throw new NotFound(res.t('userWithIDNotFound', {userId: memberId}));
+ if (!member) throw new NotFound(res.t('userWithIDNotFound', { userId: memberId }));
res.render('avatar-static', {
title: member.profile.name,
- env: _.defaults({user: member}, res.locals.habitrpg),
+ env: _.defaults({ user: member }, res.locals.habitrpg),
});
},
};
@@ -239,13 +236,13 @@ api.exportUserAvatarPng = {
async handler (req, res) {
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let memberId = req.params.memberId;
+ const { memberId } = req.params;
- let filename = `avatars/${memberId}.png`;
- let s3url = `https://${S3_BUCKET}.s3.amazonaws.com/${filename}`;
+ const filename = `avatars/${memberId}.png`;
+ const s3url = `https://${S3_BUCKET}.s3.amazonaws.com/${filename}`;
let response;
try {
@@ -269,17 +266,17 @@ api.exportUserAvatarPng = {
})
.run();
- let s3upload = S3.upload({
+ const s3upload = S3.upload({
Bucket: S3_BUCKET,
Key: filename,
ACL: 'public-read',
StorageClass: 'REDUCED_REDUNDANCY',
ContentType: 'image/png',
- Expires: moment().add({minutes: 5}).toDate(),
+ Expires: moment().add({ minutes: 5 }).toDate(),
Body: pageBuffer,
});
- let s3res = await new Promise((resolve, reject) => {
+ const s3res = await new Promise((resolve, reject) => {
s3upload.send((err, s3uploadRes) => {
if (err) {
reject(err);
@@ -289,7 +286,7 @@ api.exportUserAvatarPng = {
});
});
- res.redirect(s3res.Location);
+ return res.redirect(s3res.Location);
},
};
@@ -305,9 +302,9 @@ api.exportUserPrivateMessages = {
url: '/export/inbox.html',
middlewares: [authWithSession],
async handler (req, res) {
- const user = res.locals.user;
+ const { user } = res.locals;
- const timezoneOffset = user.preferences.timezoneOffset;
+ const { timezoneOffset } = user.preferences;
const dateFormat = user.preferences.dateFormat.toUpperCase();
const TO = res.t('to');
const FROM = res.t('from');
@@ -317,15 +314,15 @@ api.exportUserPrivateMessages = {
let messages = '';
inbox.forEach((message, index) => {
- let recipientLabel = message.sent ? TO : FROM;
- let messageUser = message.user;
- let timestamp = moment.utc(message.timestamp).zone(timezoneOffset).format(`${dateFormat} HH:mm:ss`);
- let text = md.render(message.text);
- index = `(${index + 1}/${inbox.length})`;
+ const recipientLabel = message.sent ? TO : FROM;
+ const messageUser = message.user;
+ const timestamp = moment.utc(message.timestamp).zone(timezoneOffset).format(`${dateFormat} HH:mm:ss`);
+ const text = md.render(message.text);
+ const pageIndex = `(${index + 1}/${inbox.length})`;
messages += `
@@ -343,4 +340,4 @@ api.exportUserPrivateMessages = {
},
};
-module.exports = api;
+export default api;
diff --git a/website/server/controllers/top-level/email.js b/website/server/controllers/top-level/email.js
index c769fe6ccb..1fd0cdcdf4 100644
--- a/website/server/controllers/top-level/email.js
+++ b/website/server/controllers/top-level/email.js
@@ -5,14 +5,15 @@ import {
NotFound,
} from '../../libs/errors';
-let api = {};
+const api = {};
/**
* @api {get} /email/unsubscribe Unsubscribe an email or user from email notifications
* @apiDescription Does not require authentication
* @apiName UnsubscribeEmail
* @apiGroup Unsubscribe
- * @apiDescription This is a GET method included in official emails from Habitica that will unsubscribe the user from emails.
+ * @apiDescription This is a GET method included in official emails from Habitica
+ * that will unsubscribe the user from emails.
*
* @apiParam (Query) {String} code An unsubscription code
*
@@ -27,31 +28,32 @@ api.unsubscribe = {
async handler (req, res) {
req.checkQuery({
code: {
- notEmpty: {errorMessage: res.t('missingUnsubscriptionCode')},
+ notEmpty: { errorMessage: res.t('missingUnsubscriptionCode') },
},
});
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
- let data = JSON.parse(decrypt(req.query.code));
+ const data = JSON.parse(decrypt(req.query.code));
if (data._id) {
- let userUpdated = await User.update(
- {_id: data._id},
- { $set: {'preferences.emailNotifications.unsubscribeFromAll': true}}
+ const userUpdated = await User.update(
+ { _id: data._id },
+ { $set: { 'preferences.emailNotifications.unsubscribeFromAll': true } },
).exec();
if (userUpdated.nModified !== 1) throw new NotFound(res.t('userNotFound'));
res.send(`