{ "version": 3, "sources": ["../../../server/chat-plugins/github.ts"], "sourcesContent": ["/**\n * Chat plugin to view GitHub events in a chatroom.\n * By Mia, with design / html from xfix's original bot, https://github.com/xfix/GitHub-Bot-Legacy/\n * @author mia-pi-git\n */\n\nimport { FS, Utils } from '../../lib';\n\nconst STAFF_REPOS = Config.staffrepos || [\n\t'pokemon-showdown', 'pokemon-showdown-client', 'Pokemon-Showdown-Dex', 'pokemon-showdown-loginserver',\n];\nconst COOLDOWN = 10 * 60 * 1000;\n\nexport const gitData: GitData = JSON.parse(FS(\"config/chat-plugins/github.json\").readIfExistsSync() || \"{}\");\n\ninterface GitHookHandler {\n\ton(event: 'pull_request', callback: (repo: string, ref: string | undefined, result: PullRequest) => void): void;\n\ton(event: 'push', callback: (repo: string, ref: string, result: Push) => void): void;\n\ton(event: string, callback: (repo: string, ref: string | undefined, result: any) => void): void;\n\tlisten(): void;\n\tserver: import('http').Server;\n}\n\ninterface Push {\n\tcommits: Commit[];\n\tsender: { login: string };\n\tcompare: string;\n}\n\ninterface PullRequest {\n\taction: string;\n\tnumber: number;\n\tpull_request: {\n\t\turl: string,\n\t\thtml_url: string,\n\t\ttitle: string,\n\t\tuser: {\n\t\t\tlogin: string,\n\t\t\thtml_url: string,\n\t\t},\n\t\tmerge_commit_sha: string,\n\t};\n\tsender: { login: string };\n}\n\ninterface Commit {\n\tid: string;\n\tmessage: string;\n\tauthor: { name: string, avatar_url: string };\n\turl: string;\n}\n\ninterface GitData {\n\tusernames?: { [username: string]: string };\n\tbans?: { [username: string]: string };\n}\n\nexport const GitHub = new class {\n\treadonly hook: GitHookHandler | null = null;\n\tupdates: { [k: string]: number } = Object.create(null);\n\tconstructor() {\n\t\t// config.github: https://github.com/nlf/node-github-hook#readme\n\t\tif (!Config.github) return;\n\n\t\ttry {\n\t\t\tthis.hook = require('githubhook')({\n\t\t\t\tlogger: {\n\t\t\t\t\tlog: (line: string) => Monitor.debug(line),\n\t\t\t\t\terror: (line: string) => Monitor.notice(line),\n\t\t\t\t},\n\t\t\t\t...Config.github,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tMonitor.crashlog(err, \"GitHub hook\");\n\t\t}\n\t\tthis.listen();\n\t}\n\tlisten() {\n\t\tif (!this.hook) return;\n\t\tthis.hook.listen();\n\t\tthis.hook.on('push', (repo, ref, result) => this.handlePush(repo, ref, result));\n\t\tthis.hook.on('pull_request', (repo, ref, result) => this.handlePull(repo, ref, result));\n\t}\n\tprivate getRepoName(repo: string) {\n\t\tswitch (repo) {\n\t\tcase 'pokemon-showdown':\n\t\t\treturn 'server';\n\t\tcase 'pokemon-showdown-client':\n\t\t\treturn 'client';\n\t\tcase 'Pokemon-Showdown-Dex':\n\t\t\treturn 'dex';\n\t\tdefault:\n\t\t\treturn repo.toLowerCase();\n\t\t}\n\t}\n\thandlePush(repo: string, ref: string, result: Push) {\n\t\tconst branch = /[^/]+$/.exec(ref)?.[0] || \"\";\n\t\tif (branch !== 'master') return;\n\t\tconst messages: { [k: string]: string[] } = {\n\t\t\tstaff: [],\n\t\t\tdevelopment: [],\n\t\t};\n\t\tfor (const commit of result.commits) {\n\t\t\tconst { message, url } = commit;\n\t\t\tconst [shortMessage] = message.split('\\n\\n');\n\t\t\tconst username = this.getUsername(commit.author.name);\n\t\t\tconst repoName = this.getRepoName(repo);\n\t\t\tconst id = commit.id.substring(0, 6);\n\t\t\tmessages.development.push(\n\t\t\t\tUtils.html`[${repoName}] ${id} ${shortMessage} (${username})`\n\t\t\t);\n\t\t\tmessages.staff.push(Utils.html`[${repoName}] ${shortMessage} (${username})`);\n\t\t}\n\t\tfor (const k in messages) {\n\t\t\tthis.report(k as RoomID, repo, messages[k as RoomID]);\n\t\t}\n\t}\n\thandlePull(repo: string, ref: string | undefined, result: PullRequest) {\n\t\tif (this.isRateLimited(result.number)) return;\n\t\tif (this.isGitbanned(result)) return;\n\t\tconst url = result.pull_request.html_url;\n\t\tconst action = this.isValidAction(result.action);\n\t\tif (!action) return;\n\t\tconst repoName = this.getRepoName(repo);\n\t\tconst userName = this.getUsername(result.sender.login);\n\t\tconst title = result.pull_request.title;\n\t\tlet buf = Utils.html`[${repoName}] ${userName} `;\n\t\tbuf += Utils.html`${action} PR#${result.number}: ${title}`;\n\t\tthis.report('development', repo, buf);\n\t}\n\treport(roomid: RoomID, repo: string, messages: string[] | string) {\n\t\tif (!STAFF_REPOS.includes(repo) && roomid === 'staff') return;\n\t\tif (Array.isArray(messages)) messages = messages.join('
');\n\t\tRooms.get(roomid)?.add(`|html|
${messages}
`).update();\n\t}\n\tisGitbanned(result: PullRequest) {\n\t\tif (!gitData.bans) return false;\n\t\treturn gitData.bans[result.sender.login] || gitData.bans[result.pull_request.user.login];\n\t}\n\tisRateLimited(prNumber: number) {\n\t\tif (this.updates[prNumber]) {\n\t\t\tif (this.updates[prNumber] + COOLDOWN > Date.now()) return true;\n\t\t\tthis.updates[prNumber] = Date.now();\n\t\t\treturn false;\n\t\t}\n\t\tthis.updates[prNumber] = Date.now();\n\t\treturn false;\n\t}\n\tisValidAction(action: string) {\n\t\tif (action === 'synchronize') return 'updated';\n\t\tif (action === 'review_requested') {\n\t\t\treturn 'requested a review for';\n\t\t} else if (action === 'review_request_removed') {\n\t\t\treturn 'removed a review request for';\n\t\t}\n\t\tif (['ready_for_review', 'labeled', 'unlabeled', 'converted_to_draft'].includes(action)) {\n\t\t\treturn null;\n\t\t}\n\t\treturn action;\n\t}\n\tgetUsername(name: string) {\n\t\treturn gitData.usernames?.[toID(name)] || name;\n\t}\n\tsave() {\n\t\tFS(\"config/chat-plugins/github.json\").writeUpdate(() => JSON.stringify(gitData));\n\t}\n};\n\nexport const commands: Chat.ChatCommands = {\n\tgh: 'github',\n\tgithub: {\n\t\t''() {\n\t\t\treturn this.parse('/help github');\n\t\t},\n\t\tban(target, room, user) {\n\t\t\troom = this.requireRoom('development');\n\t\t\tthis.checkCan('mute', null, room);\n\t\t\tconst [username, reason] = Utils.splitFirst(target, ',').map(u => u.trim());\n\t\t\tif (!toID(target)) return this.parse(`/help github`);\n\t\t\tif (!toID(username)) return this.errorReply(\"Provide a username.\");\n\t\t\tif (room.auth.has(toID(GitHub.getUsername(username)))) {\n\t\t\t\treturn this.errorReply(\"That user is Dev roomauth. If you need to do this, demote them and try again.\");\n\t\t\t}\n\t\t\tif (!gitData.bans) gitData.bans = {};\n\t\t\tif (gitData.bans[toID(username)]) {\n\t\t\t\treturn this.errorReply(`${username} is already gitbanned.`);\n\t\t\t}\n\t\t\tgitData.bans[toID(username)] = reason || \" \"; // to ensure it's truthy\n\t\t\tGitHub.save();\n\t\t\tthis.privateModAction(`${user.name} banned the GitHub user ${username} from having their GitHub actions reported to this server.`);\n\t\t\tthis.modlog('GITHUB BAN', username, reason);\n\t\t},\n\t\tunban(target, room, user) {\n\t\t\troom = this.requireRoom('development');\n\t\t\tthis.checkCan('mute', null, room);\n\t\t\ttarget = toID(target);\n\t\t\tif (!target) return this.parse('/help github');\n\t\t\tif (!gitData.bans?.[target]) return this.errorReply(\"That user is not gitbanned.\");\n\t\t\tdelete gitData.bans[target];\n\t\t\tif (!Object.keys(gitData.bans).length) delete gitData.bans;\n\t\t\tGitHub.save();\n\t\t\tthis.privateModAction(`${user.name} allowed the GitHub user ${target} to have their GitHub actions reported to this server.`);\n\t\t\tthis.modlog('GITHUB UNBAN', target);\n\t\t},\n\t\tbans() {\n\t\t\tconst room = this.requireRoom('development');\n\t\t\tthis.checkCan('mute', null, room);\n\t\t\treturn this.parse('/j view-github-bans');\n\t\t},\n\t\tsetname: 'addusername',\n\t\taddusername(target, room, user) {\n\t\t\troom = this.requireRoom('development');\n\t\t\tthis.checkCan('mute', null, room);\n\t\t\tconst [gitName, username] = Utils.splitFirst(target, ',').map(u => u.trim());\n\t\t\tif (!toID(gitName) || !toID(username)) return this.parse(`/help github`);\n\t\t\tif (!gitData.usernames) gitData.usernames = {};\n\t\t\tgitData.usernames[toID(gitName)] = username;\n\t\t\tGitHub.save();\n\t\t\tthis.privateModAction(`${user.name} set ${gitName}'s name on reported GitHub actions to be ${username}.`);\n\t\t\tthis.modlog('GITHUB SETNAME', null, `'${gitName}' to '${username}'`);\n\t\t},\n\t\tclearname: 'removeusername',\n\t\tremoveusername(target, room, user) {\n\t\t\troom = this.requireRoom('development');\n\t\t\tthis.checkCan('mute', null, room);\n\t\t\ttarget = toID(target);\n\t\t\tif (!target) return this.parse(`/help github`);\n\t\t\tconst name = gitData.usernames?.[target];\n\t\t\tif (!name) return this.errorReply(`${target} is not a GitHub username on our list.`);\n\t\t\tdelete gitData.usernames?.[target];\n\t\t\tif (!Object.keys(gitData.usernames || {}).length) delete gitData.usernames;\n\t\t\tGitHub.save();\n\t\t\tthis.privateModAction(`${user.name} removed ${target}'s name from the GitHub username list.`);\n\t\t\tthis.modlog('GITHUB CLEARNAME', target, `from the name ${name}`);\n\t\t},\n\t\tnames() {\n\t\t\treturn this.parse('/j view-github-names');\n\t\t},\n\t},\n\tgithubhelp: [\n\t\t`/github ban [username], [reason] - Bans a GitHub user from having their GitHub actions reported to Dev room. Requires: % @ # ~`,\n\t\t`/github unban [username] - Unbans a GitHub user from having their GitHub actions reported to Dev room. Requires: % @ # ~`,\n\t\t`/github bans - Lists all GitHub users that are currently gitbanned. Requires: % @ # ~`,\n\t\t`/github setname [username], [name] - Sets a GitHub user's name on reported GitHub actions to be [name]. Requires: % @ # ~`,\n\t\t`/github clearname [username] - Removes a GitHub user's name from the GitHub username list. Requires: % @ # ~`,\n\t\t`/github names - Lists all GitHub usernames that are currently on our list.`,\n\t],\n};\n\nexport const pages: Chat.PageTable = {\n\tgithub: {\n\t\tbans(query, user) {\n\t\t\tconst room = Rooms.get('development');\n\t\t\tif (!room) return this.errorReply(\"No Development room found.\");\n\t\t\tthis.checkCan('mute', null, room);\n\t\t\tif (!gitData.bans) return this.errorReply(\"There are no gitbans at this time.\");\n\t\t\tlet buf = `

Current Gitbans:


    `;\n\t\t\tfor (const [username, reason] of Object.entries(gitData.bans)) {\n\t\t\t\tbuf += `
  1. ${username} - ${reason.trim() || '(No reason found)'}
  2. `;\n\t\t\t}\n\t\t\tbuf += `
`;\n\t\t\treturn buf;\n\t\t},\n\t\tnames() {\n\t\t\tif (!gitData.usernames) return this.errorReply(\"There are no GitHub usernames in the list.\");\n\t\t\tlet buf = `

Current GitHub username mappings:


    `;\n\t\t\tfor (const [username, name] of Object.entries(gitData.usernames)) {\n\t\t\t\tbuf += `
  1. ${username} - ${name}
  2. `;\n\t\t\t}\n\t\t\tbuf += `
`;\n\t\t\treturn buf;\n\t\t},\n\t},\n};\n\nexport function destroy() {\n\tGitHub.hook?.server.close();\n}\n"], "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,iBAA0B;AAE1B,MAAM,cAAc,OAAO,cAAc;AAAA,EACxC;AAAA,EAAoB;AAAA,EAA2B;AAAA,EAAwB;AACxE;AACA,MAAM,WAAW,KAAK,KAAK;AAEpB,MAAM,UAAmB,KAAK,UAAM,eAAG,iCAAiC,EAAE,iBAAiB,KAAK,IAAI;AA4CpG,MAAM,SAAS,IAAI,MAAM;AAAA,EAG/B,cAAc;AAFd,SAAS,OAA8B;AACvC,mBAAmC,uBAAO,OAAO,IAAI;AAGpD,QAAI,CAAC,OAAO;AAAQ;AAEpB,QAAI;AACH,WAAK,OAAO,QAAQ,YAAY,EAAE;AAAA,QACjC,QAAQ;AAAA,UACP,KAAK,CAAC,SAAiB,QAAQ,MAAM,IAAI;AAAA,UACzC,OAAO,CAAC,SAAiB,QAAQ,OAAO,IAAI;AAAA,QAC7C;AAAA,QACA,GAAG,OAAO;AAAA,MACX,CAAC;AAAA,IACF,SAAS,KAAP;AACD,cAAQ,SAAS,KAAK,aAAa;AAAA,IACpC;AACA,SAAK,OAAO;AAAA,EACb;AAAA,EACA,SAAS;AACR,QAAI,CAAC,KAAK;AAAM;AAChB,SAAK,KAAK,OAAO;AACjB,SAAK,KAAK,GAAG,QAAQ,CAAC,MAAM,KAAK,WAAW,KAAK,WAAW,MAAM,KAAK,MAAM,CAAC;AAC9E,SAAK,KAAK,GAAG,gBAAgB,CAAC,MAAM,KAAK,WAAW,KAAK,WAAW,MAAM,KAAK,MAAM,CAAC;AAAA,EACvF;AAAA,EACQ,YAAY,MAAc;AACjC,YAAQ,MAAM;AAAA,MACd,KAAK;AACJ,eAAO;AAAA,MACR,KAAK;AACJ,eAAO;AAAA,MACR,KAAK;AACJ,eAAO;AAAA,MACR;AACC,eAAO,KAAK,YAAY;AAAA,IACzB;AAAA,EACD;AAAA,EACA,WAAW,MAAc,KAAa,QAAc;AACnD,UAAM,SAAS,SAAS,KAAK,GAAG,IAAI,CAAC,KAAK;AAC1C,QAAI,WAAW;AAAU;AACzB,UAAM,WAAsC;AAAA,MAC3C,OAAO,CAAC;AAAA,MACR,aAAa,CAAC;AAAA,IACf;AACA,eAAW,UAAU,OAAO,SAAS;AACpC,YAAM,EAAE,SAAS,IAAI,IAAI;AACzB,YAAM,CAAC,YAAY,IAAI,QAAQ,MAAM,MAAM;AAC3C,YAAM,WAAW,KAAK,YAAY,OAAO,OAAO,IAAI;AACpD,YAAM,WAAW,KAAK,YAAY,IAAI;AACtC,YAAM,KAAK,OAAO,GAAG,UAAU,GAAG,CAAC;AACnC,eAAS,YAAY;AAAA,QACpB,iBAAM,oCAAoC,6BAA6B,8BAA8B,UAAU,6CAA6C;AAAA,MAC7J;AACA,eAAS,MAAM,KAAK,iBAAM,oCAAoC,6BAA6B,QAAQ,iDAAiD,kBAAkB;AAAA,IACvK;AACA,eAAW,KAAK,UAAU;AACzB,WAAK,OAAO,GAAa,MAAM,SAAS,CAAW,CAAC;AAAA,IACrD;AAAA,EACD;AAAA,EACA,WAAW,MAAc,KAAyB,QAAqB;AACtE,QAAI,KAAK,cAAc,OAAO,MAAM;AAAG;AACvC,QAAI,KAAK,YAAY,MAAM;AAAG;AAC9B,UAAM,MAAM,OAAO,aAAa;AAChC,UAAM,SAAS,KAAK,cAAc,OAAO,MAAM;AAC/C,QAAI,CAAC;AAAQ;AACb,UAAM,WAAW,KAAK,YAAY,IAAI;AACtC,UAAM,WAAW,KAAK,YAAY,OAAO,OAAO,KAAK;AACrD,UAAM,QAAQ,OAAO,aAAa;AAClC,QAAI,MAAM,iBAAM,oCAAoC,gDAAgD;AACpG,WAAO,iBAAM,OAAO,mBAAmB,WAAW,OAAO,eAAe;AACxE,SAAK,OAAO,eAAe,MAAM,GAAG;AAAA,EACrC;AAAA,EACA,OAAO,QAAgB,MAAc,UAA6B;AACjE,QAAI,CAAC,YAAY,SAAS,IAAI,KAAK,WAAW;AAAS;AACvD,QAAI,MAAM,QAAQ,QAAQ;AAAG,iBAAW,SAAS,KAAK,QAAQ;AAC9D,UAAM,IAAI,MAAM,GAAG,IAAI,8BAA8B,gBAAgB,EAAE,OAAO;AAAA,EAC/E;AAAA,EACA,YAAY,QAAqB;AAChC,QAAI,CAAC,QAAQ;AAAM,aAAO;AAC1B,WAAO,QAAQ,KAAK,OAAO,OAAO,KAAK,KAAK,QAAQ,KAAK,OAAO,aAAa,KAAK,KAAK;AAAA,EACxF;AAAA,EACA,cAAc,UAAkB;AAC/B,QAAI,KAAK,QAAQ,QAAQ,GAAG;AAC3B,UAAI,KAAK,QAAQ,QAAQ,IAAI,WAAW,KAAK,IAAI;AAAG,eAAO;AAC3D,WAAK,QAAQ,QAAQ,IAAI,KAAK,IAAI;AAClC,aAAO;AAAA,IACR;AACA,SAAK,QAAQ,QAAQ,IAAI,KAAK,IAAI;AAClC,WAAO;AAAA,EACR;AAAA,EACA,cAAc,QAAgB;AAC7B,QAAI,WAAW;AAAe,aAAO;AACrC,QAAI,WAAW,oBAAoB;AAClC,aAAO;AAAA,IACR,WAAW,WAAW,0BAA0B;AAC/C,aAAO;AAAA,IACR;AACA,QAAI,CAAC,oBAAoB,WAAW,aAAa,oBAAoB,EAAE,SAAS,MAAM,GAAG;AACxF,aAAO;AAAA,IACR;AACA,WAAO;AAAA,EACR;AAAA,EACA,YAAY,MAAc;AACzB,WAAO,QAAQ,YAAY,KAAK,IAAI,CAAC,KAAK;AAAA,EAC3C;AAAA,EACA,OAAO;AACN,uBAAG,iCAAiC,EAAE,YAAY,MAAM,KAAK,UAAU,OAAO,CAAC;AAAA,EAChF;AACD;AAEO,MAAM,WAA8B;AAAA,EAC1C,IAAI;AAAA,EACJ,QAAQ;AAAA,IACP,KAAK;AACJ,aAAO,KAAK,MAAM,cAAc;AAAA,IACjC;AAAA,IACA,IAAI,QAAQ,MAAM,MAAM;AACvB,aAAO,KAAK,YAAY,aAAa;AACrC,WAAK,SAAS,QAAQ,MAAM,IAAI;AAChC,YAAM,CAAC,UAAU,MAAM,IAAI,iBAAM,WAAW,QAAQ,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAC1E,UAAI,CAAC,KAAK,MAAM;AAAG,eAAO,KAAK,MAAM,cAAc;AACnD,UAAI,CAAC,KAAK,QAAQ;AAAG,eAAO,KAAK,WAAW,qBAAqB;AACjE,UAAI,KAAK,KAAK,IAAI,KAAK,OAAO,YAAY,QAAQ,CAAC,CAAC,GAAG;AACtD,eAAO,KAAK,WAAW,+EAA+E;AAAA,MACvG;AACA,UAAI,CAAC,QAAQ;AAAM,gBAAQ,OAAO,CAAC;AACnC,UAAI,QAAQ,KAAK,KAAK,QAAQ,CAAC,GAAG;AACjC,eAAO,KAAK,WAAW,GAAG,gCAAgC;AAAA,MAC3D;AACA,cAAQ,KAAK,KAAK,QAAQ,CAAC,IAAI,UAAU;AACzC,aAAO,KAAK;AACZ,WAAK,iBAAiB,GAAG,KAAK,+BAA+B,oEAAoE;AACjI,WAAK,OAAO,cAAc,UAAU,MAAM;AAAA,IAC3C;AAAA,IACA,MAAM,QAAQ,MAAM,MAAM;AACzB,aAAO,KAAK,YAAY,aAAa;AACrC,WAAK,SAAS,QAAQ,MAAM,IAAI;AAChC,eAAS,KAAK,MAAM;AACpB,UAAI,CAAC;AAAQ,eAAO,KAAK,MAAM,cAAc;AAC7C,UAAI,CAAC,QAAQ,OAAO,MAAM;AAAG,eAAO,KAAK,WAAW,6BAA6B;AACjF,aAAO,QAAQ,KAAK,MAAM;AAC1B,UAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,EAAE;AAAQ,eAAO,QAAQ;AACtD,aAAO,KAAK;AACZ,WAAK,iBAAiB,GAAG,KAAK,gCAAgC,8DAA8D;AAC5H,WAAK,OAAO,gBAAgB,MAAM;AAAA,IACnC;AAAA,IACA,OAAO;AACN,YAAM,OAAO,KAAK,YAAY,aAAa;AAC3C,WAAK,SAAS,QAAQ,MAAM,IAAI;AAChC,aAAO,KAAK,MAAM,qBAAqB;AAAA,IACxC;AAAA,IACA,SAAS;AAAA,IACT,YAAY,QAAQ,MAAM,MAAM;AAC/B,aAAO,KAAK,YAAY,aAAa;AACrC,WAAK,SAAS,QAAQ,MAAM,IAAI;AAChC,YAAM,CAAC,SAAS,QAAQ,IAAI,iBAAM,WAAW,QAAQ,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAC3E,UAAI,CAAC,KAAK,OAAO,KAAK,CAAC,KAAK,QAAQ;AAAG,eAAO,KAAK,MAAM,cAAc;AACvE,UAAI,CAAC,QAAQ;AAAW,gBAAQ,YAAY,CAAC;AAC7C,cAAQ,UAAU,KAAK,OAAO,CAAC,IAAI;AACnC,aAAO,KAAK;AACZ,WAAK,iBAAiB,GAAG,KAAK,YAAY,mDAAmD,WAAW;AACxG,WAAK,OAAO,kBAAkB,MAAM,IAAI,gBAAgB,WAAW;AAAA,IACpE;AAAA,IACA,WAAW;AAAA,IACX,eAAe,QAAQ,MAAM,MAAM;AAClC,aAAO,KAAK,YAAY,aAAa;AACrC,WAAK,SAAS,QAAQ,MAAM,IAAI;AAChC,eAAS,KAAK,MAAM;AACpB,UAAI,CAAC;AAAQ,eAAO,KAAK,MAAM,cAAc;AAC7C,YAAM,OAAO,QAAQ,YAAY,MAAM;AACvC,UAAI,CAAC;AAAM,eAAO,KAAK,WAAW,GAAG,8CAA8C;AACnF,aAAO,QAAQ,YAAY,MAAM;AACjC,UAAI,CAAC,OAAO,KAAK,QAAQ,aAAa,CAAC,CAAC,EAAE;AAAQ,eAAO,QAAQ;AACjE,aAAO,KAAK;AACZ,WAAK,iBAAiB,GAAG,KAAK,gBAAgB,8CAA8C;AAC5F,WAAK,OAAO,oBAAoB,QAAQ,iBAAiB,MAAM;AAAA,IAChE;AAAA,IACA,QAAQ;AACP,aAAO,KAAK,MAAM,sBAAsB;AAAA,IACzC;AAAA,EACD;AAAA,EACA,YAAY;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;AAEO,MAAM,QAAwB;AAAA,EACpC,QAAQ;AAAA,IACP,KAAK,OAAO,MAAM;AACjB,YAAM,OAAO,MAAM,IAAI,aAAa;AACpC,UAAI,CAAC;AAAM,eAAO,KAAK,WAAW,4BAA4B;AAC9D,WAAK,SAAS,QAAQ,MAAM,IAAI;AAChC,UAAI,CAAC,QAAQ;AAAM,eAAO,KAAK,WAAW,oCAAoC;AAC9E,UAAI,MAAM;AACV,iBAAW,CAAC,UAAU,MAAM,KAAK,OAAO,QAAQ,QAAQ,IAAI,GAAG;AAC9D,eAAO,eAAe,uBAAuB,OAAO,KAAK,KAAK;AAAA,MAC/D;AACA,aAAO;AACP,aAAO;AAAA,IACR;AAAA,IACA,QAAQ;AACP,UAAI,CAAC,QAAQ;AAAW,eAAO,KAAK,WAAW,4CAA4C;AAC3F,UAAI,MAAM;AACV,iBAAW,CAAC,UAAU,IAAI,KAAK,OAAO,QAAQ,QAAQ,SAAS,GAAG;AACjE,eAAO,eAAe,uBAAuB;AAAA,MAC9C;AACA,aAAO;AACP,aAAO;AAAA,IACR;AAAA,EACD;AACD;AAEO,SAAS,UAAU;AACzB,SAAO,MAAM,OAAO,MAAM;AAC3B;", "names": [] }