2017-06-02 20:55:02 +00:00
< template lang = "pug" >
2017-06-27 20:02:55 +00:00
b - modal # guild - form ( : title = "title" , : hide - footer = "true" , size = 'lg' )
2017-06-02 20:55:02 +00:00
form ( @ submit . stop . prevent = "submit" )
. form - group
label
2017-08-21 15:36:31 +00:00
strong ( v - once ) { { $t ( 'name' ) } } *
2017-08-23 03:58:13 +00:00
b - form - input ( type = "text" , : placeholder = "$t('newGuildPlaceholder')" , v - model = "workingGroup.name" )
. form - group ( v - if = 'workingGroup.id && members.length > 0' )
2017-06-02 20:55:02 +00:00
label
2017-08-22 20:39:45 +00:00
strong ( v - once ) { { $t ( 'guildOrPartyLeader' ) } } *
2017-08-23 03:58:13 +00:00
select . form - control ( v - model = "workingGroup.newLeader" )
2017-10-02 01:42:02 +00:00
option ( v - for = 'potentialLeader in potentialLeaders' , : value = "potentialLeader._id" ) { { potentialLeader . name } }
2017-06-02 20:55:02 +00:00
2017-08-31 22:14:09 +00:00
. form - group ( v - if = '!this.workingGroup.id' )
2017-06-02 20:55:02 +00:00
label
2017-08-22 20:39:45 +00:00
strong ( v - once ) { { $t ( 'privacySettings' ) } } *
2017-06-02 20:55:02 +00:00
br
label . custom - control . custom - checkbox
2017-08-23 03:58:13 +00:00
input . custom - control - input ( type = "checkbox" , v - model = "workingGroup.onlyLeaderCreatesChallenges" )
2017-06-02 20:55:02 +00:00
span . custom - control - indicator
span . custom - control - description ( v - once ) { { $t ( 'onlyLeaderCreatesChallenges' ) } }
2017-09-01 13:15:54 +00:00
# groupPrivateDescription1 . icon ( : title = "$t('privateDescription')" )
2017-06-08 19:04:19 +00:00
. svg - icon ( v - html = 'icons.information' )
2017-09-01 13:15:54 +00:00
b - tooltip (
: title = "$t('privateDescription')" ,
target = "groupPrivateDescription1" ,
)
2017-06-02 20:55:02 +00:00
2017-07-31 19:54:52 +00:00
// br
// @TODO Implement in V2 label.custom-control.custom-checkbox
2017-08-23 03:58:13 +00:00
input . custom - control - input ( type = "checkbox" , v - model = "workingGroup.guildLeaderCantBeMessaged" )
2017-06-02 20:55:02 +00:00
span . custom - control - indicator
span . custom - control - description ( v - once ) { { $t ( 'guildLeaderCantBeMessaged' ) } }
2017-08-26 16:53:10 +00:00
// "guildLeaderCantBeMessaged": "Leader can not be messaged directly",
// @TODO discuss the impact of this with moderators before implementing
2017-06-02 20:55:02 +00:00
br
2017-08-21 15:36:31 +00:00
label . custom - control . custom - checkbox ( v - if = '!isParty' )
2017-08-23 03:58:13 +00:00
input . custom - control - input ( type = "checkbox" , v - model = "workingGroup.privateGuild" )
2017-06-02 20:55:02 +00:00
span . custom - control - indicator
span . custom - control - description ( v - once ) { { $t ( 'privateGuild' ) } }
2017-09-01 13:15:54 +00:00
# groupPrivateDescription2 . icon ( : title = "$t('privateDescription')" )
2017-06-08 19:04:19 +00:00
. svg - icon ( v - html = 'icons.information' )
2017-09-01 13:15:54 +00:00
b - tooltip (
: title = "$t('privateDescription')" ,
target = "groupPrivateDescription2" ,
)
2017-06-02 20:55:02 +00:00
2017-07-31 19:54:52 +00:00
// br
// @TODO: Implement in v2 label.custom-control.custom-checkbox(v-if='!creatingParty')
2017-08-26 16:53:10 +00:00
input . custom - control - input ( type = "checkbox" , v - model = "workingGroup.allowGuildInvitationsFromNonMembers" )
2017-06-02 20:55:02 +00:00
span . custom - control - indicator
2017-08-26 16:53:10 +00:00
span . custom - control - description ( v - once ) { { $t ( 'allowGuildInvitationsFromNonMembers' ) } }
// "allowGuildInvitationsFromNonMembers": "Allow Guild invitations from non-members",
2017-06-02 20:55:02 +00:00
2017-08-31 22:14:09 +00:00
. form - group ( v - if = '!isParty' )
2017-06-02 20:55:02 +00:00
label
2017-08-22 20:39:45 +00:00
strong ( v - once ) { { $t ( 'guildSummary' ) } } *
div . summary - count { { charactersRemaining } } { { $t ( 'charactersRemaining' ) } }
2017-09-16 12:19:07 +00:00
textarea . form - control . summary - textarea ( : placeholder = "isParty ? $t('partyDescriptionPlaceholder') : $t('guildSummaryPlaceholder')" , v - model = "workingGroup.summary" )
2017-08-22 20:39:45 +00:00
// @TODO: need summary only for PUBLIC GUILDS, not for tavern, private guilds, or party
2017-06-02 20:55:02 +00:00
2017-08-22 20:39:45 +00:00
. form - group
2017-06-02 20:55:02 +00:00
label
2017-08-22 20:39:45 +00:00
strong ( v - once ) { { $t ( 'groupDescription' ) } } *
2017-10-04 02:15:00 +00:00
a . float - right ( v - markdown = '$t("markdownFormattingHelp")' )
2017-08-31 22:14:09 +00:00
textarea . form - control . description - textarea ( type = "text" , textarea , : placeholder = "isParty ? $t('partyDescriptionPlaceholder') : $t('guildDescriptionPlaceholder')" , v - model = "workingGroup.description" )
2017-06-02 20:55:02 +00:00
2017-08-23 03:58:13 +00:00
. form - group ( v - if = 'creatingParty && !workingGroup.id' )
2017-06-27 20:02:55 +00:00
span
toggleSwitch ( : label = "$t('inviteMembersNow')" , v - model = 'inviteMembers' )
2017-08-21 15:36:31 +00:00
. form - group ( style = 'position: relative;' , v - if = '!creatingParty && !isParty' )
2017-06-02 20:55:02 +00:00
label
2017-08-22 20:39:45 +00:00
strong ( v - once ) { { $t ( 'categories' ) } } *
2017-06-02 20:55:02 +00:00
div . category - wrap ( @ click . prevent = "toggleCategorySelect" )
2017-08-23 03:58:13 +00:00
span . category - select ( v - if = 'workingGroup.categories.length === 0' ) { { $t ( 'none' ) } }
. category - label ( v - for = 'category in workingGroup.categories' ) { { $t ( categoriesHashByKey [ category ] ) } }
2017-06-02 20:55:02 +00:00
. category - box ( v - if = "showCategorySelect" )
. form - check (
v - for = "group in categoryOptions" ,
: key = "group.key" ,
2017-09-07 19:26:53 +00:00
v - if = 'group.key !== "habitica_official" || user.contributor.admin'
2017-06-02 20:55:02 +00:00
)
label . custom - control . custom - checkbox
2017-08-23 03:58:13 +00:00
input . custom - control - input ( type = "checkbox" , : value = "group.key" , v - model = "workingGroup.categories" )
2017-06-02 20:55:02 +00:00
span . custom - control - indicator
span . custom - control - description ( v - once ) { { $t ( group . label ) } }
button . btn . btn - primary ( @ click . prevent = "toggleCategorySelect" ) { { $t ( 'close' ) } }
2017-08-22 20:39:45 +00:00
// @TODO: need categories only for PUBLIC GUILDS, not for tavern, private guilds, or party
2017-06-02 20:55:02 +00:00
2017-08-23 03:58:13 +00:00
. form - group ( v - if = 'inviteMembers && !workingGroup.id' )
2017-06-27 20:02:55 +00:00
label
strong ( v - once ) Invite via Email or User ID
2017-08-22 20:39:45 +00:00
p ( v - once ) { { $t ( 'inviteMembersHowTo' ) } } *
2017-06-27 20:02:55 +00:00
div
div ( v - for = '(member, index) in membersToInvite' )
input ( type = 'text' , v - model = 'member.value' )
button ( @ click . prevent = 'removeMemberToInvite(index)' ) Remove
div
input ( type = 'text' , placeholder = 'Email address or User ID' , v - model = 'newMemberToInvite.value' )
button ( @ click . prevent = 'addMemberToInvite()' ) Add
2017-06-02 20:55:02 +00:00
. form - group . text - center
2017-08-23 03:58:13 +00:00
div . item - with - icon ( v - if = '!this.workingGroup.id' )
2017-06-08 19:04:19 +00:00
. svg - icon ( v - html = "icons.gem" )
2017-06-02 20:55:02 +00:00
span . count 4
2017-08-23 03:58:13 +00:00
button . btn . btn - primary . btn - md ( v - if = '!workingGroup.id' , : disabled = '!workingGroup.name || !workingGroup.description' ) { { creatingParty ? $t ( 'createParty' ) : $t ( 'createGuild' ) } }
button . btn . btn - primary . btn - md ( v - if = 'workingGroup.id' , : disabled = '!workingGroup.name || !workingGroup.description' ) { { isParty ? $t ( 'updateParty' ) : $t ( 'updateGuild' ) } }
. gem - description ( v - once , v - if = '!this.workingGroup.id' ) { { $t ( 'guildGemCostInfo' ) } }
2017-06-02 20:55:02 +00:00
< / template >
2017-06-08 19:04:19 +00:00
< style lang = "scss" scoped >
@ import '~client/assets/scss/colors.scss' ;
2017-08-18 20:29:49 +00:00
. svg - icon {
width : 16 px ;
}
2017-06-02 20:55:02 +00:00
textarea {
height : 150 px ;
}
2017-06-08 19:04:19 +00:00
2017-08-22 20:39:45 +00:00
. summary - count , . gem - description {
2017-06-02 20:55:02 +00:00
font - size : 12 px ;
line - height : 1.33 ;
2017-08-22 20:39:45 +00:00
margin - top : 1 em ;
2017-06-02 20:55:02 +00:00
color : $gray - 200 ;
}
2017-08-22 20:39:45 +00:00
. summary - count {
2017-06-02 20:55:02 +00:00
text - align : right ;
}
. gem - description {
2017-08-22 20:39:45 +00:00
text - align : center ;
}
. summary - textarea {
height : 90 px ;
}
. description - textarea {
height : 220 px ;
2017-06-02 20:55:02 +00:00
}
. item - with - icon {
display : inline - block ;
img {
height : 20 px ;
margin - right : .5 em ;
}
. count {
font - size : 14 px ;
font - weight : bold ;
margin - right : 1 em ;
color : $green - 10 ;
}
}
. icon {
margin - left : .5 em ;
display : inline - block ;
}
< / style >
< script >
2017-09-07 19:26:53 +00:00
import { mapState } from 'client/libs/store' ;
2017-06-27 20:02:55 +00:00
import toggleSwitch from 'client/components/ui/toggleSwitch' ;
2017-10-04 02:15:00 +00:00
import markdownDirective from 'client/directives/markdown' ;
2017-06-08 19:04:19 +00:00
import gemIcon from 'assets/svg/gem.svg' ;
import informationIcon from 'assets/svg/information.svg' ;
2017-08-22 20:39:45 +00:00
import { MAX _SUMMARY _SIZE _FOR _GUILDS } from '../../../common/script/constants' ;
2017-07-31 19:54:52 +00:00
// @TODO: Not sure the best way to pass party creating status
// Since we need the modal in the header, passing props doesn't work
// because we can't import the create group in the index of groups
// I think state is the correct spot, but maybe we should separate into
// two modals?
2017-06-02 20:55:02 +00:00
export default {
components : {
2017-06-27 20:02:55 +00:00
toggleSwitch ,
2017-06-02 20:55:02 +00:00
} ,
2017-10-04 02:15:00 +00:00
directives : {
markdown : markdownDirective ,
} ,
2017-06-02 20:55:02 +00:00
data ( ) {
let data = {
2017-08-23 03:58:13 +00:00
workingGroup : {
2017-06-02 20:55:02 +00:00
id : '' ,
name : '' ,
type : 'guild' ,
privacy : 'private' ,
2017-08-22 20:39:45 +00:00
summary : '' ,
2017-06-02 20:55:02 +00:00
description : '' ,
categories : [ ] ,
onlyLeaderCreatesChallenges : true ,
guildLeaderCantBeMessaged : true ,
privateGuild : true ,
2017-08-26 16:53:10 +00:00
allowGuildInvitationsFromNonMembers : true ,
2017-06-02 20:55:02 +00:00
newLeader : '' ,
} ,
categoryOptions : [
{
2017-08-09 16:56:48 +00:00
label : 'habitica_official' ,
key : 'habitica_official' ,
2017-06-02 20:55:02 +00:00
} ,
{
2017-08-09 16:56:48 +00:00
label : 'academics' ,
key : 'academics' ,
2017-06-02 20:55:02 +00:00
} ,
{
2017-08-09 16:56:48 +00:00
label : 'advocacy_causes' ,
key : 'advocacy_causes' ,
2017-06-02 20:55:02 +00:00
} ,
{
2017-08-09 16:56:48 +00:00
label : 'creativity' ,
key : 'creativity' ,
2017-06-02 20:55:02 +00:00
} ,
{
2017-08-09 16:56:48 +00:00
label : 'entertainment' ,
key : 'entertainment' ,
2017-06-02 20:55:02 +00:00
} ,
{
2017-08-09 16:56:48 +00:00
label : 'finance' ,
key : 'finance' ,
2017-06-02 20:55:02 +00:00
} ,
{
2017-08-09 16:56:48 +00:00
label : 'health_fitness' ,
key : 'health_fitness' ,
2017-06-02 20:55:02 +00:00
} ,
{
2017-08-09 16:56:48 +00:00
label : 'hobbies_occupations' ,
key : 'hobbies_occupations' ,
} ,
{
label : 'location_based' ,
key : 'location_based' ,
} ,
{
label : 'mental_health' ,
2017-08-16 20:03:07 +00:00
key : 'mental_health' ,
2017-08-09 16:56:48 +00:00
} ,
{
2017-10-16 23:04:49 +00:00
label : 'getting_organized' ,
key : 'getting_organized' ,
2017-06-02 20:55:02 +00:00
} ,
{
2017-08-16 20:03:07 +00:00
label : 'recovery_support_groups' ,
key : 'recovery_support_groups' ,
2017-06-02 20:55:02 +00:00
} ,
{
2017-08-09 16:56:48 +00:00
label : 'spirituality' ,
2017-08-16 20:03:07 +00:00
key : 'spirituality' ,
2017-06-02 20:55:02 +00:00
} ,
{
2017-08-09 16:56:48 +00:00
label : 'time_management' ,
key : 'time_management' ,
2017-06-02 20:55:02 +00:00
} ,
] ,
showCategorySelect : false ,
2017-07-29 22:08:36 +00:00
members : [ ] ,
2017-06-27 20:02:55 +00:00
inviteMembers : false ,
newMemberToInvite : {
value : '' ,
type : '' ,
} ,
membersToInvite : [ ] ,
2017-06-02 20:55:02 +00:00
} ;
let hashedCategories = { } ;
data . categoryOptions . forEach ( ( category ) => {
hashedCategories [ category . key ] = category . label ;
} ) ;
data . categoriesHashByKey = hashedCategories ;
2017-06-08 19:04:19 +00:00
data . icons = Object . freeze ( {
gem : gemIcon ,
information : informationIcon ,
} ) ;
2017-06-02 20:55:02 +00:00
return data ;
} ,
2017-08-31 22:14:09 +00:00
computed : {
2017-09-07 19:26:53 +00:00
... mapState ( { user : 'user.data' } ) ,
2017-08-31 22:14:09 +00:00
editingGroup ( ) {
return this . $store . state . editingGroup ;
} ,
charactersRemaining ( ) {
let currentLength = this . workingGroup . summary ? this . workingGroup . summary . length : 0 ;
return MAX _SUMMARY _SIZE _FOR _GUILDS - currentLength ;
} ,
title ( ) {
if ( this . creatingParty ) return this . $t ( 'createParty' ) ;
if ( ! this . workingGroup . _id && ! this . workingGroup . id ) return this . $t ( 'createGuild' ) ;
if ( this . isParty ) return this . $t ( 'updateParty' ) ;
return this . $t ( 'updateGuild' ) ;
} ,
creatingParty ( ) {
return this . $store . state . groupFormOptions . createParty ;
} ,
isParty ( ) {
return this . workingGroup . type === 'party' ;
} ,
2017-10-02 01:42:02 +00:00
potentialLeaders ( ) {
let leaders = [ { _id : this . user . _id , name : this . user . profile . name } ] ;
// @TODO consider pushing all recent posters to the top of the list if they are guild members - more likely to be the ones the leader wants to see (and then ignore them in the while below)
let i = 0 ;
while ( this . members [ i ] ) {
let memb = this . members [ i ] ;
i ++ ;
if ( memb . _id !== this . user . _id ) leaders . push ( { _id : memb . _id , name : memb . profile . name } ) ;
}
return leaders ;
} ,
2017-08-31 22:14:09 +00:00
} ,
watch : {
editingGroup ( ) {
let editingGroup = this . editingGroup ;
2017-08-23 03:58:13 +00:00
if ( ! editingGroup . _id ) {
this . resetWorkingGroup ( ) ;
return ;
}
this . workingGroup . name = editingGroup . name ;
this . workingGroup . type = editingGroup . type ;
this . workingGroup . privateGuild = true ;
if ( editingGroup . privacy === 'public' ) {
this . workingGroup . privateGuild = false ;
}
2017-08-29 20:23:09 +00:00
if ( editingGroup . categories ) {
editingGroup . categories . forEach ( category => {
this . workingGroup . categories . push ( category . slug ) ;
} ) ;
}
2017-08-23 03:58:13 +00:00
if ( editingGroup . summary ) this . workingGroup . summary = editingGroup . summary ;
if ( editingGroup . description ) this . workingGroup . description = editingGroup . description ;
if ( editingGroup . _id ) this . workingGroup . id = editingGroup . _id ;
if ( editingGroup . leader . _id ) this . workingGroup . newLeader = editingGroup . leader . _id ;
2017-07-31 19:54:52 +00:00
if ( editingGroup . _id ) this . getMembers ( ) ;
2017-08-21 15:36:31 +00:00
} ,
2017-06-02 20:55:02 +00:00
} ,
methods : {
2017-07-29 22:08:36 +00:00
async getMembers ( ) {
2017-08-23 03:58:13 +00:00
if ( ! this . workingGroup . id ) return ;
2017-07-29 22:08:36 +00:00
let members = await this . $store . dispatch ( 'members:getGroupMembers' , {
2017-08-23 03:58:13 +00:00
groupId : this . workingGroup . id ,
2017-07-29 22:08:36 +00:00
includeAllPublicFields : true ,
} ) ;
this . members = members ;
} ,
2017-06-27 20:02:55 +00:00
addMemberToInvite ( ) {
// @TODO: determine type
this . membersToInvite . push ( this . newMemberToInvite ) ;
this . newMemberToInvite = {
value : '' ,
type : '' ,
} ;
} ,
removeMemberToInvite ( index ) {
this . membersToInvite . splice ( index , 1 ) ;
} ,
2017-06-02 20:55:02 +00:00
toggleCategorySelect ( ) {
this . showCategorySelect = ! this . showCategorySelect ;
} ,
async submit ( ) {
2017-08-23 03:58:13 +00:00
if ( this . $store . state . user . data . balance < 1 && ! this . workingGroup . id ) {
2017-06-02 20:55:02 +00:00
// @TODO: Add proper notifications
2017-09-25 18:02:12 +00:00
alert ( this . $t ( 'notEnoughGems' ) ) ;
2017-06-02 20:55:02 +00:00
return ;
2017-09-08 19:23:58 +00:00
// @TODO return $rootScope.openModal('buyGems', {track:"Gems > Gems > Create Group"});
// @TODO when modal is implemented, enable analytics
/ * A n a l y t i c s . t r a c k ( {
hitType : 'event' ,
eventCategory : 'button' ,
eventAction : 'click' ,
eventLabel : 'Health Warning' ,
} ) ; * /
2017-06-02 20:55:02 +00:00
}
2017-09-25 18:02:12 +00:00
let errors = [ ] ;
2017-08-22 20:39:45 +00:00
2017-09-25 18:02:12 +00:00
if ( ! this . workingGroup . name ) errors . push ( this . $t ( 'nameRequired' ) ) ;
if ( ! this . workingGroup . summary ) errors . push ( this . $t ( 'summaryRequired' ) ) ;
if ( this . workingGroup . summary . length > MAX _SUMMARY _SIZE _FOR _GUILDS ) errors . push ( this . $t ( 'summaryTooLong' ) ) ;
if ( ! this . workingGroup . description ) errors . push ( this . $t ( 'descriptionRequired' ) ) ;
if ( ! this . isParty && ( ! this . workingGroup . categories || this . workingGroup . categories . length === 0 ) ) errors . push ( this . $t ( 'categoiresRequired' ) ) ;
2017-08-22 20:39:45 +00:00
2017-09-25 18:02:12 +00:00
if ( errors . length > 0 ) {
alert ( errors . join ( '\n' ) ) ;
2017-06-02 20:55:02 +00:00
return ;
}
// @TODO: Add proper notifications
2017-08-23 03:58:13 +00:00
if ( ! this . workingGroup . id && ! confirm ( this . $t ( 'confirmGuild' ) ) ) return ;
2017-06-02 20:55:02 +00:00
2017-08-23 03:58:13 +00:00
if ( ! this . workingGroup . privateGuild ) {
this . workingGroup . privacy = 'public' ;
2017-06-02 20:55:02 +00:00
}
2017-08-23 03:58:13 +00:00
if ( ! this . workingGroup . onlyLeaderCreatesChallenges ) {
this . workingGroup . leaderOnly = {
2017-06-02 20:55:02 +00:00
challenges : true ,
} ;
}
2017-08-23 03:58:13 +00:00
let categoryKeys = this . workingGroup . categories ;
2017-08-18 20:29:49 +00:00
let serverCategories = [ ] ;
categoryKeys . forEach ( key => {
let catName = this . categoriesHashByKey [ key ] ;
serverCategories . push ( {
slug : key ,
name : catName ,
} ) ;
} ) ;
2017-08-23 03:58:13 +00:00
this . workingGroup . categories = serverCategories ;
2017-08-09 16:56:48 +00:00
2017-08-18 20:29:49 +00:00
let newgroup ;
2017-08-23 03:58:13 +00:00
if ( this . workingGroup . id ) {
await this . $store . dispatch ( 'guilds:update' , { group : this . workingGroup } ) ;
this . $root . $emit ( 'updatedGroup' , this . workingGroup ) ;
2017-07-29 22:08:36 +00:00
// @TODO: this doesn't work because of the async resource
// if (updatedGroup.type === 'party') this.$store.state.party = {data: updatedGroup};
2017-06-02 20:55:02 +00:00
} else {
2017-08-23 03:58:13 +00:00
newgroup = await this . $store . dispatch ( 'guilds:create' , { group : this . workingGroup } ) ;
2017-08-09 16:56:48 +00:00
this . $store . state . user . data . balance -= 1 ;
2017-06-02 20:55:02 +00:00
}
this . $store . state . editingGroup = { } ;
2017-08-23 03:58:13 +00:00
this . workingGroup = {
2017-06-02 20:55:02 +00:00
name : '' ,
type : 'guild' ,
privacy : 'private' ,
description : '' ,
categories : [ ] ,
onlyLeaderCreatesChallenges : true ,
guildLeaderCantBeMessaged : true ,
privateGuild : true ,
2017-08-26 16:53:10 +00:00
allowGuildInvitationsFromNonMembers : true ,
2017-06-02 20:55:02 +00:00
} ;
2017-06-27 20:02:55 +00:00
2017-08-09 16:56:48 +00:00
if ( newgroup && newgroup . _id ) {
this . $router . push ( ` /groups/guild/ ${ newgroup . _id } ` ) ;
}
2017-11-08 17:40:37 +00:00
this . $root . $emit ( 'bv::hide::modal' , 'guild-form' ) ;
2017-06-02 20:55:02 +00:00
} ,
2017-08-23 03:58:13 +00:00
resetWorkingGroup ( ) {
this . workingGroup = {
2017-08-31 22:14:09 +00:00
id : '' ,
2017-08-23 03:58:13 +00:00
name : '' ,
type : 'guild' ,
privacy : 'private' ,
2017-08-31 22:14:09 +00:00
summary : '' ,
2017-08-23 03:58:13 +00:00
description : '' ,
categories : [ ] ,
onlyLeaderCreatesChallenges : true ,
guildLeaderCantBeMessaged : true ,
privateGuild : true ,
2017-08-26 16:53:10 +00:00
allowGuildInvitationsFromNonMembers : true ,
2017-08-31 22:14:09 +00:00
newLeader : '' ,
2017-08-23 03:58:13 +00:00
} ;
} ,
2017-06-02 20:55:02 +00:00
} ,
} ;
< / script >