{ "version": 3, "sources": ["../../../../server/chat-plugins/lottery.ts"], "sourcesContent": ["const LOTTERY_FILE = 'config/chat-plugins/lottery.json';\r\n\r\nimport {FS, Utils} from '../../lib';\r\n\r\nconst lotteriesContents = FS(LOTTERY_FILE).readIfExistsSync();\r\nconst lotteries: {\r\n\t[roomid: string]: {\r\n\t\tmaxWinners: number,\r\n\t\tname: string,\r\n\t\tmarkup: string,\r\n\t\tparticipants: {[ip: string]: string},\r\n\t\twinners: string[],\r\n\t\trunning: boolean,\r\n\t},\r\n} = lotteriesContents ? Object.assign(Object.create(null), JSON.parse(lotteriesContents)) : Object.create(null);\r\n\r\nfunction createLottery(roomid: RoomID, maxWinners: number, name: string, markup: string) {\r\n\tif (lotteries[roomid] && !lotteries[roomid].running) {\r\n\t\tdelete lotteries[roomid];\r\n\t}\r\n\tconst lottery = lotteries[roomid];\r\n\tlotteries[roomid] = {\r\n\t\tmaxWinners, name, markup, participants: lottery?.participants || Object.create(null),\r\n\t\twinners: lottery?.winners || [], running: true,\r\n\t};\r\n\twriteLotteries();\r\n}\r\nfunction writeLotteries() {\r\n\tfor (const roomid of Object.keys(lotteries)) {\r\n\t\tif (!Rooms.get(roomid)) {\r\n\t\t\tdelete lotteries[roomid];\r\n\t\t}\r\n\t}\r\n\tFS(LOTTERY_FILE).writeUpdate(() => JSON.stringify(lotteries));\r\n}\r\nfunction destroyLottery(roomid: RoomID) {\r\n\tdelete lotteries[roomid];\r\n\twriteLotteries();\r\n}\r\nfunction endLottery(roomid: RoomID, winners: string[]) {\r\n\tconst lottery = lotteries[roomid];\r\n\tif (!lottery) return;\r\n\tlottery.winners = winners;\r\n\tlottery.running = false;\r\n\tObject.freeze(lottery);\r\n\twriteLotteries();\r\n}\r\n\r\nfunction isSignedUp(roomid: RoomID, user: User) {\r\n\tconst lottery = lotteries[roomid];\r\n\tif (!lottery) return;\r\n\tconst participants = lottery.participants;\r\n\tconst participantNames = Object.values(participants).map(toID);\r\n\tif (participantNames.includes(user.id)) return true;\r\n\tif (Config.noipchecks) return false;\r\n\treturn !!participants[user.latestIp];\r\n}\r\n\r\nfunction addUserToLottery(roomid: RoomID, user: User) {\r\n\tconst lottery = lotteries[roomid];\r\n\tif (!lottery) return;\r\n\tconst participants = lottery.participants;\r\n\tif (!isSignedUp(roomid, user)) {\r\n\t\tparticipants[user.latestIp] = user.name;\r\n\t\twriteLotteries();\r\n\t\treturn true;\r\n\t}\r\n\treturn false;\r\n}\r\nfunction removeUserFromLottery(roomid: RoomID, user: User) {\r\n\tconst lottery = lotteries[roomid];\r\n\tif (!lottery) return;\r\n\tconst participants = lottery.participants;\r\n\tfor (const [ip, participant] of Object.entries(participants)) {\r\n\t\tif (toID(participant) === user.id || ip === user.latestIp) {\r\n\t\t\tdelete participants[ip];\r\n\t\t\twriteLotteries();\r\n\t\t\treturn true;\r\n\t\t}\r\n\t}\r\n\treturn false;\r\n}\r\nfunction getWinnersInLottery(roomid: RoomID) {\r\n\tconst lottery = lotteries[roomid];\r\n\tif (!lottery) return;\r\n\tconst winners = [];\r\n\tconst participants = Object.values(lottery.participants);\r\n\tfor (let i = 0; i < lottery.maxWinners; i++) {\r\n\t\tconst randomIdx = participants.length * Math.random() << 0;\r\n\t\tconst winner = participants[randomIdx];\r\n\t\twinners.push(winner);\r\n\t\tparticipants.splice(randomIdx, 1);\r\n\t}\r\n\treturn winners;\r\n}\r\n\r\nexport const commands: Chat.ChatCommands = {\r\n\tlottery: {\r\n\t\t''(target, room) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst lottery = lotteries[room.roomid];\r\n\t\t\tif (!lottery) {\r\n\t\t\t\treturn this.errorReply(\"This room doesn't have a lottery running.\");\r\n\t\t\t}\r\n\t\t\treturn this.parse(`/join view-lottery-${room.roomid}`);\r\n\t\t},\r\n\t\tedit: 'create',\r\n\t\tcreate(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('declare', null, room);\r\n\t\t\tif (room.battle || !room.persist) {\r\n\t\t\t\treturn this.errorReply('This room does not support the creation of lotteries.');\r\n\t\t\t}\r\n\t\t\tconst lottery = lotteries[room.roomid];\r\n\t\t\tconst edited = lottery?.running;\r\n\t\t\tif (cmd === 'edit' && !target && lottery) {\r\n\t\t\t\tthis.sendReply('Source:');\r\n\t\t\t\tconst markup = Utils.html`${lottery.markup}`.replace(/\\n/g, '
');\r\n\t\t\t\treturn this.sendReplyBox(`/lottery edit ${lottery.maxWinners}, ${lottery.name}, ${markup}`);\r\n\t\t\t}\r\n\t\t\tconst [maxWinners, name, markup] = Utils.splitFirst(target, ',', 2).map(val => val.trim());\r\n\t\t\tif (!(maxWinners && name && markup.length)) {\r\n\t\t\t\treturn this.errorReply(\"You're missing a command parameter - see /help lottery for this command's syntax.\");\r\n\t\t\t}\r\n\t\t\tconst maxWinnersNum = parseInt(maxWinners);\r\n\t\t\tthis.checkHTML(markup);\r\n\t\t\tif (isNaN(maxWinnersNum)) {\r\n\t\t\t\treturn this.errorReply(`${maxWinners} is not a valid number.`);\r\n\t\t\t}\r\n\t\t\tif (maxWinnersNum < 1) {\r\n\t\t\t\treturn this.errorReply('The maximum winners should be at least 1.');\r\n\t\t\t}\r\n\t\t\tif (maxWinnersNum > Number.MAX_SAFE_INTEGER) {\r\n\t\t\t\treturn this.errorReply('The maximum winners number is too large, please pick a smaller number.');\r\n\t\t\t}\r\n\t\t\tif (name.length > 50) {\r\n\t\t\t\treturn this.errorReply('Name needs to be under 50 characters.');\r\n\t\t\t}\r\n\t\t\tcreateLottery(room.roomid, maxWinnersNum, name, markup);\r\n\t\t\tthis.sendReply(`The lottery was successfully ${edited ? 'edited' : 'created'}.`);\r\n\t\t\tif (!edited) {\r\n\t\t\t\tthis.add(\r\n\t\t\t\t\tUtils.html`|raw|
${user.name} created the` +\r\n\t\t\t\t\t` \"${name}\" lottery!
`\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\tthis.modlog(`LOTTERY ${edited ? 'EDIT' : 'CREATE'} ${name}`, null, `${maxWinnersNum} max winners`);\r\n\t\t},\r\n\t\tdelete(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('declare', null, room);\r\n\t\t\tconst lottery = lotteries[room.roomid];\r\n\t\t\tif (!lottery) {\r\n\t\t\t\treturn this.errorReply('This room does not have a lottery running.');\r\n\t\t\t}\r\n\t\t\tdestroyLottery(room.roomid);\r\n\t\t\tthis.addModAction(`${user.name} deleted the \"${lottery.name}\" lottery.`);\r\n\t\t\tthis.modlog('LOTTERY DELETE');\r\n\t\t\tthis.sendReply('The lottery was successfully deleted.');\r\n\t\t},\r\n\t\tend(target, room) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('declare', null, room);\r\n\t\t\tconst lottery = lotteries[room.roomid];\r\n\t\t\tif (!lottery) {\r\n\t\t\t\treturn this.errorReply('This room does not have a lottery running.');\r\n\t\t\t}\r\n\t\t\tif (!lottery.running) {\r\n\t\t\t\treturn this.errorReply(`The \"${lottery.name}\" lottery already ended.`);\r\n\t\t\t}\r\n\t\t\tfor (const [ip, participant] of Object.entries(lottery.participants)) {\r\n\t\t\t\tconst userid = toID(participant);\r\n\t\t\t\tconst pUser = Users.get(userid);\r\n\t\t\t\tif (\r\n\t\t\t\t\tPunishments.userids.get(userid) ||\r\n\t\t\t\t\tPunishments.getRoomPunishments(pUser || userid, {publicOnly: true, checkIps: true}).length\r\n\t\t\t\t) {\r\n\t\t\t\t\tdelete lottery.participants[ip];\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (lottery.maxWinners >= Object.keys(lottery.participants).length) {\r\n\t\t\t\treturn this.errorReply('There have been not enough participants for you to be able to end this. If you wish to end it anyway use /lottery delete.');\r\n\t\t\t}\r\n\t\t\tconst winners = getWinnersInLottery(room.roomid);\r\n\t\t\tif (!winners) return this.errorReply(`An error occured while getting the winners.`);\r\n\t\t\tthis.add(\r\n\t\t\t\tUtils.html`|raw|
${Chat.toListString(winners)} won the \"${lottery.name}\" lottery!
`\r\n\t\t\t);\r\n\t\t\tthis.modlog(`LOTTERY END ${lottery.name}`);\r\n\t\t\tendLottery(room.roomid, winners);\r\n\t\t},\r\n\t\tjoin(target, room, user) {\r\n\t\t\t// This hack is used for the HTML room to be able to\r\n\t\t\t// join lotteries in other rooms from the global room\r\n\t\t\tconst roomid = target || room?.roomid;\r\n\t\t\tif (!roomid) {\r\n\t\t\t\treturn this.errorReply(`This is not a valid room.`);\r\n\t\t\t}\r\n\t\t\tconst lottery = lotteries[roomid];\r\n\t\t\tif (!lottery) {\r\n\t\t\t\treturn this.errorReply(`${roomid} does not have a lottery running.`);\r\n\t\t\t}\r\n\t\t\tif (!lottery.running) {\r\n\t\t\t\treturn this.errorReply(`The \"${lottery.name}\" lottery already ended.`);\r\n\t\t\t}\r\n\t\t\tif (!user.named) {\r\n\t\t\t\treturn this.popupReply('You must be logged into an account to participate.');\r\n\t\t\t}\r\n\t\t\tif (!user.autoconfirmed) {\r\n\t\t\t\treturn this.popupReply('You must be autoconfirmed to join lotteries.');\r\n\t\t\t}\r\n\t\t\tif (user.locked || Punishments.getRoomPunishments(user, {publicOnly: true, checkIps: true}).length) {\r\n\t\t\t\treturn this.popupReply('Punished users cannot join lotteries.');\r\n\t\t\t}\r\n\t\t\tconst success = addUserToLottery(roomid as RoomID, user);\r\n\t\t\tif (success) {\r\n\t\t\t\tthis.popupReply('You have successfully joined the lottery.');\r\n\t\t\t} else {\r\n\t\t\t\tthis.popupReply('You are already in the lottery.');\r\n\t\t\t}\r\n\t\t},\r\n\t\tleave(target, room, user) {\r\n\t\t\t// This hack is used for the HTML room to be able to\r\n\t\t\t// join lotteries in other rooms from the global room\r\n\t\t\tconst roomid = target || room?.roomid;\r\n\t\t\tif (!roomid) {\r\n\t\t\t\treturn this.errorReply('This can only be used in rooms.');\r\n\t\t\t}\r\n\t\t\tconst lottery = lotteries[roomid];\r\n\t\t\tif (!lottery) {\r\n\t\t\t\treturn this.errorReply(`${roomid} does not have a lottery running.`);\r\n\t\t\t}\r\n\t\t\tif (!lottery.running) {\r\n\t\t\t\treturn this.errorReply(`The \"${lottery.name}\" lottery already ended.`);\r\n\t\t\t}\r\n\t\t\tconst success = removeUserFromLottery(roomid as RoomID, user);\r\n\t\t\tif (success) {\r\n\t\t\t\tthis.popupReply('You have successfully left the lottery.');\r\n\t\t\t} else {\r\n\t\t\t\tthis.popupReply('You have not joined the lottery.');\r\n\t\t\t}\r\n\t\t},\r\n\t\tparticipants(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst lottery = lotteries[room.roomid];\r\n\t\t\tif (!lottery) {\r\n\t\t\t\treturn this.errorReply('This room does not have a lottery running.');\r\n\t\t\t}\r\n\t\t\tconst canSeeIps = user.can('ip');\r\n\t\t\tconst participants = Object.entries(lottery.participants).map(\r\n\t\t\t\t([ip, participant]) => `- ${participant}${canSeeIps ? ' (IP: ' + ip + ')' : ''}`\r\n\t\t\t);\r\n\t\t\tlet buf = '';\r\n\t\t\tif (user.can('declare', null, room)) {\r\n\t\t\t\tbuf += `
List of participants (${participants.length}):${participants.join('
')}
`;\r\n\t\t\t} else {\r\n\t\t\t\tbuf += `${participants.length} participant(s) joined this lottery.`;\r\n\t\t\t}\r\n\t\t\tthis.sendReplyBox(buf);\r\n\t\t},\r\n\t\thelp() {\r\n\t\t\treturn this.parse('/help lottery');\r\n\t\t},\r\n\t},\r\n\tlotteryhelp: [\r\n\t\t`/lottery - opens the current lottery, if it exists.`,\r\n\t\t`/lottery create max winners, name, html - creates a new lottery with [name] as the header and [html] as body. Max winners is the amount of people that will win the lottery. Requires # &`,\r\n\t\t`/lottery delete - deletes the current lottery without declaring a winner. Requires # &`,\r\n\t\t`/lottery end - ends the current lottery, declaring a random participant as the winner. Requires # &`,\r\n\t\t`/lottery edit max winners, name, html - edits the lottery with the provided parameters. Requires # &`,\r\n\t\t`/lottery join - joins the current lottery, if it exists, you need to be not currently punished in any public room, not locked and be autoconfirmed.`,\r\n\t\t`/lottery leave - leaves the current lottery, if it exists.`,\r\n\t\t`/lottery participants - shows the current participants in the lottery.`,\r\n\t],\r\n};\r\n\r\nexport const pages: Chat.PageTable = {\r\n\tlottery(query, user) {\r\n\t\tthis.title = 'Lottery';\r\n\t\tconst room = this.requireRoom();\r\n\r\n\t\tlet buf = '
';\r\n\t\tconst lottery = lotteries[room.roomid];\r\n\t\tif (!lottery) {\r\n\t\t\tbuf += `

There is no lottery running in ${room.title}

`;\r\n\t\t\treturn buf;\r\n\t\t}\r\n\t\tbuf += `

${lottery.name}

${lottery.markup}
`;\r\n\t\tif (lottery.running) {\r\n\t\t\tconst userSignedUp = lottery.participants[user.latestIp] ||\r\n\t\t\t\tObject.values(lottery.participants).map(toID).includes(user.id);\r\n\t\t\tbuf += ``;\r\n\t\t} else {\r\n\t\t\tbuf += '

This lottery has already ended. The winners are:

';\r\n\t\t\tbuf += '';\r\n\t\t}\r\n\t\treturn buf;\r\n\t},\r\n};\r\n"], "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAwB;AAFxB,MAAM,eAAe;AAIrB,MAAM,wBAAoB,eAAG,YAAY,EAAE,iBAAiB;AAC5D,MAAM,YASF,oBAAoB,OAAO,OAAO,uBAAO,OAAO,IAAI,GAAG,KAAK,MAAM,iBAAiB,CAAC,IAAI,uBAAO,OAAO,IAAI;AAE9G,SAAS,cAAc,QAAgB,YAAoB,MAAc,QAAgB;AACxF,MAAI,UAAU,MAAM,KAAK,CAAC,UAAU,MAAM,EAAE,SAAS;AACpD,WAAO,UAAU,MAAM;AAAA,EACxB;AACA,QAAM,UAAU,UAAU,MAAM;AAChC,YAAU,MAAM,IAAI;AAAA,IACnB;AAAA,IAAY;AAAA,IAAM;AAAA,IAAQ,cAAc,SAAS,gBAAgB,uBAAO,OAAO,IAAI;AAAA,IACnF,SAAS,SAAS,WAAW,CAAC;AAAA,IAAG,SAAS;AAAA,EAC3C;AACA,iBAAe;AAChB;AACA,SAAS,iBAAiB;AACzB,aAAW,UAAU,OAAO,KAAK,SAAS,GAAG;AAC5C,QAAI,CAAC,MAAM,IAAI,MAAM,GAAG;AACvB,aAAO,UAAU,MAAM;AAAA,IACxB;AAAA,EACD;AACA,qBAAG,YAAY,EAAE,YAAY,MAAM,KAAK,UAAU,SAAS,CAAC;AAC7D;AACA,SAAS,eAAe,QAAgB;AACvC,SAAO,UAAU,MAAM;AACvB,iBAAe;AAChB;AACA,SAAS,WAAW,QAAgB,SAAmB;AACtD,QAAM,UAAU,UAAU,MAAM;AAChC,MAAI,CAAC;AAAS;AACd,UAAQ,UAAU;AAClB,UAAQ,UAAU;AAClB,SAAO,OAAO,OAAO;AACrB,iBAAe;AAChB;AAEA,SAAS,WAAW,QAAgB,MAAY;AAC/C,QAAM,UAAU,UAAU,MAAM;AAChC,MAAI,CAAC;AAAS;AACd,QAAM,eAAe,QAAQ;AAC7B,QAAM,mBAAmB,OAAO,OAAO,YAAY,EAAE,IAAI,IAAI;AAC7D,MAAI,iBAAiB,SAAS,KAAK,EAAE;AAAG,WAAO;AAC/C,MAAI,OAAO;AAAY,WAAO;AAC9B,SAAO,CAAC,CAAC,aAAa,KAAK,QAAQ;AACpC;AAEA,SAAS,iBAAiB,QAAgB,MAAY;AACrD,QAAM,UAAU,UAAU,MAAM;AAChC,MAAI,CAAC;AAAS;AACd,QAAM,eAAe,QAAQ;AAC7B,MAAI,CAAC,WAAW,QAAQ,IAAI,GAAG;AAC9B,iBAAa,KAAK,QAAQ,IAAI,KAAK;AACnC,mBAAe;AACf,WAAO;AAAA,EACR;AACA,SAAO;AACR;AACA,SAAS,sBAAsB,QAAgB,MAAY;AAC1D,QAAM,UAAU,UAAU,MAAM;AAChC,MAAI,CAAC;AAAS;AACd,QAAM,eAAe,QAAQ;AAC7B,aAAW,CAAC,IAAI,WAAW,KAAK,OAAO,QAAQ,YAAY,GAAG;AAC7D,QAAI,KAAK,WAAW,MAAM,KAAK,MAAM,OAAO,KAAK,UAAU;AAC1D,aAAO,aAAa,EAAE;AACtB,qBAAe;AACf,aAAO;AAAA,IACR;AAAA,EACD;AACA,SAAO;AACR;AACA,SAAS,oBAAoB,QAAgB;AAC5C,QAAM,UAAU,UAAU,MAAM;AAChC,MAAI,CAAC;AAAS;AACd,QAAM,UAAU,CAAC;AACjB,QAAM,eAAe,OAAO,OAAO,QAAQ,YAAY;AACvD,WAAS,IAAI,GAAG,IAAI,QAAQ,YAAY,KAAK;AAC5C,UAAM,YAAY,aAAa,SAAS,KAAK,OAAO,KAAK;AACzD,UAAM,SAAS,aAAa,SAAS;AACrC,YAAQ,KAAK,MAAM;AACnB,iBAAa,OAAO,WAAW,CAAC;AAAA,EACjC;AACA,SAAO;AACR;AAEO,MAAM,WAA8B;AAAA,EAC1C,SAAS;AAAA,IACR,GAAG,QAAQ,MAAM;AAChB,aAAO,KAAK,YAAY;AACxB,YAAM,UAAU,UAAU,KAAK,MAAM;AACrC,UAAI,CAAC,SAAS;AACb,eAAO,KAAK,WAAW,2CAA2C;AAAA,MACnE;AACA,aAAO,KAAK,MAAM,sBAAsB,KAAK,QAAQ;AAAA,IACtD;AAAA,IACA,MAAM;AAAA,IACN,OAAO,QAAQ,MAAM,MAAM,YAAY,KAAK;AAC3C,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,WAAW,MAAM,IAAI;AACnC,UAAI,KAAK,UAAU,CAAC,KAAK,SAAS;AACjC,eAAO,KAAK,WAAW,uDAAuD;AAAA,MAC/E;AACA,YAAM,UAAU,UAAU,KAAK,MAAM;AACrC,YAAM,SAAS,SAAS;AACxB,UAAI,QAAQ,UAAU,CAAC,UAAU,SAAS;AACzC,aAAK,UAAU,SAAS;AACxB,cAAMA,UAAS,iBAAM,OAAO,QAAQ,SAAS,QAAQ,OAAO,QAAQ;AACpE,eAAO,KAAK,aAAa,qDAAqD,QAAQ,eAAe,QAAQ,SAASA,gBAAe;AAAA,MACtI;AACA,YAAM,CAAC,YAAY,MAAM,MAAM,IAAI,iBAAM,WAAW,QAAQ,KAAK,CAAC,EAAE,IAAI,SAAO,IAAI,KAAK,CAAC;AACzF,UAAI,EAAE,cAAc,QAAQ,OAAO,SAAS;AAC3C,eAAO,KAAK,WAAW,mFAAmF;AAAA,MAC3G;AACA,YAAM,gBAAgB,SAAS,UAAU;AACzC,WAAK,UAAU,MAAM;AACrB,UAAI,MAAM,aAAa,GAAG;AACzB,eAAO,KAAK,WAAW,GAAG,mCAAmC;AAAA,MAC9D;AACA,UAAI,gBAAgB,GAAG;AACtB,eAAO,KAAK,WAAW,2CAA2C;AAAA,MACnE;AACA,UAAI,gBAAgB,OAAO,kBAAkB;AAC5C,eAAO,KAAK,WAAW,wEAAwE;AAAA,MAChG;AACA,UAAI,KAAK,SAAS,IAAI;AACrB,eAAO,KAAK,WAAW,uCAAuC;AAAA,MAC/D;AACA,oBAAc,KAAK,QAAQ,eAAe,MAAM,MAAM;AACtD,WAAK,UAAU,gCAAgC,SAAS,WAAW,YAAY;AAC/E,UAAI,CAAC,QAAQ;AACZ,aAAK;AAAA,UACJ,iBAAM,2CAA2C,KAAK,qBACtD,4BAA4B,KAAK,WAAW;AAAA,QAC7C;AAAA,MACD;AACA,WAAK,OAAO,WAAW,SAAS,SAAS,YAAY,QAAQ,MAAM,GAAG,2BAA2B;AAAA,IAClG;AAAA,IACA,OAAO,QAAQ,MAAM,MAAM;AAC1B,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,WAAW,MAAM,IAAI;AACnC,YAAM,UAAU,UAAU,KAAK,MAAM;AACrC,UAAI,CAAC,SAAS;AACb,eAAO,KAAK,WAAW,4CAA4C;AAAA,MACpE;AACA,qBAAe,KAAK,MAAM;AAC1B,WAAK,aAAa,GAAG,KAAK,qBAAqB,QAAQ,gBAAgB;AACvE,WAAK,OAAO,gBAAgB;AAC5B,WAAK,UAAU,uCAAuC;AAAA,IACvD;AAAA,IACA,IAAI,QAAQ,MAAM;AACjB,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,WAAW,MAAM,IAAI;AACnC,YAAM,UAAU,UAAU,KAAK,MAAM;AACrC,UAAI,CAAC,SAAS;AACb,eAAO,KAAK,WAAW,4CAA4C;AAAA,MACpE;AACA,UAAI,CAAC,QAAQ,SAAS;AACrB,eAAO,KAAK,WAAW,QAAQ,QAAQ,8BAA8B;AAAA,MACtE;AACA,iBAAW,CAAC,IAAI,WAAW,KAAK,OAAO,QAAQ,QAAQ,YAAY,GAAG;AACrE,cAAM,SAAS,KAAK,WAAW;AAC/B,cAAM,QAAQ,MAAM,IAAI,MAAM;AAC9B,YACC,YAAY,QAAQ,IAAI,MAAM,KAC9B,YAAY,mBAAmB,SAAS,QAAQ,EAAC,YAAY,MAAM,UAAU,KAAI,CAAC,EAAE,QACnF;AACD,iBAAO,QAAQ,aAAa,EAAE;AAAA,QAC/B;AAAA,MACD;AACA,UAAI,QAAQ,cAAc,OAAO,KAAK,QAAQ,YAAY,EAAE,QAAQ;AACnE,eAAO,KAAK,WAAW,2HAA2H;AAAA,MACnJ;AACA,YAAM,UAAU,oBAAoB,KAAK,MAAM;AAC/C,UAAI,CAAC;AAAS,eAAO,KAAK,WAAW,6CAA6C;AAClF,WAAK;AAAA,QACJ,iBAAM,2CAA2C,KAAK,aAAa,OAAO,qCAAqC,KAAK,WAAW,QAAQ;AAAA,MACxI;AACA,WAAK,OAAO,eAAe,QAAQ,MAAM;AACzC,iBAAW,KAAK,QAAQ,OAAO;AAAA,IAChC;AAAA,IACA,KAAK,QAAQ,MAAM,MAAM;AAGxB,YAAM,SAAS,UAAU,MAAM;AAC/B,UAAI,CAAC,QAAQ;AACZ,eAAO,KAAK,WAAW,2BAA2B;AAAA,MACnD;AACA,YAAM,UAAU,UAAU,MAAM;AAChC,UAAI,CAAC,SAAS;AACb,eAAO,KAAK,WAAW,GAAG,yCAAyC;AAAA,MACpE;AACA,UAAI,CAAC,QAAQ,SAAS;AACrB,eAAO,KAAK,WAAW,QAAQ,QAAQ,8BAA8B;AAAA,MACtE;AACA,UAAI,CAAC,KAAK,OAAO;AAChB,eAAO,KAAK,WAAW,oDAAoD;AAAA,MAC5E;AACA,UAAI,CAAC,KAAK,eAAe;AACxB,eAAO,KAAK,WAAW,8CAA8C;AAAA,MACtE;AACA,UAAI,KAAK,UAAU,YAAY,mBAAmB,MAAM,EAAC,YAAY,MAAM,UAAU,KAAI,CAAC,EAAE,QAAQ;AACnG,eAAO,KAAK,WAAW,uCAAuC;AAAA,MAC/D;AACA,YAAM,UAAU,iBAAiB,QAAkB,IAAI;AACvD,UAAI,SAAS;AACZ,aAAK,WAAW,2CAA2C;AAAA,MAC5D,OAAO;AACN,aAAK,WAAW,iCAAiC;AAAA,MAClD;AAAA,IACD;AAAA,IACA,MAAM,QAAQ,MAAM,MAAM;AAGzB,YAAM,SAAS,UAAU,MAAM;AAC/B,UAAI,CAAC,QAAQ;AACZ,eAAO,KAAK,WAAW,iCAAiC;AAAA,MACzD;AACA,YAAM,UAAU,UAAU,MAAM;AAChC,UAAI,CAAC,SAAS;AACb,eAAO,KAAK,WAAW,GAAG,yCAAyC;AAAA,MACpE;AACA,UAAI,CAAC,QAAQ,SAAS;AACrB,eAAO,KAAK,WAAW,QAAQ,QAAQ,8BAA8B;AAAA,MACtE;AACA,YAAM,UAAU,sBAAsB,QAAkB,IAAI;AAC5D,UAAI,SAAS;AACZ,aAAK,WAAW,yCAAyC;AAAA,MAC1D,OAAO;AACN,aAAK,WAAW,kCAAkC;AAAA,MACnD;AAAA,IACD;AAAA,IACA,aAAa,QAAQ,MAAM,MAAM;AAChC,aAAO,KAAK,YAAY;AACxB,YAAM,UAAU,UAAU,KAAK,MAAM;AACrC,UAAI,CAAC,SAAS;AACb,eAAO,KAAK,WAAW,4CAA4C;AAAA,MACpE;AACA,YAAM,YAAY,KAAK,IAAI,IAAI;AAC/B,YAAM,eAAe,OAAO,QAAQ,QAAQ,YAAY,EAAE;AAAA,QACzD,CAAC,CAAC,IAAI,WAAW,MAAM,KAAK,cAAc,YAAY,WAAW,KAAK,MAAM;AAAA,MAC7E;AACA,UAAI,MAAM;AACV,UAAI,KAAK,IAAI,WAAW,MAAM,IAAI,GAAG;AACpC,eAAO,oEAAoE,aAAa,8BAA8B,aAAa,KAAK,MAAM;AAAA,MAC/I,OAAO;AACN,eAAO,GAAG,aAAa;AAAA,MACxB;AACA,WAAK,aAAa,GAAG;AAAA,IACtB;AAAA,IACA,OAAO;AACN,aAAO,KAAK,MAAM,eAAe;AAAA,IAClC;AAAA,EACD;AAAA,EACA,aAAa;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;AAEO,MAAM,QAAwB;AAAA,EACpC,QAAQ,OAAO,MAAM;AACpB,SAAK,QAAQ;AACb,UAAM,OAAO,KAAK,YAAY;AAE9B,QAAI,MAAM;AACV,UAAM,UAAU,UAAU,KAAK,MAAM;AACrC,QAAI,CAAC,SAAS;AACb,aAAO,sCAAsC,KAAK;AAClD,aAAO;AAAA,IACR;AACA,WAAO,kCAAkC,QAAQ,YAAY,QAAQ;AACrE,QAAI,QAAQ,SAAS;AACpB,YAAM,eAAe,QAAQ,aAAa,KAAK,QAAQ,KACtD,OAAO,OAAO,QAAQ,YAAY,EAAE,IAAI,IAAI,EAAE,SAAS,KAAK,EAAE;AAC/D,aAAO,8FAA8F,eAAe,UAAU,UAAU,KAAK,WAAW,eAAe,eAAe;AAAA,IACvL,OAAO;AACN,aAAO;AACP,aAAO;AACP,iBAAW,UAAU,QAAQ,SAAS;AACrC,eAAO,OAAO;AAAA,MACf;AACA,aAAO;AAAA,IACR;AACA,WAAO;AAAA,EACR;AACD;", "names": ["markup"] }