{ "version": 3, "sources": ["../../../../server/chat-plugins/poll.ts"], "sourcesContent": ["/*\r\n * Poll chat plugin\r\n * By bumbadadabum and Zarel.\r\n */\r\nimport {Utils} from '../../lib';\r\n\r\nconst MINUTES = 60000;\r\nconst MAX_QUESTIONS = 10;\r\n\r\ninterface PollAnswer {\r\n\tname: string; votes: number; correct?: boolean;\r\n}\r\n\r\nexport interface PollOptions {\r\n\tactivityNumber?: number;\r\n\tquestion: string;\r\n\tsupportHTML: boolean;\r\n\tmultiPoll: boolean;\r\n\tpendingVotes?: {[userid: string]: number[]};\r\n\tvoters?: {[k: string]: number[]};\r\n\tvoterIps?: {[k: string]: number[]};\r\n\tmaxVotes?: number;\r\n\ttotalVotes?: number;\r\n\ttimeoutMins?: number;\r\n\ttimerEnd?: number;\r\n\tisQuiz?: boolean;\r\n\tanswers: string[] | PollAnswer[];\r\n}\r\n\r\nexport interface PollData extends PollOptions {\r\n\treadonly activityid: 'poll';\r\n}\r\n\r\nexport class Poll extends Rooms.MinorActivity {\r\n\treadonly activityid = 'poll' as ID;\r\n\tname = \"Poll\";\r\n\tactivityNumber: number;\r\n\tquestion: string;\r\n\tmultiPoll: boolean;\r\n\tpendingVotes: {[userid: string]: number[]};\r\n\tvoters: {[k: string]: number[]};\r\n\tvoterIps: {[k: string]: number[]};\r\n\ttotalVotes: number;\r\n\tisQuiz: boolean;\r\n\t/** Max votes of 0 means no vote cap */\r\n\tmaxVotes: number;\r\n\tanswers: Map;\r\n\tconstructor(room: Room, options: PollOptions) {\r\n\t\tsuper(room);\r\n\t\tthis.activityNumber = options.activityNumber || room.nextGameNumber();\r\n\t\tthis.question = options.question;\r\n\t\tthis.supportHTML = options.supportHTML;\r\n\t\tthis.multiPoll = options.multiPoll;\r\n\t\tthis.pendingVotes = options.pendingVotes || {};\r\n\t\tthis.voters = options.voters || {};\r\n\t\tthis.voterIps = options.voterIps || {};\r\n\t\tthis.totalVotes = options.totalVotes || 0;\r\n\t\tthis.maxVotes = options.maxVotes || 0;\r\n\r\n\t\t// backwards compatibility\r\n\t\tif (!options.answers) options.answers = (options as any).questions;\r\n\r\n\t\tthis.answers = Poll.getAnswers(options.answers);\r\n\t\tthis.isQuiz = options.isQuiz ?? [...this.answers.values()].some(answer => answer.correct);\r\n\t\tthis.setTimer(options);\r\n\t}\r\n\r\n\tselect(user: User, option: number) {\r\n\t\tconst userid = user.id;\r\n\t\tif (!this.multiPoll) {\r\n\t\t\t// vote immediately\r\n\t\t\tthis.pendingVotes[userid] = [option];\r\n\t\t\tthis.submit(user);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!this.pendingVotes[userid]) {\r\n\t\t\tthis.pendingVotes[userid] = [];\r\n\t\t}\r\n\t\tif (this.pendingVotes[userid].includes(option)) {\r\n\t\t\tthrow new Chat.ErrorMessage(this.room.tr`That option is already selected.`);\r\n\t\t}\r\n\t\tthis.pendingVotes[userid].push(option);\r\n\t\tthis.updateFor(user);\r\n\t\tthis.save();\r\n\t}\r\n\r\n\tdeselect(user: User, option: number) {\r\n\t\tconst userid = user.id;\r\n\t\tconst pendingVote = this.pendingVotes[userid];\r\n\t\tif (!pendingVote?.includes(option)) {\r\n\t\t\tthrow new Chat.ErrorMessage(this.room.tr`That option is not selected.`);\r\n\t\t}\r\n\t\tpendingVote.splice(pendingVote.indexOf(option), 1);\r\n\t\tthis.updateFor(user);\r\n\t\tthis.save();\r\n\t}\r\n\r\n\tsubmit(user: User) {\r\n\t\tconst ip = user.latestIp;\r\n\t\tconst userid = user.id;\r\n\r\n\t\tif (userid in this.voters || (!Config.noipchecks && ip in this.voterIps)) {\r\n\t\t\tdelete this.pendingVotes[userid];\r\n\t\t\tthrow new Chat.ErrorMessage(this.room.tr`You have already voted for this poll.`);\r\n\t\t}\r\n\t\tconst selected = this.pendingVotes[userid];\r\n\t\tif (!selected) throw new Chat.ErrorMessage(this.room.tr`No options selected.`);\r\n\r\n\t\tthis.voters[userid] = selected;\r\n\t\tthis.voterIps[ip] = selected;\r\n\t\tfor (const option of selected) {\r\n\t\t\tthis.answers.get(option)!.votes++;\r\n\t\t}\r\n\t\tdelete this.pendingVotes[userid];\r\n\t\tthis.totalVotes++;\r\n\t\tif (this.maxVotes && this.totalVotes >= this.maxVotes) {\r\n\t\t\tthis.end(this.room);\r\n\t\t\treturn this.room\r\n\t\t\t\t.add(`|c|&|/log The poll hit the max vote cap of ${this.maxVotes}, and has ended.`)\r\n\t\t\t\t.update();\r\n\t\t}\r\n\r\n\t\tthis.update();\r\n\t\tthis.save();\r\n\t}\r\n\r\n\tblankvote(user: User) {\r\n\t\tconst ip = user.latestIp;\r\n\t\tconst userid = user.id;\r\n\r\n\t\tif (!(userid in this.voters) || !(ip in this.voterIps)) {\r\n\t\t\tthis.voters[userid] = [];\r\n\t\t\tthis.voterIps[ip] = [];\r\n\t\t}\r\n\r\n\t\tthis.updateTo(user);\r\n\t\tthis.save();\r\n\t}\r\n\r\n\tgenerateVotes(user: User | null) {\r\n\t\tconst iconText = this.isQuiz ?\r\n\t\t\t` ${this.room.tr`Quiz`}` :\r\n\t\t\t` ${this.room.tr`Poll`}`;\r\n\t\tlet output = `

${iconText}`;\r\n\t\toutput += ` ${Poll.getQuestionMarkup(this.question, this.supportHTML)}

`;\r\n\r\n\t\tif (this.multiPoll) {\r\n\t\t\tconst empty = ``;\r\n\t\t\tconst chosen = ``;\r\n\r\n\t\t\tconst pendingVotes = (user && this.pendingVotes[user.id]) || [];\r\n\t\t\tfor (const [num, answer] of this.answers) {\r\n\t\t\t\tconst selected = pendingVotes.includes(num);\r\n\t\t\t\toutput += `
`;\r\n\t\t\t}\r\n\t\t\tconst submitButton = pendingVotes.length ? (\r\n\t\t\t\t``\r\n\t\t\t) : (\r\n\t\t\t\t``\r\n\t\t\t);\r\n\t\t\toutput += `
${submitButton}
`;\r\n\t\t\toutput += `
`;\r\n\t\t} else {\r\n\t\t\tfor (const [num, answer] of this.answers) {\r\n\t\t\t\toutput += `
`;\r\n\t\t\t}\r\n\t\t\toutput += `
`;\r\n\t\t\toutput += ``;\r\n\t\t}\r\n\r\n\t\treturn output;\r\n\t}\r\n\r\n\tstatic generateResults(\r\n\t\toptions: Rooms.MinorActivityData, room: Room,\r\n\t\tended = false, choice: number[] | null = null\r\n\t) {\r\n\t\tconst iconText = options.isQuiz ?\r\n\t\t\t` ${room.tr`Quiz`}` :\r\n\t\t\t` ${room.tr`Poll`}`;\r\n\t\tconst icon = `${iconText}${ended ? ' ' + room.tr`ended` : \"\"} ${options.totalVotes || 0} ${room.tr`votes`}`;\r\n\t\tlet output = `

${icon} ${this.getQuestionMarkup(options.question, options.supportHTML)}

`;\r\n\t\tconst answers = Poll.getAnswers(options.answers);\r\n\r\n\t\t// indigo, blue, green\r\n\t\t// nums start at 1 so the actual order is 1. blue, 2. green, 3. indigo, 4. blue\r\n\t\tconst colors = ['#88B', '#79A', '#8A8'];\r\n\t\tfor (const [num, answer] of answers) {\r\n\t\t\tconst chosen = choice?.includes(num);\r\n\t\t\tconst percentage = Math.round((answer.votes * 100) / (options.totalVotes || 1));\r\n\t\t\tconst answerMarkup = options.isQuiz ?\r\n\t\t\t\t`${answer.correct ? '' : ''}${this.getAnswerMarkup(answer, options.supportHTML)}${answer.correct ? '' : ''}` :\r\n\t\t\t\tthis.getAnswerMarkup(answer, options.supportHTML);\r\n\t\t\toutput += `
${num}. ${chosen ? '' : ''}${answerMarkup}${chosen ? '' : ''} (${answer.votes} vote${answer.votes === 1 ? '' : 's'})
 ${percentage}%
`;\r\n\t\t}\r\n\t\tif (!choice && !ended) {\r\n\t\t\toutput += `
(${room.tr`You can't vote after viewing results`})
`;\r\n\t\t}\r\n\t\toutput += '
';\r\n\r\n\t\treturn output;\r\n\t}\r\n\r\n\tstatic getQuestionMarkup(question: string, supportHTML = false) {\r\n\t\tif (supportHTML) return question;\r\n\t\treturn Chat.formatText(question);\r\n\t}\r\n\r\n\tstatic getAnswerMarkup(answer: PollAnswer, supportHTML = false) {\r\n\t\tif (supportHTML) return answer.name;\r\n\t\treturn Chat.formatText(answer.name);\r\n\t}\r\n\r\n\tupdate() {\r\n\t\tconst state = this.toJSON();\r\n\t\t// Update the poll results for everyone that has voted\r\n\t\tconst blankvote = Poll.generateResults(state, this.room, false);\r\n\r\n\t\tfor (const id in this.room.users) {\r\n\t\t\tconst user = this.room.users[id];\r\n\t\t\tconst selection = this.voters[user.id] || this.voterIps[user.latestIp];\r\n\t\t\tif (selection) {\r\n\t\t\t\tif (selection.length) {\r\n\t\t\t\t\tuser.sendTo(\r\n\t\t\t\t\t\tthis.room,\r\n\t\t\t\t\t\t`|uhtmlchange|poll${this.activityNumber}|${Poll.generateResults(state, this.room, false, selection)}`\r\n\t\t\t\t\t);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tuser.sendTo(this.room, `|uhtmlchange|poll${this.activityNumber}|${blankvote}`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tupdateTo(user: User, connection: Connection | null = null) {\r\n\t\tconst state = this.toJSON();\r\n\t\tconst recipient = connection || user;\r\n\t\tconst selection = this.voters[user.id] || this.voterIps[user.latestIp];\r\n\t\tif (selection) {\r\n\t\t\trecipient.sendTo(\r\n\t\t\t\tthis.room,\r\n\t\t\t\t`|uhtmlchange|poll${this.activityNumber}|${Poll.generateResults(state, this.room, false, selection)}`\r\n\t\t\t);\r\n\t\t} else {\r\n\t\t\trecipient.sendTo(this.room, `|uhtmlchange|poll${this.activityNumber}|${this.generateVotes(user)}`);\r\n\t\t}\r\n\t}\r\n\r\n\tupdateFor(user: User) {\r\n\t\tconst state = this.toJSON();\r\n\t\tif (user.id in this.voters) {\r\n\t\t\tuser.sendTo(\r\n\t\t\t\tthis.room,\r\n\t\t\t\t`|uhtmlchange|poll${this.activityNumber}|${Poll.generateResults(state, this.room, false, this.voters[user.id])}`\r\n\t\t\t);\r\n\t\t} else {\r\n\t\t\tuser.sendTo(this.room, `|uhtmlchange|poll${this.activityNumber}|${this.generateVotes(user)}`);\r\n\t\t}\r\n\t}\r\n\r\n\tdisplay() {\r\n\t\tconst state = this.toJSON();\r\n\t\tconst blankvote = Poll.generateResults(state, this.room, false);\r\n\t\tconst blankquestions = this.generateVotes(null);\r\n\r\n\t\tfor (const id in this.room.users) {\r\n\t\t\tconst thisUser = this.room.users[id];\r\n\t\t\tconst selection = this.voters[thisUser.id] || this.voterIps[thisUser.latestIp];\r\n\t\t\tif (selection) {\r\n\t\t\t\tif (selection.length) {\r\n\t\t\t\t\tthisUser.sendTo(this.room,\r\n\t\t\t\t\t\t`|uhtml|poll${this.activityNumber}|${Poll.generateResults(state, this.room, false, selection)}`);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthisUser.sendTo(this.room, `|uhtml|poll${this.activityNumber}|${blankvote}`);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.multiPoll && thisUser.id in this.pendingVotes) {\r\n\t\t\t\t\tthisUser.sendTo(this.room, `|uhtml|poll${this.activityNumber}|${this.generateVotes(thisUser)}`);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthisUser.sendTo(this.room, `|uhtml|poll${this.activityNumber}|${blankquestions}`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tdisplayTo(user: User, connection: Connection | null = null) {\r\n\t\tconst state = this.toJSON();\r\n\t\tconst recipient = connection || user;\r\n\t\tif (user.id in this.voters) {\r\n\t\t\trecipient.sendTo(\r\n\t\t\t\tthis.room,\r\n\t\t\t\t`|uhtml|poll${this.activityNumber}|${Poll.generateResults(state, this.room, false, this.voters[user.id])}`\r\n\t\t\t);\r\n\t\t} else if (user.latestIp in this.voterIps && !Config.noipchecks) {\r\n\t\t\trecipient.sendTo(this.room, `|uhtml|poll${this.activityNumber}|${Poll.generateResults(\r\n\t\t\t\tstate, this.room, false, this.voterIps[user.latestIp]\r\n\t\t\t)}`);\r\n\t\t} else {\r\n\t\t\trecipient.sendTo(this.room, `|uhtml|poll${this.activityNumber}|${this.generateVotes(user)}`);\r\n\t\t}\r\n\t}\r\n\r\n\tonConnect(user: User, connection: Connection | null = null) {\r\n\t\tthis.displayTo(user, connection);\r\n\t}\r\n\r\n\tonRename(user: User, oldid: ID, joining: boolean) {\r\n\t\tif (user.id in this.voters) {\r\n\t\t\tthis.updateFor(user);\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy() {\r\n\t\tconst results = Poll.generateResults(this.toJSON(), this.room, true);\r\n\t\tthis.room.send(`|uhtmlchange|poll${this.activityNumber}|
(${this.room.tr`The poll has ended – scroll down to see the results`})
`);\r\n\t\tthis.room.add(`|html|${results}`).update();\r\n\t\tthis.room.setMinorActivity(null);\r\n\t}\r\n\r\n\ttoJSON(): PollData {\r\n\t\treturn {\r\n\t\t\tactivityid: 'poll',\r\n\t\t\tactivityNumber: this.activityNumber,\r\n\t\t\tquestion: this.question,\r\n\t\t\tsupportHTML: this.supportHTML,\r\n\t\t\tmultiPoll: this.multiPoll,\r\n\t\t\tpendingVotes: this.pendingVotes,\r\n\t\t\tvoters: this.voters,\r\n\t\t\tvoterIps: this.voterIps,\r\n\t\t\ttotalVotes: this.totalVotes,\r\n\t\t\ttimeoutMins: this.timeoutMins,\r\n\t\t\ttimerEnd: this.timerEnd,\r\n\t\t\tisQuiz: this.isQuiz,\r\n\t\t\tanswers: [...this.answers.values()],\r\n\t\t};\r\n\t}\r\n\r\n\tsave() {\r\n\t\tthis.room.settings.minorActivity = this.toJSON();\r\n\t\tthis.room.saveSettings();\r\n\t}\r\n\r\n\tstatic getAnswers(answers: string[] | PollAnswer[]) {\r\n\t\tconst out = new Map();\r\n\t\tif (answers.length && typeof answers[0] === 'string') {\r\n\t\t\tfor (const [i, answer] of (answers as string[]).entries()) {\r\n\t\t\t\tout.set(i + 1, {\r\n\t\t\t\t\tname: answer.startsWith('+') ? answer.slice(1) : answer,\r\n\t\t\t\t\tvotes: 0,\r\n\t\t\t\t\tcorrect: answer.startsWith('+'),\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tfor (const [i, answer] of (answers as PollAnswer[]).entries()) {\r\n\t\t\t\tout.set(i + 1, answer);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn out;\r\n\t}\r\n}\r\n\r\nexport const commands: Chat.ChatCommands = {\r\n\tpoll: {\r\n\t\thtmlcreate: 'new',\r\n\t\tcreate: 'new',\r\n\t\tcreatemulti: 'new',\r\n\t\thtmlcreatemulti: 'new',\r\n\t\tqueue: 'new',\r\n\t\tqueuehtml: 'new',\r\n\t\thtmlqueue: 'new',\r\n\t\tqueuemulti: 'new',\r\n\t\thtmlqueuemulti: 'new',\r\n\t\tnew(target, room, user, connection, cmd, message) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!target) return this.parse('/help poll new');\r\n\t\t\ttarget = target.trim();\r\n\t\t\tif (target.length > 1024) return this.errorReply(this.tr`Poll too long.`);\r\n\t\t\tif (room.battle) return this.errorReply(this.tr`Battles do not support polls.`);\r\n\r\n\t\t\tconst text = this.filter(target);\r\n\t\t\tif (target !== text) return this.errorReply(this.tr`You are not allowed to use filtered words in polls.`);\r\n\r\n\t\t\tconst supportHTML = cmd.includes('html');\r\n\t\t\tconst multiPoll = cmd.includes('multi');\r\n\t\t\tconst queue = cmd.includes('queue');\r\n\r\n\t\t\tlet params = [];\r\n\t\t\tlet separator = '';\r\n\t\t\tif (text.includes('\\n')) {\r\n\t\t\t\tseparator = '\\n';\r\n\t\t\t} else if (text.includes('|')) {\r\n\t\t\t\tseparator = '|';\r\n\t\t\t} else if (text.includes(',')) {\r\n\t\t\t\tseparator = ',';\r\n\t\t\t} else {\r\n\t\t\t\treturn this.errorReply(this.tr`Not enough arguments for /poll new.`);\r\n\t\t\t}\r\n\r\n\t\t\tlet currentParam = \"\";\r\n\t\t\tfor (let i = 0; i < text.length; ++i) {\r\n\t\t\t\tconst currentCharacter = text[i];\r\n\t\t\t\tconst nextCharacter = text[i + 1];\r\n\r\n\t\t\t\t// If the current character is an escape character, insert the next character\r\n\t\t\t\t// into the param and then skip over checking it in our loop.\r\n\t\t\t\tconst isEscapeCharacter = currentCharacter === '\\\\';\r\n\t\t\t\tif (isEscapeCharacter) {\r\n\t\t\t\t\tif (nextCharacter) {\r\n\t\t\t\t\t\tcurrentParam += nextCharacter;\r\n\t\t\t\t\t\ti += 1;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\treturn this.errorReply(this.tr`Extra escape character. To end a poll with '\\\\', enter it as '\\\\\\\\'`);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// At this point, we know this separator hasn't been escaped, so split here.\r\n\t\t\t\tconst isSeparator = currentCharacter === separator;\r\n\t\t\t\tif (isSeparator) {\r\n\t\t\t\t\tparams.push(currentParam);\r\n\t\t\t\t\tcurrentParam = \"\";\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// The current character hasn't been escaped and isn't a separator, so it can just be added to the param.\r\n\t\t\t\tcurrentParam += currentCharacter;\r\n\t\t\t}\r\n\t\t\t// Be sure to get the last param we constructed into the array.\r\n\t\t\tparams.push(currentParam);\r\n\t\t\tparams = params.map(param => param.trim());\r\n\r\n\t\t\tthis.checkCan('minigame', null, room);\r\n\t\t\tif (supportHTML) this.checkCan('declare', null, room);\r\n\t\t\tthis.checkChat();\r\n\t\t\tif (room.minorActivity && !queue) {\r\n\t\t\t\treturn this.errorReply(this.tr`There is already a poll or announcement in progress in this room.`);\r\n\t\t\t}\r\n\r\n\t\t\tif (params.length < 3) return this.errorReply(this.tr`Not enough arguments for /poll new.`);\r\n\r\n\t\t\t// the function throws on failure, so no handling needs to be done anymore\r\n\t\t\tif (supportHTML) params = params.map(parameter => this.checkHTML(parameter));\r\n\r\n\t\t\tconst questions = params.splice(1);\r\n\t\t\tif (questions.length > MAX_QUESTIONS) {\r\n\t\t\t\treturn this.errorReply(this.tr`Too many options for poll (maximum is ${MAX_QUESTIONS}).`);\r\n\t\t\t}\r\n\r\n\t\t\tif (new Set(questions).size !== questions.length) {\r\n\t\t\t\treturn this.errorReply(this.tr`There are duplicate options in the poll.`);\r\n\t\t\t}\r\n\r\n\t\t\tif (room.minorActivity) {\r\n\t\t\t\troom.queueMinorActivity({\r\n\t\t\t\t\tquestion: params[0], answers: questions, multiPoll, supportHTML, activityid: 'poll',\r\n\t\t\t\t});\r\n\t\t\t\tthis.modlog('QUEUEPOLL');\r\n\t\t\t\treturn this.privateModAction(room.tr`${user.name} queued a poll.`);\r\n\t\t\t}\r\n\t\t\troom.setMinorActivity(new Poll(room, {\r\n\t\t\t\tquestion: params[0], supportHTML, answers: questions, multiPoll,\r\n\t\t\t}));\r\n\r\n\t\t\tthis.roomlog(`${user.name} used ${message}`);\r\n\t\t\tthis.modlog('POLL');\r\n\t\t\tthis.addModAction(room.tr`A poll was started by ${user.name}.`);\r\n\t\t},\r\n\t\tnewhelp: [\r\n\t\t\t`/poll create [question], [option1], [option2], [...] - Creates a poll. Requires: % @ # &`,\r\n\t\t\t`/poll createmulti [question], [option1], [option2], [...] - Creates a poll, allowing for multiple answers to be selected. Requires: % @ # &`,\r\n\t\t\t`To queue a poll, use [queue], [queuemulti], [queuehtml], or [htmlqueuemulti].`,\r\n\t\t\t`Polls can be used as quiz questions. To do this, prepend all correct answers with a +.`,\r\n\t\t],\r\n\r\n\t\tviewqueue(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tthis.parse(`/join view-pollqueue-${room.roomid}`);\r\n\t\t},\r\n\t\tviewqueuehelp: [`/viewqueue - view the queue of polls in the room. Requires: % @ # &`],\r\n\r\n\t\tdeletequeue(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!target) return this.parse('/help deletequeue');\r\n\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst queue = room.getMinorActivityQueue();\r\n\t\t\tif (!queue) {\r\n\t\t\t\treturn this.errorReply(this.tr`The queue is already empty.`);\r\n\t\t\t}\r\n\t\t\tconst slot = parseInt(target);\r\n\t\t\tif (isNaN(slot)) {\r\n\t\t\t\treturn this.errorReply(this.tr`Can't delete poll at slot ${target} - \"${target}\" is not a number.`);\r\n\t\t\t}\r\n\t\t\tif (!queue[slot - 1]) return this.errorReply(this.tr`There is no poll in queue at slot ${slot}.`);\r\n\r\n\t\t\troom.clearMinorActivityQueue(slot - 1);\r\n\r\n\t\t\troom.modlog({\r\n\t\t\t\taction: 'DELETEQUEUE',\r\n\t\t\t\tloggedBy: user.id,\r\n\t\t\t\tnote: slot.toString(),\r\n\t\t\t});\r\n\t\t\troom.sendMods(this.tr`(${user.name} deleted the queued poll in slot ${slot}.)`);\r\n\t\t\troom.update();\r\n\t\t\tthis.refreshPage(`pollqueue-${room.roomid}`);\r\n\t\t},\r\n\t\tdeletequeuehelp: [\r\n\t\t\t`/poll deletequeue [number] - deletes poll at the corresponding queue slot (1 = next, 2 = the one after that, etc). Requires: % @ # &`,\r\n\t\t],\r\n\t\tclearqueue(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst queue = room.getMinorActivityQueue();\r\n\t\t\tif (!queue) {\r\n\t\t\t\treturn this.errorReply(this.tr`The queue is already empty.`);\r\n\t\t\t}\r\n\t\t\troom.clearMinorActivityQueue();\r\n\t\t\tthis.modlog('CLEARQUEUE');\r\n\t\t\tthis.sendReply(this.tr`Cleared poll queue.`);\r\n\t\t},\r\n\t\tclearqueuehelp: [\r\n\t\t\t`/poll clearqueue - deletes the queue of polls. Requires: % @ # &`,\r\n\t\t],\r\n\r\n\t\tdeselect: 'select',\r\n\t\tvote: 'select',\r\n\t\tselect(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst poll = this.requireMinorActivity(Poll);\r\n\t\t\tif (!target) return this.parse('/help poll vote');\r\n\r\n\t\t\tconst parsed = parseInt(target);\r\n\t\t\tif (isNaN(parsed)) return this.errorReply(this.tr`To vote, specify the number of the option.`);\r\n\r\n\t\t\tif (!poll.answers.has(parsed)) return this.sendReply(this.tr`Option not in poll.`);\r\n\r\n\t\t\tif (cmd === 'deselect') {\r\n\t\t\t\tpoll.deselect(user, parsed);\r\n\t\t\t} else {\r\n\t\t\t\tpoll.select(user, parsed);\r\n\t\t\t}\r\n\t\t},\r\n\t\tselecthelp: [\r\n\t\t\t`/poll select [number] - Select option [number].`,\r\n\t\t\t`/poll deselect [number] - Deselects option [number].`,\r\n\t\t],\r\n\r\n\t\tsubmit(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst poll = this.requireMinorActivity(Poll);\r\n\r\n\t\t\tpoll.submit(user);\r\n\t\t},\r\n\t\tsubmithelp: [`/poll submit - Submits your vote.`],\r\n\r\n\t\ttimer(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst poll = this.requireMinorActivity(Poll);\r\n\r\n\t\t\tif (target) {\r\n\t\t\t\tthis.checkCan('minigame', null, room);\r\n\t\t\t\tif (target === 'clear') {\r\n\t\t\t\t\tif (!poll.endTimer()) return this.errorReply(this.tr(\"There is no timer to clear.\"));\r\n\t\t\t\t\treturn this.add(this.tr`The poll timer was turned off.`);\r\n\t\t\t\t}\r\n\t\t\t\tconst timeoutMins = parseFloat(target);\r\n\t\t\t\tif (isNaN(timeoutMins) || timeoutMins <= 0 || timeoutMins > 7 * 24 * 60) {\r\n\t\t\t\t\treturn this.errorReply(this.tr`Time should be a number of minutes less than one week.`);\r\n\t\t\t\t}\r\n\t\t\t\tpoll.setTimer({timeoutMins});\r\n\t\t\t\troom.add(this.tr`The poll timer was turned on: the poll will end in ${Chat.toDurationString(timeoutMins * MINUTES)}.`);\r\n\t\t\t\tthis.modlog('POLL TIMER', null, `${timeoutMins} minutes`);\r\n\t\t\t\treturn this.privateModAction(room.tr`The poll timer was set to ${timeoutMins} minute(s) by ${user.name}.`);\r\n\t\t\t} else {\r\n\t\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\t\tif (poll.timeout) {\r\n\t\t\t\t\treturn this.sendReply(this.tr`The poll timer is on and will end in ${Chat.toDurationString(poll.timeoutMins * MINUTES)}.`);\r\n\t\t\t\t} else {\r\n\t\t\t\t\treturn this.sendReply(this.tr`The poll timer is off.`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\ttimerhelp: [\r\n\t\t\t`/poll timer [minutes] - Sets the poll to automatically end after [minutes] minutes. Requires: % @ # &`,\r\n\t\t\t`/poll timer clear - Clears the poll's timer. Requires: % @ # &`,\r\n\t\t],\r\n\r\n\t\tresults(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst poll = this.requireMinorActivity(Poll);\r\n\r\n\t\t\tpoll.blankvote(user);\r\n\t\t},\r\n\t\tresultshelp: [\r\n\t\t\t`/poll results - Shows the results of the poll without voting. NOTE: you can't go back and vote after using this.`,\r\n\t\t],\r\n\r\n\t\tclose: 'end',\r\n\t\tstop: 'end',\r\n\t\tend(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('minigame', null, room);\r\n\t\t\tthis.checkChat();\r\n\t\t\tconst poll = this.requireMinorActivity(Poll);\r\n\t\t\tthis.modlog('POLL END');\r\n\t\t\tthis.privateModAction(room.tr`The poll was ended by ${user.name}.`);\r\n\t\t\tpoll.end(room, Poll);\r\n\t\t},\r\n\t\tendhelp: [`/poll end - Ends a poll and displays the results. Requires: % @ # &`],\r\n\r\n\t\tshow: '',\r\n\t\tdisplay: '',\r\n\t\t''(target, room, user, connection) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst poll = this.requireMinorActivity(Poll);\r\n\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\troom.update();\r\n\r\n\t\t\tif (this.broadcasting) {\r\n\t\t\t\tpoll.display();\r\n\t\t\t} else {\r\n\t\t\t\tpoll.displayTo(user, connection);\r\n\t\t\t}\r\n\t\t},\r\n\t\tdisplayhelp: [`/poll display - Displays the poll`],\r\n\r\n\t\tmv: 'maxvotes',\r\n\t\tmaxvotes(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst poll = this.requireMinorActivity(Poll);\r\n\t\t\tlet num = parseInt(target);\r\n\t\t\tif (this.meansNo(target)) { // special case for convenience\r\n\t\t\t\tnum = 0;\r\n\t\t\t}\r\n\t\t\tif (isNaN(num)) {\r\n\t\t\t\treturn this.errorReply(`Invalid max vote cap: '${target}'`);\r\n\t\t\t}\r\n\t\t\tif (poll.maxVotes === num) {\r\n\t\t\t\treturn this.errorReply(`The poll's vote cap is already set to ${num}.`);\r\n\t\t\t}\r\n\t\t\tpoll.maxVotes = num;\r\n\t\t\tthis.addModAction(`${user.name} set the poll's vote cap to ${num}.`);\r\n\t\t\tlet ended = false;\r\n\t\t\tif (poll.totalVotes > poll.maxVotes) {\r\n\t\t\t\tpoll.end(room);\r\n\t\t\t\tthis.addModAction(`The poll has more votes than the maximum vote cap, and has ended.`);\r\n\t\t\t\tended = true;\r\n\t\t\t}\r\n\t\t\tif (!ended) poll.save();\r\n\t\t\tthis.modlog('POLL MAXVOTES', null, `${poll.maxVotes}${ended ? ` (ended poll)` : \"\"}`);\r\n\t\t},\r\n\t},\r\n\tpollhelp() {\r\n\t\tthis.sendReply(\r\n\t\t\t`|html|
/poll allows rooms to run their own polls (limit 1 at a time).
` +\r\n\t\t\t`Polls can be used as quiz questions, by putting + before correct answers.
` +\r\n\t\t\t`/poll create [question], [option1], [option2], [...] - Creates a poll. Requires: % @ # &
` +\r\n\t\t\t`/poll createmulti [question], [option1], [option2], [...] - Creates a poll, allowing for multiple answers to be selected. Requires: % @ # &
` +\r\n\t\t\t`/poll htmlcreate(multi) [question], [option1], [option2], [...] - Creates a poll, with HTML allowed in the question and options. Requires: # &
` +\r\n\t\t\t`/poll vote [number] - Votes for option [number].
` +\r\n\t\t\t`/poll timer [minutes] - Sets the poll to automatically end after [minutes]. Requires: % @ # &.
` +\r\n\t\t\t`/poll results - Shows the results of the poll without voting. NOTE: you can't go back and vote after using this.
` +\r\n\t\t\t`/poll display - Displays the poll.
` +\r\n\t\t\t`/poll end - Ends a poll and displays the results. Requires: % @ # &.
` +\r\n\t\t\t`/poll queue [question], [option1], [option2], [...] - Add a poll in queue. Requires: % @ # &
` +\r\n\t\t\t`/poll deletequeue [number] - Deletes poll at the corresponding queue slot (1 = next, 2 = the one after that, etc).
` +\r\n\t\t\t`/poll clearqueue - Deletes the queue of polls. Requires: % @ # &.
` +\r\n\t\t\t`/poll viewqueue - View the queue of polls in the room. Requires: % @ # &
` +\r\n\t\t\t`/poll maxvotes [number] - Set the max poll votes to the given [number]. Requires: % @ # &
` +\r\n\t\t\t`
`\r\n\t\t);\r\n\t},\r\n};\r\n\r\nexport const pages: Chat.PageTable = {\r\n\tpollqueue(args, user) {\r\n\t\tconst room = this.requireRoom();\r\n\r\n\t\tlet buf = `
${this.tr`Queued polls:`}`;\r\n\t\tbuf += `
`;\r\n\t\tconst queue = room.getMinorActivityQueue()?.filter(activity => activity.activityid === 'poll');\r\n\t\tif (!queue) {\r\n\t\t\tbuf += `
${this.tr`No polls queued.`}
`;\r\n\t\t\treturn buf;\r\n\t\t}\r\n\t\tfor (const [i, poll] of queue.entries()) {\r\n\t\t\tconst number = i + 1; // for translation convienence\r\n\t\t\tconst button = (\r\n\t\t\t\t`${this.tr`#${number} in queue`} ` +\r\n\t\t\t\t``\r\n\t\t\t);\r\n\t\t\tbuf += `
`;\r\n\t\t\tbuf += `${button}
${Poll.generateResults(poll, room, false)}`;\r\n\t\t}\r\n\t\tbuf += `
`;\r\n\t\treturn buf;\r\n\t},\r\n};\r\n\r\nprocess.nextTick(() => {\r\n\tChat.multiLinePattern.register('/poll (new|create|createmulti|htmlcreate|htmlcreatemulti|queue|queuemulti|htmlqueuemulti) ');\r\n});\r\n\r\n// should handle restarts and also hotpatches\r\nfor (const room of Rooms.rooms.values()) {\r\n\tif (room.getMinorActivityQueue(true)) {\r\n\t\tfor (const poll of room.getMinorActivityQueue(true)!) {\r\n\t\t\tif (!poll.activityid) {\r\n\t\t\t\t// @ts-ignore\r\n\t\t\t\tpoll.activityid = poll.activityId;\r\n\t\t\t\t// @ts-ignore\r\n\t\t\t\tdelete poll.activityId;\r\n\t\t\t}\r\n\t\t\tif (!poll.activityNumber) {\r\n\t\t\t\t// @ts-ignore\r\n\t\t\t\tpoll.activityNumber = poll.pollNumber;\r\n\t\t\t\t// @ts-ignore\r\n\t\t\t\tdelete poll.pollNumber;\r\n\t\t\t}\r\n\t\t\troom.saveSettings();\r\n\t\t}\r\n\t}\r\n\tif (room.settings.minorActivity) {\r\n\t\tif (!room.settings.minorActivity.activityid) {\r\n\t\t\t// @ts-ignore\r\n\t\t\troom.settings.minorActivity.activityid = room.settings.minorActivity.activityId;\r\n\t\t\t// @ts-ignore\r\n\t\t\tdelete room.settings.minorActivity.activityId;\r\n\t\t}\r\n\t\tif (typeof room.settings.minorActivity.activityNumber !== 'number') {\r\n\t\t\t// @ts-ignore\r\n\t\t\troom.settings.minorActivity.activityNumber = room.settings.minorActivity.pollNumber ||\r\n\t\t\t\t// @ts-ignore\r\n\t\t\t\troom.settings.minorActivity.announcementNumber;\r\n\t\t}\r\n\t\troom.saveSettings();\r\n\t}\r\n\tif (room.settings.minorActivity?.activityid === 'poll') {\r\n\t\troom.setMinorActivity(new Poll(room, room.settings.minorActivity), true);\r\n\t}\r\n}\r\n"], "mappings": "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", "names": [] }