From 18629bfa646e4b0596a3c1ae9c6a3e3ba58347b9 Mon Sep 17 00:00:00 2001 From: Qube Date: Wed, 18 Jul 2018 21:40:26 +0700 Subject: Add pre-animation, flash, shake, flip, and text color + Fix shout order according to AO2 specification --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index 43d0a2a..3f4563b 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","r","value","n","__esModule","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","mode","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","playerID","charID","chars","emotes","selectedEmote","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","track","_this2","hashCode","setInterval","sendCheck","character","song","e","document","getElementById","style","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","pre","escape","preanim","nameplate","sound","type","snddelay","evidence","flash","color","isnew","length","className","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","desc","icon","hmusiclist","newentry","createElement","text","options","add","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startspeaking","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","_this3","clearTimeout","setTimeout","updateText","_this4","trim","shout","1","2","3","fontSize","offsetHeight","replace","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","id","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","estring","window","String","hash","charCodeAt"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(message)}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(message)}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#0#0#0#0#%`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\tpre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: args[5],\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\t// flip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${args[1]}: ${args[2]}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\tif (this.chatmsg.content.trim() == \"\") {\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"block\";\r\n\t\t}\r\n\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"takethat\",\r\n\t\t\t\t\"3\": \"objection\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 800;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t}\r\n\r\n\t\tif (this.textTimer >= this.shoutTimer) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","toggleaffect","toggleflip","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","playerID","charID","chars","emotes","selectedEmote","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","flash","color","track","_this2","hashCode","setInterval","sendCheck","character","song","e","document","getElementById","style","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","sound","type","snddelay","evidence","isnew","length","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","desc","icon","hmusiclist","newentry","createElement","text","options","add","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","log","parseInt","setTimeout","updateText","filename","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","backgroundColor","shout","1","2","3","$","effect","direction","toggle","fontSize","offsetHeight","unsafe","replace","escapeHtml","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","id","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","estring","window","trim","hash","charCodeAt"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(message)}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(message)}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#0#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: args[5],\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${args[1]}: ${args[2]}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tconsole.log(animdelay);\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay+2)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\t\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n"],"sourceRoot":""} \ No newline at end of file -- cgit From 93c2650aac8a12797701d8ca6002db560d7b4529 Mon Sep 17 00:00:00 2001 From: Qube Date: Wed, 18 Jul 2018 23:12:29 +0700 Subject: Add client side encoding-decoding option (Unicode Escape and UTF-16 Array) --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index 3f4563b..d54e9c7 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","toggleaffect","toggleflip","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","playerID","charID","chars","emotes","selectedEmote","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","flash","color","track","_this2","hashCode","setInterval","sendCheck","character","song","e","document","getElementById","style","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","sound","type","snddelay","evidence","isnew","length","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","desc","icon","hmusiclist","newentry","createElement","text","options","add","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","log","parseInt","setTimeout","updateText","filename","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","backgroundColor","shout","1","2","3","$","effect","direction","toggle","fontSize","offsetHeight","unsafe","replace","escapeHtml","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","id","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","estring","window","trim","hash","charCodeAt"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(message)}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(message)}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#0#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: args[5],\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${args[1]}: ${args[2]}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tconsole.log(animdelay);\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay+2)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\t\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","toggleaffect","toggleflip","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","playerID","charID","chars","emotes","selectedEmote","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","flash","color","track","_this2","hashCode","setInterval","sendCheck","character","song","e","document","getElementById","style","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","decodeChat","unescapeChat","sound","type","snddelay","evidence","isnew","length","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","desc","icon","hmusiclist","newentry","createElement","text","options","add","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","log","parseInt","setTimeout","updateText","filename","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","backgroundColor","shout","1","2","3","$","effect","direction","toggle","fontSize","offsetHeight","unsafe","replace","escapeHtml","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","id","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","estring","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#0#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeChat(unescapeChat(args[5])),\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tconsole.log(animdelay);\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay+2)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\t\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(/\\/g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n"],"sourceRoot":""} \ No newline at end of file -- cgit From 119a6b4f03fcd6defc68b504d9b529a9f0c562d0 Mon Sep 17 00:00:00 2001 From: Qube Date: Thu, 19 Jul 2018 00:27:30 +0700 Subject: Add BBCode --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index d54e9c7..0520ba6 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","toggleaffect","toggleflip","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","playerID","charID","chars","emotes","selectedEmote","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","flash","color","track","_this2","hashCode","setInterval","sendCheck","character","song","e","document","getElementById","style","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","decodeChat","unescapeChat","sound","type","snddelay","evidence","isnew","length","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","desc","icon","hmusiclist","newentry","createElement","text","options","add","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","log","parseInt","setTimeout","updateText","filename","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","backgroundColor","shout","1","2","3","$","effect","direction","toggle","fontSize","offsetHeight","unsafe","replace","escapeHtml","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","id","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","estring","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#0#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeChat(unescapeChat(args[5])),\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tconsole.log(animdelay);\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay+2)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\t\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(/\\/g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","toggleaffect","toggleflip","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","playerID","charID","chars","emotes","selectedEmote","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","flash","color","track","_this2","hashCode","setInterval","sendCheck","target","document","getElementById","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","evidence","isnew","length","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","desc","icon","hmusiclist","newentry","createElement","text","options","add","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","parseInt","setTimeout","updateText","filename","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","shout","1","2","3","$","effect","direction","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","id","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash","ready","initialObservBBCode"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#0#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay+2)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\t\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(/\\/g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n});\r\n"],"sourceRoot":""} \ No newline at end of file -- cgit From 5b12a4d6572bca5ae73474f84362cc3507ae3f3c Mon Sep 17 00:00:00 2001 From: Qube Date: Thu, 19 Jul 2018 09:55:00 +0700 Subject: Fix escape decode and adjust pre-animation. --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index 0520ba6..7794698 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","toggleaffect","toggleflip","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","playerID","charID","chars","emotes","selectedEmote","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","flash","color","track","_this2","hashCode","setInterval","sendCheck","target","document","getElementById","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","evidence","isnew","length","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","desc","icon","hmusiclist","newentry","createElement","text","options","add","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","parseInt","setTimeout","updateText","filename","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","shout","1","2","3","$","effect","direction","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","id","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash","ready","initialObservBBCode"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#0#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay+2)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\t\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(/\\/g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n});\r\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","toggleaffect","toggleflip","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","playerID","charID","chars","emotes","selectedEmote","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","flash","color","track","_this2","hashCode","setInterval","sendCheck","target","document","getElementById","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","evidence","isnew","length","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","desc","icon","hmusiclist","newentry","createElement","text","options","add","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","parseInt","setTimeout","updateText","filename","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","shout","1","2","3","$","effect","direction","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","id","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash","ready","initialObservBBCode"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#0#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\t\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n});\r\n"],"sourceRoot":""} \ No newline at end of file -- cgit From adf3cacdf2c6426a7eb7ea5fc500082992f357aa Mon Sep 17 00:00:00 2001 From: Qube Date: Thu, 19 Jul 2018 20:12:57 +0700 Subject: Add evidence and mainmenu --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index 7794698..238e89d 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","toggleaffect","toggleflip","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","playerID","charID","chars","emotes","selectedEmote","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","flash","color","track","_this2","hashCode","setInterval","sendCheck","target","document","getElementById","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","evidence","isnew","length","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","desc","icon","hmusiclist","newentry","createElement","text","options","add","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","parseInt","setTimeout","updateText","filename","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","shout","1","2","3","$","effect","direction","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","id","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash","ready","initialObservBBCode"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#0#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\t\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n});\r\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","findEvidenceIcon","updateEvidenceIcon","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","playerID","charID","chars","emotes","evidences","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","evidence","flash","color","desc","img","id","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","parseInt","setTimeout","updateText","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","opacity","height","shout","1","2","3","$","effect","direction","backgroundImage","right","left","animate","marginLeft","marginRight","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","selectedIndex","sendPE","sendEE","sendDE","evidence_filename","evidence_iconbox","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash","ready","initialObservBBCode","loadResources"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id, name, desc, img) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\tmarginLeft: \"10.6in\"\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\tmarginRight: \"10.6in\"\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = findEvidenceIcon(evidence);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find evidence icon in select box via id.\r\n * @param {integer} id the id of evidence\r\n */\r\nexport function findEvidenceIcon(id) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\t\tfor (let i = 1; i < evidence_select.length; ++i){\r\n\t\t\tif (evidence_select.options[i].value == client.evidences[id - 1].filename){\r\n\t\t\t return i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.findEvidenceIcon = findEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\r\n\t\tevidence_filename.value = \"\";\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n});\r\n"],"sourceRoot":""} \ No newline at end of file -- cgit From 67d1e2252b8f46605d49a6c95c80475b890ec3b8 Mon Sep 17 00:00:00 2001 From: Qube Date: Fri, 20 Jul 2018 00:23:20 +0700 Subject: Add location section (Area selector and background change) + fix desk to 'bancodefensa' and 'bancoacusacion' when 'defensedesk' and 'prosecutiondesk' are not existed --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index 238e89d..b6efd58 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","findEvidenceIcon","updateEvidenceIcon","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","playerID","charID","chars","emotes","evidences","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","evidence","flash","color","desc","img","id","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","parseInt","setTimeout","updateText","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","opacity","height","shout","1","2","3","$","effect","direction","backgroundImage","right","left","animate","marginLeft","marginRight","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","selectedIndex","sendPE","sendEE","sendDE","evidence_filename","evidence_iconbox","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash","ready","initialObservBBCode","loadResources"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id, name, desc, img) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\tmarginLeft: \"10.6in\"\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\tmarginRight: \"10.6in\"\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = findEvidenceIcon(evidence);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find evidence icon in select box via id.\r\n * @param {integer} id the id of evidence\r\n */\r\nexport function findEvidenceIcon(id) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\t\tfor (let i = 1; i < evidence_select.length; ++i){\r\n\t\t\tif (evidence_select.options[i].value == client.evidences[id - 1].filename){\r\n\t\t\t return i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.findEvidenceIcon = findEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\r\n\t\tevidence_filename.value = \"\";\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n});\r\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","changeBackgroundOOC","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","playerID","charID","chars","emotes","evidences","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","evidence","flash","color","desc","img","id","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","clip","tr","td","icon_chosen","thispick","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","parseInt","setTimeout","updateText","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","opacity","height","shout","1","2","3","$","effect","direction","backgroundImage","right","left","animate","marginLeft","marginRight","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","ImageExist","url","Image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","bg_command","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash","ready","initialObservBBCode","loadResources"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id, name, desc, img) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index > 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = escape(args[1]);\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\t\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\tmarginLeft: \"10.6in\"\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\tmarginRight: \"10.6in\"\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tif(ImageExist(bgfolder + \"defensedesk.png\")){\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\t}else{\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t\t}\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tif(ImageExist(bgfolder + \"defensedesk.png\")){\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\t} else {\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t\t}\t\t\t\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Change background.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n});\r\n"],"sourceRoot":""} \ No newline at end of file -- cgit From e2b70d9457ead36007b6b512496cf9ff532bf025 Mon Sep 17 00:00:00 2001 From: Qube Date: Fri, 20 Jul 2018 00:32:31 +0700 Subject: Fix handleBN --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index b6efd58..1f14ef6 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","changeBackgroundOOC","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","playerID","charID","chars","emotes","evidences","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","evidence","flash","color","desc","img","id","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","clip","tr","td","icon_chosen","thispick","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","parseInt","setTimeout","updateText","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","opacity","height","shout","1","2","3","$","effect","direction","backgroundImage","right","left","animate","marginLeft","marginRight","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","ImageExist","url","Image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","bg_command","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash","ready","initialObservBBCode","loadResources"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id, name, desc, img) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index > 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = escape(args[1]);\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\t\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\tmarginLeft: \"10.6in\"\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\tmarginRight: \"10.6in\"\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tif(ImageExist(bgfolder + \"defensedesk.png\")){\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\t}else{\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t\t}\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tif(ImageExist(bgfolder + \"defensedesk.png\")){\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\t} else {\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t\t}\t\t\t\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Change background.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n});\r\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","changeBackgroundOOC","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","playerID","charID","chars","emotes","evidences","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","evidence","flash","color","desc","img","id","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","clip","tr","td","icon_chosen","thispick","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","parseInt","setTimeout","updateText","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","opacity","height","shout","1","2","3","$","effect","direction","backgroundImage","right","left","animate","marginLeft","marginRight","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","ImageExist","url","Image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","bg_command","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash","ready","initialObservBBCode","loadResources"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id, name, desc, img) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = escape(args[1]);\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\t\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\tmarginLeft: \"10.6in\"\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\tmarginRight: \"10.6in\"\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tif(ImageExist(bgfolder + \"defensedesk.png\")){\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\t}else{\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t\t}\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tif(ImageExist(bgfolder + \"defensedesk.png\")){\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\t} else {\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t\t}\t\t\t\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Change background.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n});\r\n"],"sourceRoot":""} \ No newline at end of file -- cgit From f2a436227ec386ec2497b980d738631f9f5b6a70 Mon Sep 17 00:00:00 2001 From: Qube Date: Fri, 20 Jul 2018 10:21:37 +0700 Subject: Fix evidence not show in def side --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index 1f14ef6..d7f3a32 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","changeBackgroundOOC","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","playerID","charID","chars","emotes","evidences","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","evidence","flash","color","desc","img","id","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","clip","tr","td","icon_chosen","thispick","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","parseInt","setTimeout","updateText","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","opacity","height","shout","1","2","3","$","effect","direction","backgroundImage","right","left","animate","marginLeft","marginRight","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","ImageExist","url","Image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","bg_command","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash","ready","initialObservBBCode","loadResources"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id, name, desc, img) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = escape(args[1]);\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\t\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\tmarginLeft: \"10.6in\"\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\tmarginRight: \"10.6in\"\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tif(ImageExist(bgfolder + \"defensedesk.png\")){\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\t}else{\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t\t}\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tif(ImageExist(bgfolder + \"defensedesk.png\")){\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\t} else {\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t\t}\t\t\t\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Change background.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n});\r\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","changeBackgroundOOC","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","playerID","charID","chars","emotes","evidences","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","evidence","flash","color","desc","img","id","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","clip","tr","td","icon_chosen","thispick","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","parseInt","setTimeout","updateText","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","opacity","height","shout","1","2","3","$","effect","direction","backgroundImage","right","left","animate","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","ImageExist","url","Image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","bg_command","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash","ready","initialObservBBCode","loadResources"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id, name, desc, img) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\t\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tif(ImageExist(bgfolder + \"defensedesk.png\")){\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\t}else{\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t\t}\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tif(ImageExist(bgfolder + \"defensedesk.png\")){\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\t} else {\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t\t}\t\t\t\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Change background.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n});\r\n"],"sourceRoot":""} \ No newline at end of file -- cgit From 1e55e05fc9ca04437abf7823e3ab50c131529bf0 Mon Sep 17 00:00:00 2001 From: Qube Date: Fri, 20 Jul 2018 20:57:37 +0700 Subject: Add witness testinomy, cross examination, call mod function + Fix animation sequence more reliable (using gify API to calculate animation duration) + Resign interface to gain more space. --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index d7f3a32..0898258 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","changeBackgroundOOC","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","playerID","charID","chars","emotes","evidences","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","evidence","flash","color","desc","img","id","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","clip","tr","td","icon_chosen","thispick","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","parseInt","setTimeout","updateText","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","opacity","height","shout","1","2","3","$","effect","direction","backgroundImage","right","left","animate","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","ImageExist","url","Image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","bg_command","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash","ready","initialObservBBCode","loadResources"],"mappings":"aACA,IAAAA,KAGA,SAAAC,EAAAC,GAGA,GAAAF,EAAAE,GACA,OAAAF,EAAAE,GAAAC,QAGA,IAAAC,EAAAJ,EAAAE,IACAG,EAAAH,EACAI,GAAA,EACAH,YAUA,OANAI,EAAAL,GAAAM,KAAAJ,EAAAD,QAAAC,IAAAD,QAAAF,GAGAG,EAAAE,GAAA,EAGAF,EAAAD,QAKAF,EAAAQ,EAAAF,EAGAN,EAAAS,EAAAV,EAGAC,EAAAU,EAAA,SAAAR,EAAAS,EAAAC,GACAZ,EAAAa,EAAAX,EAAAS,IACAG,OAAAC,eAAAb,EAAAS,GAA0CK,YAAA,EAAAC,IAAAL,KAK1CZ,EAAAkB,EAAA,SAAAhB,GACA,oBAAAiB,eAAAC,aACAN,OAAAC,eAAAb,EAAAiB,OAAAC,aAAwDC,MAAA,WAExDP,OAAAC,eAAAb,EAAA,cAAiDmB,OAAA,KAQjDrB,EAAAsB,EAAA,SAAAD,EAAAE,GAEA,GADA,EAAAA,IAAAF,EAAArB,EAAAqB,IACA,EAAAE,EAAA,OAAAF,EACA,KAAAE,GAAA,iBAAAF,QAAAG,WAAA,OAAAH,EACA,IAAAI,EAAAX,OAAAY,OAAA,MAGA,GAFA1B,EAAAkB,EAAAO,GACAX,OAAAC,eAAAU,EAAA,WAAyCT,YAAA,EAAAK,UACzC,EAAAE,GAAA,iBAAAF,EAAA,QAAAM,KAAAN,EAAArB,EAAAU,EAAAe,EAAAE,EAAA,SAAAA,GAAgH,OAAAN,EAAAM,IAAqBC,KAAA,KAAAD,IACrI,OAAAF,GAIAzB,EAAA6B,EAAA,SAAA1B,GACA,IAAAS,EAAAT,KAAAqB,WACA,WAA2B,OAAArB,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAH,EAAAU,EAAAE,EAAA,IAAAA,GACAA,GAIAZ,EAAAa,EAAA,SAAAiB,EAAAC,GAAsD,OAAAjB,OAAAkB,UAAAC,eAAA1B,KAAAuB,EAAAC,IAGtD/B,EAAAkC,EAAA,GAIAlC,IAAAmC,EAAA,8aCo8BgBC,eAYAC,YAuCAC,oBAUAC,eASAC,sBAQAC,oBAQAC,qBASAC,oBAWAC,aAWAC,cA6EAC,oBAaAC,gBA2CAC,aAgBAC,gBAaAC,iBAmCAC,gBAeAC,iBAiBAC,gBAUAC,mBA4BAC,uBAeAC,uBAkBAC,wBAeAC,4BAoBAC,iBAiBAC,eAaAC,kBAcAC,eAgBAC,cAhhDhB,IAAIC,KACJC,SAASC,OAAOC,OAAO,GAAGC,MAAM,KAAKC,QAAQ,SAASC,GACrDN,EAAUM,EAAKF,MAAM,KAAK,IAAME,EAAKF,MAAM,KAAK,KAKjD,IAAMG,EAAWP,EAAUQ,GACvBjD,EAAOyC,EAAUzC,KAEfkD,EAAUT,EAAUU,OAAS,4CAC7BC,EAAaF,EAAU,gBAMzBG,GAAa,EACb,uGAAuGC,KAAKC,UAAUC,aACzHH,GAAa,GAGd,IAAII,EAAiB,EACjBC,EAAe,EACfC,EAAgB,EAChBC,EAAoB,IAAIC,KAAK,GAE3BC,aACL,SAAAA,EAAYC,GAAS,IAAAC,EAAAC,KAAAC,EAAAD,KAAAH,GACpBG,KAAKE,KAAO,IAAIC,UAAU,QAAUL,GAEpCE,KAAKE,KAAKE,OAAY,SAACC,GAAD,OAASN,EAAKO,OAAOD,IAC3CL,KAAKE,KAAKK,QAAY,SAACF,GAAD,OAASN,EAAKS,QAAQH,IAC5CL,KAAKE,KAAKO,UAAY,SAACJ,GAAD,OAASN,EAAKW,UAAUL,IAC9CL,KAAKE,KAAKS,QAAY,SAACN,GAAD,OAASN,EAAKa,QAAQP,IAE5CL,KAAKa,MAAO,EACZb,KAAKc,aAAc,EAEnBd,KAAKe,SAAW,EAChBf,KAAKgB,QAAU,EAEfhB,KAAKiB,SACLjB,KAAKkB,UACLlB,KAAKmB,aAELnB,KAAKoB,eAAiB,EACtBpB,KAAKqB,iBAAmB,EAExBrB,KAAKsB,aAAe,KAGpBtB,KAAKuB,UAAYjG,SAEjB0E,KAAKwB,UACJC,GAAc,SAACC,GAAD,OAAU3B,EAAK4B,SAASD,IACtCE,GAAc,SAACF,GAAD,OAAU3B,EAAK8B,SAASH,IACtCI,GAAc,SAACJ,GAAD,OAAU3B,EAAKgC,SAASL,IACtCM,IAAc,SAACN,GAAD,OAAU3B,EAAKkC,UAAUP,IACvCQ,GAAc,SAACR,GAAD,OAAU3B,EAAKoC,SAAST,IACtCU,GAAc,SAACV,GAAD,OAAU3B,EAAKsC,SAASX,IACtCY,GAAc,SAACZ,GAAD,OAAU3B,EAAKwC,SAASb,IACtCc,GAAc,SAACd,GAAD,OAAU3B,EAAK0C,SAASf,IACtCgB,GAAc,SAAChB,GAAD,OAAU3B,EAAK4C,SAASjB,IACtCkB,GAAc,SAAClB,GAAD,OAAU3B,EAAK8C,SAASnB,IACtCoB,MAAc,SAACpB,GAAD,OAAU3B,EAAKgD,YAAYrB,IACzCsB,KAAc,SAACtB,GAAD,OAAU3B,EAAKkD,WAAWvB,IACxCwB,GAAc,SAACxB,GAAD,OAAU3B,EAAKoD,SAASzB,IACtC0B,IAAc,SAAC1B,GAAD,OAAU3B,EAAKsD,UAAU3B,IACvC4B,GAAc,SAAC5B,GAAD,OAAU3B,EAAKwD,SAAS7B,IACtC8B,GAAc,SAAC9B,GAAD,OAAU3B,EAAK0D,SAAS/B,IACtCgC,GAAc,SAAChC,GAAD,OAAU3B,EAAK4D,SAASjC,IACtCkC,GAAc,SAAClC,GAAD,OAAU3B,EAAK8D,SAASnC,IACtCoC,WAAc,SAACpC,GAAD,OAAU3B,EAAKgE,iBAAiBrC,IAC9CsC,GAAc,SAACtC,GAAD,OAAU3B,EAAKkE,SAASvC,IACtCwC,MAAc,SAACxC,MAGhB1B,KAAKmE,oBAAsB,IAAIvE,KAAK,0CAOpC,OAAOI,KAAKiB,MAAMjB,KAAKgB,0CAOvB,OAAOhB,KAAKkB,OAAOlB,KAAKoB,oDAOxB,OAAQpB,KAAKc,YAAcd,KAAKqB,iBAAmB,kCAO5C+C,GACPpE,KAAKE,KAAKmE,KAAV,SAAwBrE,KAAKe,SAA7B,IAAyCuD,EAAWC,EAAWH,IAA/D,qCAeMI,EAAUrJ,EAAMsJ,EAAQL,EAASM,EAAMC,EAAUC,EAAMC,EAAWC,EAAWC,EAAUlE,EAAMmE,EAAOC,GAC1GjF,KAAKE,KAAKmE,KACT,WAAWG,EAAX,IAAuBrJ,EAAvB,IAA+BsJ,EAA/B,IACIH,EAAWC,EAAWH,IAD1B,IACuCM,EADvC,IAC+CC,EAD/C,IAC2DC,EAD3D,IAEI5E,KAAKgB,OAFT,IAEmB6D,EAFnB,IAEgCnF,EAFhC,IAEiDqF,EAFjD,IAE6DlE,EAF7D,IAEqEmE,EAFrE,IAE8EC,EAF9E,qCAYK9J,EAAM+J,EAAMC,GAClBnF,KAAKE,KAAKmE,KAAV,MAAqBC,EAAWC,EAAWpJ,IAA3C,IAAqDmJ,EAAWC,EAAWW,IAA3E,IAAqFC,EAArF,qCAUMC,EAAIjK,EAAM+J,EAAMC,GACtBnF,KAAKE,KAAKmE,KAAV,MAAqBe,EAArB,IAA2Bd,EAAWC,EAAWpJ,IAAjD,IAA2DmJ,EAAWC,EAAWW,IAAjF,IAA2FC,EAA3F,qCAOMC,EAAIjK,EAAM+J,EAAMC,GACtBnF,KAAKE,KAAKmE,KAAV,MAAqBe,EAArB,8CAOeC,GACfrF,KAAKE,KAAKmE,KAAV,MAAqBgB,EAArB,IAA8BrF,KAAKgB,OAAnC,8CAUAhB,KAAKE,KAAKmE,KAAK,6CAOH,IAAAiB,EAAAtF,KACZA,KAAKE,KAAKmE,KAAV,MAAqB/E,UAAUC,UAAUgG,WAAzC,MACAvF,KAAKE,KAAKmE,KAAK,oBACfrE,KAAKsB,aAAekE,YAAY,kBAAMF,EAAKG,aAAa,6CAQxD,IAAIC,EAAkBC,SAASC,eAAe,cAC9CF,EAAgBG,IAAI,IAAIC,OAAO,SAAU,IACzC,IAAI,IAAIlL,EAAI,EAAGA,GAAKmL,aAAaC,OAAQpL,IACvC8K,EAAgBG,IAAI,IAAIC,OAAOC,aAAanL,EAAI,KAGlD,IAAIqL,EAAoBN,SAASC,eAAe,aAChDK,EAAkBJ,IAAI,IAAIC,OAAO,SAAU,IAC3C,IAAI,IAAIlL,EAAI,EAAGA,GAAKsL,eAAeF,OAAQpL,IACzCqL,EAAkBJ,IAAI,IAAIC,OAAOI,eAAetL,EAAI,mDAWtD,IAAIuL,EAASR,SAASC,eAAe,qBACtB,IAAIQ,iBAAiB,SAASC,GAC3CA,EAAUxH,QAAQ,SAASyH,GAC5B,IAAIC,EAAWD,EAASE,WACP,OAAbD,GACHA,EAAS1H,QAAS,SAAS4H,GACN,KAAhBA,EAAKC,QACRD,EAAKE,MAAM1B,MAAQwB,EAAKG,aAAa,KACZ,KAAhBH,EAAKC,UACVD,EAAKI,aAAa,KACrBJ,EAAKE,MAAMG,gBAAkBL,EAAKG,aAAa,MAE/CH,EAAKE,MAAMG,gBAAkB,SAC7BL,EAAKE,MAAM1B,MAAQ,gBAQf8B,QAAQZ,GADHa,YAAY,EAAKC,WAAW,0CAQ7BC,GACblH,KAAKE,KAAKmE,KAAV,MAAqBrE,KAAKe,SAA1B,IAAsCmG,EAAtC,4CAOSC,GACTnH,KAAKE,KAAKmE,KAAV,MAAqB8C,uCAOrBnH,KAAKE,KAAKmE,KAAV,MAAqBrE,KAAKgB,OAA1B,qCAMMoG,GAEO,UAATrL,GACH4J,SAASC,eAAe,kBAAkBe,MAAMU,QAAU,OAC1D1B,SAASC,eAAe,qBAAqBe,MAAMU,QAAU,QAE7DC,GAAOC,6CAQDH,GACPI,QAAQC,MAAR,8BAA4CL,EAAEM,OAA9C,KAAyDN,EAAEO,KAA3D,KACe,OAAXP,EAAEO,OACLhC,SAASC,eAAe,gBAAgBe,MAAMU,QAAU,QACxD1B,SAASC,eAAe,YAAYgC,YAAcR,EAAEO,KACpD3H,KAAK6H,6CAQGT,GACT,IAAIU,EAAMV,EAAEW,KACZP,QAAQQ,MAAMF,GACd,IACIpG,EADQoG,EAAIlJ,MAAM,KACL,GAAGA,MAAM,KACtBqJ,EAASvG,EAAK,GACdwG,EAAUlI,KAAKwB,SAASyG,QACL,IAAZC,EACVA,EAAQxG,GAER8F,QAAQW,KAAR,yBAAsCF,mCAQhCb,GACPI,QAAQC,MAAR,6BAA2CL,EAAEM,OAA7C,KAAwDN,EAAEO,KAA1D,KACAhC,SAASC,eAAe,gBAAgBe,MAAMU,QAAU,QACxD1B,SAASC,eAAe,YAAYgC,YAAcR,EAAEO,KACpD3H,KAAK6H,4CAIL,IACC7H,KAAKE,KAAKkI,MAAM,MACf,MAAOhB,IAGTiB,cAAcrI,KAAKsB,+CAOXI,GAER,GAAIA,EAAK,IAAM4G,GAASC,QAAQC,QAAS,CACxC7C,SAASC,eAAe,qBAAqB6C,UAAY,GAwBzD,IAvBA,IAAIF,GAEHrB,WAAY,EACZwB,QAASC,OAAOjH,EAAK,IACrBkH,UAAWlH,EAAK,GAChBvG,KAAMuG,EAAK,GACX8C,SAAU,MAAQmE,OAAOjH,EAAK,IAC9B+C,OAAQ,MAAQkE,OAAOjH,EAAK,IAC5B8G,QA+xCJ,SAAsBK,GACrB,OAAOA,EACLC,QAAQ,OAAQ,QAChBA,QAAQ,cAAe,SACvBA,QAAQ,cAAe,SACvBA,QAAQ,gBAAiB,WACzBA,QAAQ,cAAe,WACvBA,QAAQ,gBAAiB,WACzBA,QAAQ,gBAAiB,WACzBA,QAAQ,yBAA0B,cAClCA,QAAQ,cAAe,SACvBA,QAAQ,0BAA2B,cACnCA,QAAQ,WAAY,QA3yCVC,CAAaC,EAAWC,GAAWC,EAAaxH,EAAK,OAC9DgD,KAAMhD,EAAK,GACXyH,MAAOR,OAAOjH,EAAK,IACnB0H,KAAM1H,EAAK,GAEX2H,SAAU3H,EAAK,IACfoD,UAAWpD,EAAK,IAChBqD,SAAUrD,EAAK,IACfb,KAAMa,EAAK,IACXsD,MAAOtD,EAAK,IACZuD,MAAOvD,EAAK,IACZ4H,OAAO,GAIC1O,EAAI,EAAGA,EAAIoF,KAAKiB,MAAM+E,OAAQpL,IACtC,GAAIoF,KAAKiB,MAAMrG,GAAGO,MAAQuG,EAAK,GAAI,CAClC6G,EAAQrB,UAAYtM,EACpB,MAIE2N,EAAQrB,WAAalH,KAAKgB,QA0sBjC,WACC2E,SAASC,eAAe,mBAAmB/J,MAAQ,GAC/C2D,IACHmG,SAASC,eAAe,iBAAmBpG,GAAgB+J,UAAY,gBACvE/J,EAAiB,GAEdE,IACHiG,SAASC,eAAe,UAAYlG,GAAe6J,UAAY,gBAC/D7J,EAAgB,GAjtBd8J,GAGDlB,GAASmB,IAAIlB,qCAQN7G,GACR,IAAMgI,EAAS/D,SAASC,eAAe,iBACvC8D,EAAOjB,WAAgBQ,GAAWC,EAAaxH,EAAK,KAApD,KAA6DuH,GAAWC,EAAaxH,EAAK,KAA1F,OACIgI,EAAOC,UAAYD,EAAOE,aAAe,KAC5CF,EAAOC,UAAYD,EAAOE,+CAQnBlI,GACR,IAAMoB,EAAQwF,GAASxF,OACvBA,EAAM+G,QACN/G,EAAMgH,IAAM3K,EAAauC,EAAK,GAC9BoB,EAAMiH,OACFrI,EAAK,IAAM,GAEdsI,EADgBhK,KAAKiB,MAAMS,EAAK,IAAIvG,KACpC,qBAA6CuG,EAAK,IAElDsI,8BAAwCtI,EAAK,sCAQrCA,GACT4G,GAASxF,MAAM+G,QACfvB,GAASxF,MAAQ,IAAImH,MAAMjK,KAAKuB,UAAUG,EAAK,KAC/C,IAAMoB,EAAQwF,GAASxF,MAEvBA,EAAMoH,OAASxI,EAAK,GACpBoB,EAAMqH,QAAS,IAAIvK,MAAOwK,UAAY,IACtCtH,EAAMuH,iBAAiB,iBAAkB,WACxCvH,EAAMwH,aAAeC,WAAWzH,EAAMoH,SAAU,IAAItK,MAAOwK,UAAY,IAAOtH,EAAMqH,SAASK,QAAQ,GACrG1H,EAAMiH,SACJ,oCAQKrI,GACRiE,SAASC,eAAe,sBAAsB6C,UAAY,qBAAuB/G,EAAK,GACtF1B,KAAKE,KAAKmE,KAAK,OAAU3C,EAAK,GAAK,GAAM,GAAK,MAC9C,IAAK,IAAI9G,EAAI,EAAGA,EAAI8G,EAAKsE,OAAS,EAAGpL,IACpC,GAAIA,EAAI,GAAK,EAAG,CACf,IAAI6P,EAAS/I,EAAK9G,GAAGgE,MAAM,KAC3BoB,KAAKiB,MAAMS,EAAK9G,EAAI,KACnBO,KAAQsP,EAAO,GACfvF,KAAQuF,EAAO,GACf1F,SAAY0F,EAAO,GACnBC,KAAQzL,EAAU,cAAgB0J,OAAO8B,EAAO,IAAM,oDAWjD/I,GACRiE,SAASC,eAAe,sBAAsB6C,UAAY,qBAC1D,IAAK,IAAI7N,EAAI,EAAGA,EAAI8G,EAAKsE,OAAS,EAAGpL,IAAK,CACzC,IAAI6P,EAAS/I,EAAK9G,GAAGgE,MAAM,KAC3BoB,KAAKiB,MAAMrG,EAAI,IACdO,KAAQsP,EAAO,GACfvF,KAAQuF,EAAO,GACf1F,SAAY0F,EAAO,GACnBC,KAAQzL,EAAU,cAAgB0J,OAAO8B,EAAO,IAAM,kBAGxDzK,KAAKE,KAAKmE,KAAK,yCAUP3C,GACRiE,SAASC,eAAe,sBAAsB6C,UAAY,oBAAsB/G,EAAK,GAErF1B,KAAKE,KAAKmE,KAAK,yCASP3C,GACR1B,KAAKmB,aACL,IAAK,IAAIvG,EAAI,EAAGA,EAAI8G,EAAKsE,OAAS,EAAGpL,IAAK,CACzC,IAAI+P,EAAMjJ,EAAK9G,GAAGgE,MAAM,KACxBoB,KAAKmB,UAAUvG,EAAI,IAClBO,KAAQ6N,EAAWC,GAAWC,EAAayB,EAAI,MAC/CzF,KAAQ8D,EAAWC,GAAWC,EAAayB,EAAI,MAC/CC,SAAYjC,OAAOgC,EAAI,IACvBD,KAAQzL,EAAU,YAAc0J,OAAOgC,EAAI,KAI7C,IAAIE,EAAelF,SAASC,eAAe,aAC3CiF,EAAapC,UAAY,GACzB,IAAI,IAAI7N,EAAI,EAAGA,GAAKoF,KAAKmB,UAAU6E,OAAQpL,IAC1CiQ,EAAapC,WAAa,aAAezI,KAAKmB,UAAUvG,EAAI,GAAG8P,KAC9D,aAAe9P,EAAG,UAAYoF,KAAKmB,UAAUvG,EAAI,GAAGO,KACpD,iDAC0BP,EAAG,uCASvB8G,GACRiE,SAASC,eAAe,sBAAsB6C,UAAY,iBAAmB/G,EAAK,GAClF1B,KAAKE,KAAKmE,KAAK,OAAU3C,EAAK,GAAK,GAAM,GAAK,MAE9C,IADA,IAAIoJ,EAAanF,SAASC,eAAe,oBAChChL,EAAI,EAAGA,EAAI8G,EAAKsE,OAAS,EAAGpL,IACpC,GAAIA,EAAI,GAAK,EAAG,CACf,IAAImQ,EAAWpF,SAASqF,cAAc,UACtCD,EAASE,KAAOvJ,EAAK9G,GACrBkQ,EAAWI,QAAQrF,IAAIkF,qCAUjBrJ,GACRiE,SAASC,eAAe,sBAAsB6C,UAAY,iBAG1D,IAFA,IAAIqC,EAAanF,SAASC,eAAe,oBAAqBuF,GAAY,EAEjEvQ,EAAI,EAAGA,EAAI8G,EAAKsE,OAAS,EAAGpL,IAMpC,GAJG,8BAA8ByE,KAAKqC,EAAK9G,MAAQuQ,IAClDA,GAAY,GAGVA,EAAW,CAEb,IAAIJ,EAAWpF,SAASqF,cAAc,UACtCD,EAASE,KAAOvJ,EAAK9G,GACrBkQ,EAAWI,QAAQrF,IAAIkF,OAEjB,CAEN,IAAIK,EAAUzF,SAASqF,cAAc,QACrCI,EAAQ7B,UAAY,eACpB6B,EAAQxD,YAAclG,EAAK9G,GAC3BwQ,EAAQC,QAAU,WAAYtO,EAAWiD,OACzC2F,SAASC,eAAe,SAAS0F,YAAYF,GAK/C,IAAIG,EAAW5F,SAASC,eAAe,SACnC4F,EAAc7F,SAASqF,cAAc,UACzCQ,EAAYP,KAAOM,EAASE,UAAU7D,YACtCkD,EAAWY,aAAaF,EAAaV,EAAWa,YAChDJ,EAASK,YAAYL,EAASE,WAE9BzL,KAAKE,KAAKmE,KAAK,4CAQJ3C,GACX,IAAK,IAAI9G,EAAI,EAAGA,EAAI8G,EAAKsE,OAAS,EAAGpL,IACpCoF,KAAKuB,UAAUG,EAAK,EAAI9G,IAAM8G,EAAK,EAAI9G,EAAI,sCAUlC8G,GACViE,SAASC,eAAe,kBAAkBe,MAAMU,QAAU,OAC1D1B,SAASC,eAAe,qBAAqBe,MAAMU,QAAU,yCAOrD3F,GACR4G,GAASuD,OAASlD,OAAOjH,EAAK,IAC9B,IAAIoK,EAAW/N,EAAmB,YAAa4K,OAAOjH,EAAK,KAC3DiE,SAASC,eAAe,aAAamG,cAAgBD,EACrD5N,IACe,GAAZ4N,IACFnG,SAASC,eAAe,eAAe/J,MAAQ6F,EAAK,IAErDiE,SAASC,eAAe,cAAckE,IAAM7K,EAAU,cAAgB0J,OAAOjH,EAAK,IAAM,sDAI/EA,qCAQDA,GAGO,GAAXA,EAAK,GACRiE,SAASC,eAAe,qBAAqBe,MAAMqF,KAAO,YAjlB3C,GAilBqEtK,EAAK,GAAK,GAAK,eAEnGiE,SAASC,eAAe,wBAAwBe,MAAMqF,KAAO,YAnlB9C,GAmlBwEtK,EAAK,GAAK,GAAK,gDAQ/FA,GACR1B,KAAKe,SAAWW,EAAK,oCAGbA,GACR1B,KAAKE,KAAKmE,KAAK,8CAQP3C,GACJtC,EACHY,KAAKE,KAAKmE,KAAK,cAEfrE,KAAKE,KAAKmE,KAAK,iDAQA3C,GAChBiE,SAASC,eAAe,oBAAoB6C,UAAY,GACxD,IAAK,IAAI7N,EAAI,EAAGA,EAAIoF,KAAKiB,MAAM+E,OAAQpL,IAAK,CAC3C,GAAIA,EArnBmB,GAqnBM,EAC5B,IAAIqR,EAAKtG,SAASqF,cAAc,MAEjC,IAAIkB,EAAKvG,SAASqF,cAAc,MAC5BmB,SACAC,EAAWpM,KAAKiB,MAAMrG,GAAG8P,KAE5ByB,EADkB,MAAfzK,EAAK9G,EAAI,GACE,QAEA,GAEfsR,EAAGzD,UAAY,wBAAwB0D,EAAxB,cAAiDvR,EAAjD,UACNwR,EADM,UACYpM,KAAKiB,MAAMrG,GAAGO,KAD1B,uBACqDP,EADrD,iCAGfqR,EAAGX,YAAYY,GACXtR,EApoBmB,GAooBM,GAC5B+K,SAASC,eAAe,oBAAoB0F,YAAYW,GAG1DI,EAAiB,wCAOT3K,GACR1B,KAAKgB,OAASU,EAAK,GACnBiE,SAASC,eAAe,qBAAqBe,MAAMU,QAAU,OAC7D,IAAIiF,EAAKtM,KAAKsM,KACVpL,EAASlB,KAAKkB,OACdqL,EAAM,IAAIC,eACdD,EAAIE,KAAK,MAAOxN,EAAU,cAAgB0J,OAAO3I,KAAKsM,KAAKnR,MAAQ,aAAa,GAChFoR,EAAIG,aAAe,OACnBH,EAAII,OAAS,SAAUvF,GACtB,GAAmB,KAAfpH,KAAK4M,OAAe,CACvB,IAAIC,EAAW7M,KAAK8M,aAChBC,EAAWC,EAAIC,MAAMJ,GACzBP,EAAG5H,KAAOqI,EAASG,QAAQxI,KAC3B,IAAK,IAAI9J,EAAI,EAAGA,EAAImS,EAASI,SAASC,OAAQxS,IAAK,CAClD,IAAIyS,EAAYN,EAASI,SAASvS,GAAGgE,MAAM,KACvC0O,EAAO,IACPC,EAAQ,SACmB,IAApBR,EAASS,SACnBF,EAAOP,EAASS,OAAO5S,SAEO,IAApBmS,EAASU,SACnBF,EAAQR,EAASU,OAAO7S,IAEzBsG,EAAOtG,IACNsK,KAAMmI,EAAU,GAChB7I,SAAU6I,EAAU,GACpB5I,OAAQ4I,EAAU,GAClBzI,KAAMyI,EAAU,GAChBK,IAAKJ,EACLK,SAAUJ,EACVK,WAAY3O,EAAU,cAAgB0J,OAAO2D,EAAGnR,MAAQ,mBAAqBP,EAAI,WACjFiT,UAAW5O,EAAU,cAAgB0J,OAAO2D,EAAGnR,MAAQ,mBAAqBP,EAAI,WAEjF+K,SAASC,eAAe,cAAc6C,WAAa,aAAevH,EAAOtG,GAAGgT,WAAa,aAAehT,EAAI,UAAYsG,EAAOtG,GAAGsK,KAAO,gDAAkDtK,EAAI,MAEhM6C,EAAY,KAGd8O,EAAIlI,gBAIAyJ,aACL,SAAAA,IAAc7N,EAAAD,KAAA8N,GACb9N,KAAK+N,QAAU,GACf/N,KAAKuI,SACJe,OAAS,EACTd,QAAW,GACX1D,UAAa,IACbqE,MAAS,GACT6E,cAAgB,EAChBC,eAAiB,EACjBvJ,KAAQ,KACRO,MAAS,IACToE,SAAY,EACZ6E,aAAgB,GAEjBlO,KAAKmO,KAAO,IAAIlE,MAAMhL,EAAU,mCAChCe,KAAKmO,KAAKC,OAAS,GAKnBpO,KAAKqO,aAAe,IAAIC,MAAM,GAC9B,IAAK,IAAI1T,EAAI,EAAGA,EAAIoF,KAAKqO,aAAarI,OAAQpL,IAC7CoF,KAAKqO,aAAazT,GAAK,IAAIqP,MAAMhL,EAAU,mCAC3Ce,KAAKqO,aAAazT,GAAGwT,OAAS,GAE/BpO,KAAKuO,mBAAqB,EAE1BvO,KAAKwO,SAAW,IAAIvE,MAAMhL,EAAU,mCACpCe,KAAKyO,UAAY,EAEjBzO,KAAK8C,MAAQ,IAAImH,MACjBjK,KAAK8C,MAAMiH,OAEX/J,KAAK0O,QAAU,KAEf1O,KAAK6L,OAAS,MAEd7L,KAAK2O,WAAa,EAClB3O,KAAK4O,UAAY,EAEjB5O,KAAK6O,YAAa,kDAQlB,OAAO7O,KAAK6O,iDAOCT,GACb,IAAK,IAAIxT,EAAI,EAAGA,EAAIoF,KAAKqO,aAAarI,OAAQpL,IAC7CoF,KAAKqO,aAAazT,GAAGwT,OAASA,qCAQ/B,OAAUnP,EAAV,cAA+Be,KAAK6L,OAApC,gCAOGtD,GACHvI,KAAKuI,QAAUA,EACfyB,EAAYzB,EAAQC,QAASD,EAAQK,WACrCyD,EAAiB9D,EAAQ7D,MACzB1E,KAAK+N,QAAU,GACf/N,KAAKyO,UAAY,EACjBzO,KAAK4O,UAAY,EACjB5O,KAAK6O,YAAa,EAClBC,aAAa9O,KAAK0O,SAEK,KAAnBnG,EAAQG,QACXH,EAAQ2F,aAAelO,KAAK+O,cAAc9P,EAAU,cAAgB0J,OAAOJ,EAAQpN,MAAQ,IAAMoN,EAAQG,QAAU,OAAO1I,KAAKgP,aAE/HhP,KAAKgP,YAAY,uCAQPC,GACX3G,GAASC,QAAQ2F,aAAegB,SAASD,GACzC3G,GAASoG,QAAUS,WAAW,kBAAM7G,GAAS8G,cAxxBvB,0CAgyBTxE,EAASyE,GAEtB,IAAIC,EAAU,IAAI9C,eAClB8C,EAAQ7C,KAAK,MAAO7B,GAAU,GAC9B0E,EAAQ5C,aAAe,cACvB4C,EAAQjF,iBAAiB,OAAQ,WAOhC,IANA,IAAIkF,EAAM,IAAIC,WAAWF,EAAQG,UAIjCC,EAAW,EAEF9U,EAAI,EAAGA,EAAI2U,EAAIvJ,OAAQpL,IAI/B,GAHO+U,OAAOC,aAAcL,EAAI3U,IAGlB,IAAV2U,EAAI3U,IACU,KAAd2U,EAAI3U,EAAI,IACM,GAAd2U,EAAI3U,EAAI,IACM,GAAd2U,EAAI3U,EAAI,GAAY,CAEtB,IAAIiV,EAASN,EAAI3U,EAAI,IAAM,EAAmB,IAAb2U,EAAI3U,EAAI,GAIzC8U,GAAYG,EAAQ,EAAI,GAAMA,EAIjCR,EAAoB,GAAXK,KAEVJ,EAAQjL,4CAQI,IAAAyL,EAAA9P,KAYZ,GAVyB,GAArBA,KAAKuI,QAAQ1H,KAChB8E,SAASC,eAAe,eAAee,MAAMoJ,UAAY,aAEzDpK,SAASC,eAAe,eAAee,MAAMoJ,UAAY,YAGtD/P,KAAK6O,aACR7O,KAAK0O,QAAUS,WAAW,kBAAMW,EAAKV,cAh1BhB,KAm1BlBpP,KAAKuI,QAAQe,MAAO,CAEvB3D,SAASC,eAAe,qBAAqBe,MAAMG,gBAAkB,cAErEnB,SAASC,eAAe,eAAee,MAAMU,QAAU,OACvD1B,SAASC,eAAe,eAAee,MAAMU,QAAU,OACvD1B,SAASC,eAAe,cAAce,MAAMqJ,QAAU,IACtDrK,SAASC,eAAe,cAAce,MAAMsJ,OAAS,KACrD,IAMIC,GALHC,EAAK,SACLC,EAAK,YACLC,EAAK,YAGarQ,KAAKuI,QAAQzD,gBACX,IAAVoL,GACVvK,SAASC,eAAe,gBAAgBkE,IAAM7K,EAAU,QAAUiR,EAAQ,OACzE,IAAIjG,MAAShL,EAAb,eAAmCe,KAAKuI,QAAQpN,KAAhD,IAAwD+U,EAAxD,QAAsEnG,OACvE/J,KAAK2O,WAAa,KAElB3O,KAAK2O,WAAa,EAGnB3O,KAAKuI,QAAQe,OAAQ,EACrBtJ,KAAKuI,QAAQyF,cAAe,EAG7B,GAAGhO,KAAK4O,WAAa5O,KAAK2O,YAAc3O,KAAKuI,QAAQyF,aAE1B,GAAtBhO,KAAKuI,QAAQvD,OAEhBhF,KAAKwO,SAAS3E,QACd7J,KAAKyO,UAAY,EACjBzO,KAAKwO,SAAS1E,IAAM7K,EAAU,8BAC9Be,KAAKwO,SAASzE,OACduG,EAAE,sBAAsBC,OAAQ,SAASC,UAAY,QACrB,GAAtBxQ,KAAKuI,QAAQvD,QAEvBW,SAASC,eAAe,qBAAqBe,MAAMG,gBAAkB,QACrE9G,KAAKwO,SAAS3E,QACd7J,KAAKyO,UAAY,EACjBzO,KAAKwO,SAAS1E,IAAM7K,EAAU,qCAC9Be,KAAKwO,SAASzE,OACduG,EAAE,sBAAsBC,OAAO,YAI7BvQ,KAAKuI,QAAQ2F,aAAe,IAC9BvI,SAASC,eAAe,gBAAgBkE,IAAM,uBAC9CuC,EAAiBrM,KAAKuI,QAAQ7D,MAC9BiB,SAASC,eAAe,eAAekE,IAAM7K,EAAU,cAAgB0J,OAAO3I,KAAKuI,QAAQpN,MAAQ,IAAM6E,KAAKuI,QAAQG,QAAU,QAEjI1I,KAAKuI,QAAQyF,cAAe,EAC5BhO,KAAKuI,QAAQ0F,eAAgB,OACvB,GAAIjO,KAAK4O,WAAa5O,KAAK2O,WAAa3O,KAAKuI,QAAQ2F,eAAiBlO,KAAKuI,QAAQyF,aACzF,GAAIhO,KAAKuI,QAAQ0F,cAAe,CAC5BjO,KAAKuI,QAAQxD,SAAW,IAE1BY,SAASC,eAAe,cAAce,MAAM8J,gBAAkB,QAASnJ,GAAOnG,UAAUnB,KAAKuI,QAAQxD,SAAW,GAAG2F,KAAM,KAEhG,OAArB1K,KAAKuI,QAAQ7D,MAEhBiB,SAASC,eAAe,cAAce,MAAM+J,MAAQ,QACpD/K,SAASC,eAAe,cAAce,MAAMgK,KAAO,UACnDL,EAAG,eAAgBM,SAClBX,OAAQ,MACRD,QAAS,GACP,OAEHrK,SAASC,eAAe,cAAce,MAAM+J,MAAQ,UACpD/K,SAASC,eAAe,cAAce,MAAMgK,KAAO,QACnDL,EAAG,eAAgBM,SAClBX,OAAQ,MACRD,QAAS,GACP,OAILM,EAAE,gBAAgBO,OAAQ,QAC1BP,EAAE,gBAAgBO,OAAO,QAAQL,UAAY,SACb,GAA7BxQ,KAAKuI,QAAQ2F,eACfvI,SAASC,eAAe,gBAAgBkE,IAAM,uBAC9CuC,EAAiBrM,KAAKuI,QAAQ7D,OAE/BiB,SAASC,eAAe,eAAekE,IAAM7K,EAAU,cAAgB0J,OAAO3I,KAAKuI,QAAQpN,MAAQ,IAAM6E,KAAKuI,QAAQ/D,SAAW,OACjImB,SAASC,eAAe,eAAee,MAAMmK,SAAkE,GAAtDnL,SAASC,eAAe,eAAemL,aAAsB,KACtHpL,SAASC,eAAe,eAAee,MAAMmK,SAAkE,IAAtDnL,SAASC,eAAe,eAAemL,aAAuB,KACvHpL,SAASC,eAAe,eAAe6C,UAAY,MAAQO,EAAWhJ,KAAKuI,QAAQK,WAAa,OAEhG,IASIoI,EAAa,YARhBC,EAAK,UACLd,EAAK,UACLC,EAAK,UACLC,EAAK,UACLa,EAAK,UACLC,EAAK,UACLC,EAAK,WAE+BpR,KAAKuI,QAAQtD,QAAU,WAC5DU,SAASC,eAAe,qBAAqBe,MAAQqK,EACrDhR,KAAKuI,QAAQ0F,eAAgB,EAEzBjO,KAAK+N,SAAW/N,KAAKuI,QAAQC,UAChC7C,SAASC,eAAe,eAAekE,IAAM7K,EAAU,cAAgB0J,OAAO3I,KAAKuI,QAAQpN,MAAQ,IAAM6E,KAAKuI,QAAQ9D,OAAS,OAC/HzE,KAAK6O,YAAa,EAClBC,aAAa9O,KAAK0O,eAGf1O,KAAK+N,SAAW/N,KAAKuI,QAAQC,UACwB,KAApDxI,KAAKuI,QAAQC,QAAQ6I,OAAOrR,KAAK+N,QAAQ/H,UAC5ChG,KAAKqO,aAAarO,KAAKuO,oBAAoBxE,OAC3C/J,KAAKuO,qBACLvO,KAAKuO,oBAAsBvO,KAAKqO,aAAarI,QAE9ChG,KAAK+N,QAAU/N,KAAKuI,QAAQC,QAAQ8I,UAAU,EAAGtR,KAAK+N,QAAQ/H,OAAS,GACvEL,SAASC,eAAe,qBAAqB6C,UAAYzI,KAAK+N,QAC1D/N,KAAK+N,SAAW/N,KAAKuI,QAAQC,UAChCxI,KAAK4O,UAAY,EACjB5O,KAAK6O,YAAa,EAClBlJ,SAASC,eAAe,eAAekE,IAAM7K,EAAU,cAAgB0J,OAAO3I,KAAKuI,QAAQpN,MAAQ,IAAM6E,KAAKuI,QAAQ9D,OAAS,OAC/HqK,aAAa9O,KAAK0O,YAMjB1O,KAAKyO,WAAazO,KAAKuI,QAAQc,SAAWrJ,KAAK2O,YAAc3O,KAAK4O,YACtE5O,KAAKwO,SAAS3E,QACd7J,KAAKyO,UAAY,EACS,KAAtBzO,KAAKuI,QAAQY,OAAsC,KAAtBnJ,KAAKuI,QAAQY,QAC7CnJ,KAAKwO,SAAS1E,IAAM7K,EAAU,kBAAoB0J,OAAO3I,KAAKuI,QAAQY,OAAS,OAC/EnJ,KAAKwO,SAASzE,SAGhB/J,KAAK4O,UAAY5O,KAAK4O,UAz9BA,YA69BlB5B,iFACQjF,GACZ,IAAIwJ,GACHC,QAAS,6BACTC,MAAO,oCACPC,QAAS,YAEN7V,KAEA2V,EAAU,KAmBd,OApBYzJ,EAAKnJ,MAAM,cAEjBC,QAAQ,SAAS8S,GACtB,IAAIJ,EAAMG,QAAQrS,KAAKsS,IAEG,GAAfA,EAAK3L,OAET,GAAIuL,EAAME,MAAMpS,KAAKsS,GAAO,CAClC,IAAIC,EAAQD,EAAKC,MAAML,EAAME,OACzBD,EACH3V,EAAM2V,GAASI,EAAM,IAAMA,EAAM,GAEjC/V,EAAM+V,EAAM,IAAMA,EAAM,QAEnB,GAAIL,EAAMC,QAAQnS,KAAKsS,GAAO,CACpC,IAAIC,EAAQD,EAAKC,MAAML,EAAMC,SAC7B3V,EAAM+V,EAAM,OACZJ,EAAUI,EAAM,MAGX/V,WAQF,SAASe,EAAWiV,GACL,IAAjBA,EAAMC,UACTxK,GAAOyK,QAAQpM,SAASC,eAAe,sBAAsB/J,OAC7D8J,SAASC,eAAe,sBAAsB/J,MAAQ,IASjD,SAASgB,EAAQgV,GACvB,GAAqB,IAAjBA,EAAMC,QAAe,CACxB,IAAIE,EAAS1K,GAAOgF,KAChB2F,EAAQ3K,GAAO4K,UACfC,EAAQ7K,GAAO8K,aACfC,EAAW/K,GAAOzG,KAAO,EAAE,EAC3ByR,EAAU3M,SAASC,eAAe,aAAa/J,MAC/C8I,EAAW,IACXE,EAAY,IACZc,SAASC,eAAe,WAAW2M,UACtC5N,EAAWsN,EAAMvE,IACjB7I,EAAYoN,EAAMtE,UAEnBrG,GAAOkL,OAAOP,EAAMzN,SAAUwN,EAAO7W,KAAM8W,EAAMxN,OAAQkB,SAASC,eAAe,mBAAmB/J,MAAOmW,EAAOtN,KAAMC,EAAUsN,EAAMrN,KAAMC,EAAWnF,EAAeyS,EAAOE,EAAQ7S,EAAgB8S,IA0BlM,SAASxV,EAAgB+U,GAC/B,IAAIY,EAAY9M,SAASC,eAAe,oBAAoB/J,MAC5DyL,GAAOoL,gBAAgBD,GAQjB,SAAS1V,EAAW4V,GAC1B,IAAIF,EAAaE,EAAG/K,YACpBN,GAAOoL,gBAAgBD,GAOjB,SAASzV,IACfsL,GAASxF,MAAMsL,OAASzI,SAASC,eAAe,kBAAkB/J,MAAQ,IAOpE,SAASoB,IACfqL,GAASkG,SAASJ,OAASzI,SAASC,eAAe,kBAAkB/J,MAAQ,IAOvE,SAASqB,IACfoL,GAASsK,cAAcjN,SAASC,eAAe,kBAAkB/J,MAAQ,KAQnE,SAASsB,EAAgB0U,GAC/BvK,GAAOuL,gBACPlN,SAASC,eAAe,qBAAqBe,MAAMU,QAAU,QAC7D1B,SAASC,eAAe,cAAc6C,UAAY,GAQ5C,SAASrL,EAAS0V,GAGxB,OAFAA,EAAMnS,QAAU,GAChBmS,EAAMhJ,IAAM,wBACL,EAQD,SAASzM,EAAUyV,GAGzB,OAFAA,EAAMnS,QAAU,GAChBmS,EAAMhJ,IAAM,yBACL,EAQR,SAASiJ,EAAWC,GACnB,IAAI7N,EAAM,IAAI8N,MAEd,OADA9N,EAAI2E,IAAMkJ,EACW,GAAd7N,EAAI8K,OASZ,SAAS5D,EAAiB6G,GACzB,IAAIC,EACAC,EAAW9K,GAAS+K,WAGxB,OAFA1N,SAASC,eAAe,aAAae,MAAMU,QAAU,OACrD1B,SAASC,eAAe,gBAAgBe,MAAMU,QAAU,OAChD6L,GACP,IAAK,MACJvN,SAASC,eAAe,gBAAgBkE,IAAMsJ,EAAW,mBACzDzN,SAASC,eAAe,gBAAgBe,MAAMU,QAAU,QACrD0L,EAAWK,EAAW,mBACxBzN,SAASC,eAAe,gBAAgBkE,IAAMsJ,EAAW,kBAEzDzN,SAASC,eAAe,gBAAgBkE,IAAMsJ,EAAW,mBAE1DD,EAAY,UACZ,MACD,IAAK,MACJxN,SAASC,eAAe,gBAAgBkE,IAAMsJ,EAAW,sBACzDzN,SAASC,eAAe,gBAAgBe,MAAMU,QAAU,QACrD0L,EAAWK,EAAW,mBACxBzN,SAASC,eAAe,gBAAgBkE,IAAMsJ,EAAW,sBAEzDzN,SAASC,eAAe,gBAAgBkE,IAAMsJ,EAAW,qBAE1DD,EAAY,cACZ,MACD,IAAK,MACJxN,SAASC,eAAe,gBAAgBkE,IAAMsJ,EAAW,kBACzDD,EAAY,UACZ,MACD,IAAK,MACJxN,SAASC,eAAe,gBAAgBkE,IAAMsJ,EAAW,qBACzDD,EAAY,cACZ,MACD,IAAK,MACJxN,SAASC,eAAe,gBAAgBkE,IAAMsJ,EAAW,mBACzDzN,SAASC,eAAe,gBAAgBe,MAAMU,QAAU,QACxD1B,SAASC,eAAe,gBAAgBkE,IAAMsJ,EAAW,cACzDD,EAAY,cACZ,MACD,IAAK,MACJxN,SAASC,eAAe,gBAAgBkE,IAAMsJ,EAAW,iBACzDD,EAAY,cAGe,GAAzB7K,GAASC,QAAQa,OACpBzD,SAASC,eAAe,gBAAgBe,MAAMU,QAAU,OACxD1B,SAASC,eAAe,gBAAgBkE,IAAM7K,EAAU,kBAAoBkU,EAAY,mBAOnF,SAAS7V,IACfgK,GAAOO,WACPP,GAAS,IAAIzH,EAAOd,MAEnBhD,EAAO,OACP4J,SAASC,eAAe,gBAAgBe,MAAMU,QAAU,QAQnD,SAAS9J,IACf+J,GAAOC,aASR,SAASyC,EAAYsJ,GAAqC,IAA9BnY,EAA8BoY,UAAAvN,OAAA,QAAAwN,IAAAD,UAAA,GAAAA,UAAA,GAAvB,GAAIE,EAAmBF,UAAAvN,OAAA,QAAAwN,IAAAD,UAAA,GAAAA,UAAA,GAAZ,IAAI3T,KAC3C8T,EAAQ/N,SAASqF,cAAc,KAC/B2I,EAAYhO,SAASqF,cAAc,QAOzC,GANA2I,EAAUvO,GAAK,aACfuO,EAAUrI,YAAY3F,SAASiO,eAAezY,IAC9CuY,EAAMpI,YAAYqI,GAClBD,EAAMpI,YAAY3F,SAASiO,eAAeN,IAGtC3T,EAAkBkU,eAAiBJ,EAAKI,aAAc,CACzD,IAAMC,EAAYnO,SAASqF,cAAc,QACzC8I,EAAU1O,GAAK,aACf0O,EAAUC,UAAYN,EAAKO,wBAAmBR,GAC7CS,KAAM,UACNC,OAAQ,YAETR,EAAMpI,YAAYwI,GAGnB,IAAMK,EAAYxO,SAASC,eAAe,cAC1CuO,EAAU7I,YAAYoI,GAElBS,EAAUxK,UAAYwK,EAAUvK,aAAe,MAClDuK,EAAUxK,UAAYwK,EAAUvK,cAGjCjK,EAAoB,IAAIC,KAOlB,SAASpC,EAAS4W,GACpBA,EAAa,IAChB9M,GAAO+M,cAAcD,IAGrBzO,SAASC,eAAe,qBAAqBe,MAAMU,QAAU,OAC7D1B,SAASC,eAAe,mBAAmBe,MAAMU,QAAU,OAC3D1B,SAASC,eAAe,cAAce,MAAMU,QAAU,QASjD,SAAS5J,EAAY6W,IACE,GAAzBhN,GAAOlG,gBACVuE,SAASC,eAAe,OAAS0B,GAAOlG,eAAe0I,IAAMxC,GAAO4K,UAAUtE,YAE/EtG,GAAOlG,cAAgBkT,EACvB3O,SAASC,eAAe,OAAS0O,GAAKxK,IAAMxC,GAAO4K,UAAUrE,UAQvD,SAASnQ,EAAaqH,GAC5B,GAAIuC,GAAOjG,kBAAoB0D,EAAU,CAErCuC,GAAOjG,iBAAmB,IAC5BsE,SAASC,eAAe,OAAS0B,GAAOjG,kBAAkBkI,UAAY,iBAEvE5D,SAASC,eAAe,OAASb,GAAUwE,UAAY,qBACvDjC,GAAOjG,iBAAmB0D,EAG1BY,SAASC,eAAe,YAAY/J,MAAQyL,GAAOnG,UAAU4D,EAAW,GAAG5J,KAC3EwK,SAASC,eAAe,YAAY/J,MAAQyL,GAAOnG,UAAU4D,EAAW,GAAGG,KAG3E,IAAIqP,EAAWxW,EAAmB,aAAcuJ,GAAOnG,UAAU4D,EAAW,GAAG6F,UAC/EjF,SAASC,eAAe,cAAcmG,cAAgBwI,EACvC,GAAXA,IACH5O,SAASC,eAAe,gBAAgB/J,MAAQyL,GAAOnG,UAAU4D,EAAW,GAAG6F,UAEhF5M,IAGA2H,SAASC,eAAe,WAAW2D,UAAY,sCAC/C5D,SAASC,eAAe,YAAY2D,UAAY,6BAChD5D,SAASC,eAAe,cAAc2D,UAAY,6BAClD5D,SAASC,eAAe,WAAW2D,UAAY,kCAE/CzL,IAQK,SAASH,IACf,IAAI+H,EAAkBC,SAASC,eAAe,cAC9C0B,GAAOkN,OAAQ7O,SAASC,eAAe,YAAY/J,MAClD8J,SAASC,eAAe,YAAY/J,MACF,GAAjC6J,EAAgBqG,cAChBpG,SAASC,eAAe,gBAAgB/J,MACxC6J,EAAgBwF,QAAQxF,EAAgBqG,eAAed,MAEzDnN,IAOM,SAASF,IACf,IAAI8H,EAAkBC,SAASC,eAAe,cAC1CR,EAAK8J,SAAS5H,GAAOjG,kBAAoB,EAC7CiG,GAAOmN,OAAQrP,EACdO,SAASC,eAAe,YAAY/J,MACpC8J,SAASC,eAAe,YAAY/J,MACF,GAAjC6J,EAAgBqG,cAChBpG,SAASC,eAAe,gBAAgB/J,MACxC6J,EAAgBwF,QAAQxF,EAAgBqG,eAAed,MAEzDnN,IAOM,SAASD,IACf,IAAIuH,EAAK8J,SAAS5H,GAAOjG,kBAAoB,EAC7CiG,GAAOoN,OAAOtP,GACdtH,IAOM,SAASA,IAEZwJ,GAAOjG,iBAAmB,IAC5BsE,SAASC,eAAe,OAAS0B,GAAOjG,kBAAkBkI,UAAY,iBAEvEjC,GAAOjG,iBAAmB,EAG1BsE,SAASC,eAAe,cAAcmG,cAAgB,EACtD/N,IACA2H,SAASC,eAAe,gBAAgB/J,MAAQ,GAChD8J,SAASC,eAAe,YAAY/J,MAAQ,GAC5C8J,SAASC,eAAe,YAAY/J,MAAQ,GAC5C8J,SAASC,eAAe,YAAYe,MAAM8J,gBAAkB,wBAG5D9K,SAASC,eAAe,WAAW2D,UAAY,6BAC/C5D,SAASC,eAAe,YAAY2D,UAAY,sCAChD5D,SAASC,eAAe,cAAc2D,UAAY,sCAClD5D,SAASC,eAAe,WAAW2D,UAAY,sCASzC,SAASxL,EAAmB4W,EAAY9Y,GAG7C,IADA,IAAI+Y,EAAiBjP,SAASC,eAAe+O,GACpC/Z,EAAI,EAAGA,EAAIga,EAAe5O,SAAUpL,EAC5C,GAAIga,EAAe1J,QAAQtQ,GAAGiB,OAASA,EACtC,OAAOjB,EAGT,OAAO,EAOF,SAASoD,IACf,IAAI0H,EAAkBC,SAASC,eAAe,cAC1CiP,EAAoBlP,SAASC,eAAe,gBAC5CkP,EAAmBnP,SAASC,eAAe,YAEV,GAAjCF,EAAgBqG,eACnB8I,EAAkBlO,MAAMU,QAAU,UAClCyN,EAAiBnO,MAAM8J,gBAAkB,QAAUxR,EAAU,YAAc4V,EAAkBhZ,MAAQ,OAErGgZ,EAAkBlO,MAAMU,QAAU,OAClCyN,EAAiBnO,MAAM8J,gBAAkB,QAAUxR,EAAU,YAAcyG,EAAgB7J,MAAQ,MAQ9F,SAASoC,IACf,IAAI2M,EAAW,GAAI3E,EAAoBN,SAASC,eAAe,aAC5DmP,EAAapP,SAASC,eAAe,cAAc/J,MAErD+O,EADsC,GAAnC3E,EAAkB8F,cACVpG,SAASC,eAAe,eAAe/J,MAEvCoK,EAAkBpK,MAE9ByL,GAAOyK,QAAQ,IAAMgD,EAAWjM,QAAQ,KAAK8B,IAOvC,SAAS1M,IACf,IAAI+H,EAAoBN,SAASC,eAAe,aAC5CoP,EAAsBrP,SAASC,eAAe,eAC9CqP,EAAqBtP,SAASC,eAAe,cAEV,GAAnCK,EAAkB8F,eACrBiJ,EAAoBrO,MAAMU,QAAU,UACpC4N,EAAmBnL,IAAM7K,EAAU,cAAgB+V,EAAoBnZ,MAAQ,sBAE/EmZ,EAAoBrO,MAAMU,QAAU,OACpC4N,EAAmBnL,IAAM7K,EAAU,cAAgBgH,EAAkBpK,MAAQ,qBAUxE,SAASsC,EAAaoS,GACxBA,GAAU/Q,GACbmG,SAASC,eAAe,iBAAmB2K,GAAQhH,UAAY,gBAC/D/J,EAAiB,IAEjBmG,SAASC,eAAe,iBAAmB2K,GAAQhH,UAAY,qBAC3D/J,IACHmG,SAASC,eAAe,iBAAmBpG,GAAgB+J,UAAY,iBAExE/J,EAAiB+Q,GAQZ,SAASnS,IACXkJ,GAAOzG,KACV8E,SAASC,eAAe,eAAe2D,UAAY,gBAEnD5D,SAASC,eAAe,eAAe2D,UAAY,qBAEpDjC,GAAOzG,MAAQyG,GAAOzG,KAOhB,SAASxC,IACXiJ,GAAOxG,YACV6E,SAASC,eAAe,kBAAkB2D,UAAY,gBAEtD5D,SAASC,eAAe,kBAAkB2D,UAAY,qBAEvDjC,GAAOxG,aAAewG,GAAOxG,YAQvB,SAASxC,EAAW4W,GACtBA,GAAQzV,IACXkG,SAASC,eAAe,QAAUsP,GAAM3L,UAAY,mBACpD5D,SAASC,eAAe,WAAasP,GAAM3L,UAAY,sBACvD5D,SAASC,eAAe,QAAUnG,GAAc8J,UAAY,YAC5D5D,SAASC,eAAe,WAAanG,GAAc8J,UAAY,eAC/D9J,EAAeyV,GAUV,SAAS3W,EAAY2R,GACvBA,GAASxQ,GACZiG,SAASC,eAAe,UAAYsK,GAAO3G,UAAY,gBACvD7J,EAAgB,IAEhBiG,SAASC,eAAe,UAAYsK,GAAO3G,UAAY,qBACnD7J,IACHiG,SAASC,eAAe,UAAYlG,GAAe6J,UAAY,iBAEhE7J,EAAgBwQ,GAWlB,SAASlH,EAAWmM,GACnB,OAAOA,EACLrM,QAAQ,KAAM,SACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,UACdA,QAAQ,KAAM,UAOjB,SAASxE,EAAWuE,GACnB,OAAOA,EACLC,QAAQ,KAAM,WACdA,QAAQ,KAAM,SACdA,QAAQ,KAAM,aACdA,QAAQ,MAAO,YAOlB,SAASI,EAAaL,GACrB,OAAOA,EACLC,QAAQ,WAAY,KACpBA,QAAQ,SAAU,KAClBA,QAAQ,aAAc,KACtBA,QAAQ,YAAa,KAOxB,SAASvE,EAAWsE,GACnB,IAAIuM,EAAmBzP,SAASC,eAAe,mBAAmB/J,MAClE,GAAwB,WAApBuZ,EAEH,OAAOvM,EAAQC,QAAQ,WAAY,SAASuM,GAC3C,MAAO,OAAS,MAAQA,EAAGC,aAAaC,SAAS,KAAKC,OAAO,KACxD,GAAwB,SAApBJ,EAA4B,CAItC,IAFA,IAAIK,EAAS,IAAIC,YAA2B,EAAf7M,EAAQ7C,QACjC2P,EAAS,IAAIC,YAAYH,GACpB7a,EAAE,EAAGib,EAAOhN,EAAQ7C,OAAQpL,EAAIib,EAAQjb,IAChD+a,EAAO/a,GAAKiO,EAAQyM,WAAW1a,GAEhC,OAAO+U,OAAOgG,GAEd,OAAO9M,EAQT,SAASI,GAAWJ,GACnB,IAAIiN,EAAmBnQ,SAASC,eAAe,mBAAmB/J,MAClE,MAAwB,WAApBia,EAEUjN,EAAQC,QAAQ,oBAAqB,SAAU8I,EAAOmE,GAClE,OAAOpG,OAAOC,aAAaV,SAAS6G,EAAO,OACd,SAApBD,EAEHnG,OAAOC,aAAaoG,MAAM,KAAM,IAAIJ,YAAY/M,EAAQjK,MAAM,OAE9DiK,EAplBToN,OAAOrZ,WAAaA,EAsBpBqZ,OAAOpZ,QAAUA,EA2BjBoZ,OAAOnZ,gBAAkBA,EAUzBmZ,OAAOlZ,WAAaA,EAQpBkZ,OAAOjZ,kBAAoBA,EAQ3BiZ,OAAOhZ,gBAAkBA,EAQzBgZ,OAAO/Y,iBAAmBA,EAW1B+Y,OAAO9Y,gBAAkBA,EAWzB8Y,OAAO7Y,SAAWA,EAWlB6Y,OAAO5Y,UAAYA,EAgFnB4Y,OAAO3Y,gBAAkBA,EAQzB2Y,OAAO1Y,YAAcA,EAkDrB0Y,OAAOzY,SAAWA,EAalByY,OAAOxY,YAAcA,EAoCrBwY,OAAOvY,aAAeA,EAetBuY,OAAOtY,YAAcA,EAiBrBsY,OAAOrY,aAAeA,EAUtBqY,OAAOpY,YAAcA,EA0BrBoY,OAAOnY,eAAiBA,EAiBxBmY,OAAOlY,mBAAqBA,EAkB5BkY,OAAOjY,mBAAqBA,EAe5BiY,OAAOhY,oBAAsBA,EAkB7BgY,OAAO/X,wBAA0BA,EAmBjC+X,OAAO9X,aAAeA,EAatB8X,OAAO7X,WAAaA,EAapB6X,OAAO5X,cAAgBA,EAevB4X,OAAO3X,WAAaA,EAmBpB2X,OAAO1X,YAAcA,OAuGiB,IAA3BoR,OAAOnT,UAAU0Z,OAExBvG,OAAOnT,UAAU0Z,KAAO,WAEpB,OAAOvG,OAAO3P,MAAM8I,QAAQ,aAAc,MAKlD6G,OAAOnT,UAAU+I,SAAW,WAC3B,IAAc3K,EAAVub,EAAO,EACX,GAAoB,IAAhBnW,KAAKgG,OAAc,OAAOmQ,EAC9B,IAAKvb,EAAI,EAAGA,EAAIoF,KAAKgG,OAAQpL,IAE3Bub,GAAUA,GAAQ,GAAKA,EADfnW,KAAKsV,WAAW1a,GAExBub,GAAQ,EAEV,OAAOA,GAQR,IAAI7O,GAAS,IAAIzH,EAAOd,GACpBuJ,GAAW,IAAIwF,EAEnBwC,EAAE3K,UAAUyQ,MAAM,WACjB9O,GAAO+O,sBACP/O,GAAOgP","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 65;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id, name, desc, img) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\t\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\tchangeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tif(ImageExist(bgfolder + \"defensedesk.png\")){\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t\t}else{\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t\t}\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tif(ImageExist(bgfolder + \"defensedesk.png\")){\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t\t} else {\r\n\t\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t\t}\t\t\t\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Change background.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n});\r\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","shouts","FileExist","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","clip","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","transform","opacity","height","shout","1","2","3","$","effect","direction","backgroundImage","right","left","animate","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","sendZZ","sendRT","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","String","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\t\t\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\":{\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\":{\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\":{\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\":{\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\":{\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\t\t\t\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif(this.chars[this.charID].side == \"jud\"){\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// Calculate gif duration of shouts\r\n\t\tlet shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"];\r\n\t\t\tFileExist(shout_src, this.callbackLoadImageResources, shouts[i]);\t\t\r\n\t\t}\r\n\t\t\r\n\t\t// Calculate gif duration of testimony\r\n\t\tlet testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tlet testimony_src = AO_HOST + \"themes/default/\"+ testimony[i] +\".gif\";\r\n\t\t\t// Check iamge existed\r\n\t\t\tFileExist(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tFileExist(AO_HOST + this.resources[testimony[i]][\"sfx\"], this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src,client.callbackGetResourceLength, resource);\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length; \r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\t\r\n\t}\t\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"menu_wt\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"menu_ce\").style.display = \"inline-table\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"menu_wt\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"menu_ce\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\t\r\n\tclient.sendZZ(\"\");\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n});\r\n"],"sourceRoot":""} \ No newline at end of file -- cgit From c1730c3e16d088c03f27adab3ebfb4e6f7a37d1a Mon Sep 17 00:00:00 2001 From: Qube Date: Sat, 21 Jul 2018 01:00:48 +0700 Subject: Add penalty bars function and confirm dialog for "call mod" button. --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index 0898258..3ec58e5 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","shouts","FileExist","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","clip","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","transform","opacity","height","shout","1","2","3","$","effect","direction","backgroundImage","right","left","animate","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","sendZZ","sendRT","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","String","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\t\t\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\":{\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\":{\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\":{\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\":{\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\":{\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\t\t\t\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif(this.chars[this.charID].side == \"jud\"){\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// Calculate gif duration of shouts\r\n\t\tlet shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"];\r\n\t\t\tFileExist(shout_src, this.callbackLoadImageResources, shouts[i]);\t\t\r\n\t\t}\r\n\t\t\r\n\t\t// Calculate gif duration of testimony\r\n\t\tlet testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tlet testimony_src = AO_HOST + \"themes/default/\"+ testimony[i] +\".gif\";\r\n\t\t\t// Check iamge existed\r\n\t\t\tFileExist(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tFileExist(AO_HOST + this.resources[testimony[i]][\"sfx\"], this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src,client.callbackGetResourceLength, resource);\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length; \r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\t\r\n\t}\t\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"menu_wt\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"menu_ce\").style.display = \"inline-table\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"menu_wt\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"menu_ce\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\t\r\n\tclient.sendZZ(\"\");\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n});\r\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","addHPD","redHPD","addHPP","redHPP","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","hp","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","shouts","FileExist","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","percent_hp","$","animate","width","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","transform","opacity","height","shout","1","2","3","effect","direction","backgroundImage","right","left","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","dialog","sendRT","sendHP","String","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources","autoOpen","resizable","show","hide","modal","buttons","Sure","sendZZ","Cancel"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\t\t\r\n\t\tthis.hp = [0,0];\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\t\t\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\":{\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\":{\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\":{\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\":{\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\":{\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\t\t\t\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {int} side the position\r\n\t * @param {int} hp the health point\r\n\t */\r\n\tsendHP(side,hp) {\r\n\t\tthis.serv.send(`HP#${side}#${hp}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif(this.chars[this.charID].side == \"jud\"){\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// Calculate gif duration of shouts\r\n\t\tlet shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"];\r\n\t\t\tFileExist(shout_src, this.callbackLoadImageResources, shouts[i]);\t\t\r\n\t\t}\r\n\t\t\r\n\t\t// Calculate gif duration of testimony\r\n\t\tlet testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tlet testimony_src = AO_HOST + \"themes/default/\"+ testimony[i] +\".gif\";\r\n\t\t\t// Check iamge existed\r\n\t\t\tFileExist(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tFileExist(AO_HOST + this.resources[testimony[i]][\"sfx\"], this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src,client.callbackGetResourceLength, resource);\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length; \r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\t\r\n\t}\t\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tlet percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t}\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\r\n\t$( \"#callmod_dialog\" ).dialog( \"open\" );\t\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Add defense health point.\r\n */\r\nexport function addHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Reduce defense health point.\r\n */\r\nexport function redHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Add prosecution health point.\r\n */\r\nexport function addHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Reduce prosecution health point.\r\n */\r\nexport function redHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n\t\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$( function() {\r\n\t$( \"#callmod_dialog\" ).dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\t\"Sure\": function() {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t},\r\n\t\t\tCancel: function() {\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""} \ No newline at end of file -- cgit From 67443e853de53562fc8d85a9655324e246ef22ba Mon Sep 17 00:00:00 2001 From: Qube Date: Sat, 21 Jul 2018 11:25:30 +0700 Subject: Add jquery ui mobile support + bbcode description in guide. --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index 3ec58e5..2c5261c 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","addHPD","redHPD","addHPP","redHPP","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","hp","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","shouts","FileExist","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","percent_hp","$","animate","width","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","transform","opacity","height","shout","1","2","3","effect","direction","backgroundImage","right","left","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","dialog","sendRT","sendHP","String","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources","autoOpen","resizable","show","hide","modal","buttons","Sure","sendZZ","Cancel"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\t\t\r\n\t\tthis.hp = [0,0];\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\t\t\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\":{\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\":{\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\":{\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\":{\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\":{\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\t\t\t\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {int} side the position\r\n\t * @param {int} hp the health point\r\n\t */\r\n\tsendHP(side,hp) {\r\n\t\tthis.serv.send(`HP#${side}#${hp}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif(this.chars[this.charID].side == \"jud\"){\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// Calculate gif duration of shouts\r\n\t\tlet shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"];\r\n\t\t\tFileExist(shout_src, this.callbackLoadImageResources, shouts[i]);\t\t\r\n\t\t}\r\n\t\t\r\n\t\t// Calculate gif duration of testimony\r\n\t\tlet testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tlet testimony_src = AO_HOST + \"themes/default/\"+ testimony[i] +\".gif\";\r\n\t\t\t// Check iamge existed\r\n\t\t\tFileExist(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tFileExist(AO_HOST + this.resources[testimony[i]][\"sfx\"], this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src,client.callbackGetResourceLength, resource);\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length; \r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\t\r\n\t}\t\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tlet percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t}\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\r\n\t$( \"#callmod_dialog\" ).dialog( \"open\" );\t\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Add defense health point.\r\n */\r\nexport function addHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Reduce defense health point.\r\n */\r\nexport function redHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Add prosecution health point.\r\n */\r\nexport function addHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Reduce prosecution health point.\r\n */\r\nexport function redHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n\t\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$( function() {\r\n\t$( \"#callmod_dialog\" ).dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\t\"Sure\": function() {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t},\r\n\t\t\tCancel: function() {\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","addHPD","redHPD","addHPP","redHPP","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","hp","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","shouts","FileExist","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","percent_hp","$","animate","width","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","transform","opacity","height","shout","1","2","3","effect","direction","backgroundImage","right","left","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","dialog","sendRT","sendHP","String","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources","autoOpen","resizable","show","hide","modal","buttons","Sure","sendZZ","Cancel"],"mappings":"aACA,IAAAA,KAGA,SAAAC,EAAAC,GAGA,GAAAF,EAAAE,GACA,OAAAF,EAAAE,GAAAC,QAGA,IAAAC,EAAAJ,EAAAE,IACAG,EAAAH,EACAI,GAAA,EACAH,YAUA,OANAI,EAAAL,GAAAM,KAAAJ,EAAAD,QAAAC,IAAAD,QAAAF,GAGAG,EAAAE,GAAA,EAGAF,EAAAD,QAKAF,EAAAQ,EAAAF,EAGAN,EAAAS,EAAAV,EAGAC,EAAAU,EAAA,SAAAR,EAAAS,EAAAC,GACAZ,EAAAa,EAAAX,EAAAS,IACAG,OAAAC,eAAAb,EAAAS,GAA0CK,YAAA,EAAAC,IAAAL,KAK1CZ,EAAAkB,EAAA,SAAAhB,GACA,oBAAAiB,eAAAC,aACAN,OAAAC,eAAAb,EAAAiB,OAAAC,aAAwDC,MAAA,WAExDP,OAAAC,eAAAb,EAAA,cAAiDmB,OAAA,KAQjDrB,EAAAsB,EAAA,SAAAD,EAAAE,GAEA,GADA,EAAAA,IAAAF,EAAArB,EAAAqB,IACA,EAAAE,EAAA,OAAAF,EACA,KAAAE,GAAA,iBAAAF,QAAAG,WAAA,OAAAH,EACA,IAAAI,EAAAX,OAAAY,OAAA,MAGA,GAFA1B,EAAAkB,EAAAO,GACAX,OAAAC,eAAAU,EAAA,WAAyCT,YAAA,EAAAK,UACzC,EAAAE,GAAA,iBAAAF,EAAA,QAAAM,KAAAN,EAAArB,EAAAU,EAAAe,EAAAE,EAAA,SAAAA,GAAgH,OAAAN,EAAAM,IAAqBC,KAAA,KAAAD,IACrI,OAAAF,GAIAzB,EAAA6B,EAAA,SAAA1B,GACA,IAAAS,EAAAT,KAAAqB,WACA,WAA2B,OAAArB,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAH,EAAAU,EAAAE,EAAA,IAAAA,GACAA,GAIAZ,EAAAa,EAAA,SAAAiB,EAAAC,GAAsD,OAAAjB,OAAAkB,UAAAC,eAAA1B,KAAAuB,EAAAC,IAGtD/B,EAAAkC,EAAA,GAIAlC,IAAAmC,EAAA,8aC4nCgBC,eAYAC,YAuCAC,oBAUAC,eASAC,sBAQAC,oBAQAC,qBASAC,oBAWAC,aAWAC,cAsGAC,oBAaAC,gBA2CAC,aAgBAC,gBAaAC,iBAmCAC,gBAeAC,iBAiBAC,gBAUAC,mBA4BAC,uBAeAC,uBAkBAC,yBAqBAC,wBAeAC,kBAYAC,uBAQAC,YAQAC,WAQAC,WAQAC,WAQAC,WAQAC,WAQAC,YAQAC,6BAoBAC,kBAiBAC,gBAaAC,mBAcAC,gBAgBAC,eAl0DhB,IAAIC,KACJC,SAASC,OAAOC,OAAO,GAAGC,MAAM,KAAKC,QAAQ,SAASC,GACrDN,EAAUM,EAAKF,MAAM,KAAK,IAAME,EAAKF,MAAM,KAAK,KAKjD,IAAMG,EAAWP,EAAUQ,GACvB3D,EAAOmD,EAAUnD,KAEf4D,EAAUT,EAAUU,OAAS,4CAC7BC,EAAaF,EAAU,gBAMzBG,GAAa,EACb,uGAAuGC,KAAKC,UAAUC,aACzHH,GAAa,GAGd,IAAII,EAAiB,EACjBC,EAAe,EACfC,EAAgB,EAChBC,EAAoB,IAAIC,KAAK,GAE3BC,aACL,SAAAA,EAAYC,GAAS,IAAAC,EAAAC,KAAAC,EAAAD,KAAAH,GACpBG,KAAKE,KAAO,IAAIC,UAAU,QAAUL,GAEpCE,KAAKE,KAAKE,OAAY,SAACC,GAAD,OAASN,EAAKO,OAAOD,IAC3CL,KAAKE,KAAKK,QAAY,SAACF,GAAD,OAASN,EAAKS,QAAQH,IAC5CL,KAAKE,KAAKO,UAAY,SAACJ,GAAD,OAASN,EAAKW,UAAUL,IAC9CL,KAAKE,KAAKS,QAAY,SAACN,GAAD,OAASN,EAAKa,QAAQP,IAE5CL,KAAKa,MAAO,EACZb,KAAKc,aAAc,EAEnBd,KAAKe,IAAM,EAAE,GAEbf,KAAKgB,SAAW,EAChBhB,KAAKiB,QAAU,EACfjB,KAAKkB,YAAc,EAEnBlB,KAAKmB,SACLnB,KAAKoB,UACLpB,KAAKqB,aAELrB,KAAKsB,WACJC,QACCC,IAAO,kBACPC,SAAY,KAEbC,WACCF,IAAO,qBACPC,SAAY,KAEbE,UACCH,IAAO,oBACPC,SAAY,KAEbG,kBACCJ,IAAO,4BACPC,SAAY,KACZI,IAAO,oCAERC,kBACCN,IAAO,4BACPC,SAAY,KACZI,IAAO,sCAIT7B,KAAK+B,eAAiB,EACtB/B,KAAKgC,iBAAmB,EAExBhC,KAAKiC,aAAe,KAGpBjC,KAAKkC,UAAYtH,SAEjBoF,KAAKmC,UACJC,GAAc,SAACC,GAAD,OAAUtC,EAAKuC,SAASD,IACtCE,GAAc,SAACF,GAAD,OAAUtC,EAAKyC,SAASH,IACtCI,GAAc,SAACJ,GAAD,OAAUtC,EAAK2C,SAASL,IACtCM,IAAc,SAACN,GAAD,OAAUtC,EAAK6C,UAAUP,IACvCQ,GAAc,SAACR,GAAD,OAAUtC,EAAK+C,SAAST,IACtCU,GAAc,SAACV,GAAD,OAAUtC,EAAKiD,SAASX,IACtCY,GAAc,SAACZ,GAAD,OAAUtC,EAAKmD,SAASb,IACtCc,GAAc,SAACd,GAAD,OAAUtC,EAAKqD,SAASf,IACtCgB,GAAc,SAAChB,GAAD,OAAUtC,EAAKuD,SAASjB,IACtCkB,GAAc,SAAClB,GAAD,OAAUtC,EAAKyD,SAASnB,IACtCoB,MAAc,SAACpB,GAAD,OAAUtC,EAAK2D,YAAYrB,IACzCsB,KAAc,SAACtB,GAAD,OAAUtC,EAAK6D,WAAWvB,IACxCwB,GAAc,SAACxB,GAAD,OAAUtC,EAAK+D,SAASzB,IACtC0B,IAAc,SAAC1B,GAAD,OAAUtC,EAAKiE,UAAU3B,IACvC4B,GAAc,SAAC5B,GAAD,OAAUtC,EAAKmE,SAAS7B,IACtC8B,GAAc,SAAC9B,GAAD,OAAUtC,EAAKqE,SAAS/B,IACtCgC,GAAc,SAAChC,GAAD,OAAUtC,EAAKuE,SAASjC,IACtCkC,GAAc,SAAClC,GAAD,OAAUtC,EAAKyE,SAASnC,IACtCoC,GAAc,SAACpC,GAAD,OAAUtC,EAAK2E,SAASrC,IACtCsC,GAAc,SAACtC,GAAD,OAAUtC,EAAK6E,SAASvC,IACtCwC,WAAc,SAACxC,GAAD,OAAUtC,EAAK+E,iBAAiBzC,IAC9C0C,GAAc,SAAC1C,GAAD,OAAUtC,EAAKiF,SAAS3C,IACtC4C,MAAc,SAAC5C,MAGhBrC,KAAKkF,oBAAsB,IAAItF,KAAK,0CAOpC,OAAOI,KAAKmB,MAAMnB,KAAKiB,0CAOvB,OAAOjB,KAAKoB,OAAOpB,KAAK+B,oDAOxB,OAAQ/B,KAAKc,YAAcd,KAAKgC,iBAAmB,kCAO5CmD,GACPnF,KAAKE,KAAKkF,KAAV,SAAwBpF,KAAKgB,SAA7B,IAAyCqE,GAAWC,GAAWH,IAA/D,qCAeMI,EAAU9K,EAAM+K,EAAQL,EAASM,EAAMC,EAAUC,EAAMC,EAAWlE,EAAWmE,EAAUhF,EAAMiF,EAAOC,GAC1G/F,KAAKE,KAAKkF,KACT,WAAWG,EAAX,IAAuB9K,EAAvB,IAA+B+K,EAA/B,IACIH,GAAWC,GAAWH,IAD1B,IACuCM,EADvC,IAC+CC,EAD/C,IAC2DC,EAD3D,IAEI3F,KAAKiB,OAFT,IAEmB2E,EAFnB,IAEgClG,EAFhC,IAEiDmG,EAFjD,IAE6DhF,EAF7D,IAEqEiF,EAFrE,IAE8EC,EAF9E,qCAYKtL,EAAMuL,EAAMC,GAClBjG,KAAKE,KAAKkF,KAAV,MAAqBC,GAAWC,GAAW7K,IAA3C,IAAqD4K,GAAWC,GAAWU,IAA3E,IAAqFC,EAArF,qCAUMC,EAAIzL,EAAMuL,EAAMC,GACtBjG,KAAKE,KAAKkF,KAAV,MAAqBc,EAArB,IAA2Bb,GAAWC,GAAW7K,IAAjD,IAA2D4K,GAAWC,GAAWU,IAAjF,IAA2FC,EAA3F,qCAOMC,GACNlG,KAAKE,KAAKkF,KAAV,MAAqBc,EAArB,qCAQMT,EAAK1E,GACXf,KAAKE,KAAKkF,KAAV,MAAqBK,EAArB,IAA6B1E,EAA7B,qCAOMoF,GACNnG,KAAKE,KAAKkF,KAAV,MAAqBe,EAArB,qCAOMC,GAC6B,OAAhCpG,KAAKmB,MAAMnB,KAAKiB,QAAQwE,MAC1BzF,KAAKE,KAAKkF,KAAV,MAAqBgB,EAArB,8CAQcC,GACfrG,KAAKE,KAAKkF,KAAV,MAAqBiB,EAArB,IAA8BrG,KAAKiB,OAAnC,8CAUAjB,KAAKE,KAAKkF,KAAK,6CAOH,IAAAkB,EAAAtG,KACZA,KAAKE,KAAKkF,KAAV,MAAqB9F,UAAUC,UAAUgH,WAAzC,MACAvG,KAAKE,KAAKkF,KAAK,oBACfpF,KAAKiC,aAAeuE,YAAY,kBAAMF,EAAKG,aAAa,6CAQxD,IAAIC,EAAkBC,SAASC,eAAe,cAC9CF,EAAgBG,IAAI,IAAIC,OAAO,SAAU,IACzC,IAAI,IAAI5M,EAAI,EAAGA,GAAK6M,aAAaC,OAAQ9M,IACvCwM,EAAgBG,IAAI,IAAIC,OAAOC,aAAa7M,EAAI,KAGlD,IAAI+M,EAAoBN,SAASC,eAAe,aAChDK,EAAkBJ,IAAI,IAAIC,OAAO,SAAU,IAC3C,IAAI,IAAI5M,EAAI,EAAGA,GAAKgN,eAAeF,OAAQ9M,IACzC+M,EAAkBJ,IAAI,IAAIC,OAAOI,eAAehN,EAAI,KAItD,IADA,IAAIiN,GAAU,SAAU,YAAa,YAC5BjN,EAAI,EAAGA,EAAIiN,EAAOH,OAAQ9M,IAAK,CAEvCkN,EADgBnI,EAAUe,KAAKsB,UAAU6F,EAAOjN,IAAtB,IACL8F,KAAKqH,2BAA4BF,EAAOjN,IAK9D,IADA,IAAIkM,GAAa,mBAAoB,oBAC5BlM,EAAI,EAAGA,EAAIkM,EAAUY,OAAQ9M,IAAK,CAG1CkN,EAFoBnI,EAAU,kBAAmBmH,EAAUlM,GAAI,OAEtC8F,KAAKqH,2BAA4BjB,EAAUlM,IAEpEkN,EAAUnI,EAAUe,KAAKsB,UAAU8E,EAAUlM,IAAzB,IAAqC8F,KAAKsH,yBAA0BlB,EAAUlM,wDAYzEqN,EAAQC,EAAUhG,GACzC+F,IACFE,GAAOnG,UAAUkG,GAAjB,IAAoChG,EACpCkG,GAASC,cAAcnG,EAAIiG,GAAOG,0BAA2BJ,sDASrCR,EAAQQ,GACjCC,GAAOnG,UAAUkG,GAAjB,SAAyCR,mDASjBO,EAAQC,EAAUhG,GACvC+F,IACFE,GAAOnG,UAAUkG,GAAjB,IAAoChG,iDASrC,IAAIqG,EAASlB,SAASC,eAAe,qBACtB,IAAIkB,iBAAiB,SAASC,GAC3CA,EAAUlJ,QAAQ,SAASmJ,GAC5B,IAAIC,EAAWD,EAASE,WACP,OAAbD,GACHA,EAASpJ,QAAS,SAASsJ,GACN,KAAhBA,EAAKC,QACRD,EAAKE,MAAMtC,MAAQoC,EAAKG,aAAa,KACZ,KAAhBH,EAAKC,UACVD,EAAKI,aAAa,KACrBJ,EAAKE,MAAMG,gBAAkBL,EAAKG,aAAa,MAE/CH,EAAKE,MAAMG,gBAAkB,SAC7BL,EAAKE,MAAMtC,MAAQ,gBAQf0C,QAAQZ,GADHa,YAAY,EAAKC,WAAW,0CAQ7BC,GACb5I,KAAKE,KAAKkF,KAAV,MAAqBpF,KAAKgB,SAA1B,IAAsC4H,EAAtC,4CAOSC,GACT7I,KAAKE,KAAKkF,KAAV,MAAqByD,uCAOrB7I,KAAKE,KAAKkF,KAAV,MAAqBpF,KAAKiB,OAA1B,qCAMM6H,GAEO,UAATzN,GACHsL,SAASC,eAAe,kBAAkByB,MAAMU,QAAU,OAC1DpC,SAASC,eAAe,qBAAqByB,MAAMU,QAAU,QAE7DtB,GAAOuB,6CAQDF,GACPG,QAAQC,MAAR,8BAA4CJ,EAAEK,OAA9C,KAAyDL,EAAEM,KAA3D,KACe,OAAXN,EAAEM,OACLzC,SAASC,eAAe,gBAAgByB,MAAMU,QAAU,QACxDpC,SAASC,eAAe,YAAYyC,YAAcP,EAAEM,KACpDpJ,KAAKsJ,6CAQGR,GACT,IAAI3C,EAAM2C,EAAES,KACZN,QAAQO,MAAMrD,GACd,IACI9D,EADQ8D,EAAIvH,MAAM,KACL,GAAGA,MAAM,KACtB6K,EAASpH,EAAK,GACdqH,EAAU1J,KAAKmC,SAASsH,QACL,IAAZC,EACVA,EAAQrH,GAER4G,QAAQU,KAAR,yBAAsCF,mCAQhCX,GACPG,QAAQC,MAAR,6BAA2CJ,EAAEK,OAA7C,KAAwDL,EAAEM,KAA1D,KACAzC,SAASC,eAAe,gBAAgByB,MAAMU,QAAU,QACxDpC,SAASC,eAAe,YAAYyC,YAAcP,EAAEM,KACpDpJ,KAAKsJ,4CAIL,IACCtJ,KAAKE,KAAK0J,MAAM,MACf,MAAOd,IAGTe,cAAc7J,KAAKiC,+CAOXI,GAER,GAAIA,EAAK,IAAMqF,GAASoC,QAAQC,QAAS,CACxCpD,SAASC,eAAe,qBAAqBoD,UAAY,GAwBzD,IAvBA,IAAIF,GAEHlB,WAAY,EACZqB,QAASC,OAAO7H,EAAK,IACrB8H,UAAW9H,EAAK,GAChB5H,KAAM4H,EAAK,GACXkD,SAAU,MAAQ2E,OAAO7H,EAAK,IAC9BmD,OAAQ,MAAQ0E,OAAO7H,EAAK,IAC5B0H,QAs+CJ,SAAsBK,GACrB,OAAOA,EACLC,QAAQ,OAAQ,QAChBA,QAAQ,cAAe,SACvBA,QAAQ,cAAe,SACvBA,QAAQ,cAAe,WACvBA,QAAQ,cAAe,SACvBA,QAAQ,gBAAiB,WACzBA,QAAQ,gBAAiB,WACzBA,QAAQ,yBAA0B,cAClCA,QAAQ,cAAe,SACvBA,QAAQ,0BAA2B,cACnCA,QAAQ,WAAY,QAl/CVC,CAAaC,GAAWC,GAAWC,GAAapI,EAAK,OAC9DoD,KAAMpD,EAAK,GACXqI,MAAOR,OAAO7H,EAAK,IACnBsI,KAAMtI,EAAK,GAEXuI,SAAUvI,EAAK,IACfX,UAAWW,EAAK,IAChBwD,SAAUxD,EAAK,IACfxB,KAAMwB,EAAK,IACXyD,MAAOzD,EAAK,IACZ0D,MAAO1D,EAAK,IACZwI,OAAO,GAIC3Q,EAAI,EAAGA,EAAI8F,KAAKmB,MAAM6F,OAAQ9M,IACtC,GAAI8F,KAAKmB,MAAMjH,GAAGO,MAAQ4H,EAAK,GAAI,CAClCyH,EAAQlB,UAAY1O,EACpB,MAIE4P,EAAQlB,WAAa5I,KAAKiB,QAuxBjC,WACC0F,SAASC,eAAe,mBAAmBzL,MAAQ,GAC/CqE,IACHmH,SAASC,eAAe,iBAAmBpH,GAAgBsL,UAAY,gBACvEtL,EAAiB,GAEdE,IACHiH,SAASC,eAAe,UAAYlH,GAAeoL,UAAY,gBAC/DpL,EAAgB,GA9xBdqL,GAGDrD,GAASsD,IAAIlB,qCAQNzH,GACR,IAAM4I,EAAStE,SAASC,eAAe,iBACvCqE,EAAOjB,WAAgBQ,GAAWC,GAAapI,EAAK,KAApD,KAA6DmI,GAAWC,GAAapI,EAAK,KAA1F,OACI4I,EAAOC,UAAYD,EAAOE,aAAe,KAC5CF,EAAOC,UAAYD,EAAOE,+CAQnB9I,GACR,IAAMoB,EAAQiE,GAASjE,OACvBA,EAAM2H,QACN3H,EAAMjC,IAAMrC,EAAakD,EAAK,GAC9BoB,EAAM4H,OACFhJ,EAAK,IAAM,GAEdiJ,EADgBtL,KAAKmB,MAAMkB,EAAK,IAAI5H,KACpC,qBAA6C4H,EAAK,IAElDiJ,8BAAwCjJ,EAAK,sCAQrCA,GACTqF,GAASjE,MAAM2H,QACf1D,GAASjE,MAAQ,IAAI8H,MAAMvL,KAAKkC,UAAUG,EAAK,KAC/C,IAAMoB,EAAQiE,GAASjE,MAEvBA,EAAM+H,OAASnJ,EAAK,GACpBoB,EAAMgI,QAAS,IAAI7L,MAAO8L,UAAY,IACtCjI,EAAMkI,iBAAiB,iBAAkB,WACxClI,EAAMmI,aAAeC,WAAWpI,EAAM+H,SAAU,IAAI5L,MAAO8L,UAAY,IAAOjI,EAAMgI,SAASK,QAAQ,GACrGrI,EAAM4H,SACJ,oCAQKhJ,GACRsE,SAASC,eAAe,sBAAsBoD,UAAY,qBAAuB3H,EAAK,GACtFrC,KAAKE,KAAKkF,KAAK,OAAU/C,EAAK,GAAK,GAAM,GAAK,MAC9C,IAAK,IAAInI,EAAI,EAAGA,EAAImI,EAAK2E,OAAS,EAAG9M,IACpC,GAAIA,EAAI,GAAK,EAAG,CACf,IAAI6R,EAAS1J,EAAKnI,GAAG0E,MAAM,KAC3BoB,KAAKmB,MAAMkB,EAAKnI,EAAI,KACnBO,KAAQsR,EAAO,GACf/F,KAAQ+F,EAAO,GACflG,SAAYkG,EAAO,GACnBC,KAAQ/M,EAAU,cAAgBiL,OAAO6B,EAAO,IAAM,oDAWjD1J,GACRsE,SAASC,eAAe,sBAAsBoD,UAAY,qBAC1D,IAAK,IAAI9P,EAAI,EAAGA,EAAImI,EAAK2E,OAAS,EAAG9M,IAAK,CACzC,IAAI6R,EAAS1J,EAAKnI,GAAG0E,MAAM,KAC3BoB,KAAKmB,MAAMjH,EAAI,IACdO,KAAQsR,EAAO,GACf/F,KAAQ+F,EAAO,GACflG,SAAYkG,EAAO,GACnBC,KAAQ/M,EAAU,cAAgBiL,OAAO6B,EAAO,IAAM,kBAGxD/L,KAAKE,KAAKkF,KAAK,yCAUP/C,GACRsE,SAASC,eAAe,sBAAsBoD,UAAY,oBAAsB3H,EAAK,GAErFrC,KAAKE,KAAKkF,KAAK,yCASP/C,GACRrC,KAAKqB,aACL,IAAK,IAAInH,EAAI,EAAGA,EAAImI,EAAK2E,OAAS,EAAG9M,IAAK,CACzC,IAAI+R,EAAM5J,EAAKnI,GAAG0E,MAAM,KACxBoB,KAAKqB,UAAUnH,EAAI,IAClBO,KAAQ8P,GAAWC,GAAWC,GAAawB,EAAI,MAC/CjG,KAAQuE,GAAWC,GAAWC,GAAawB,EAAI,MAC/CC,SAAYhC,OAAO+B,EAAI,IACvBD,KAAQ/M,EAAU,YAAciL,OAAO+B,EAAI,KAI7C,IAAIE,EAAexF,SAASC,eAAe,aAC3CuF,EAAanC,UAAY,GACzB,IAAI,IAAI9P,EAAI,EAAGA,GAAK8F,KAAKqB,UAAU2F,OAAQ9M,IAC1CiS,EAAanC,WAAa,aAAehK,KAAKqB,UAAUnH,EAAI,GAAG8R,KAC9D,aAAe9R,EAAG,UAAY8F,KAAKqB,UAAUnH,EAAI,GAAGO,KACpD,iDAC0BP,EAAG,uCASvBmI,GACRsE,SAASC,eAAe,sBAAsBoD,UAAY,iBAAmB3H,EAAK,GAClFrC,KAAKE,KAAKkF,KAAK,OAAU/C,EAAK,GAAK,GAAM,GAAK,MAE9C,IADA,IAAI+J,EAAazF,SAASC,eAAe,oBAChC1M,EAAI,EAAGA,EAAImI,EAAK2E,OAAS,EAAG9M,IACpC,GAAIA,EAAI,GAAK,EAAG,CACf,IAAImS,EAAW1F,SAAS2F,cAAc,UACtCD,EAASE,KAAOlK,EAAKnI,GACrBkS,EAAWI,QAAQ3F,IAAIwF,qCAUjBhK,GACRsE,SAASC,eAAe,sBAAsBoD,UAAY,iBAG1D,IAFA,IAAIoC,EAAazF,SAASC,eAAe,oBAAqB6F,GAAY,EAEjEvS,EAAI,EAAGA,EAAImI,EAAK2E,OAAS,EAAG9M,IAMpC,GAJG,8BAA8BmF,KAAKgD,EAAKnI,MAAQuS,IAClDA,GAAY,GAGVA,EAAW,CAEb,IAAIJ,EAAW1F,SAAS2F,cAAc,UACtCD,EAASE,KAAOlK,EAAKnI,GACrBkS,EAAWI,QAAQ3F,IAAIwF,OAEjB,CAEN,IAAIK,EAAU/F,SAAS2F,cAAc,QACrCI,EAAQ5B,UAAY,eACpB4B,EAAQrD,YAAchH,EAAKnI,GAC3BwS,EAAQC,QAAU,WAAYtQ,EAAW2D,OACzC2G,SAASC,eAAe,SAASgG,YAAYF,GAK/C,IAAIG,EAAWlG,SAASC,eAAe,SACnCkG,EAAcnG,SAAS2F,cAAc,UACzCQ,EAAYP,KAAOM,EAASE,UAAU1D,YACtC+C,EAAWY,aAAaF,EAAaV,EAAWa,YAChDJ,EAASK,YAAYL,EAASE,WAE9B/M,KAAKE,KAAKkF,KAAK,4CAQJ/C,GACX,IAAK,IAAInI,EAAI,EAAGA,EAAImI,EAAK2E,OAAS,EAAG9M,IACpC8F,KAAKkC,UAAUG,EAAK,EAAInI,IAAMmI,EAAK,EAAInI,EAAI,sCAUlCmI,GACVsE,SAASC,eAAe,kBAAkByB,MAAMU,QAAU,OAC1DpC,SAASC,eAAe,qBAAqByB,MAAMU,QAAU,yCAOrD1G,GACRqF,GAASyF,OAASjD,OAAO7H,EAAK,IAC9B,IAAI+K,EAAW/P,EAAmB,YAAa6M,OAAO7H,EAAK,KAC3DsE,SAASC,eAAe,aAAayG,cAAgBD,EACrDlP,KACe,GAAZkP,IACFzG,SAASC,eAAe,eAAezL,MAAQkH,EAAK,IAErDsE,SAASC,eAAe,cAAcpF,IAAMvC,EAAU,cAAgBiL,OAAO7H,EAAK,IAAM,qBACrE,GAAhBrC,KAAKiB,OACPqM,EAAiB,OAEjBA,EAAiBtN,KAAKmB,MAAMnB,KAAKiB,QAAQwE,wCAKjCpD,qCAQDA,GACR,IAAIkL,EAAuB,GAAVlL,EAAK,GACP,GAAXA,EAAK,IAERrC,KAAKe,GAAG,GAAKsB,EAAK,GAClBmL,EAAE,oCAAoCC,SAAUC,MAASH,EAAa,KAAO,OAG7EvN,KAAKe,GAAG,GAAKsB,EAAK,GAClBmL,EAAE,uCAAuCC,SAAUC,MAASH,EAAa,KAAO,uCAQzElL,GACO,cAAXA,EAAK,GAERrC,KAAKkB,YAAc,EAGnBlB,KAAKkB,YAAc,EAEpBwG,GAASiG,wDAODtL,GACR,IAAM4I,EAAStE,SAASC,eAAe,iBACvCqE,EAAOjB,WAAP,WAAgCQ,GAAWC,GAAapI,EAAK,KAA7D,OACI4I,EAAOC,UAAYD,EAAOE,aAAe,KAC5CF,EAAOC,UAAYD,EAAOE,+CAQnB9I,GACRrC,KAAKgB,SAAWqB,EAAK,oCAGbA,GACRrC,KAAKE,KAAKkF,KAAK,8CAQP/C,GACJjD,EACHY,KAAKE,KAAKkF,KAAK,cAEfpF,KAAKE,KAAKkF,KAAK,iDAQA/C,GAChBsE,SAASC,eAAe,oBAAoBoD,UAAY,GACxD,IAAK,IAAI9P,EAAI,EAAGA,EAAI8F,KAAKmB,MAAM6F,OAAQ9M,IAAK,CAC3C,GAAIA,EAnwBmB,GAmwBM,EAC5B,IAAI0T,EAAKjH,SAAS2F,cAAc,MAEjC,IAAIuB,EAAKlH,SAAS2F,cAAc,MAC5BwB,SACAC,EAAW/N,KAAKmB,MAAMjH,GAAG8R,KAE5B8B,EADkB,MAAfzL,EAAKnI,EAAI,GACE,QAEA,GAEf2T,EAAG7D,UAAY,wBAAwB8D,EAAxB,cAAiD5T,EAAjD,UACN6T,EADM,UACY/N,KAAKmB,MAAMjH,GAAGO,KAD1B,uBACqDP,EADrD,iCAGf0T,EAAGhB,YAAYiB,GACX3T,EAlxBmB,GAkxBM,GAC5ByM,SAASC,eAAe,oBAAoBgG,YAAYgB,qCAUlDvL,GACRrC,KAAKiB,OAASoB,EAAK,GACnBsE,SAASC,eAAe,qBAAqByB,MAAMU,QAAU,OAC7D,IAAIiF,EAAKhO,KAAKgO,KACV5M,EAASpB,KAAKoB,OACd6M,EAAM,IAAIC,eACdvH,SAASC,eAAe,cAAcoD,UAAY,GAClDiE,EAAIE,KAAK,MAAOlP,EAAU,cAAgBiL,OAAOlK,KAAKgO,KAAKvT,MAAQ,aAAa,GAChFwT,EAAIG,aAAe,OACnBH,EAAII,OAAS,SAAUvF,GACtB,GAAmB,KAAf9I,KAAKsO,OAAe,CACvB,IAAIC,EAAWvO,KAAKwO,aAChBC,EAAWC,EAAIC,MAAMJ,GACzBP,EAAGvI,KAAOgJ,EAASG,QAAQnJ,KAC3BlI,EAAqByQ,EAAGvI,MACxB,IAAK,IAAIvL,EAAI,EAAGA,EAAIuU,EAASI,SAASC,OAAQ5U,IAAK,CAClD,IAAI6U,EAAYN,EAASI,SAAS3U,GAAG0E,MAAM,KACvCoQ,EAAO,IACPC,EAAQ,SACmB,IAApBR,EAASS,SACnBF,EAAOP,EAASS,OAAOhV,SAEO,IAApBuU,EAASU,SACnBF,EAAQR,EAASU,OAAOjV,IAEzBkH,EAAOlH,IACN8L,KAAM+I,EAAU,GAChBxJ,SAAUwJ,EAAU,GACpBvJ,OAAQuJ,EAAU,GAClBpJ,KAAMoJ,EAAU,GAChBlN,IAAKmN,EACLI,SAAUH,EACVI,WAAYpQ,EAAU,cAAgBiL,OAAO8D,EAAGvT,MAAQ,mBAAqBP,EAAI,WACjFoV,UAAWrQ,EAAU,cAAgBiL,OAAO8D,EAAGvT,MAAQ,mBAAqBP,EAAI,WAEjFyM,SAASC,eAAe,cAAcoD,WAAa,aAAe5I,EAAOlH,GAAGmV,WAAa,aAAenV,EAAI,UAAYkH,EAAOlH,GAAG8L,KAAO,gDAAkD9L,EAAI,MAEhM6C,EAAY,KAGdkR,EAAI7I,gBAIAmK,aACL,SAAAA,IAActP,EAAAD,KAAAuP,GACbvP,KAAKwP,QAAU,GACfxP,KAAK8J,SACJe,OAAS,EACTd,QAAW,GACXrI,UAAa,IACbgJ,MAAS,GACT+E,cAAgB,EAChBC,eAAiB,EACjBjK,KAAQ,KACRM,MAAS,IACT6E,SAAY,EACZ+E,aAAgB,GAEjB3P,KAAK4P,KAAO,IAAIrE,MAAMtM,EAAU,mCAChCe,KAAK4P,KAAKC,OAAS,GAKnB7P,KAAK8P,aAAe,IAAIC,MAAM,GAC9B,IAAK,IAAI7V,EAAI,EAAGA,EAAI8F,KAAK8P,aAAa9I,OAAQ9M,IAC7C8F,KAAK8P,aAAa5V,GAAK,IAAIqR,MAAMtM,EAAU,mCAC3Ce,KAAK8P,aAAa5V,GAAG2V,OAAS,GAE/B7P,KAAKgQ,mBAAqB,EAE1BhQ,KAAKiQ,SAAW,IAAI1E,MAAMtM,EAAU,mCACpCe,KAAKkQ,UAAY,EAEjBlQ,KAAKyD,MAAQ,IAAI8H,MACjBvL,KAAKyD,MAAM4H,OAEXrL,KAAKmQ,QAAU,KACfnQ,KAAKoQ,iBAAmB,KAExBpQ,KAAKmN,OAAS,MAEdnN,KAAKqQ,eAAiB,EACtBrQ,KAAKsQ,WAAa,EAClBtQ,KAAKuQ,UAAY,EAEjBvQ,KAAKwQ,YAAa,kDAQlB,OAAOxQ,KAAKwQ,iDAOCX,GACb,IAAK,IAAI3V,EAAI,EAAGA,EAAI8F,KAAK8P,aAAa9I,OAAQ9M,IAC7C8F,KAAK8P,aAAa5V,GAAG2V,OAASA,qCAQ/B,OAAU5Q,EAAV,cAA+Be,KAAKmN,OAApC,gCAOGrD,GACH9J,KAAK8J,QAAUA,EACfwB,EAAYxB,EAAQC,QAASD,EAAQK,WACrCmD,EAAiBxD,EAAQrE,MACzBzF,KAAKwP,QAAU,GACfxP,KAAKkQ,UAAY,EACjBlQ,KAAKuQ,UAAY,EACjBvQ,KAAKwQ,YAAa,EAClBC,aAAazQ,KAAKmQ,SAEK,KAAnBrG,EAAQG,QACXH,EAAQ6F,aAAe3P,KAAK2H,cAAc1I,EAAU,cAAgBiL,OAAOJ,EAAQrP,MAAQ,IAAMqP,EAAQG,QAAU,OAAOjK,KAAK0Q,aAE/H1Q,KAAK0Q,YAAY,uCAQPC,GACXjJ,GAASoC,QAAQ6F,aAAeiB,SAASD,GACzCjJ,GAASyI,QAAUU,WAAW,kBAAMnJ,GAASoJ,cA16BvB,mDAg7BD,IAAAC,EAAA/Q,KACrB,GAAGyH,GAAOvG,YAAc,EAAE,CACzB,IAAIkF,EAAY,GACU,GAAtBqB,GAAOvG,YACVkF,EAAY,mBACoB,GAAtBqB,GAAOvG,cACjBkF,EAAY,oBAEZ,IAAImF,MAAM9D,GAAOnG,UAAU8E,GAAjB,KAAqCiF,OAChDrL,KAAKqQ,eAAiB,EACtB1J,SAASC,eAAe,oBAAoBpF,IAAMiG,GAAOnG,UAAU8E,GAAjB,IAClDpG,KAAKoQ,iBAAmBS,WAAW,kBAAME,EAAKC,mBA37BzB,2CAq8BT9E,EAAU+E,EAAUC,GACjC,IAAIC,EAAU,IAAIjD,eAClBiD,EAAQhD,KAAK,MAAOjC,GAAU,GAC9BiF,EAAQ/C,aAAe,cACvB+C,EAAQxF,iBAAiB,OAAQ,WAGhC,IAAIyF,EAAUC,KAAKC,QAAQH,EAAQI,UACnCtI,QAAQuI,IAAIJ,EAAA,UAEZH,EAASG,EAAA,SAAqBF,KAE/BC,EAAQ/L,iDAMQ,IAAAqM,EAAAzR,KAEhBA,KAAKqQ,eAAiBrQ,KAAKqQ,eAz9BL,GA29BI,GAAtB5I,GAAOvG,YAENlB,KAAKqQ,gBAAkB5I,GAAOnG,UAAP,0BAE1BtB,KAAK0R,mBAEL1R,KAAKoQ,iBAAmBS,WAAW,kBAAMY,EAAKT,mBAj+B1B,IAm+BW,GAAtBvJ,GAAOvG,YAEblB,KAAKqQ,gBAAkB5I,GAAOnG,UAAP,0BAE1BtB,KAAK0R,mBAEL1R,KAAKoQ,iBAAmBS,WAAW,kBAAMY,EAAKT,mBAz+B1B,IA4+BrBhR,KAAK0R,8DAQNjK,GAAOvG,YAAc,EACrBlB,KAAKqQ,eAAiB,EACtB1J,SAASC,eAAe,oBAAoBpF,IAAM,uBAClDiP,aAAazQ,KAAKoQ,uDAQN,IAAAuB,EAAA3R,KAYZ,GAVyB,GAArBA,KAAK8J,QAAQjJ,KAChB8F,SAASC,eAAe,eAAeyB,MAAMuJ,UAAY,aAEzDjL,SAASC,eAAe,eAAeyB,MAAMuJ,UAAY,YAGtD5R,KAAKwQ,aACRxQ,KAAKmQ,QAAUU,WAAW,kBAAMc,EAAKb,cAxgChB,KA2gClB9Q,KAAK8J,QAAQe,MAAO,CAEvBlE,SAASC,eAAe,qBAAqByB,MAAMG,gBAAkB,cAErE7B,SAASC,eAAe,eAAeyB,MAAMU,QAAU,OACvDpC,SAASC,eAAe,eAAeyB,MAAMU,QAAU,OACvDpC,SAASC,eAAe,cAAcyB,MAAMwJ,QAAU,IACtDlL,SAASC,eAAe,cAAcyB,MAAMyJ,OAAS,KACrD,IAMIC,GALHC,EAAK,SACLC,EAAK,YACLC,EAAK,YAGalS,KAAK8J,QAAQpI,gBACX,IAAVqQ,GACVpL,SAASC,eAAe,gBAAgBpF,IAAMiG,GAAOnG,UAAUyQ,GAAjB,IAC7C,IAAIxG,MAAStM,EAAb,eAAmCe,KAAK8J,QAAQrP,KAAhD,IAAwDsX,EAAxD,QAAsE1G,OACvErL,KAAKsQ,WAAa,KAElBtQ,KAAKsQ,WAAa,EAGnBtQ,KAAK8J,QAAQe,OAAQ,EACrB7K,KAAK8J,QAAQ2F,cAAe,EAG7B,GAAGzP,KAAKuQ,WAAavQ,KAAKsQ,YAActQ,KAAK8J,QAAQ2F,aAE1B,GAAtBzP,KAAK8J,QAAQhE,OAEhB9F,KAAKiQ,SAAS7E,QACdpL,KAAKkQ,UAAY,EACjBlQ,KAAKiQ,SAASzO,IAAMvC,EAAU,8BAC9Be,KAAKiQ,SAAS5E,OACdmC,EAAE,sBAAsB2E,OAAQ,SAASC,UAAY,QACrB,GAAtBpS,KAAK8J,QAAQhE,QAEvBa,SAASC,eAAe,qBAAqByB,MAAMG,gBAAkB,QACrExI,KAAKiQ,SAAS7E,QACdpL,KAAKkQ,UAAY,EACjBlQ,KAAKiQ,SAASzO,IAAMvC,EAAU,qCAC9Be,KAAKiQ,SAAS5E,OACdmC,EAAE,sBAAsB2E,OAAO,YAI7BnS,KAAK8J,QAAQ6F,aAAe,IAC9BhJ,SAASC,eAAe,gBAAgBpF,IAAM,uBAC9C8L,EAAiBtN,KAAK8J,QAAQrE,MAC9BkB,SAASC,eAAe,eAAepF,IAAMvC,EAAU,cAAgBiL,OAAOlK,KAAK8J,QAAQrP,MAAQ,IAAMuF,KAAK8J,QAAQG,QAAU,QAEjIjK,KAAK8J,QAAQ2F,cAAe,EAC5BzP,KAAK8J,QAAQ4F,eAAgB,OACvB,GAAI1P,KAAKuQ,WAAavQ,KAAKsQ,WAAatQ,KAAK8J,QAAQ6F,eAAiB3P,KAAK8J,QAAQ2F,aACzF,GAAIzP,KAAK8J,QAAQ4F,cAAe,CAC5B1P,KAAK8J,QAAQjE,SAAW,IAE1Bc,SAASC,eAAe,cAAcyB,MAAMgK,gBAAkB,QAAS5K,GAAOpG,UAAUrB,KAAK8J,QAAQjE,SAAW,GAAGmG,KAAM,KAEhG,OAArBhM,KAAK8J,QAAQrE,MAEhBkB,SAASC,eAAe,cAAcyB,MAAMiK,MAAQ,QACpD3L,SAASC,eAAe,cAAcyB,MAAMkK,KAAO,UACnD/E,EAAG,eAAgBC,SAClBqE,OAAQ,MACRD,QAAS,GACP,OAEHlL,SAASC,eAAe,cAAcyB,MAAMiK,MAAQ,UACpD3L,SAASC,eAAe,cAAcyB,MAAMkK,KAAO,QACnD/E,EAAG,eAAgBC,SAClBqE,OAAQ,MACRD,QAAS,GACP,OAILrE,EAAE,gBAAgBgF,OAAQ,QAC1BhF,EAAE,gBAAgBgF,OAAO,QAAQJ,UAAY,SACb,GAA7BpS,KAAK8J,QAAQ6F,eACfhJ,SAASC,eAAe,gBAAgBpF,IAAM,uBAC9C8L,EAAiBtN,KAAK8J,QAAQrE,OAE/BkB,SAASC,eAAe,eAAepF,IAAMvC,EAAU,cAAgBiL,OAAOlK,KAAK8J,QAAQrP,MAAQ,IAAMuF,KAAK8J,QAAQvE,SAAW,OACjIoB,SAASC,eAAe,eAAeyB,MAAMoK,SAAkE,GAAtD9L,SAASC,eAAe,eAAe8L,aAAsB,KACtH/L,SAASC,eAAe,eAAeyB,MAAMoK,SAAkE,IAAtD9L,SAASC,eAAe,eAAe8L,aAAuB,KACvH/L,SAASC,eAAe,eAAeoD,UAAY,MAAQO,GAAWvK,KAAK8J,QAAQK,WAAa,OAEhG,IASIwI,EAAa,YARhBC,EAAK,UACLZ,EAAK,UACLC,EAAK,UACLC,EAAK,UACLW,EAAK,UACLC,EAAK,UACLC,EAAK,WAE+B/S,KAAK8J,QAAQ/D,QAAU,WAC5DY,SAASC,eAAe,qBAAqByB,MAAQsK,EACrD3S,KAAK8J,QAAQ4F,eAAgB,EAEzB1P,KAAKwP,SAAWxP,KAAK8J,QAAQC,UAChCpD,SAASC,eAAe,eAAepF,IAAMvC,EAAU,cAAgBiL,OAAOlK,KAAK8J,QAAQrP,MAAQ,IAAMuF,KAAK8J,QAAQtE,OAAS,OAC/HxF,KAAKwQ,YAAa,EAClBC,aAAazQ,KAAKmQ,eAGfnQ,KAAKwP,SAAWxP,KAAK8J,QAAQC,UACwB,KAApD/J,KAAK8J,QAAQC,QAAQiJ,OAAOhT,KAAKwP,QAAQxI,UAC5ChH,KAAK8P,aAAa9P,KAAKgQ,oBAAoB3E,OAC3CrL,KAAKgQ,qBACLhQ,KAAKgQ,oBAAsBhQ,KAAK8P,aAAa9I,QAE9ChH,KAAKwP,QAAUxP,KAAK8J,QAAQC,QAAQkJ,UAAU,EAAGjT,KAAKwP,QAAQxI,OAAS,GACvEL,SAASC,eAAe,qBAAqBoD,UAAYhK,KAAKwP,QAC1DxP,KAAKwP,SAAWxP,KAAK8J,QAAQC,UAChC/J,KAAKuQ,UAAY,EACjBvQ,KAAKwQ,YAAa,EAClB7J,SAASC,eAAe,eAAepF,IAAMvC,EAAU,cAAgBiL,OAAOlK,KAAK8J,QAAQrP,MAAQ,IAAMuF,KAAK8J,QAAQtE,OAAS,OAC/HiL,aAAazQ,KAAKmQ,YAMjBnQ,KAAKkQ,WAAalQ,KAAK8J,QAAQc,SAAW5K,KAAKsQ,YAActQ,KAAKuQ,YACtEvQ,KAAKiQ,SAAS7E,QACdpL,KAAKkQ,UAAY,EACS,KAAtBlQ,KAAK8J,QAAQY,OAAsC,KAAtB1K,KAAK8J,QAAQY,QAC7C1K,KAAKiQ,SAASzO,IAAMvC,EAAU,kBAAoBiL,OAAOlK,KAAK8J,QAAQY,OAAS,OAC/E1K,KAAKiQ,SAAS5E,SAGhBrL,KAAKuQ,UAAYvQ,KAAKuQ,UAjpCA,YAqpClB7B,iFACQnF,GACZ,IAAI2J,GACHC,QAAS,6BACTjC,MAAO,oCACPkC,QAAS,YAENjY,KAEAgY,EAAU,KAmBd,OApBY5J,EAAK3K,MAAM,cAEjBC,QAAQ,SAASwU,GACtB,IAAIH,EAAME,QAAQ/T,KAAKgU,IAEG,GAAfA,EAAKrM,OAET,GAAIkM,EAAMhC,MAAM7R,KAAKgU,GAAO,CAClC,IAAIC,EAAQD,EAAKC,MAAMJ,EAAMhC,OACzBiC,EACHhY,EAAMgY,GAASG,EAAM,IAAMA,EAAM,GAEjCnY,EAAMmY,EAAM,IAAMA,EAAM,QAEnB,GAAIJ,EAAMC,QAAQ9T,KAAKgU,GAAO,CACpC,IAAIC,EAAQD,EAAKC,MAAMJ,EAAMC,SAC7BhY,EAAMmY,EAAM,OACZH,EAAUG,EAAM,MAGXnY,WAQF,SAASe,EAAWqX,GACL,IAAjBA,EAAMC,UACT/L,GAAOgM,QAAQ9M,SAASC,eAAe,sBAAsBzL,OAC7DwL,SAASC,eAAe,sBAAsBzL,MAAQ,IASjD,SAASgB,EAAQoX,GACvB,GAAqB,IAAjBA,EAAMC,QAAe,CACxB,IAAIE,EAASjM,GAAOuG,KAChB2F,EAAQlM,GAAOmM,UACfC,EAAQpM,GAAOqM,aACfC,EAAWtM,GAAO5G,KAAO,EAAE,EAC3BmT,EAAUrN,SAASC,eAAe,aAAazL,MAC/CuK,EAAW,IACXE,EAAY,IACZe,SAASC,eAAe,WAAWqN,UACtCvO,EAAWiO,EAAM9R,IACjB+D,EAAY+N,EAAMvE,UAEnB3H,GAAOyM,OAAOP,EAAMpO,SAAUmO,EAAOjZ,KAAMkZ,EAAMnO,OAAQmB,SAASC,eAAe,mBAAmBzL,MAAOuY,EAAOjO,KAAMC,EAAUiO,EAAMhO,KAAMC,EAAWlG,EAAemU,EAAOE,EAAQvU,EAAgBwU,IA0BlM,SAAS5X,EAAgBmX,GAC/B,IAAIY,EAAYxN,SAASC,eAAe,oBAAoBzL,MAC5DsM,GAAO2M,gBAAgBD,GAQjB,SAAS9X,EAAWgY,GAC1B,IAAIF,EAAaE,EAAGhL,YACpB5B,GAAO2M,gBAAgBD,GAOjB,SAAS7X,IACfoL,GAASjE,MAAMoM,OAASlJ,SAASC,eAAe,kBAAkBzL,MAAQ,IAOpE,SAASoB,IACfmL,GAASuI,SAASJ,OAASlJ,SAASC,eAAe,kBAAkBzL,MAAQ,IAOvE,SAASqB,IACfkL,GAAS4M,cAAc3N,SAASC,eAAe,kBAAkBzL,MAAQ,KAQnE,SAASsB,EAAgB8W,GAC/B9L,GAAO8M,gBACP5N,SAASC,eAAe,qBAAqByB,MAAMU,QAAU,QAC7DpC,SAASC,eAAe,cAAcoD,UAAY,GAQ5C,SAAStN,EAAS8X,GAGxB,OAFAA,EAAM7T,QAAU,GAChB6T,EAAMhT,IAAM,wBACL,EAQD,SAAS7E,EAAU6X,GAGzB,OAFAA,EAAM7T,QAAU,GAChB6T,EAAMhT,IAAM,yBACL,EAUR,SAAS4F,EAAUqN,EAAIxD,EAASC,GAC/B,IAAIwD,EAAQ,IAAIxG,eAChBwG,EAAMC,mBAAqB,WACH,GAAnB3U,KAAK4U,YAAkC,KAAf5U,KAAKsO,OAChC2C,GAAS,EAAMC,EAAOuD,GAEtBxD,GAAS,EAAOC,EAAOuD,IAGzBC,EAAMvG,KAAK,MAAOsG,GAAK,GACvBC,EAAMtP,OASP,SAASkI,EAAiBuH,GACzB,IAAIC,EACAC,EAAWrN,GAASsN,WAGxB,OAFArO,SAASC,eAAe,aAAayB,MAAMU,QAAU,OACrDpC,SAASC,eAAe,gBAAgByB,MAAMU,QAAU,OAChD8L,GACP,IAAK,MACJlO,SAASC,eAAe,gBAAgBpF,IAAMuT,EAAW,mBACzDpO,SAASC,eAAe,gBAAgByB,MAAMU,QAAU,QACxD3B,EAAU2N,EAAW,kBAAmBE,EAA0BJ,GAClEC,EAAY,UACZ,MACD,IAAK,MACJnO,SAASC,eAAe,gBAAgBpF,IAAMuT,EAAW,sBACzDpO,SAASC,eAAe,gBAAgByB,MAAMU,QAAU,QACxD3B,EAAU2N,EAAW,kBAAmBE,EAA0BJ,GAClEC,EAAY,cACZ,MACD,IAAK,MACJnO,SAASC,eAAe,gBAAgBpF,IAAMuT,EAAW,kBACzDD,EAAY,UACZ,MACD,IAAK,MACJnO,SAASC,eAAe,gBAAgBpF,IAAMuT,EAAW,qBACzDD,EAAY,cACZ,MACD,IAAK,MACJnO,SAASC,eAAe,gBAAgBpF,IAAMuT,EAAW,mBACzDpO,SAASC,eAAe,gBAAgByB,MAAMU,QAAU,QACxDpC,SAASC,eAAe,gBAAgBpF,IAAMuT,EAAW,cACzDD,EAAY,cACZ,MACD,IAAK,MACJnO,SAASC,eAAe,gBAAgBpF,IAAMuT,EAAW,iBACzDD,EAAY,cAGe,GAAzBpN,GAASoC,QAAQa,OACpBhE,SAASC,eAAe,gBAAgByB,MAAMU,QAAU,OACxDpC,SAASC,eAAe,gBAAgBpF,IAAMvC,EAAU,kBAAoB6V,EAAY,mBAW1F,SAASG,EAAyB1N,EAAOsN,GACxC,IAAIE,EAAWrN,GAASsN,WAGtBrO,SAASC,eAAe,gBAAgBpF,IAF1B,OAAZqT,EACAtN,EAC4CwN,EAAW,kBAEXA,EAAW,mBAGvDxN,EAC4CwN,EAAW,sBAEXA,EAAW,qBAQrD,SAASnY,IACf6K,GAAO6B,WACP7B,GAAS,IAAI5H,EAAOd,MAEnB1D,EAAO,OACPsL,SAASC,eAAe,gBAAgByB,MAAMU,QAAU,QAQnD,SAASlM,IACf4K,GAAOuB,aASR,SAASsC,EAAY4J,GAAqC,IAA9Bza,EAA8B0a,UAAAnO,OAAA,QAAAoO,IAAAD,UAAA,GAAAA,UAAA,GAAvB,GAAIE,EAAmBF,UAAAnO,OAAA,QAAAoO,IAAAD,UAAA,GAAAA,UAAA,GAAZ,IAAIvV,KAC3C0V,EAAQ3O,SAAS2F,cAAc,KAC/BiJ,EAAY5O,SAAS2F,cAAc,QAOzC,GANAiJ,EAAUrP,GAAK,aACfqP,EAAU3I,YAAYjG,SAAS6O,eAAe/a,IAC9C6a,EAAM1I,YAAY2I,GAClBD,EAAM1I,YAAYjG,SAAS6O,eAAeN,IAGtCvV,EAAkB8V,eAAiBJ,EAAKI,aAAc,CACzD,IAAMC,EAAY/O,SAAS2F,cAAc,QACzCoJ,EAAUxP,GAAK,aACfwP,EAAUC,UAAYN,EAAKO,wBAAmBR,GAC7CS,KAAM,UACNC,OAAQ,YAETR,EAAM1I,YAAY8I,GAGnB,IAAMK,EAAYpP,SAASC,eAAe,cAC1CmP,EAAUnJ,YAAY0I,GAElBS,EAAU7K,UAAY6K,EAAU5K,aAAe,MAClD4K,EAAU7K,UAAY6K,EAAU5K,cAGjCxL,EAAoB,IAAIC,KAOlB,SAAS9C,EAASkZ,GACpBA,EAAa,IAChBvO,GAAOwO,cAAcD,IAGrBrP,SAASC,eAAe,qBAAqByB,MAAMU,QAAU,OAC7DpC,SAASC,eAAe,mBAAmByB,MAAMU,QAAU,OAC3DpC,SAASC,eAAe,cAAcyB,MAAMU,QAAU,QASjD,SAAShM,EAAYmZ,IACE,GAAzBzO,GAAO1F,gBACV4E,SAASC,eAAe,OAASa,GAAO1F,eAAeP,IAAMiG,GAAOmM,UAAUvE,YAE/E5H,GAAO1F,cAAgBmU,EACvBvP,SAASC,eAAe,OAASsP,GAAK1U,IAAMiG,GAAOmM,UAAUtE,UAQvD,SAAStS,EAAa6I,GAC5B,GAAI4B,GAAOzF,kBAAoB6D,EAAU,CAErC4B,GAAOzF,iBAAmB,IAC5B2E,SAASC,eAAe,OAASa,GAAOzF,kBAAkB8I,UAAY,iBAEvEnE,SAASC,eAAe,OAASf,GAAUiF,UAAY,qBACvDrD,GAAOzF,iBAAmB6D,EAG1Bc,SAASC,eAAe,YAAYzL,MAAQsM,GAAOpG,UAAUwE,EAAW,GAAGpL,KAC3EkM,SAASC,eAAe,YAAYzL,MAAQsM,GAAOpG,UAAUwE,EAAW,GAAGG,KAG3E,IAAImQ,EAAW9Y,EAAmB,aAAcoK,GAAOpG,UAAUwE,EAAW,GAAGqG,UAC/EvF,SAASC,eAAe,cAAcyG,cAAgB8I,EACvC,GAAXA,IACHxP,SAASC,eAAe,gBAAgBzL,MAAQsM,GAAOpG,UAAUwE,EAAW,GAAGqG,UAEhF5O,IAGAqJ,SAASC,eAAe,WAAWkE,UAAY,sCAC/CnE,SAASC,eAAe,YAAYkE,UAAY,6BAChDnE,SAASC,eAAe,cAAckE,UAAY,6BAClDnE,SAASC,eAAe,WAAWkE,UAAY,kCAE/C1N,IAQK,SAASH,IACf,IAAIyJ,EAAkBC,SAASC,eAAe,cAC9Ca,GAAO2O,OAAQzP,SAASC,eAAe,YAAYzL,MAClDwL,SAASC,eAAe,YAAYzL,MACF,GAAjCuL,EAAgB2G,cAChB1G,SAASC,eAAe,gBAAgBzL,MACxCuL,EAAgB8F,QAAQ9F,EAAgB2G,eAAed,MAEzDnP,IAOM,SAASF,IACf,IAAIwJ,EAAkBC,SAASC,eAAe,cAC1CV,EAAK0K,SAASnJ,GAAOzF,kBAAoB,EAC7CyF,GAAO4O,OAAQnQ,EACdS,SAASC,eAAe,YAAYzL,MACpCwL,SAASC,eAAe,YAAYzL,MACF,GAAjCuL,EAAgB2G,cAChB1G,SAASC,eAAe,gBAAgBzL,MACxCuL,EAAgB8F,QAAQ9F,EAAgB2G,eAAed,MAEzDnP,IAOM,SAASD,IACf,IAAI+I,EAAK0K,SAASnJ,GAAOzF,kBAAoB,EAC7CyF,GAAO6O,OAAOpQ,GACd9I,IAOM,SAASA,IAEZqK,GAAOzF,iBAAmB,IAC5B2E,SAASC,eAAe,OAASa,GAAOzF,kBAAkB8I,UAAY,iBAEvErD,GAAOzF,iBAAmB,EAG1B2E,SAASC,eAAe,cAAcyG,cAAgB,EACtD/P,IACAqJ,SAASC,eAAe,gBAAgBzL,MAAQ,GAChDwL,SAASC,eAAe,YAAYzL,MAAQ,GAC5CwL,SAASC,eAAe,YAAYzL,MAAQ,GAC5CwL,SAASC,eAAe,YAAYyB,MAAMgK,gBAAkB,wBAG5D1L,SAASC,eAAe,WAAWkE,UAAY,6BAC/CnE,SAASC,eAAe,YAAYkE,UAAY,sCAChDnE,SAASC,eAAe,cAAckE,UAAY,sCAClDnE,SAASC,eAAe,WAAWkE,UAAY,sCASzC,SAASzN,EAAmBkZ,EAAYpb,GAG7C,IADA,IAAIqb,EAAiB7P,SAASC,eAAe2P,GACpCrc,EAAI,EAAGA,EAAIsc,EAAexP,SAAU9M,EAC5C,GAAIsc,EAAehK,QAAQtS,GAAGiB,OAASA,EACtC,OAAOjB,EAGT,OAAO,EAOF,SAASoD,IACf,IAAIoJ,EAAkBC,SAASC,eAAe,cAC1C6P,EAAoB9P,SAASC,eAAe,gBAC5C8P,EAAmB/P,SAASC,eAAe,YAEV,GAAjCF,EAAgB2G,eACnBoJ,EAAkBpO,MAAMU,QAAU,UAClC2N,EAAiBrO,MAAMgK,gBAAkB,QAAUpT,EAAU,YAAcwX,EAAkBtb,MAAQ,OAErGsb,EAAkBpO,MAAMU,QAAU,OAClC2N,EAAiBrO,MAAMgK,gBAAkB,QAAUpT,EAAU,YAAcyH,EAAgBvL,MAAQ,MAQ9F,SAASoC,EAAqBkI,GACzB,OAARA,GACFkB,SAASC,eAAe,gBAAgByB,MAAMU,QAAU,eACxDpC,SAASC,eAAe,aAAayB,MAAMU,QAAU,SAErDpC,SAASC,eAAe,aAAayB,MAAMU,QAAU,eACrDpC,SAASC,eAAe,gBAAgByB,MAAMU,QAAU,QAGzD,IAAI,IAAI7O,EAAI,EAAGyc,EAAchQ,SAASC,eAAe,eAAe4F,QAAStS,EAAIyc,EAAY3P,OAAQ9M,IACnG,GAAGuL,GAAQkR,EAAYzc,GAAGiB,MAEzB,YADAwb,EAAYtJ,cAAgBnT,GAUzB,SAASsD,IACf,IAAI0O,EAAW,GAAIjF,EAAoBN,SAASC,eAAe,aAC5DgQ,EAAajQ,SAASC,eAAe,cAAczL,MAErD+Q,EADsC,GAAnCjF,EAAkBoG,cACV1G,SAASC,eAAe,eAAezL,MAEvC8L,EAAkB9L,MAE9BsM,GAAOgM,QAAQ,IAAMmD,EAAWvM,QAAQ,KAAK6B,IAOvC,SAASzO,IACf,IAAIkZ,EAAchQ,SAASC,eAAe,eACvCiQ,EAAelQ,SAASC,eAAe,gBAAgBzL,MAE1DsM,GAAOgM,QAAQ,IAAMoD,EAAaxM,QAAQ,KAAKsM,EAAYxb,QAC3DoC,EAAqBoZ,EAAYxb,OAO3B,SAASuC,IACf+J,GAAOgM,QAAQ,IAAM9M,SAASC,eAAe,sBAAsBzL,OAO7D,SAASwC,IACf6P,EAAG,mBAAoBsJ,OAAQ,QAOzB,SAASlZ,IACf6J,GAAOsP,OAAO,cAOR,SAASlZ,IACf4J,GAAOsP,OAAO,cAOR,SAASjZ,IACf2J,GAAOuP,OAAO,EAAEC,OAAOrG,SAASnJ,GAAO1G,GAAG,IAAM,IAO1C,SAAShD,IACf0J,GAAOuP,OAAO,EAAEC,OAAOrG,SAASnJ,GAAO1G,GAAG,IAAM,IAO1C,SAAS/C,IACfyJ,GAAOuP,OAAO,EAAEC,OAAOrG,SAASnJ,GAAO1G,GAAG,IAAM,IAO1C,SAAS9C,KACfwJ,GAAOuP,OAAO,EAAEC,OAAOrG,SAASnJ,GAAO1G,GAAG,IAAM,IAO1C,SAAS7C,KACf,IAAI+I,EAAoBN,SAASC,eAAe,aAC5CsQ,EAAsBvQ,SAASC,eAAe,eAC9CuQ,EAAqBxQ,SAASC,eAAe,cAEV,GAAnCK,EAAkBoG,eACrB6J,EAAoB7O,MAAMU,QAAU,UACpCoO,EAAmB3V,IAAMvC,EAAU,cAAgBiY,EAAoB/b,MAAQ,sBAE/E+b,EAAoB7O,MAAMU,QAAU,OACpCoO,EAAmB3V,IAAMvC,EAAU,cAAgBgI,EAAkB9L,MAAQ,qBAUxE,SAASgD,GAAagU,GACxBA,GAAU3S,GACbmH,SAASC,eAAe,iBAAmBuL,GAAQrH,UAAY,gBAC/DtL,EAAiB,IAEjBmH,SAASC,eAAe,iBAAmBuL,GAAQrH,UAAY,qBAC3DtL,IACHmH,SAASC,eAAe,iBAAmBpH,GAAgBsL,UAAY,iBAExEtL,EAAiB2S,GAQZ,SAAS/T,KACXqJ,GAAO5G,KACV8F,SAASC,eAAe,eAAekE,UAAY,gBAEnDnE,SAASC,eAAe,eAAekE,UAAY,qBAEpDrD,GAAO5G,MAAQ4G,GAAO5G,KAOhB,SAASxC,KACXoJ,GAAO3G,YACV6F,SAASC,eAAe,kBAAkBkE,UAAY,gBAEtDnE,SAASC,eAAe,kBAAkBkE,UAAY,qBAEvDrD,GAAO3G,aAAe2G,GAAO3G,YAQvB,SAASxC,GAAW8Y,GACtBA,GAAQ3X,IACXkH,SAASC,eAAe,QAAUwQ,GAAMtM,UAAY,mBACpDnE,SAASC,eAAe,WAAawQ,GAAMtM,UAAY,sBACvDnE,SAASC,eAAe,QAAUnH,GAAcqL,UAAY,YAC5DnE,SAASC,eAAe,WAAanH,GAAcqL,UAAY,eAC/DrL,EAAe2X,GAUV,SAAS7Y,GAAYwT,GACvBA,GAASrS,GACZiH,SAASC,eAAe,UAAYmL,GAAOjH,UAAY,gBACvDpL,EAAgB,IAEhBiH,SAASC,eAAe,UAAYmL,GAAOjH,UAAY,qBACnDpL,IACHiH,SAASC,eAAe,UAAYlH,GAAeoL,UAAY,iBAEhEpL,EAAgBqS,GAWlB,SAASxH,GAAW8M,GACnB,OAAOA,EACLhN,QAAQ,KAAM,SACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,UACdA,QAAQ,KAAM,UAOjB,SAAShF,GAAW+E,GACnB,OAAOA,EACLC,QAAQ,KAAM,WACdA,QAAQ,KAAM,SACdA,QAAQ,KAAM,aACdA,QAAQ,MAAO,YAOlB,SAASI,GAAaL,GACrB,OAAOA,EACLC,QAAQ,WAAY,KACpBA,QAAQ,SAAU,KAClBA,QAAQ,aAAc,KACtBA,QAAQ,YAAa,KAOxB,SAAS/E,GAAW8E,GACnB,IAAIkN,EAAmB3Q,SAASC,eAAe,mBAAmBzL,MAClE,GAAwB,WAApBmc,EAEH,OAAOlN,EAAQC,QAAQ,WAAY,SAASkN,GAC3C,MAAO,OAAS,MAAQA,EAAGC,aAAaC,SAAS,KAAKC,OAAO,KACxD,GAAwB,SAApBJ,EAA4B,CAItC,IAFA,IAAIK,EAAS,IAAIC,YAA2B,EAAfxN,EAAQpD,QACjCO,EAAS,IAAIsQ,YAAYF,GACpBzd,EAAE,EAAG4d,EAAO1N,EAAQpD,OAAQ9M,EAAI4d,EAAQ5d,IAChDqN,EAAOrN,GAAKkQ,EAAQoN,WAAWtd,GAEhC,OAAO+c,OAAO1P,GAEd,OAAO6C,EAQT,SAASI,GAAWJ,GACnB,IAAI2N,EAAmBpR,SAASC,eAAe,mBAAmBzL,MAClE,MAAwB,WAApB4c,EAEU3N,EAAQC,QAAQ,oBAAqB,SAAUiJ,EAAO0E,GAClE,OAAOf,OAAOgB,aAAarH,SAASoH,EAAO,OACd,SAApBD,EAEHd,OAAOgB,aAAaC,MAAM,KAAM,IAAIL,YAAYzN,EAAQxL,MAAM,OAE9DwL,EA9sBT+N,OAAOjc,WAAaA,EAsBpBic,OAAOhc,QAAUA,EA2BjBgc,OAAO/b,gBAAkBA,EAUzB+b,OAAO9b,WAAaA,EAQpB8b,OAAO7b,kBAAoBA,EAQ3B6b,OAAO5b,gBAAkBA,EAQzB4b,OAAO3b,iBAAmBA,EAW1B2b,OAAO1b,gBAAkBA,EAWzB0b,OAAOzb,SAAWA,EAWlByb,OAAOxb,UAAYA,EAyGnBwb,OAAOvb,gBAAkBA,EAQzBub,OAAOtb,YAAcA,EAkDrBsb,OAAOrb,SAAWA,EAalBqb,OAAOpb,YAAcA,EAoCrBob,OAAOnb,aAAeA,EAetBmb,OAAOlb,YAAcA,EAiBrBkb,OAAOjb,aAAeA,EAUtBib,OAAOhb,YAAcA,EA0BrBgb,OAAO/a,eAAiBA,EAiBxB+a,OAAO9a,mBAAqBA,EAkB5B8a,OAAO7a,mBAAqBA,EAqB5B6a,OAAO5a,qBAAuBA,EAe9B4a,OAAO3a,oBAAsBA,EAY7B2a,OAAO1a,cAAgBA,EAQvB0a,OAAOza,mBAAqBA,EAQ5Bya,OAAOxa,QAAUA,EAQjBwa,OAAOva,OAASA,EAQhBua,OAAOta,OAASA,EAQhBsa,OAAOra,OAASA,EAQhBqa,OAAOpa,OAASA,EAQhBoa,OAAOna,OAASA,EAQhBma,OAAOla,OAASA,GAkBhBka,OAAOja,wBAA0BA,GAmBjCia,OAAOha,aAAeA,GAatBga,OAAO/Z,WAAaA,GAapB+Z,OAAO9Z,cAAgBA,GAevB8Z,OAAO7Z,WAAaA,GAmBpB6Z,OAAO5Z,YAAcA,QAuGiB,IAA3B0Y,OAAOnb,UAAUsc,OAExBnB,OAAOnb,UAAUsc,KAAO,WAEpB,OAAOnB,OAAOjX,MAAMqK,QAAQ,aAAc,MAKlD4M,OAAOnb,UAAUyK,SAAW,WAC3B,IAAcrM,EAAVme,EAAO,EACX,GAAoB,IAAhBrY,KAAKgH,OAAc,OAAOqR,EAC9B,IAAKne,EAAI,EAAGA,EAAI8F,KAAKgH,OAAQ9M,IAE3Bme,GAAUA,GAAQ,GAAKA,EADfrY,KAAKwX,WAAWtd,GAExBme,GAAQ,EAEV,OAAOA,GAQR,IAAI5Q,GAAS,IAAI5H,EAAOd,GACpB2I,GAAW,IAAI6H,EAEnB/B,EAAE7G,UAAU2R,MAAM,WACjB7Q,GAAO8Q,sBACP9Q,GAAO+Q,kBAKRhL,EAAG,WACFA,EAAG,mBAAoBsJ,QACtB2B,UAAU,EACVC,WAAW,EACXC,MACCxG,OAAQ,OACRC,UAAU,OACV3Q,SAAU,KAEXmX,MACCzG,OAAQ,OACRC,UAAU,OACV3Q,SAAU,KAEXqQ,OAAQ,OACRpE,MAAO,IACPmL,OAAO,EACPC,SACCC,KAAQ,WACPtR,GAAOuR,OAAO,IACdxL,EAAGxN,MAAO8W,OAAQ,UAEnBmC,OAAQ,WACPzL,EAAGxN,MAAO8W,OAAQ","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\t\t\r\n\t\tthis.hp = [0,0];\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\t\t\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\":{\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\":{\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\":{\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\":{\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\":{\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\t\t\t\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {int} side the position\r\n\t * @param {int} hp the health point\r\n\t */\r\n\tsendHP(side,hp) {\r\n\t\tthis.serv.send(`HP#${side}#${hp}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif(this.chars[this.charID].side == \"jud\"){\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// Calculate gif duration of shouts\r\n\t\tlet shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"];\r\n\t\t\tFileExist(shout_src, this.callbackLoadImageResources, shouts[i]);\t\t\r\n\t\t}\r\n\t\t\r\n\t\t// Calculate gif duration of testimony\r\n\t\tlet testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tlet testimony_src = AO_HOST + \"themes/default/\"+ testimony[i] +\".gif\";\r\n\t\t\t// Check iamge existed\r\n\t\t\tFileExist(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tFileExist(AO_HOST + this.resources[testimony[i]][\"sfx\"], this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src,client.callbackGetResourceLength, resource);\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length; \r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\t\r\n\t}\t\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tlet percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t}\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\r\n\t$( \"#callmod_dialog\" ).dialog( \"open\" );\t\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Add defense health point.\r\n */\r\nexport function addHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Reduce defense health point.\r\n */\r\nexport function redHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Add prosecution health point.\r\n */\r\nexport function addHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Reduce prosecution health point.\r\n */\r\nexport function redHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n\t\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$( function() {\r\n\t$( \"#callmod_dialog\" ).dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\t\"Sure\": function() {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t},\r\n\t\t\tCancel: function() {\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""} \ No newline at end of file -- cgit From bdf8f9f3391ee80ec7a3d99d62f845ac7dfa0f7e Mon Sep 17 00:00:00 2001 From: Qube Date: Sat, 21 Jul 2018 14:39:06 +0700 Subject: Add option to edit server chat name (a.k.a Fake name) and adjust settings menu. --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index 2c5261c..3cac64f 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","addHPD","redHPD","addHPP","redHPP","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","hp","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","shouts","FileExist","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","percent_hp","$","animate","width","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","transform","opacity","height","shout","1","2","3","effect","direction","backgroundImage","right","left","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","dialog","sendRT","sendHP","String","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources","autoOpen","resizable","show","hide","modal","buttons","Sure","sendZZ","Cancel"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\t\t\r\n\t\tthis.hp = [0,0];\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\t\t\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\":{\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\":{\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\":{\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\":{\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\":{\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\t\t\t\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {int} side the position\r\n\t * @param {int} hp the health point\r\n\t */\r\n\tsendHP(side,hp) {\r\n\t\tthis.serv.send(`HP#${side}#${hp}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif(this.chars[this.charID].side == \"jud\"){\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// Calculate gif duration of shouts\r\n\t\tlet shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"];\r\n\t\t\tFileExist(shout_src, this.callbackLoadImageResources, shouts[i]);\t\t\r\n\t\t}\r\n\t\t\r\n\t\t// Calculate gif duration of testimony\r\n\t\tlet testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tlet testimony_src = AO_HOST + \"themes/default/\"+ testimony[i] +\".gif\";\r\n\t\t\t// Check iamge existed\r\n\t\t\tFileExist(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tFileExist(AO_HOST + this.resources[testimony[i]][\"sfx\"], this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src,client.callbackGetResourceLength, resource);\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length; \r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\t\r\n\t}\t\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tlet percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t}\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\r\n\t$( \"#callmod_dialog\" ).dialog( \"open\" );\t\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Add defense health point.\r\n */\r\nexport function addHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Reduce defense health point.\r\n */\r\nexport function redHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Add prosecution health point.\r\n */\r\nexport function addHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Reduce prosecution health point.\r\n */\r\nexport function redHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n\t\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$( function() {\r\n\t$( \"#callmod_dialog\" ).dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\t\"Sure\": function() {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t},\r\n\t\t\tCancel: function() {\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","addHPD","redHPD","addHPP","redHPP","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","hp","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","document","getElementById","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","add","Option","evidence_arr","length","background_select","background_arr","shouts","FileExist","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","percent_hp","$","animate","width","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","transform","opacity","height","shout","1","2","3","effect","direction","backgroundImage","right","left","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","dialog","sendRT","sendHP","String","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources","autoOpen","resizable","show","hide","modal","buttons","Sure","sendZZ","Cancel"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\t\t\r\n\t\tthis.hp = [0,0];\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\t\t\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\":{\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\":{\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\":{\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\":{\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\":{\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\t\t\t\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#${escapeChat(encodeChat(document.getElementById(\"OOC_name\").value))}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {int} side the position\r\n\t * @param {int} hp the health point\r\n\t */\r\n\tsendHP(side,hp) {\r\n\t\tthis.serv.send(`HP#${side}#${hp}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif(this.chars[this.charID].side == \"jud\"){\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Set to playerID to server chat name\r\n\t\tdocument.getElementById(\"OOC_name\").value = \"web\" + this.playerID;\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// Calculate gif duration of shouts\r\n\t\tlet shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"];\r\n\t\t\tFileExist(shout_src, this.callbackLoadImageResources, shouts[i]);\t\t\r\n\t\t}\r\n\t\t\r\n\t\t// Calculate gif duration of testimony\r\n\t\tlet testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tlet testimony_src = AO_HOST + \"themes/default/\"+ testimony[i] +\".gif\";\r\n\t\t\t// Check iamge existed\r\n\t\t\tFileExist(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tFileExist(AO_HOST + this.resources[testimony[i]][\"sfx\"], this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src,client.callbackGetResourceLength, resource);\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length; \r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\t\r\n\t}\t\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tlet percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t}\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\r\n\t$( \"#callmod_dialog\" ).dialog( \"open\" );\t\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Add defense health point.\r\n */\r\nexport function addHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Reduce defense health point.\r\n */\r\nexport function redHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Add prosecution health point.\r\n */\r\nexport function addHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Reduce prosecution health point.\r\n */\r\nexport function redHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n\t\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$( function() {\r\n\t$( \"#callmod_dialog\" ).dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\t\"Sure\": function() {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t},\r\n\t\t\tCancel: function() {\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""} \ No newline at end of file -- cgit From 4cf6fb8e8609dbf84149d0410393f9e3436fea91 Mon Sep 17 00:00:00 2001 From: Qube Date: Sat, 21 Jul 2018 21:07:06 +0700 Subject: Convert all character animation name to lowercase if user use asset from default asset site. --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index 3cac64f..feb0e2c 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","addHPD","redHPD","addHPP","redHPP","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","hp","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","document","getElementById","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","add","Option","evidence_arr","length","background_select","background_arr","shouts","FileExist","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","percent_hp","$","animate","width","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","transform","opacity","height","shout","1","2","3","effect","direction","backgroundImage","right","left","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","dialog","sendRT","sendHP","String","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources","autoOpen","resizable","show","hide","modal","buttons","Sure","sendZZ","Cancel"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\t\t\r\n\t\tthis.hp = [0,0];\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\t\t\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\":{\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\":{\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\":{\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\":{\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\":{\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\t\t\t\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#${escapeChat(encodeChat(document.getElementById(\"OOC_name\").value))}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {int} side the position\r\n\t * @param {int} hp the health point\r\n\t */\r\n\tsendHP(side,hp) {\r\n\t\tthis.serv.send(`HP#${side}#${hp}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif(this.chars[this.charID].side == \"jud\"){\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Set to playerID to server chat name\r\n\t\tdocument.getElementById(\"OOC_name\").value = \"web\" + this.playerID;\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// Calculate gif duration of shouts\r\n\t\tlet shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"];\r\n\t\t\tFileExist(shout_src, this.callbackLoadImageResources, shouts[i]);\t\t\r\n\t\t}\r\n\t\t\r\n\t\t// Calculate gif duration of testimony\r\n\t\tlet testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tlet testimony_src = AO_HOST + \"themes/default/\"+ testimony[i] +\".gif\";\r\n\t\t\t// Check iamge existed\r\n\t\t\tFileExist(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tFileExist(AO_HOST + this.resources[testimony[i]][\"sfx\"], this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src,client.callbackGetResourceLength, resource);\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length; \r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\t\r\n\t}\t\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tlet percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t}\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\r\n\t$( \"#callmod_dialog\" ).dialog( \"open\" );\t\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Add defense health point.\r\n */\r\nexport function addHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Reduce defense health point.\r\n */\r\nexport function redHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Add prosecution health point.\r\n */\r\nexport function addHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Reduce prosecution health point.\r\n */\r\nexport function redHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n\t\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$( function() {\r\n\t$( \"#callmod_dialog\" ).dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\t\"Sure\": function() {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t},\r\n\t\t\tCancel: function() {\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","addHPD","redHPD","addHPP","redHPP","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","hp","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","document","getElementById","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","add","Option","evidence_arr","length","background_select","background_arr","shouts","FileExist","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","percent_hp","$","animate","width","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","isOfficialAssets","withCredentials","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","toLowerCase","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","transform","opacity","height","shout","1","2","3","effect","direction","backgroundImage","right","left","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","dialog","sendRT","sendHP","String","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources","autoOpen","resizable","show","hide","modal","buttons","Sure","sendZZ","Cancel"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\t\t\r\n\t\tthis.hp = [0,0];\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\t\t\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\":{\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\":{\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\":{\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\":{\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\":{\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\t\t\t\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#${escapeChat(encodeChat(document.getElementById(\"OOC_name\").value))}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {int} side the position\r\n\t * @param {int} hp the health point\r\n\t */\r\n\tsendHP(side,hp) {\r\n\t\tthis.serv.send(`HP#${side}#${hp}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif(this.chars[this.charID].side == \"jud\"){\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Set to playerID to server chat name\r\n\t\tdocument.getElementById(\"OOC_name\").value = \"web\" + this.playerID;\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// Calculate gif duration of shouts\r\n\t\tlet shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"];\r\n\t\t\tFileExist(shout_src, this.callbackLoadImageResources, shouts[i]);\t\t\r\n\t\t}\r\n\t\t\r\n\t\t// Calculate gif duration of testimony\r\n\t\tlet testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tlet testimony_src = AO_HOST + \"themes/default/\"+ testimony[i] +\".gif\";\r\n\t\t\t// Check iamge existed\r\n\t\t\tFileExist(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tFileExist(AO_HOST + this.resources[testimony[i]][\"sfx\"], this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src,client.callbackGetResourceLength, resource);\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length; \r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\t\r\n\t}\t\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tlet percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t}\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\tlet isOfficialAssets = (AO_HOST == \"http://assets.aceattorneyonline.com/base/\");\r\n\t\txhr.withCredentials = false;\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: (isOfficialAssets)? emoteinfo[0].toLowerCase() : emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: (isOfficialAssets)? emoteinfo[1].toLowerCase() : emoteinfo[1],\r\n\t\t\t\t\t\tsilent: (isOfficialAssets)? emoteinfo[2].toLowerCase() : emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: (isOfficialAssets)? esfx.toLowerCase() : esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + ((isOfficialAssets)? escape(me.name).toLowerCase() : escape(me.name)) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + ((isOfficialAssets)? escape(me.name).toLowerCase() : escape(me.name)) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\r\n\t$( \"#callmod_dialog\" ).dialog( \"open\" );\t\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Add defense health point.\r\n */\r\nexport function addHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Reduce defense health point.\r\n */\r\nexport function redHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Add prosecution health point.\r\n */\r\nexport function addHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Reduce prosecution health point.\r\n */\r\nexport function redHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n\t\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$( function() {\r\n\t$( \"#callmod_dialog\" ).dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\t\"Sure\": function() {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t},\r\n\t\t\tCancel: function() {\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""} \ No newline at end of file -- cgit From 8818ba99f804b1b1845a4757d67cc32d552956e1 Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Sat, 8 Sep 2018 19:02:32 -0500 Subject: Continue major cleanup and style fixes --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index feb0e2c..6c826b9 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","addHPD","redHPD","addHPP","redHPP","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","hp","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","document","getElementById","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","add","Option","evidence_arr","length","background_select","background_arr","shouts","FileExist","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","percent_hp","$","animate","width","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","isOfficialAssets","withCredentials","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","toLowerCase","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","transform","opacity","height","shout","1","2","3","effect","direction","backgroundImage","right","left","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","dialog","sendRT","sendHP","String","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources","autoOpen","resizable","show","hide","modal","buttons","Sure","sendZZ","Cancel"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\t\t\r\n\t\tthis.hp = [0,0];\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\t\t\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\":{\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\":{\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\":{\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\":{\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\":{\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\t\t\t\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#${escapeChat(encodeChat(document.getElementById(\"OOC_name\").value))}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {int} side the position\r\n\t * @param {int} hp the health point\r\n\t */\r\n\tsendHP(side,hp) {\r\n\t\tthis.serv.send(`HP#${side}#${hp}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif(this.chars[this.charID].side == \"jud\"){\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Set to playerID to server chat name\r\n\t\tdocument.getElementById(\"OOC_name\").value = \"web\" + this.playerID;\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// Calculate gif duration of shouts\r\n\t\tlet shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"];\r\n\t\t\tFileExist(shout_src, this.callbackLoadImageResources, shouts[i]);\t\t\r\n\t\t}\r\n\t\t\r\n\t\t// Calculate gif duration of testimony\r\n\t\tlet testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tlet testimony_src = AO_HOST + \"themes/default/\"+ testimony[i] +\".gif\";\r\n\t\t\t// Check iamge existed\r\n\t\t\tFileExist(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tFileExist(AO_HOST + this.resources[testimony[i]][\"sfx\"], this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src,client.callbackGetResourceLength, resource);\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length; \r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\t\r\n\t}\t\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '\"'';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tlet percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t}\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\tlet isOfficialAssets = (AO_HOST == \"http://assets.aceattorneyonline.com/base/\");\r\n\t\txhr.withCredentials = false;\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: (isOfficialAssets)? emoteinfo[0].toLowerCase() : emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: (isOfficialAssets)? emoteinfo[1].toLowerCase() : emoteinfo[1],\r\n\t\t\t\t\t\tsilent: (isOfficialAssets)? emoteinfo[2].toLowerCase() : emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: (isOfficialAssets)? esfx.toLowerCase() : esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + ((isOfficialAssets)? escape(me.name).toLowerCase() : escape(me.name)) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + ((isOfficialAssets)? escape(me.name).toLowerCase() : escape(me.name)) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"\" + emotes[i].desc + \"\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\r\n\t$( \"#callmod_dialog\" ).dialog( \"open\" );\t\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Add defense health point.\r\n */\r\nexport function addHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Reduce defense health point.\r\n */\r\nexport function redHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Add prosecution health point.\r\n */\r\nexport function addHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Reduce prosecution health point.\r\n */\r\nexport function redHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n\t\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$( function() {\r\n\t$( \"#callmod_dialog\" ).dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\t\"Sure\": function() {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t},\r\n\t\t\tCancel: function() {\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/evidence.js","webpack:///./webAO/backgrounds.js","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","r","value","n","__esModule","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickChar","pickEmotion","pickEvidence","addEvidence","editEvidence","deleteEvidence","cancelEvidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callMod","initWT","initCE","addHPD","redHPD","addHPP","redHPP","updateBackgroundPreview","toggleEffect","toggleFlip","togglePresent","toggleMenu","toggleShout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","mode","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","hp","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","document","getElementById","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","add","Option","evidence_arr","background_select","background_arr","background","shouts","length","fileExists","toLowerCase","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","escapeHtml","decodeChat","unescapeChat","replace","chatmsg","content","innerHTML","preanim","escape","nameplate","prepChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","lastChild","startsWith","audio_title","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","percent_hp","$","animate","width","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","withCredentials","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","testimonyOverlay","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","nameBox","chatBox","charSprite","eviBox","shoutSprite","chatBoxInner","transform","opacity","height","shout","1","2","3","effect","direction","backgroundImage","right","left","fontSize","offsetHeight","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","dialog","sendRT","sendHP","String","background_filename","background_preview","menu","unsafe","estring","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources","autoOpen","resizable","show","hide","modal","buttons","Sure","sendZZ","Cancel"],"mappings":"aACA,IAAAA,KAGA,SAAAC,EAAAC,GAGA,GAAAF,EAAAE,GACA,OAAAF,EAAAE,GAAAC,QAGA,IAAAC,EAAAJ,EAAAE,IACAG,EAAAH,EACAI,GAAA,EACAH,YAUA,OANAI,EAAAL,GAAAM,KAAAJ,EAAAD,QAAAC,IAAAD,QAAAF,GAGAG,EAAAE,GAAA,EAGAF,EAAAD,QAKAF,EAAAQ,EAAAF,EAGAN,EAAAS,EAAAV,EAGAC,EAAAU,EAAA,SAAAR,EAAAS,EAAAC,GACAZ,EAAAa,EAAAX,EAAAS,IACAG,OAAAC,eAAAb,EAAAS,GACAK,cAAA,EACAC,YAAA,EACAC,IAAAN,KAMAZ,EAAAmB,EAAA,SAAAjB,GACAY,OAAAC,eAAAb,EAAA,cAAiDkB,OAAA,KAIjDpB,EAAAqB,EAAA,SAAAlB,GACA,IAAAS,EAAAT,KAAAmB,WACA,WAA2B,OAAAnB,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAH,EAAAU,EAAAE,EAAA,IAAAA,GACAA,GAIAZ,EAAAa,EAAA,SAAAU,EAAAC,GAAsD,OAAAV,OAAAW,UAAAC,eAAAnB,KAAAgB,EAAAC,IAGtDxB,EAAA2B,EAAA,GAIA3B,IAAA4B,EAAA,8FClEC,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,kBACA,oBACA,iBACA,kBACA,kBACA,kBACA,iBACA,kBACA,gBACA,iBACA,oBACA,oBACA,sBACA,oBACA,mBACA,iBACA,kBACA,iBACA,kBACA,oBACA,iBACA,oBACA,gBACA,kBACA,kBACA,iBACA,mBACA,oBACA,kBACA,mBACA,kBACA,oBACA,qBACA,mBACA,oBACA,mBACA,gBACA,kBACA,oBACA,kBACA,qBACA,qBACA,sBACA,uBACA,sBACA,oBACA,qBACA,uBACA,wBACA,mBACA,oBACA,wBACA,yBACA,wBACA,oBACA,qBACA,sBACA,qBACA,qBACA,sBACA,uBACA,qBACA,oBACA,qBACA,wBACA,qBACA,oBACA,cACA,kBACA,eACA,kBACA,eACA,iBACA,gBACA,eACA,gBACA,cACA,eACA,gBACA,eACA,gBACA,cACA,cACA,cACA,eACA,eACA,eACA,eACA,iBACA,iBACA,kBACA,gBACA,eACA,mBACA,kBACA,mBACA,mBACA,kBACA,mBACA,kBACA,mBACA,mBACA,oBACA,kBACA,uBACA,wBACA,qBACA,sBACA,mBACA,mBACA,iBACA,kBACA,mBACA,kBACA,kBACA,oBACA,qBACA,mBACA,iBACA,qBACA,mBACA,sBACA,mBACA,oBACA,kBACA,iBACA,kBACA,cACA,YACA,aACA,aACA,eACA,eACA,gBACA,iBACA,iBACA,iBACA,aACA,iBACA,cACA,eACA,eACA,eACA,eACA,cACA,eACA,eACA,eACA,eACA,sBACA,uBACA,aACA,eACA,cACA,gBACA,cACA,gBACA,oBACA,cACA,cACA,eACA,eACA,iBACA,kBACA,mBACA,cACA,oBACA,aACA,cACA,cACA,mBACA,aACA,cACA,aACA,aACA,cACA,cACA,cACA,cACA,eACA,gBACA,gBACA,gBACA,gBACA,iBACA,qBACA,iBACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,aACA,iBACA,kBACA,iBACA,kBACA,eACA,gBACA,gBACA,eACA,gBACA,gBACA,gBACA,gBACA,sBACA,iBACA,cACA,eACA,oBACA,gBACA,iBACA,iBACA,gBACA,eACA,eACA,eACA,eACA,gBACA,iBACA,iBACA,iBACA,iBACA,eACA,gBACA,cACA,qBACA,sBACA,sBACA,eACA,mBACA,gBACA,cACA,iBACA,kBACA,gBACA,gBACA,mBACA,aACA,cACA,cACA,eACA,gBACA,eACA,gBACA,cACA,aACA,cACA,cACA,cACA,cACA,aACA,cACA,cACA,cACA,iBACA,oBACA,0BACA,oBACA,oBACA,cACA,oBACA,cACA,YACA,kBACA,eACA,YACA,gBACA,eACA,kBACA,gBACA,eACA,gBACA,gBACA,gBACA,iBACA,cACA,eACA,eACA,iBACA,kBACA,iBACA,kBACA,sBACA,gBACA,iBACA,gBACA,iBACA,aACA,cACA,cACA,cACA,sBACA,iBACA,kBACA,cACA,eACA,eACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,cACA,eACA,cACA,eACA,cACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,mBACA,aACA,cACA,oBACA,eACA,gBACA,aACA,cACA,cACA,kBACA,oBACA,qBACA,qBACA,gBACA,aACA,cACA,cACA,cACA,cACA,cACA,eACA,eACA,gBACA,kBACA,mBACA,mBACA,mBACA,iBACA,mBACA,gBACA,oBACA,qBACA,qBACA,qBACA,oBACA,kBACA,oBACA,qBACA,iBACA,kBACA,kBACA,oBACA,iBACA,kBACA,kBACA,qBACA,qBACA,kBACA,kBACA,mBACA,oBACA,iBACA,oBACA,kBACA,gBACA,WACA,YACA,YACA,YACA,YACA,gBACA,cACA,aACA,eACA,aACA,YACA,iBACA,eACA,eACA,mBACA,qBACA,sBACA,sBACA,sBACA,sBACA,sBACA,eACA,aACA,cACA,cACA,cACA,cACA,aACA,aACA,cACA,cACA,eACA,cACA,cACA,cACA,eACA,gBACA,gBACA,iBACA,0BACA,cACA,oBACA,eACA,YACA,aACA,aACA,WACA,YACA,YACA,cACA,aACA,eACA,gBACA,iBACA,YACA,aACA,aACA,aACA,eACA,cACA,cACA,YACA,mBACA,aACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,SACA,iBACA,kBACA,kBACA,kBACA,gBACA,iBACA,iBACA,cACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,oBACA,mBACA,aACA,cACA,cACA,cACA,eACA,eACA,iBACA,cACA,gBACA,eACA,gBACA,gBACA,cACA,oBACA,aACA,aACA,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,iBACA,gBACA,cACA,oBACA,mBACA,oBACA,oBACA,mBACA,iBACA,uBACA,oBACA,iBACA,mBACA,oBACA,mBACA,iBACA,mBACA,kBACA,sBACA,mBACA,oBACA,qBACA,oBACA,mBACA,oBACA,kBACA,kBACA,kBACA,sBACA,kBACA,oBACA,iBACA,kBACA,kBACA,oBACA,gBACA,kBACA,kBACA,mBACA,kBACA,mBACA,mBACA,wBACA,oBACA,mBACA,oBACA,qBACA,oBACA,mBACA,kBACA,iBACA,mBACA,oBACA,qBACA,cACA,eACA,YACA,aACA,YACA,aACA,cACA,cACA,cACA,aACA,cACA,cACA,cACA,cACA,aACA,YACA,aACA,aACA,aACA,iBACA,eACA,gBACA,mBACA,iBACA,eACA,gBACA,gBACA,aACA,WACA,cACA,aACA,cACA,cACA,cACA,aACA,cACA,iBACA,gBACA,iBACA,iBACA,aACA,cACA,cACA,kBACA,aACA,cACA,cACA,YACA,gBACA,eACA,iBACA,oBACA,0BACA,aACA,eACA,aACA,cACA,YACA,aACA,kBACA,kBACA,YACA,mBACA,YACA,aACA,aACA,gBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,cACA,eACA,gBACA,gBACA,gBACA,iBACA,kBACA,YACA,aACA,aACA,aACA,aACA,aACA,aACA,aACA,aACA,cACA,cACA,cACA,aACA,iBACA,kBACA,kBACA,aACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,eACA,eACA,gBACA,cACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,cACA,eACA,gBACA,gBACA,eACA,iBACA,uBACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,aACA,cACA,cACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,cACA,eACA,aACA,aACA,cACA,cACA,gBACA,eACA,mBACA,mBACA,mBACA,qBACA,wBACA,sBACA,kBACA,mBACA,qBACA,oBACA,sBACA,uBACA,mBACA,qBACA,oBACA,kBACA,kBACA,oBACA,uBACA,sBACA,uBACA,qBACA,mBACA,sBACA,iBACA,kBACA,qBACA,wBACA,oBACA,uBACA,oBACA,qBACA,oBACA,mBACA,oBACA,qBACA,oBACA,oBACA,eACA,aACA,cACA,cACA,eACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,cACA,cACA,cACA,eACA,eACA,eACA,cACA,gBACA,gBACA,cACA,eACA,eACA,eACA,gBACA,iBACA,aACA,cACA,cACA,mBACA,eACA,gBACA,gBACA,gBACA,aACA,cACA,cACA,kBACA,mBACA,mBACA,mBACA,oBACA,oBACA,oBACA,qBACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,UACA,gBACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,aACA,cACA,cACA,kBACA,oBACA,eACA,qBACA,sBACA,eACA,eACA,gBACA,cACA,cACA,gBACA,kBACA,oBACA,iBACA,iBACA,iBACA,qBACA,sBACA,oBACA,uBACA,uBACA,kBACA,mBACA,iBACA,kBACA,oBACA,kBACA,kBACA,iBACA,oBACA,mBACA,oBACA,oBACA,oBACA,wBACA,kBACA,mBACA,mBACA,oBACA,cACA,eACA,cACA,eACA,eACA,gBACA,aACA,cACA,sBACA,uBACA,gBACA,iBACA,iBACA,gBACA,cACA,eACA,cACA,eACA,eACA,eACA,cACA,2BACA,iBACA,eACA,gBACA,gBACA,aACA,cACA,iBACA,aACA,eACA,aACA,eACA,gBACA,cACA,cACA,eACA,eACA,cACA,eACA,gBACA,eACA,gBACA,iBACA,gBACA,cACA,cACA,mBACA,eACA,gBACA,cACA,mBACA,gBACA,iBACA,iBACA,qBACA,qBACA,eACA,iBACA,cACA,cACA,cACA,cACA,eACA,qBACA,iBACA,gBACA,mBACA,qBACA,0BACA,oBACA,kBACA,uBACA,oBACA,oBACA,qBACA,oBACA,gBACA,4BACA,qBACA,oBACA,oBACA,wBACA,oBACA,0BACA,mBACA,mBACA,mBACA,mBACA,wBACA,kBACA,wBACA,sBACA,eACA,yBACA,cACA,gBACA,iBACA,cACA,YACA,aACA,aACA,aACA,aACA,aACA,aACA,eACA,iBACA,eACA,gBACA,eACA,gBACA,eACA,gBACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,aACA,cACA,kBACA,gBACA,gBACA,oBACA,qBACA,qBACA,mBACA,mBACA,2BACA,oBACA,oBACA,mBACA,oBACA,qBACA,sBACA,mBACA,wBACA,mBACA,mBACA,kBACA,kBACA,mBACA,oBACA,mBACA,mBACA,iBACA,oBACA,mBACA,kBACA,kBACA,mBACA,qBACA,mBACA,mBACA,mBACA,qBACA,oBACA,oBACA,mBACA,oBACA,kBACA,kBACA,oBACA,sBACA,mBACA,qBACA,mBACA,mBACA,mBACA,YACA,aACA,eACA,cACA,eACA,aACA,kBACA,aACA,cACA,gBACA,eACA,eACA,eACA,aACA,iBACA,cACA,aACA,oBACA,eACA,gBACA,aACA,cACA,cACA,cACA,iBACA,kBACA,iBACA,kBACA,iBACA,kBACA,mBACA,mBACA,aACA,cACA,cACA,cACA,cACA,cACA,cACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,aACA,kBACA,iBACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,WACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,qBACA,kBACA,qBACA,gBACA,iBACA,iBACA,eACA,gBACA,iBACA,eACA,gBACA,iBACA,eACA,cACA,iBACA,aACA,aACA,gBACA,gBACA,mBACA,sBACA,kBACA,mBACA,kBACA,oBACA,mBACA,qBACA,oBACA,kBACA,gBACA,kBACA,mBACA,kBACA,sBACA,oBACA,iBACA,kBACA,iBACA,iBACA,mBACA,kBACA,gBACA,oBACA,kBACA,oBACA,kBACA,WACA,YACA,cACA,cACA,YACA,eACA,eACA,gBACA,gBACA,YACA,aACA,eACA,iBACA,eACA,aACA,WACA,YACA,aACA,cACA,cACA,cACA,cACA,mBACA,oBACA,YACA,aACA,cACA,cACA,cACA,gBACA,eACA,iBACA,cACA,cACA,aACA,cACA,eACA,gBACA,cACA,gBACA,iBACA,iBACA,kBACA,kBACA,mBACA,iBACA,kBACA,cACA,iBACA,aACA,cACA,cACA,cACA,cACA,cACA,cACA,gBACA,iBACA,iBACA,cACA,qBACA,sBACA,sBACA,eACA,gBACA,aACA,cACA,cACA,eACA,eACA,cACA,eACA,eACA,gBACA,iBACA,aACA,cACA,cACA,cACA,eACA,cACA,eACA,YACA,6GCvyCA,aACA,QACA,MACA,eACA,sBACA,WACA,YACA,WACA,mBACA,YACA,WACA,iBACA,YACA,YACA,cACA,aACA,aACA,eACA,YACA,WACA,eACA,WACA,aACA,oBACA,oBACA,mBACA,yBACA,iBACA,sBACA,kBACA,2BACA,mBACA,mBACA,cACA,kBACA,wBACA,sBACA,oBACA,YACA,uBACA,aACA,UACA,eACA,8BACA,yBACA,YACA,mBACA,qBACA,oBACA,oBACA,eACA,mBACA,sBACA,sBACA,cACA,oBACA,aACA,WACA,gBACA,iBACA,iBACA,oBACA,UACA,aACA,sBACA,WACA,kBACA,qBACA,wBACA,2BACA,kBACA,UACA,eACA,kBACA,iBACA,iBACA,oBACA,UACA,kBACA,mBACA,eACA,YACA,mBACA,oBACA,eACA,gBACA,kBACA,iBACA,UACA,mBACA,eACA,qBACA,iBACA,MACA,cACA,aACA,gBACA,QACA,SACA,gBACA,cACA,eACA,mBACA,cACA,cACA,eACA,WACA,gBACA,oBACA,WACA,gBACA,aACA,aACA,OACA,WACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,OACA,OACA,OACA,gBACA,iBACA,mBACA,iBACA,kBACA,uBACA,kBACA,KACA,cACA,kBACA,cACA,cACA,aACA,aACA,aACA,aACA,aACA,cACA,OACA,YACA,aACA,MACA,eACA,SACA,cACA,iBACA,YACA,sBACA,gBACA,YACA,eACA,eACA,kBACA,iBACA,eACA,wBACA,cACA,cACA,gBACA,eACA,cACA,mBACA,iBACA,kBACA,cACA,mBACA,eACA,kBACA,kBACA,kBACA,iBACA,cACA,cACA,eACA,gBACA,aACA,aACA,iBACA,aACA,YACA,cACA,YACA,YACA,iBACA,cACA,eACA,YACA,KACA,UACA,cACA,gBACA,6BACA,gBACA,mBACA,UACA,UACA,kBACA,sBACA,kBACA,gBACA,UACA,UACA,MACA,mBACA,oBACA,wBACA,4BACA,6BACA,kBACA,gBACA,YACA,kBACA,aACA,aACA,eACA,OACA,YACA,WACA,gBACA,kBACA,gBACA,mBACA,sBACA,kBACA,gBACA,gBACA,oBACA,oBACA,qBACA,aACA,oBACA,kBACA,eACA,SACA,UACA,WACA,SACA,SACA,UACA,WACA,UACA,eACA,cACA,cACA,gBACA,SACA,WACA,eACA,mBACA,mBACA,yBACA,0BACA,cACA,eACA,eACA,YACA,uBACA,oBACA,KACA,SACA,kBACA,aACA,WACA,SACA,kBACA,aACA,aACA,kBACA,oBACA,oBACA,eACA,iBACA,sBACA,WACA,cACA,iBACA,YACA,kBACA,kBACA,oBACA,aACA,wBACA,wBACA,oBACA,iBACA,mBACA,eACA,gBACA,kBACA,oBACA,YACA,WACA,UACA,aACA,cACA,mBACA,WACA,SACA,iBACA,QACA,YACA,UACA,iBACA,qBACA,mBACA,sBACA,6BACA,kCACA,0BACA,2BACA,uBACA,wBACA,0BACA,0BACA,iBACA,mBACA,wBACA,iCACA,6BACA,sBACA,kBACA,mBACA,0BACA,mBACA,gBACA,oBACA,kBACA,kBACA,4BACA,yBACA,uBACA,cACA,qBACA,mBACA,cACA,eACA,iBACA,oBACA,eACA,wBACA,sBACA,iBACA,gBACA,cACA,iBACA,oBACA,UACA,cACA,YACA,yBACA,aACA,SACA,WACA,aACA,eACA,yBACA,aACA,aACA,WACA,QACA,WACA,eACA,gBACA,gBACA,sBACA,WACA,UACA,cACA,gBACA,gBACA,iBACA,0BACA,kBACA,oBACA,aACA,eACA,mBACA,gBACA,eACA,YACA,aACA,SACA,eACA,eACA,cACA,gBACA,gBACA,gBACA,QACA,mBACA,cACA,SACA,cACA,WACA,cACA,aACA,YACA,eACA,UACA,UACA,UACA,WACA,aACA,aACA,iBACA,WACA,WACA,YACA,YACA,YACA,aACA,WACA,UACA,eACA,QACA,gBACA,UACA,uBACA,kBACA,eACA,qBACA,yBACA,mBACA,8BACA,kCACA,sBACA,eACA,qBACA,yBACA,yBACA,eACA,oBACA,cACA,yBACA,cACA,iBACA,SACA,YACA,eACA,cACA,oBACA,aACA,kBACA,gBACA,YACA,kBACA,aACA,WACA,iBACA,qBACA,WACA,cACA,eACA,iBACA,eACA,iBACA,cACA,gBACA,aACA,aACA,sBACA,WACA,cACA,WACA,oBACA,kBACA,eACA,iBACA,eACA,2BACA,yBACA,aACA,eACA,aACA,UACA,YACA,aACA,OACA,YACA,uBACA,oBACA,qBACA,qBACA,qBACA,sBACA,uBACA,uBACA,uBACA,wBACA,kBACA,cACA,eACA,cACA,iBACA,cACA,eACA,qBACA,eACA,oBACA,eACA,qBACA,aACA,gBACA,gBACA,gBACA,WACA,YACA,YACA,aACA,eACA,aACA,cACA,YACA,YACA,aACA,cACA,SACA,iBACA,oBACA,WACA,cACA,MACA,UACA,WACA,oBACA,gBACA,sBACA,aACA,iBACA,kBACA,mBACA,mBACA,oBACA,gBACA,mBACA,YACA,YACA,WACA,uBACA,WACA,cACA,YACA,cACA,cACA,SACA,iBACA,wBACA,SACA,WACA,gBACA,mBACA,oBACA,mBACA,wBACA,eACA,iBACA,iBACA,aACA,iBACA,SACA,UACA,gBACA,iBACA,cACA,QACA,OACA,aACA,aACA,iBACA,aACA,aACA,oBACA,0BACA,OACA,MACA,SACA,SACA,OACA,OACA,kBACA,MACA,iBACA,UACA,mBACA,kBACA,oBACA,YACA,gBACA,gBACA,eACA,OACA,QACA,YACA,gBACA,aACA,WACA,WACA,WACA,QACA,UACA,UACA,UACA,UACA,YACA,SACA,aACA,OACA,mBACA,SACA,eACA,SACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WACA,cACA,kBACA,UACA,oBACA,iBACA,uBACA,kBACA,UACA,aACA,kBACA,kBACA,aACA,aACA,oBACA,oBACA,gBACA,kBACA,UACA,UACA,eACA,SACA,MACA,WACA,MACA,KACA,MACA,qBACA,6BACA,0BACA,4BACA,yBACA,2BACA,uBACA,wBACA,0BACA,wBACA,SACA,SACA,eACA,eACA,kBACA,kBACA,WACA,WACA,YACA,YACA,YACA,YACA,YACA,aACA,SACA,YACA,cACA,iBACA,uBACA,cACA,mBACA,iBACA,uBACA,YACA,qBACA,iBACA,MACA,WACA,oBACA,SACA,gBACA,oBACA,iBACA,MACA,8BACA,oBACA,gCACA,sBACA,sBACA,YACA,wBACA,cACA,QACA,YACA,aACA,iBACA,cACA,YACA,aACA,yBACA,iBACA,aACA,6VCwjBeC,eAYAC,YAuCAC,oBAUAC,eASAC,sBAQAC,oBAQAC,qBASAC,oBAWAC,aAWAC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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 2);\n","export default [\r\n\t\"1.gif\",\r\n\t\"1.png\",\r\n\t\"2.png\",\r\n\t\"3.png\",\r\n\t\"4.png\",\r\n\t\"5.gif\",\r\n\t\"5.png\",\r\n\t\"6.gif\",\r\n\t\"6.png\",\r\n\t\"AACastApril.png\",\r\n\t\"AACastBellboy.png\",\r\n\t\"AACastButz.png\",\r\n\t\"AACastButz2.png\",\r\n\t\"AACastButz3.png\",\r\n\t\"AACastCindy.png\",\r\n\t\"AACastCody.png\",\r\n\t\"AACastDarke.png\",\r\n\t\"AACastEma.png\",\r\n\t\"AACastGant.png\",\r\n\t\"AACastGoodman.png\",\r\n\t\"AACastGregory.png\",\r\n\t\"AACastGrossberg.png\",\r\n\t\"AACastGumshoe.png\",\r\n\t\"AACastHammer.png\",\r\n\t\"AACastJake.png\",\r\n\t\"AACastJudge.png\",\r\n\t\"AACastLana.png\",\r\n\t\"AACastLotta.png\",\r\n\t\"AACastManfred.png\",\r\n\t\"AACastMaya.png\",\r\n\t\"AACastMeekins.png\",\r\n\t\"AACastMia.png\",\r\n\t\"AACastMiles.png\",\r\n\t\"AACastMisty.png\",\r\n\t\"AACastNeil.png\",\r\n\t\"AACastOldbag.png\",\r\n\t\"AACastOldbag2.png\",\r\n\t\"AACastPayne.png\",\r\n\t\"AACastPayne2.png\",\r\n\t\"AACastPenny.png\",\r\n\t\"AACastPhoenix.png\",\r\n\t\"AACastPhoenix2.png\",\r\n\t\"AACastPowers.png\",\r\n\t\"AACastPowers2.png\",\r\n\t\"AACastSahwit.png\",\r\n\t\"AACastSal.png\",\r\n\t\"AACastStarr.png\",\r\n\t\"AACastVasquez.png\",\r\n\t\"AACastWhite.png\",\r\n\t\"AAI2CastBlaise.png\",\r\n\t\"AAI2CastBonnie.png\",\r\n\t\"AAI2CastCameron.png\",\r\n\t\"AAI2CastCourtney.png\",\r\n\t\"AAI2CastDelicia.png\",\r\n\t\"AAI2CastDogen.png\",\r\n\t\"AAI2CastElbird.png\",\r\n\t\"AAI2CastGustavia.png\",\r\n\t\"AAI2CastGustavia2.png\",\r\n\t\"AAI2CastJill.png\",\r\n\t\"AAI2CastKarin.png\",\r\n\t\"AAI2CastKatherine.png\",\r\n\t\"AAI2CastKatherine2.png\",\r\n\t\"AAI2CastKnightley.png\",\r\n\t\"AAI2CastMarsh.png\",\r\n\t\"AAI2CastMaster.png\",\r\n\t\"AAI2CastMaster2.png\",\r\n\t\"AAI2CastNicole.png\",\r\n\t\"AAI2CastPierre.png\",\r\n\t\"AAI2CastRaymond.png\",\r\n\t\"AAI2CastRaymond2.png\",\r\n\t\"AAI2CastRoland.png\",\r\n\t\"AAI2CastRooke.png\",\r\n\t\"AAI2CastSahwit.png\",\r\n\t\"AAI2CastSebastian.png\",\r\n\t\"AAI2CastShelly.png\",\r\n\t\"AAI2CastSimon.png\",\r\n\t\"AAI2bag.png\",\r\n\t\"AAI2balloon.png\",\r\n\t\"AAI2bell.png\",\r\n\t\"AAI2blanket.png\",\r\n\t\"AAI2body.png\",\r\n\t\"AAI2button.png\",\r\n\t\"AAI2chess.png\",\r\n\t\"AAI2clip.png\",\r\n\t\"AAI2cuffs.png\",\r\n\t\"AAI2dog.png\",\r\n\t\"AAI2door.png\",\r\n\t\"AAI2floor.png\",\r\n\t\"AAI2gate.png\",\r\n\t\"AAI2glove.png\",\r\n\t\"AAI2gun.png\",\r\n\t\"AAI2key.png\",\r\n\t\"AAI2map.png\",\r\n\t\"AAI2map2.png\",\r\n\t\"AAI2map3.png\",\r\n\t\"AAI2note.png\",\r\n\t\"AAI2rope.png\",\r\n\t\"AAI2shovel.png\",\r\n\t\"AAI2tunnel.png\",\r\n\t\"AAI2uniform.png\",\r\n\t\"AAI2video.png\",\r\n\t\"AAI2well.png\",\r\n\t\"AAICastAkbey.png\",\r\n\t\"AAICastAlba.png\",\r\n\t\"AAICastAlba2.png\",\r\n\t\"AAICastAmano.png\",\r\n\t\"AAICastBadd.png\",\r\n\t\"AAICastBuddy.png\",\r\n\t\"AAICastButz.png\",\r\n\t\"AAICastByrne.png\",\r\n\t\"AAICastCammy.png\",\r\n\t\"AAICastDeacon.png\",\r\n\t\"AAICastDeid.png\",\r\n\t\"AAICastFranziska.png\",\r\n\t\"AAICastFranziska2.png\",\r\n\t\"AAICastGumshoe.png\",\r\n\t\"AAICastGumshoe2.png\",\r\n\t\"AAICastHuang.png\",\r\n\t\"AAICastJudge.png\",\r\n\t\"AAICastKay.png\",\r\n\t\"AAICastKay2.png\",\r\n\t\"AAICastLance.png\",\r\n\t\"AAICastLang.png\",\r\n\t\"AAICastMack.png\",\r\n\t\"AAICastMaggey.png\",\r\n\t\"AAICastManfred.png\",\r\n\t\"AAICastManny.png\",\r\n\t\"AAICastNou.png\",\r\n\t\"AAICastPalaeno.png\",\r\n\t\"AAICastPaups.png\",\r\n\t\"AAICastPortsman.png\",\r\n\t\"AAICastRhoda.png\",\r\n\t\"AAICastShihna.png\",\r\n\t\"AAICastSkye.png\",\r\n\t\"AAICastYew.png\",\r\n\t\"AAICastZinc.png\",\r\n\t\"AAIFIRE.png\",\r\n\t\"AAIad.png\",\r\n\t\"AAIad2.png\",\r\n\t\"AAIad3.png\",\r\n\t\"AAIarrow.png\",\r\n\t\"AAIbadge.png\",\r\n\t\"AAIbadger.png\",\r\n\t\"AAIbadger2.png\",\r\n\t\"AAIbadger3.png\",\r\n\t\"AAIbadger4.png\",\r\n\t\"AAIbag.png\",\r\n\t\"AAIballoon.png\",\r\n\t\"AAIbody.png\",\r\n\t\"AAIbody2.png\",\r\n\t\"AAIbody3.png\",\r\n\t\"AAIbody4.png\",\r\n\t\"AAIbody5.png\",\r\n\t\"AAIbook.png\",\r\n\t\"AAIbook2.png\",\r\n\t\"AAIbook3.png\",\r\n\t\"AAIbook4.png\",\r\n\t\"AAIboxes.png\",\r\n\t\"AAIbusinesscard.png\",\r\n\t\"AAIbusinesscard2.png\",\r\n\t\"AAIcar.png\",\r\n\t\"AAIcargo.png\",\r\n\t\"AAIcart.png\",\r\n\t\"AAIchange.png\",\r\n\t\"AAIclip.png\",\r\n\t\"AAIcravat.png\",\r\n\t\"AAIdecoration.png\",\r\n\t\"AAIdoor.png\",\r\n\t\"AAIfile.png\",\r\n\t\"AAIfile2.png\",\r\n\t\"AAIfile3.png\",\r\n\t\"AAIflowers.png\",\r\n\t\"AAIfountain.png\",\r\n\t\"AAIfountain2.png\",\r\n\t\"AAIgift.png\",\r\n\t\"AAIguitarpick.png\",\r\n\t\"AAIgun.png\",\r\n\t\"AAIgun2.png\",\r\n\t\"AAIgun3.png\",\r\n\t\"AAIhandprint.png\",\r\n\t\"AAIhat.png\",\r\n\t\"AAIhoop.png\",\r\n\t\"AAIink.png\",\r\n\t\"AAIkey.png\",\r\n\t\"AAIkey2.png\",\r\n\t\"AAIkey3.png\",\r\n\t\"AAIkey4.png\",\r\n\t\"AAIkey5.png\",\r\n\t\"AAIknife.png\",\r\n\t\"AAIknife2.png\",\r\n\t\"AAIknife3.png\",\r\n\t\"AAIknife4.png\",\r\n\t\"AAIknife5.png\",\r\n\t\"AAIlantern.png\",\r\n\t\"AAIlittlethief.png\",\r\n\t\"AAIluggage.png\",\r\n\t\"AAImoney.png\",\r\n\t\"AAInote.png\",\r\n\t\"AAInote2.png\",\r\n\t\"AAInote3.png\",\r\n\t\"AAInote4.png\",\r\n\t\"AAInote5.png\",\r\n\t\"AAInote6.png\",\r\n\t\"AAInote7.png\",\r\n\t\"AAInote8.png\",\r\n\t\"AAInote9.png\",\r\n\t\"AAInote10.png\",\r\n\t\"AAInote11.png\",\r\n\t\"AAInote12.png\",\r\n\t\"AAInote13.png\",\r\n\t\"AAInote14.png\",\r\n\t\"AAInote15.png\",\r\n\t\"AAInote16.png\",\r\n\t\"AAInote17.png\",\r\n\t\"AAIpen.png\",\r\n\t\"AAIpendant.png\",\r\n\t\"AAIpendant2.png\",\r\n\t\"AAIperfume.png\",\r\n\t\"AAIperfume2.png\",\r\n\t\"AAIphone.png\",\r\n\t\"AAIphone2.png\",\r\n\t\"AAIphone3.png\",\r\n\t\"AAIphoto.png\",\r\n\t\"AAIphoto2.png\",\r\n\t\"AAIphoto3.png\",\r\n\t\"AAIphoto4.png\",\r\n\t\"AAIplates.png\",\r\n\t\"AAIquercuswound.png\",\r\n\t\"AAIreceipt.png\",\r\n\t\"AAIsafe.png\",\r\n\t\"AAIsafe2.png\",\r\n\t\"AAIsciencekit.png\",\r\n\t\"AAIshards.png\",\r\n\t\"AAIshards2.png\",\r\n\t\"AAIshards3.png\",\r\n\t\"AAIshears.png\",\r\n\t\"AAIshirt.png\",\r\n\t\"AAIsnack.png\",\r\n\t\"AAIspear.png\",\r\n\t\"AAIspill.png\",\r\n\t\"AAIstatue.png\",\r\n\t\"AAIstatue2.png\",\r\n\t\"AAIstatue3.png\",\r\n\t\"AAIstatue4.png\",\r\n\t\"AAIsuspect.png\",\r\n\t\"AAIsword.png\",\r\n\t\"AAIsword2.png\",\r\n\t\"AAItape.png\",\r\n\t\"AAItonosamanju.png\",\r\n\t\"AAItonosamanju2.png\",\r\n\t\"AAItonosamanju3.png\",\r\n\t\"AAIvideo.png\",\r\n\t\"AAIwakasaman.png\",\r\n\t\"AAIwallet.png\",\r\n\t\"AAIwire.png\",\r\n\t\"AATHATCARD.png\",\r\n\t\"AAaffidavit.png\",\r\n\t\"AAairtube.png\",\r\n\t\"AAautopsy.png\",\r\n\t\"AAbluebadger.png\",\r\n\t\"AAbook.png\",\r\n\t\"AAbook2.png\",\r\n\t\"AAbook3.png\",\r\n\t\"AAbullet.png\",\r\n\t\"AAbullet2.png\",\r\n\t\"AAcamera.png\",\r\n\t\"AAcamera2.png\",\r\n\t\"AAcards.png\",\r\n\t\"AAclip.png\",\r\n\t\"AAclip2.png\",\r\n\t\"AAclip3.png\",\r\n\t\"AAclip4.png\",\r\n\t\"AAclip5.png\",\r\n\t\"AAdata.png\",\r\n\t\"AAdata2.png\",\r\n\t\"AAdata3.png\",\r\n\t\"AAdata4.png\",\r\n\t\"AAenvelope.png\",\r\n\t\"AAevidencelaw.png\",\r\n\t\"AAfingerprintpowder.png\",\r\n\t\"AAfirecracker.png\",\r\n\t\"AAfishingpole.png\",\r\n\t\"AAflyer.png\",\r\n\t\"AAglassshards.png\",\r\n\t\"AAglove.png\",\r\n\t\"AAgun.png\",\r\n\t\"AAhandprint.png\",\r\n\t\"AAidcard.png\",\r\n\t\"AAkey.png\",\r\n\t\"AAkeycard.png\",\r\n\t\"AAknife1.png\",\r\n\t\"AAkoptrophy.png\",\r\n\t\"AAleather.png\",\r\n\t\"AAlocker.png\",\r\n\t\"AAlocker2.png\",\r\n\t\"AAlocker3.png\",\r\n\t\"AAluminol.png\",\r\n\t\"AAluminol2.png\",\r\n\t\"AAlunch.png\",\r\n\t\"AAlunch2.png\",\r\n\t\"AAlunch3.png\",\r\n\t\"AAmagatama.png\",\r\n\t\"AAmagatama2.png\",\r\n\t\"AAmayanote.png\",\r\n\t\"AAmayoinote.png\",\r\n\t\"AAmetaldetector.png\",\r\n\t\"AAmissile.png\",\r\n\t\"AAmissile2.png\",\r\n\t\"AAmissle2.png\",\r\n\t\"AAmrmonkey.png\",\r\n\t\"AAnote.png\",\r\n\t\"AAnote2.png\",\r\n\t\"AAnote3.png\",\r\n\t\"AAnote4.png\",\r\n\t\"AAparkingticket.png\",\r\n\t\"AApassport.png\",\r\n\t\"AApassport2.png\",\r\n\t\"AAphone.png\",\r\n\t\"AAphone2.png\",\r\n\t\"AAphone3.png\",\r\n\t\"AAphone4.png\",\r\n\t\"AAphoto.png\",\r\n\t\"AAphoto2.png\",\r\n\t\"AAphoto3.png\",\r\n\t\"AAphoto4.png\",\r\n\t\"AAphoto5.png\",\r\n\t\"AAphoto6.png\",\r\n\t\"AAphoto7.png\",\r\n\t\"AAphoto8.png\",\r\n\t\"AAphoto9.png\",\r\n\t\"AAphoto10.png\",\r\n\t\"AAphoto11.png\",\r\n\t\"AApills.png\",\r\n\t\"AApills2.png\",\r\n\t\"AAplate.png\",\r\n\t\"AAplate2.png\",\r\n\t\"AApolly.png\",\r\n\t\"AAprint.png\",\r\n\t\"AAprint2.png\",\r\n\t\"AAprint3.png\",\r\n\t\"AAprint4.png\",\r\n\t\"AAprint5.png\",\r\n\t\"AAprint6.png\",\r\n\t\"AAprint7.png\",\r\n\t\"AAprint8.png\",\r\n\t\"AApsychelock.png\",\r\n\t\"AAsafe.png\",\r\n\t\"AAscarf.png\",\r\n\t\"AAscrewdriver.png\",\r\n\t\"AAscript.png\",\r\n\t\"AAscript2.png\",\r\n\t\"AAshoe.png\",\r\n\t\"AAshoe2.png\",\r\n\t\"AAspear.png\",\r\n\t\"AAstudiovan.png\",\r\n\t\"AAswitchblade.png\",\r\n\t\"AAswitchblade2.png\",\r\n\t\"AAswitchblade3.png\",\r\n\t\"AAthinker.png\",\r\n\t\"AAvase.png\",\r\n\t\"AAvase2.png\",\r\n\t\"AAvase3.png\",\r\n\t\"AAvase4.png\",\r\n\t\"AAvase5.png\",\r\n\t\"AAvideo.png\",\r\n\t\"AAvideo2.png\",\r\n\t\"AAwallet.png\",\r\n\t\"AAwiretap.png\",\r\n\t\"AJCastAlita.png\",\r\n\t\"AJCastApollo.png\",\r\n\t\"AJCastDaryan.jpg\",\r\n\t\"AJCastDaryan.png\",\r\n\t\"AJCastDrew.png\",\r\n\t\"AJCastEldoon.png\",\r\n\t\"AJCastEma.png\",\r\n\t\"AJCastKlavier.png\",\r\n\t\"AJCastKlavier2.png\",\r\n\t\"AJCastKristoph.png\",\r\n\t\"AJCastLamiroir.png\",\r\n\t\"AJCastLeTouse.png\",\r\n\t\"AJCastMachi.png\",\r\n\t\"AJCastMagnifi.png\",\r\n\t\"AJCastMeraktis.png\",\r\n\t\"AJCastOlga.png\",\r\n\t\"AJCastOlga2.png\",\r\n\t\"AJCastPayne.png\",\r\n\t\"AJCastPhoenix.png\",\r\n\t\"AJCastPlum.png\",\r\n\t\"AJCastShadi.png\",\r\n\t\"AJCastSpark.png\",\r\n\t\"AJCastStickler.png\",\r\n\t\"AJCastThalassa.png\",\r\n\t\"AJCastTrucy.gif\",\r\n\t\"AJCastTrucy.png\",\r\n\t\"AJCastValant.png\",\r\n\t\"AJCastValant2.png\",\r\n\t\"AJCastVera.png\",\r\n\t\"AJCastWinfred.png\",\r\n\t\"AJCastWocky.png\",\r\n\t\"AJCastZak.png\",\r\n\t\"AJad.png\",\r\n\t\"AJad2.png\",\r\n\t\"AJad3.png\",\r\n\t\"AJad4.png\",\r\n\t\"AJad5.png\",\r\n\t\"AJautopsy.png\",\r\n\t\"AJbadge.png\",\r\n\t\"AJbook.png\",\r\n\t\"AJbottle.png\",\r\n\t\"AJbowl.png\",\r\n\t\"AJbox.png\",\r\n\t\"AJbracelet.png\",\r\n\t\"AJbrooch.png\",\r\n\t\"AJbullet.png\",\r\n\t\"AJburntstuff.png\",\r\n\t\"AJbusinesscard.png\",\r\n\t\"AJbusinesscard2.png\",\r\n\t\"AJbusinesscard3.png\",\r\n\t\"AJbusinesscard4.png\",\r\n\t\"AJbusinesscard5.png\",\r\n\t\"AJbusinesscard6.png\",\r\n\t\"AJbutton.png\",\r\n\t\"AJcard.png\",\r\n\t\"AJcard2.png\",\r\n\t\"AJcard3.png\",\r\n\t\"AJcard4.png\",\r\n\t\"AJcard5.png\",\r\n\t\"AJcart.png\",\r\n\t\"AJclip.png\",\r\n\t\"AJclip2.png\",\r\n\t\"AJclip3.png\",\r\n\t\"AJcocoon.png\",\r\n\t\"AJdata1.png\",\r\n\t\"AJdata2.png\",\r\n\t\"AJdata3.png\",\r\n\t\"AJdevice.png\",\r\n\t\"AJdevice2.png\",\r\n\t\"AJdevice3.png\",\r\n\t\"AJearpiece.png\",\r\n\t\"AJfingerprintpowder.png\",\r\n\t\"AJframe.png\",\r\n\t\"AJgoldsnackoo.png\",\r\n\t\"AJguitar.png\",\r\n\t\"AJgun.png\",\r\n\t\"AJgun2.png\",\r\n\t\"AJgun3.png\",\r\n\t\"AJiv.png\",\r\n\t\"AJiv2.png\",\r\n\t\"AJkey.png\",\r\n\t\"AJknife.png\",\r\n\t\"AJlamp.png\",\r\n\t\"AJlocket.png\",\r\n\t\"AJluminol.png\",\r\n\t\"AJmagatama.png\",\r\n\t\"AJmap.png\",\r\n\t\"AJmap2.png\",\r\n\t\"AJmap3.png\",\r\n\t\"AJmap4.png\",\r\n\t\"AJmirror.png\",\r\n\t\"AJmixer.png\",\r\n\t\"AJmrhat.png\",\r\n\t\"AJmug.png\",\r\n\t\"AJnailpolish.png\",\r\n\t\"AJnote.png\",\r\n\t\"AJnote2.png\",\r\n\t\"AJnote3.png\",\r\n\t\"AJnote4.png\",\r\n\t\"AJnote5.png\",\r\n\t\"AJnote6.png\",\r\n\t\"AJnote7.png\",\r\n\t\"AJnote8.png\",\r\n\t\"AJnote9.png\",\r\n\t\"AJnote10.png\",\r\n\t\"AJnote11.png\",\r\n\t\"AJnote12.png\",\r\n\t\"AJnote13.png\",\r\n\t\"AJnote14.png\",\r\n\t\"AJnote15.png\",\r\n\t\"AJnote16.png\",\r\n\t\"AJnote17.png\",\r\n\t\"AJnote18.png\",\r\n\t\"AJnote19.png\",\r\n\t\"AJnote\",\r\n\t\"AJpainting.png\",\r\n\t\"AJpainting2.png\",\r\n\t\"AJpainting3.png\",\r\n\t\"AJpainting4.png\",\r\n\t\"AJpanties.png\",\r\n\t\"AJpanties2.png\",\r\n\t\"AJpanties3.png\",\r\n\t\"AJphone.png\",\r\n\t\"AJphone2.png\",\r\n\t\"AJphoto.png\",\r\n\t\"AJphoto2.png\",\r\n\t\"AJphoto3.png\",\r\n\t\"AJphoto4.png\",\r\n\t\"AJphoto5.png\",\r\n\t\"AJphoto6.png\",\r\n\t\"AJphoto7.png\",\r\n\t\"AJphoto8.png\",\r\n\t\"AJpoisonspray.png\",\r\n\t\"AJsciencekit.png\",\r\n\t\"AJshoe.png\",\r\n\t\"AJshoe2.png\",\r\n\t\"AJshoe3.png\",\r\n\t\"AJsnack.png\",\r\n\t\"AJsnack2.png\",\r\n\t\"AJsnack3.png\",\r\n\t\"AJsnackoos.png\",\r\n\t\"AJstamp.png\",\r\n\t\"AJsyringe.png\",\r\n\t\"AJticket.png\",\r\n\t\"AJticket2.png\",\r\n\t\"AJticket3.png\",\r\n\t\"AJvideo.png\",\r\n\t\"AJxraymachine.png\",\r\n\t\"Compin.png\",\r\n\t\"Credit.png\",\r\n\t\"CustomEvidence1.png\",\r\n\t\"CustomEvidence2.png\",\r\n\t\"CustomEvidence3.png\",\r\n\t\"CustomEvidence4.png\",\r\n\t\"CustomEvidence5.png\",\r\n\t\"CustomEvidence6.png\",\r\n\t\"CustomEvidence7.png\",\r\n\t\"CustomEvidence8.png\",\r\n\t\"CustomEvidence9.png\",\r\n\t\"CustomEvidence10.png\",\r\n\t\"CustomEvidence11.png\",\r\n\t\"CustomEvidence12.png\",\r\n\t\"CustomEvidence13.png\",\r\n\t\"CustomEvidence14.png\",\r\n\t\"CustomEvidence15.png\",\r\n\t\"CustomEvidence16.png\",\r\n\t\"CustomEvidence17.png\",\r\n\t\"CustomEvidence18.png\",\r\n\t\"CustomEvidence19.png\",\r\n\t\"CustomEvidence\",\r\n\t\"DDAutopsy.png\",\r\n\t\"DDBadge.png\",\r\n\t\"DDCaseCandice.png\",\r\n\t\"DDCastApollo.png\",\r\n\t\"DDCastApollo2.png\",\r\n\t\"DDCastApollo3.png\",\r\n\t\"DDCastAthena.png\",\r\n\t\"DDCastAura.png\",\r\n\t\"DDCastBlackquill.png\",\r\n\t\"DDCastCandice.png\",\r\n\t\"DDCastClay.png\",\r\n\t\"DDCastClonco.png\",\r\n\t\"DDCastClonco2.png\",\r\n\t\"DDCastCourte.png\",\r\n\t\"DDCastCrab.png\",\r\n\t\"DDCastDamien.png\",\r\n\t\"DDCastFilch.png\",\r\n\t\"DDCastFulbright.png\",\r\n\t\"DDCastJinxie.png\",\r\n\t\"DDCastJuniper.png\",\r\n\t\"DDCastJuniper2.png\",\r\n\t\"DDCastKlavier.png\",\r\n\t\"DDCastLBelle.png\",\r\n\t\"DDCastLBelle2.png\",\r\n\t\"DDCastMeans.png\",\r\n\t\"DDCastMetis.png\",\r\n\t\"DDCastMiles.png\",\r\n\t\"DDCastNineTails.png\",\r\n\t\"DDCastNorma.png\",\r\n\t\"DDCastOConnor.png\",\r\n\t\"DDCastOrla.png\",\r\n\t\"DDCastPayne.png\",\r\n\t\"DDCastPearl.png\",\r\n\t\"DDCastPhoenix.png\",\r\n\t\"DDCastRex.png\",\r\n\t\"DDCastRimes.png\",\r\n\t\"DDCastRobin.png\",\r\n\t\"DDCastRobin2.png\",\r\n\t\"DDCastSasha.png\",\r\n\t\"DDCastSasha2.png\",\r\n\t\"DDCastSasha3.png\",\r\n\t\"DDCastScuttlebutt.png\",\r\n\t\"DDCastShipley.png\",\r\n\t\"DDCastSniper.png\",\r\n\t\"DDCastSniper2.png\",\r\n\t\"DDCastStarbuck.png\",\r\n\t\"DDCastSummers.png\",\r\n\t\"DDCastTonate.png\",\r\n\t\"DDCastTrucy.png\",\r\n\t\"DDCastYuri.png\",\r\n\t\"DDSTEPladder.png\",\r\n\t\"DDScrewdriver.png\",\r\n\t\"DDStatueStands.png\",\r\n\t\"DDarrow.png\",\r\n\t\"DDbadge2.png\",\r\n\t\"DDbag.png\",\r\n\t\"DDball.png\",\r\n\t\"DDbed.png\",\r\n\t\"DDbomb.png\",\r\n\t\"DDbomb2.png\",\r\n\t\"DDbomb3.png\",\r\n\t\"DDbomb4.png\",\r\n\t\"DDbook.png\",\r\n\t\"DDbook2.png\",\r\n\t\"DDbook3.png\",\r\n\t\"DDbook4.png\",\r\n\t\"DDbook5.png\",\r\n\t\"DDbowl.png\",\r\n\t\"DDbox.png\",\r\n\t\"DDbox2.png\",\r\n\t\"DDbox3.png\",\r\n\t\"DDbox4.png\",\r\n\t\"DDbracelet.png\",\r\n\t\"DDbullet.png\",\r\n\t\"DDbullet2.png\",\r\n\t\"DDbullethole.png\",\r\n\t\"DDcalendar.png\",\r\n\t\"DDcamera.png\",\r\n\t\"DDcamera2.png\",\r\n\t\"DDcamera3.png\",\r\n\t\"DDcart.png\",\r\n\t\"DDcd.png\",\r\n\t\"DDcharm.png\",\r\n\t\"DDclip.png\",\r\n\t\"DDclip2.png\",\r\n\t\"DDclip3.png\",\r\n\t\"DDcloth.png\",\r\n\t\"DDcoin.png\",\r\n\t\"DDcoin2.png\",\r\n\t\"DDcomputer.png\",\r\n\t\"DDcostume.png\",\r\n\t\"DDcostume2.png\",\r\n\t\"DDcostumes.png\",\r\n\t\"DDdata.png\",\r\n\t\"DDdata2.png\",\r\n\t\"DDdata3.png\",\r\n\t\"DDdetonator.png\",\r\n\t\"DDdoor.png\",\r\n\t\"DDdoor2.png\",\r\n\t\"DDdoor3.png\",\r\n\t\"DDdye.png\",\r\n\t\"DDearring.png\",\r\n\t\"DDemblem.png\",\r\n\t\"DDenvelope.png\",\r\n\t\"DDfingerprint.png\",\r\n\t\"DDfingerprintpowder.png\",\r\n\t\"DDfish.png\",\r\n\t\"DDflower.png\",\r\n\t\"DDfood.png\",\r\n\t\"DDfood2.png\",\r\n\t\"DDgun.png\",\r\n\t\"DDhair.png\",\r\n\t\"DDhairspray.png\",\r\n\t\"DDhandprint.png\",\r\n\t\"DDhat.png\",\r\n\t\"DDheadphones.png\",\r\n\t\"DDkey.png\",\r\n\t\"DDkey2.png\",\r\n\t\"DDkey3.png\",\r\n\t\"DDkeycard.png\",\r\n\t\"DDkeycard2.png\",\r\n\t\"DDkeycard3.png\",\r\n\t\"DDkeycard4.png\",\r\n\t\"DDkeycard5.png\",\r\n\t\"DDkeycard6.png\",\r\n\t\"DDkeycard7.png\",\r\n\t\"DDknife.png\",\r\n\t\"DDladder.png\",\r\n\t\"DDladder2.png\",\r\n\t\"DDlighter.png\",\r\n\t\"DDluminol.png\",\r\n\t\"DDmagatama.png\",\r\n\t\"DDmagatama2.png\",\r\n\t\"DDmap.png\",\r\n\t\"DDmap2.png\",\r\n\t\"DDmap3.png\",\r\n\t\"DDmap4.png\",\r\n\t\"DDmap5.png\",\r\n\t\"DDmap6.png\",\r\n\t\"DDmap7.png\",\r\n\t\"DDmap8.png\",\r\n\t\"DDmap9.png\",\r\n\t\"DDmap10.png\",\r\n\t\"DDmap11.png\",\r\n\t\"DDmap12.png\",\r\n\t\"DDmask.png\",\r\n\t\"DDmedicine.png\",\r\n\t\"DDmedicine2.png\",\r\n\t\"DDmedicine3.png\",\r\n\t\"DDnote.png\",\r\n\t\"DDnote2.png\",\r\n\t\"DDnote4.png\",\r\n\t\"DDnote5.png\",\r\n\t\"DDnote6.png\",\r\n\t\"DDnote7.png\",\r\n\t\"DDnote8.png\",\r\n\t\"DDnote9.png\",\r\n\t\"DDnote10.png\",\r\n\t\"DDnote16.png\",\r\n\t\"DDpenguin.png\",\r\n\t\"DDphone.png\",\r\n\t\"DDphone2.png\",\r\n\t\"DDphoto.png\",\r\n\t\"DDphoto2.png\",\r\n\t\"DDphoto3.png\",\r\n\t\"DDphoto4.png\",\r\n\t\"DDphoto5.png\",\r\n\t\"DDphoto6.png\",\r\n\t\"DDphoto7.png\",\r\n\t\"DDphoto10.png\",\r\n\t\"DDphoto11.png\",\r\n\t\"DDphoto12.png\",\r\n\t\"DDphoto13.png\",\r\n\t\"DDphoto14.png\",\r\n\t\"DDphoto15.png\",\r\n\t\"DDplate.png\",\r\n\t\"DDposter.png\",\r\n\t\"DDposter2.png\",\r\n\t\"DDposter3.png\",\r\n\t\"DDpuppet.png\",\r\n\t\"DDrecorder.png\",\r\n\t\"DDscienceglasses.png\",\r\n\t\"DDscroll.png\",\r\n\t\"DDshard.png\",\r\n\t\"DDshard2.png\",\r\n\t\"DDshard3.png\",\r\n\t\"DDshard4.png\",\r\n\t\"DDshard5.png\",\r\n\t\"DDshard6.png\",\r\n\t\"DDshard7.png\",\r\n\t\"DDshoe.png\",\r\n\t\"DDskull.png\",\r\n\t\"DDstaff.png\",\r\n\t\"DDstatue.png\",\r\n\t\"DDstatue2.png\",\r\n\t\"DDstatue3.png\",\r\n\t\"DDstatue4.png\",\r\n\t\"DDstatue5.png\",\r\n\t\"DDstatue6.png\",\r\n\t\"DDstatue7.png\",\r\n\t\"DDstatue8.png\",\r\n\t\"DDstatue9.png\",\r\n\t\"DDsurgery.png\",\r\n\t\"DDsuspect.png\",\r\n\t\"DDsword.png\",\r\n\t\"DDsword2.png\",\r\n\t\"DDtail.png\",\r\n\t\"DDtank.png\",\r\n\t\"DDtank2.png\",\r\n\t\"DDvideo.png\",\r\n\t\"DDwhistle.png\",\r\n\t\"DDwidget.png\",\r\n\t\"DGSCastAuchi.png\",\r\n\t\"DGSCastBarok.png\",\r\n\t\"DGSCastBeppo.png\",\r\n\t\"DGSCastCrogrey.png\",\r\n\t\"DGSCastDemiglaski.png\",\r\n\t\"DGSCastFairplay.png\",\r\n\t\"DGSCastGina.png\",\r\n\t\"DGSCastGreen.png\",\r\n\t\"DGSCastGregson.png\",\r\n\t\"DGSCastHolmes.png\",\r\n\t\"DGSCastHosonaga.png\",\r\n\t\"DGSCastHosonaga2.png\",\r\n\t\"DGSCastHutch.png\",\r\n\t\"DGSCastJWatson.png\",\r\n\t\"DGSCastJezail.png\",\r\n\t\"DGSCastJoan.png\",\r\n\t\"DGSCastJohn.png\",\r\n\t\"DGSCastKazuma.png\",\r\n\t\"DGSCastLadyfirst.png\",\r\n\t\"DGSCastMegundal.png\",\r\n\t\"DGSCastMilverton.png\",\r\n\t\"DGSCastNatsume.png\",\r\n\t\"DGSCastNemmy.png\",\r\n\t\"DGSCastNikomina.png\",\r\n\t\"DGSCastPat.png\",\r\n\t\"DGSCastRola.png\",\r\n\t\"DGSCastRoylott.png\",\r\n\t\"DGSCastRyuunosuke.png\",\r\n\t\"DGSCastSanmon.png\",\r\n\t\"DGSCastStroganov.png\",\r\n\t\"DGSCastSusato.png\",\r\n\t\"DGSCastSuspect.png\",\r\n\t\"DGSCastTaizou.png\",\r\n\t\"DGSCastTully.png\",\r\n\t\"DGSCastVortex.png\",\r\n\t\"DGSCastWagahai.png\",\r\n\t\"DGSCastWatson.png\",\r\n\t\"DGSCastYuujin.png\",\r\n\t\"DGSbadge.png\",\r\n\t\"DGSbag.png\",\r\n\t\"DGSbag2.png\",\r\n\t\"DGSbell.png\",\r\n\t\"DGSbell2.png\",\r\n\t\"DGSbell3.png\",\r\n\t\"DGSbook.png\",\r\n\t\"DGSbook2.png\",\r\n\t\"DGSbook3.png\",\r\n\t\"DGSbook4.png\",\r\n\t\"DGSbook5.png\",\r\n\t\"DGSbook6.png\",\r\n\t\"DGSbook7.png\",\r\n\t\"DGSbook8.png\",\r\n\t\"DGSbook9.png\",\r\n\t\"DGSbook10.png\",\r\n\t\"DGSbullet.png\",\r\n\t\"DGScamera.png\",\r\n\t\"DGScane.png\",\r\n\t\"DGScart.png\",\r\n\t\"DGSclip.png\",\r\n\t\"DGSclip2.png\",\r\n\t\"DGSclip3.png\",\r\n\t\"DGSclip4.png\",\r\n\t\"DGScoin.png\",\r\n\t\"DGSdevice.png\",\r\n\t\"DGSflower.png\",\r\n\t\"DGSfood.png\",\r\n\t\"DGSfood2.png\",\r\n\t\"DGSfood3.png\",\r\n\t\"DGSfood4.png\",\r\n\t\"DGSgloves.png\",\r\n\t\"DGSgloves2.png\",\r\n\t\"DGSgun.png\",\r\n\t\"DGSgun2.png\",\r\n\t\"DGSgun3.png\",\r\n\t\"DGSherbaltea.png\",\r\n\t\"DGSknife.png\",\r\n\t\"DGSknife2.png\",\r\n\t\"DGSknife3.png\",\r\n\t\"DGSknife4.png\",\r\n\t\"DGSmap.png\",\r\n\t\"DGSmap2.png\",\r\n\t\"DGSmap3.png\",\r\n\t\"DGSmusicbox.png\",\r\n\t\"DGSmusicbox2.png\",\r\n\t\"DGSmusicbox3.png\",\r\n\t\"DGSmusicdisk.png\",\r\n\t\"DGSmusicdisk2.png\",\r\n\t\"DGSmusicdisk3.png\",\r\n\t\"DGSmusicdisk4.png\",\r\n\t\"DGSmusicdisk15.png\",\r\n\t\"DGSnote.png\",\r\n\t\"DGSnote2.png\",\r\n\t\"DGSnote3.png\",\r\n\t\"DGSnote4.png\",\r\n\t\"DGSnote5.png\",\r\n\t\"DGSnote6.png\",\r\n\t\"DGSnote7.png\",\r\n\t\"DGSnote8.png\",\r\n\t\"DGSnote9.png\",\r\n\t\"DGSnote10.png\",\r\n\t\"DGSnote11.png\",\r\n\t\"DGSnote12.png\",\r\n\t\"DGSnote13.png\",\r\n\t\"DGSnote14.png\",\r\n\t\"DGSnote15.png\",\r\n\t\"DGSnote16.png\",\r\n\t\"DGSnote17.png\",\r\n\t\"DGSnote18.png\",\r\n\t\"DGSnote19.png\",\r\n\t\"DGSnote\",\r\n\t\"DGSnote21.png\",\r\n\t\"DGSphoto.png\",\r\n\t\"DGSphoto2.png\",\r\n\t\"DGSphoto3.png\",\r\n\t\"DGSphoto4.png\",\r\n\t\"DGSphoto5.png\",\r\n\t\"DGSphoto6.png\",\r\n\t\"DGSphoto7.png\",\r\n\t\"DGSphoto8.png\",\r\n\t\"DGSphoto9.png\",\r\n\t\"DGSphoto10.png\",\r\n\t\"DGSphoto11.png\",\r\n\t\"DGSphoto12.png\",\r\n\t\"DGSphoto13.png\",\r\n\t\"DGSphoto14.png\",\r\n\t\"DGSphoto15.png\",\r\n\t\"DGSphoto16.png\",\r\n\t\"DGSphoto17.png\",\r\n\t\"DGSphoto18.png\",\r\n\t\"DGSphoto19.png\",\r\n\t\"DGSpin.png\",\r\n\t\"DGSpin2.png\",\r\n\t\"DGSpipe.png\",\r\n\t\"DGSpressing.png\",\r\n\t\"DGSsciencekit.png\",\r\n\t\"DGSshard.png\",\r\n\t\"DGSstereoscope.png\",\r\n\t\"DGSstereoscope2.png\",\r\n\t\"DGStiara.png\",\r\n\t\"DGSviola.png\",\r\n\t\"DGSviola2.png\",\r\n\t\"DGSwhip.png\",\r\n\t\"Datapad.png\",\r\n\t\"Interface.png\",\r\n\t\"JFACastAcro.png\",\r\n\t\"JFACastAdrian.png\",\r\n\t\"JFACastAmi.png\",\r\n\t\"JFACastBat.png\",\r\n\t\"JFACastBen.png\",\r\n\t\"JFACastCeleste.png\",\r\n\t\"JFACastDeKiller.png\",\r\n\t\"JFACastDustin.png\",\r\n\t\"JFACastFranziska.png\",\r\n\t\"JFACastGalactica.png\",\r\n\t\"JFACastGrey.png\",\r\n\t\"JFACastHotti.png\",\r\n\t\"JFACastIni.png\",\r\n\t\"JFACastJuan.png\",\r\n\t\"JFACastMaggey.png\",\r\n\t\"JFACastMatt.png\",\r\n\t\"JFACastMimi.png\",\r\n\t\"JFACastMoe.png\",\r\n\t\"JFACastMorgan.png\",\r\n\t\"JFACastPearl.png\",\r\n\t\"JFACastRegina.png\",\r\n\t\"JFACastRussel.png\",\r\n\t\"JFACastShelly.png\",\r\n\t\"JFACastWellington.png\",\r\n\t\"JFATHATCARD.png\",\r\n\t\"JFATHATCARD2.png\",\r\n\t\"JFAautograph.png\",\r\n\t\"JFAautograph2.png\",\r\n\t\"JFAball.png\",\r\n\t\"JFAball2.png\",\r\n\t\"JFAbear.png\",\r\n\t\"JFAbear2.png\",\r\n\t\"JFAbear3.png\",\r\n\t\"JFAbottle.png\",\r\n\t\"JFAbox.png\",\r\n\t\"JFAbox2.png\",\r\n\t\"JFAbusinesscard.png\",\r\n\t\"JFAbusinesscard2.png\",\r\n\t\"JFAbutton.png\",\r\n\t\"JFAbutton2.png\",\r\n\t\"JFAbutton3.png\",\r\n\t\"JFAcamera.png\",\r\n\t\"JFAcard.png\",\r\n\t\"JFAcard2.png\",\r\n\t\"JFAclip.png\",\r\n\t\"JFAclip2.png\",\r\n\t\"JFAclip3.png\",\r\n\t\"JFAclip4.png\",\r\n\t\"JFAcoat.png\",\r\n\t\"JFAfrequencydetector.png\",\r\n\t\"JFAglasses.png\",\r\n\t\"JFAglove.png\",\r\n\t\"JFAgrapes.png\",\r\n\t\"JFAguitar.png\",\r\n\t\"JFAgun.png\",\r\n\t\"JFAgun2.png\",\r\n\t\"JFAhammond.png\",\r\n\t\"JFAhat.png\",\r\n\t\"JFAjuice.png\",\r\n\t\"JFAkey.png\",\r\n\t\"JFAknife.png\",\r\n\t\"JFAknife2.png\",\r\n\t\"JFAleon.png\",\r\n\t\"JFAmilk.png\",\r\n\t\"JFAmilk2.png\",\r\n\t\"JFAmoney.png\",\r\n\t\"JFAnote.png\",\r\n\t\"JFAnote2.png\",\r\n\t\"JFApepper.png\",\r\n\t\"JFAphoto.png\",\r\n\t\"JFAposter.png\",\r\n\t\"JFAreceipt.png\",\r\n\t\"JFAregent.png\",\r\n\t\"JFAring.png\",\r\n\t\"JFArobe.png\",\r\n\t\"JFArobescrap.png\",\r\n\t\"JFAscarf.png\",\r\n\t\"JFAscreen.png\",\r\n\t\"JFAshoe.png\",\r\n\t\"JFAspycamera.png\",\r\n\t\"JFAticket.png\",\r\n\t\"JFAticket2.png\",\r\n\t\"JFAtracker.png\",\r\n\t\"JFAtransceiver.png\",\r\n\t\"JFAtransmitter.png\",\r\n\t\"JFAtrilo.png\",\r\n\t\"JFAuniform.png\",\r\n\t\"JFAurn1.png\",\r\n\t\"JFAurn2.png\",\r\n\t\"JFAvest.png\",\r\n\t\"JFAwhip.png\",\r\n\t\"MiscAKMS.png\",\r\n\t\"MiscAsthmaPump.png\",\r\n\t\"MiscBaggie.png\",\r\n\t\"MiscBeach.png\",\r\n\t\"MiscBlueRuby.png\",\r\n\t\"MiscCandy Cane.png\",\r\n\t\"MiscCandy Cane Dark.png\",\r\n\t\"MiscCorkscrew.png\",\r\n\t\"MiscCrowbar.png\",\r\n\t\"MiscDragonPepper.png\",\r\n\t\"MiscFlintlock.png\",\r\n\t\"MiscGenerator.png\",\r\n\t\"MiscGrapeJuice.png\",\r\n\t\"MiscGreen Hut.png\",\r\n\t\"MiscGrill.png\",\r\n\t\"MiscHalf-Eaten Burger.png\",\r\n\t\"MiscHangGlider.png\",\r\n\t\"MiscLockpicks.png\",\r\n\t\"MiscMapBiolab.png\",\r\n\t\"MiscMapCourthouse.png\",\r\n\t\"MiscMapLobby1.png\",\r\n\t\"MiscMichigan J Frog.png\",\r\n\t\"MiscMystery1.png\",\r\n\t\"MiscMystery2.png\",\r\n\t\"MiscMystery3.png\",\r\n\t\"MiscOldTrain.png\",\r\n\t\"MiscRaffleTickets.png\",\r\n\t\"MiscSpatula.png\",\r\n\t\"MiscSpecimenAlpha.png\",\r\n\t\"MiscTimeCrystal.png\",\r\n\t\"MiscTins.png\",\r\n\t\"MiscUnknown People.png\",\r\n\t\"MiscVDF.png\",\r\n\t\"MiscVodka.png\",\r\n\t\"MiscZombie.png\",\r\n\t\"Scanner.png\",\r\n\t\"SoJad.png\",\r\n\t\"SoJad2.png\",\r\n\t\"SoJad3.png\",\r\n\t\"SoJad4.png\",\r\n\t\"SoJad5.png\",\r\n\t\"SoJad6.png\",\r\n\t\"SoJad7.png\",\r\n\t\"SoJarrow.png\",\r\n\t\"SoJautopsy.png\",\r\n\t\"SoJbadge.png\",\r\n\t\"SoJbadge2.png\",\r\n\t\"SoJblimp.png\",\r\n\t\"SoJblimp2.png\",\r\n\t\"SoJblood.png\",\r\n\t\"SoJboiler.png\",\r\n\t\"SoJbook.png\",\r\n\t\"SoJbook2.png\",\r\n\t\"SoJbook3.png\",\r\n\t\"SoJbook4.png\",\r\n\t\"SoJbook5.png\",\r\n\t\"SoJbook6.png\",\r\n\t\"SoJbook7.png\",\r\n\t\"SoJbook8.png\",\r\n\t\"SoJbook9.png\",\r\n\t\"SoJbook10.png\",\r\n\t\"SoJbook11.png\",\r\n\t\"SoJbook12.png\",\r\n\t\"SoJbook13.png\",\r\n\t\"SoJbook14.png\",\r\n\t\"SoJbox.png\",\r\n\t\"SoJbox2.png\",\r\n\t\"SoJbracelet.png\",\r\n\t\"SoJbucket.png\",\r\n\t\"SoJcamera.png\",\r\n\t\"SoJcandelabra.png\",\r\n\t\"SoJcandelabra2.png\",\r\n\t\"SoJcandelabra3.png\",\r\n\t\"SoJcastAhlbi.png\",\r\n\t\"SoJcastAmara.png\",\r\n\t\"SoJcastAndistan'dhin.png\",\r\n\t\"SoJcastApollo.png\",\r\n\t\"SoJcastArchie.png\",\r\n\t\"SoJcastArmie.png\",\r\n\t\"SoJcastAthena.png\",\r\n\t\"SoJcastAtishon.png\",\r\n\t\"SoJcastBeh'leeb.png\",\r\n\t\"SoJcastBetty.png\",\r\n\t\"SoJcastBlackquill.png\",\r\n\t\"SoJcastBonny.png\",\r\n\t\"SoJcastBucky.png\",\r\n\t\"SoJcastButz.png\",\r\n\t\"SoJcastDatz.png\",\r\n\t\"SoJcastDatz2.png\",\r\n\t\"SoJcastDhurke.png\",\r\n\t\"SoJcastDumas.png\",\r\n\t\"SoJcastEllen.png\",\r\n\t\"SoJcastEma.png\",\r\n\t\"SoJcastGa'ran.png\",\r\n\t\"SoJcastGeiru.png\",\r\n\t\"SoJcastInga.png\",\r\n\t\"SoJcastMaya.png\",\r\n\t\"SoJcastMiles.png\",\r\n\t\"SoJcastNahyuta.png\",\r\n\t\"SoJcastNayna.png\",\r\n\t\"SoJcastPayne.png\",\r\n\t\"SoJcastPearl.png\",\r\n\t\"SoJcastPhoenix.png\",\r\n\t\"SoJcastPierce.png\",\r\n\t\"SoJcastPuhray.png\",\r\n\t\"SoJcastRayfa.png\",\r\n\t\"SoJcastRetinz.png\",\r\n\t\"SoJcastReus.png\",\r\n\t\"SoJcastRohl.png\",\r\n\t\"SoJcastSelena.png\",\r\n\t\"SoJcastSergeant.png\",\r\n\t\"SoJcastSorin.png\",\r\n\t\"SoJcastTahrust.png\",\r\n\t\"SoJcastTaifu.png\",\r\n\t\"SoJcastTrucy.png\",\r\n\t\"SoJcastUendo.png\",\r\n\t\"SoJcd.png\",\r\n\t\"SoJcd2.png\",\r\n\t\"SoJcharm.png\",\r\n\t\"SoJclip.png\",\r\n\t\"SoJclip2.png\",\r\n\t\"SoJcog.png\",\r\n\t\"SoJcontract.png\",\r\n\t\"SoJdog.png\",\r\n\t\"SoJflag.png\",\r\n\t\"SoJflower.png\",\r\n\t\"SoJfood1.png\",\r\n\t\"SoJfood2.png\",\r\n\t\"SoJfood3.png\",\r\n\t\"SoJgem.png\",\r\n\t\"SoJglasses.png\",\r\n\t\"SoJgoop.png\",\r\n\t\"SoJhat.png\",\r\n\t\"SoJhelicopter.png\",\r\n\t\"SoJhorse.png\",\r\n\t\"SoJhorse2.png\",\r\n\t\"SoJkey.png\",\r\n\t\"SoJkey2.png\",\r\n\t\"SoJkey3.png\",\r\n\t\"SoJkey4.png\",\r\n\t\"SoJkeycard.png\",\r\n\t\"SoJkeycharm.png\",\r\n\t\"SoJlantern.png\",\r\n\t\"SoJlantern2.png\",\r\n\t\"SoJluminol.png\",\r\n\t\"SoJmagatama.png\",\r\n\t\"SoJmagatama2.png\",\r\n\t\"SoJmagatama3.png\",\r\n\t\"SoJmap.png\",\r\n\t\"SoJmap2.png\",\r\n\t\"SoJmap3.png\",\r\n\t\"SoJmap4.png\",\r\n\t\"SoJmap5.png\",\r\n\t\"SoJmap6.png\",\r\n\t\"SoJmap7.png\",\r\n\t\"SoJmrhat.png\",\r\n\t\"SoJnote.png\",\r\n\t\"SoJnote2.png\",\r\n\t\"SoJnote3.png\",\r\n\t\"SoJnote4.png\",\r\n\t\"SoJnote5.png\",\r\n\t\"SoJnote6.png\",\r\n\t\"SoJnote7.png\",\r\n\t\"SoJnote8.png\",\r\n\t\"SoJnote9.png\",\r\n\t\"SoJnote10.png\",\r\n\t\"SoJnote11.png\",\r\n\t\"SoJnote12.png\",\r\n\t\"SoJnote13.png\",\r\n\t\"SoJnote14.png\",\r\n\t\"SoJnote15.png\",\r\n\t\"SoJnote16.png\",\r\n\t\"SoJnote17.png\",\r\n\t\"SoJorb.png\",\r\n\t\"SoJpassport.png\",\r\n\t\"SoJpendant.png\",\r\n\t\"SoJphone.png\",\r\n\t\"SoJphoto.png\",\r\n\t\"SoJphoto2.png\",\r\n\t\"SoJphoto3.png\",\r\n\t\"SoJphoto4.png\",\r\n\t\"SoJphoto5.png\",\r\n\t\"SoJphoto6.png\",\r\n\t\"SoJphoto7.png\",\r\n\t\"SoJphoto8.png\",\r\n\t\"SoJphoto9.png\",\r\n\t\"SoJphoto10.png\",\r\n\t\"SoJphoto11.png\",\r\n\t\"SoJphoto12.png\",\r\n\t\"SoJphoto13.png\",\r\n\t\"SoJphoto14.png\",\r\n\t\"SoJphoto15.png\",\r\n\t\"SoJphoto16.png\",\r\n\t\"SoJphoto17.png\",\r\n\t\"SoJphoto18.png\",\r\n\t\"SoJphoto19.png\",\r\n\t\"SoJphoto\",\r\n\t\"SoJphoto21.png\",\r\n\t\"SoJphoto22.png\",\r\n\t\"SoJphoto23.png\",\r\n\t\"SoJphoto24.png\",\r\n\t\"SoJphoto25.png\",\r\n\t\"SoJphoto26.png\",\r\n\t\"SoJphoto27.png\",\r\n\t\"SoJphoto28.png\",\r\n\t\"SoJprintpowder.png\",\r\n\t\"SoJraincoat.png\",\r\n\t\"SoJscissorlift.png\",\r\n\t\"SoJscroll.png\",\r\n\t\"SoJscroll2.png\",\r\n\t\"SoJsnackoo.png\",\r\n\t\"SoJstand.png\",\r\n\t\"SoJstatue.png\",\r\n\t\"SoJsuspect.png\",\r\n\t\"SoJsword.png\",\r\n\t\"SoJsword2.png\",\r\n\t\"SoJsyringe.png\",\r\n\t\"SoJtape1.png\",\r\n\t\"SoJtext.png\",\r\n\t\"SoJunknown.png\",\r\n\t\"SoJurn.png\",\r\n\t\"SoJusb.png\",\r\n\t\"SoJwallet.png\",\r\n\t\"SoJwidget.png\",\r\n\t\"TTCastAdrian.png\",\r\n\t\"TTCastArmstrong.png\",\r\n\t\"TTCastAtmey.png\",\r\n\t\"TTCastBikini.png\",\r\n\t\"TTCastBruto.png\",\r\n\t\"TTCastBullard.png\",\r\n\t\"TTCastDahlia.png\",\r\n\t\"TTCastDeMasque.png\",\r\n\t\"TTCastDesiree.png\",\r\n\t\"TTCastDiego.png\",\r\n\t\"TTCastElg.png\",\r\n\t\"TTCastElise.png\",\r\n\t\"TTCastFawles.png\",\r\n\t\"TTCastGodot.png\",\r\n\t\"TTCastGrossberg.png\",\r\n\t\"TTCastGumshoe.png\",\r\n\t\"TTCastIris.png\",\r\n\t\"TTCastIris2.png\",\r\n\t\"TTCastKudo.png\",\r\n\t\"TTCastLisa.png\",\r\n\t\"TTCastMaggey.png\",\r\n\t\"TTCastMiles.png\",\r\n\t\"TTCastRon.png\",\r\n\t\"TTCastSwallow.png\",\r\n\t\"TTCastTigre.png\",\r\n\t\"TTCastValerie.png\",\r\n\t\"TTCastViola.png\",\r\n\t\"TTad.png\",\r\n\t\"TTad2.png\",\r\n\t\"TTapron.png\",\r\n\t\"TTbadge.png\",\r\n\t\"TTbag.png\",\r\n\t\"TTblood1.png\",\r\n\t\"TTblood2.png\",\r\n\t\"TTbottle1.png\",\r\n\t\"TTbottle2.png\",\r\n\t\"TTbox.png\",\r\n\t\"TTbox2.png\",\r\n\t\"TTbutton.png\",\r\n\t\"TTcalendar.png\",\r\n\t\"TTcamera.png\",\r\n\t\"TTcard.png\",\r\n\t\"TTcd.png\",\r\n\t\"TTcd2.png\",\r\n\t\"TTclip.png\",\r\n\t\"TTclip2.png\",\r\n\t\"TTclip3.png\",\r\n\t\"TTclip4.png\",\r\n\t\"TTclip5.png\",\r\n\t\"TTcoldkiller.png\",\r\n\t\"TTcoldkiller2.png\",\r\n\t\"TTcup.png\",\r\n\t\"TTdata.png\",\r\n\t\"TTdata2.png\",\r\n\t\"TTdata3.png\",\r\n\t\"TTdata4.png\",\r\n\t\"TTdrawing.png\",\r\n\t\"TTemblem.png\",\r\n\t\"TTemployee.png\",\r\n\t\"TTfood1.png\",\r\n\t\"TTfood2.png\",\r\n\t\"TThood.png\",\r\n\t\"TTjewel.png\",\r\n\t\"TTjewel2.png\",\r\n\t\"TTkeycard.png\",\r\n\t\"TTknife.png\",\r\n\t\"TTlantern.png\",\r\n\t\"TTlantern2.png\",\r\n\t\"TTmagazine.png\",\r\n\t\"TTmagazine2.png\",\r\n\t\"TTmatchbook.png\",\r\n\t\"TTmatchbook2.png\",\r\n\t\"TTmedicine.png\",\r\n\t\"TTmedicine2.png\",\r\n\t\"TTmoped.png\",\r\n\t\"TTnecklace.png\",\r\n\t\"TTnote.png\",\r\n\t\"TTnote2.png\",\r\n\t\"TTnote3.png\",\r\n\t\"TTnote4.png\",\r\n\t\"TTnote5.png\",\r\n\t\"TTnote6.png\",\r\n\t\"TTnote7.png\",\r\n\t\"TTperfume.png\",\r\n\t\"TTphotoold.png\",\r\n\t\"TTsapphire.png\",\r\n\t\"TTscarf.png\",\r\n\t\"TTschichishito.png\",\r\n\t\"TTschichishito2.png\",\r\n\t\"TTschichishito3.png\",\r\n\t\"TTscroll.png\",\r\n\t\"TTscroll2.png\",\r\n\t\"TTseal.png\",\r\n\t\"TTseal2.png\",\r\n\t\"TTstaff.png\",\r\n\t\"TTstaff2.png\",\r\n\t\"TTstaff3.png\",\r\n\t\"TTstain.png\",\r\n\t\"TTstatue.png\",\r\n\t\"TTticket.png\",\r\n\t\"TTticket2.png\",\r\n\t\"TTumbrella.png\",\r\n\t\"TTvase.png\",\r\n\t\"TTvase2.png\",\r\n\t\"TTvase3.png\",\r\n\t\"TTvase4.png\",\r\n\t\"TTwallet.png\",\r\n\t\"TTwatch.png\",\r\n\t\"Vivaster.png\",\r\n\t\"empty.png\",\r\n\t\"lawyerbadge.png\"\r\n];","export default [\r\n\t\"1st server\",\r\n\t\"999.1\",\r\n\t\"999\",\r\n\t\"999Apartment\",\r\n\t\"999CaptainsQuarters\",\r\n\t\"999Cargo\",\r\n\t\"999Casino\",\r\n\t\"999Cdeck\",\r\n\t\"999CentralStairs\",\r\n\t\"999Chapel\",\r\n\t\"999Chart\",\r\n\t\"999Confinement\",\r\n\t\"999DoorsA\",\r\n\t\"999DoorsB\",\r\n\t\"999Hospital\",\r\n\t\"999Kitchen\",\r\n\t\"999Library\",\r\n\t\"999Operating\",\r\n\t\"999Shower\",\r\n\t\"999Steam\",\r\n\t\"999Steeldoor\",\r\n\t\"999Study\",\r\n\t\"999Torture\",\r\n\t\"9991stClassCabinA\",\r\n\t\"9991stClassCabinB\",\r\n\t\"9992ndClassCabin\",\r\n\t\"AA - Edgewort's Office\",\r\n\t\"AA - Gantsroom\",\r\n\t\"AA - Gatewater room\",\r\n\t\"AA - Gourd Lake\",\r\n\t\"AA - Gourd Lake Entrance\",\r\n\t\"AA - Hotel Lobby\",\r\n\t\"AA - Hotticlinic\",\r\n\t\"AA - Kurain\",\r\n\t\"AA - Parkinglot\",\r\n\t\"AA - Police Deparment\",\r\n\t\"AA - Police Station\",\r\n\t\"AA - Records Room\",\r\n\t\"AA - Sc13\",\r\n\t\"AA - Wright's Office\",\r\n\t\"AABluecorp\",\r\n\t\"AACourt\",\r\n\t\"AACourtAnime\",\r\n\t\"AACourtChristmasDecorations\",\r\n\t\"AACourtChristmasLights\",\r\n\t\"AACourtHD\",\r\n\t\"AADefendantLobby\",\r\n\t\"AADefendantLobbyHD\",\r\n\t\"AADetentionCenter\",\r\n\t\"AAEdgeworthOffice\",\r\n\t\"AAGantOffice\",\r\n\t\"AAGatewaterHotel\",\r\n\t\"AAGlobalStudiosEast\",\r\n\t\"AAGlobalStudiosWest\",\r\n\t\"AAGourdLake\",\r\n\t\"AAGrossbergOffice\",\r\n\t\"AAI2Circus\",\r\n\t\"AAI2City\",\r\n\t\"AAI2GourdLake\",\r\n\t\"AAI2LogicChess\",\r\n\t\"AAI2MuseumPast\",\r\n\t\"AAI2MuseumPresent\",\r\n\t\"AAI2PIC\",\r\n\t\"AAI2Prison\",\r\n\t\"AAICohdopianEmbassy\",\r\n\t\"AAICourt\",\r\n\t\"AAICourtFlipped\",\r\n\t\"AAIEdgeworthOffice\",\r\n\t\"AAIGatewaterLandStage\",\r\n\t\"AAIGatewaterLandWildWest\",\r\n\t\"AAIiFlyAirlines\",\r\n\t\"AALobby\",\r\n\t\"AAParkingLot\",\r\n\t\"AAPoliceStation\",\r\n\t\"AATrainStation\",\r\n\t\"AAWrightOffice\",\r\n\t\"AJBorschtBowlClub\",\r\n\t\"AJCourt\",\r\n\t\"AJCourtBirthday\",\r\n\t\"AJCourtHalloween\",\r\n\t\"AJCourtNight\",\r\n\t\"AJCourtTV\",\r\n\t\"AJDefendantLobby\",\r\n\t\"AJDetentionCenter\",\r\n\t\"AJDrewStudio\",\r\n\t\"AJHottiClinic\",\r\n\t\"AJKlavierOffice\",\r\n\t\"AJKristophCell\",\r\n\t\"AJLobby\",\r\n\t\"AJMeraktisClinic\",\r\n\t\"AJPeoplePark\",\r\n\t\"AJSunshineColiseum\",\r\n\t\"AJWrightOffice\",\r\n\t\"Ace\",\r\n\t\"AcroRoomJFA\",\r\n\t\"AirportJFA\",\r\n\t\"AlbaOfficeAAI\",\r\n\t\"Anime\",\r\n\t\"Arcade\",\r\n\t\"AtmeyOfficeTT\",\r\n\t\"Atrium (SG)\",\r\n\t\"AutumnForest\",\r\n\t\"BB - Flowerfield\",\r\n\t\"BB - Market\",\r\n\t\"BB - Street\",\r\n\t\"BandoLandAAI\",\r\n\t\"Basement\",\r\n\t\"Battlegrounds\",\r\n\t\"BerryBigCircusJFA\",\r\n\t\"Blackout\",\r\n\t\"BlueScreensTT\",\r\n\t\"BluecorpAA\",\r\n\t\"BridgeNest\",\r\n\t\"Brig\",\r\n\t\"Building\",\r\n\t\"CC1\",\r\n\t\"CC2\",\r\n\t\"CC3\",\r\n\t\"CC4\",\r\n\t\"CC5\",\r\n\t\"CC6\",\r\n\t\"CC7\",\r\n\t\"CC8\",\r\n\t\"CC9\",\r\n\t\"CC10\",\r\n\t\"CC11\",\r\n\t\"CC12\",\r\n\t\"CO - Big door\",\r\n\t\"CO - Finalroom\",\r\n\t\"CO - Meetingroom\",\r\n\t\"CO - Whitedoor\",\r\n\t\"CO - Whitelobby\",\r\n\t\"CO - Whitelowerfloor\",\r\n\t\"CO - White room\",\r\n\t\"CP\",\r\n\t\"CPRP2 Chap1\",\r\n\t\"CPRP2 Chap2and3\",\r\n\t\"CPRP2 Chap4\",\r\n\t\"CPRP2 Chap5\",\r\n\t\"CPRP Chap1\",\r\n\t\"CPRP Chap2\",\r\n\t\"CPRP Chap3\",\r\n\t\"CPRP Chap4\",\r\n\t\"CPRP Chap5\",\r\n\t\"CVStMystere\",\r\n\t\"Cafe\",\r\n\t\"CafeCourt\",\r\n\t\"CaffeeCase\",\r\n\t\"Cal\",\r\n\t\"CargoHoldAAI\",\r\n\t\"Casino\",\r\n\t\"CasinoCourt\",\r\n\t\"Cathedral (SG)\",\r\n\t\"Christmas\",\r\n\t\"Christmas Courtroom\",\r\n\t\"CinemaFamousi\",\r\n\t\"Classroom\",\r\n\t\"Co - Lobby 1\",\r\n\t\"Co - Lobby 2\",\r\n\t\"CochenOfficeAAI\",\r\n\t\"ColosseumFerox\",\r\n\t\"Control Room\",\r\n\t\"Control Room Interior\",\r\n\t\"CountyCourt\",\r\n\t\"CourtroomAA\",\r\n\t\"CourtroomAAHD\",\r\n\t\"CourtroomAAI\",\r\n\t\"CourtroomAJ\",\r\n\t\"CourtroomAJNight\",\r\n\t\"CourtroomAnime\",\r\n\t\"CourtroomCounty\",\r\n\t\"CourtroomDD\",\r\n\t\"CourtroomEnglish\",\r\n\t\"CourtroomNew\",\r\n\t\"CourtroomRuined\",\r\n\t\"CourtroomThemis\",\r\n\t\"CourtroomTouhou\",\r\n\t\"CourtroomWitch\",\r\n\t\"CruiseCourt\",\r\n\t\"CustomEight\",\r\n\t\"CustomEleven\",\r\n\t\"CustomFifteen\",\r\n\t\"CustomFive\",\r\n\t\"CustomFour\",\r\n\t\"CustomFourteen\",\r\n\t\"CustomNine\",\r\n\t\"CustomOne\",\r\n\t\"CustomSeven\",\r\n\t\"CustomSix\",\r\n\t\"CustomTen\",\r\n\t\"CustomThirteen\",\r\n\t\"CustomThree\",\r\n\t\"CustomTwelve\",\r\n\t\"CustomTwo\",\r\n\t\"DC\",\r\n\t\"DDCourt\",\r\n\t\"DDCourtGray\",\r\n\t\"DDCourtRuined\",\r\n\t\"DDCourtRuinedInvestigation\",\r\n\t\"DDCourtThemis\",\r\n\t\"DDDefendantLobby\",\r\n\t\"DDGyaxa\",\r\n\t\"DDLobby\",\r\n\t\"DDNinetailsVale\",\r\n\t\"DDShipshapeAquarium\",\r\n\t\"DDThemisAcademy\",\r\n\t\"DFreightTrain\",\r\n\t\"DGS-ENG\",\r\n\t\"DGS-JAP\",\r\n\t\"DGS\",\r\n\t\"DGSCourtJapanese\",\r\n\t\"DGSCourtOldBailey\",\r\n\t\"DGSCourtOldBaileyJury\",\r\n\t\"DGSDefendantLobbyJapanese\",\r\n\t\"DGSDefendantLobbyOldBailey\",\r\n\t\"DGSEnglishCourt\",\r\n\t\"DGSJapanCourt\",\r\n\t\"DGSLondon\",\r\n\t\"DGSenglishcourt\",\r\n\t\"DRAE-Area1\",\r\n\t\"DRAE-Area2\",\r\n\t\"DRClassTrial\",\r\n\t\"DRRP\",\r\n\t\"Dark Cave\",\r\n\t\"Darkness\",\r\n\t\"Datrone Heart\",\r\n\t\"Datrone HeartHQ\",\r\n\t\"DeLiteHouseTT\",\r\n\t\"Despair vs. Hope\",\r\n\t\"DetentionCenterAAI2\",\r\n\t\"DimensionalGate\",\r\n\t\"DogenCellAAI2\",\r\n\t\"DualDestinies\",\r\n\t\"Dungeon Courtroom\",\r\n\t\"EdgeworthOfficeAA\",\r\n\t\"EdgeworthOfficeAAI\",\r\n\t\"EmbassyAAI\",\r\n\t\"Endless Courtroom\",\r\n\t\"EngardeManorJFA\",\r\n\t\"EnglishCourt\",\r\n\t\"Errors\",\r\n\t\"Errors2\",\r\n\t\"FECastle\",\r\n\t\"FECave\",\r\n\t\"FEFort\",\r\n\t\"FEPlain\",\r\n\t\"FETavern\",\r\n\t\"Factory\",\r\n\t\"FieldFortune\",\r\n\t\"FilmSetAAI2\",\r\n\t\"Flowerfield\",\r\n\t\"ForensicCourt\",\r\n\t\"Forest\",\r\n\t\"GS4Night\",\r\n\t\"GantOfficeAA\",\r\n\t\"GetwaterHotelJFA\",\r\n\t\"GetwaterStageJFA\",\r\n\t\"GlobalStudiosIndoorsAA\",\r\n\t\"GlobalStudiosOutdoorsAA\",\r\n\t\"GourdLakeAA\",\r\n\t\"GrandChokmah\",\r\n\t\"GrandStadium\",\r\n\t\"Graveyard\",\r\n\t\"GreatWitchtrialCourt\",\r\n\t\"GrossbergOfficeAA\",\r\n\t\"HD\",\r\n\t\"HQFarm\",\r\n\t\"HQHalloweenTown\",\r\n\t\"HQHolodeck\",\r\n\t\"HQShrine\",\r\n\t\"HQTown\",\r\n\t\"HQVolcanoCherry\",\r\n\t\"HallOfFame\",\r\n\t\"HarborTown\",\r\n\t\"HarvestFestival\",\r\n\t\"HazakuraTemple1TT\",\r\n\t\"HazakuraTemple2TT\",\r\n\t\"Headquarters\",\r\n\t\"Headquarters 2\",\r\n\t\"Hell Correspondence\",\r\n\t\"Hospital\",\r\n\t\"HotelRoomAA\",\r\n\t\"HottiClinicJFA\",\r\n\t\"Innsmouth\",\r\n\t\"InsidePlaneAAI2\",\r\n\t\"Interiors (Day)\",\r\n\t\"Interiors (Night)\",\r\n\t\"JFAAirport\",\r\n\t\"JFABerryBigCircusEast\",\r\n\t\"JFABerryBigCircusWest\",\r\n\t\"JFAGatewaterHotel\",\r\n\t\"JFAHottiClinic\",\r\n\t\"JFAKurainVillage\",\r\n\t\"JFAMattHouse\",\r\n\t\"JapaneseCourt\",\r\n\t\"Kamurocho (Day)\",\r\n\t\"Kamurocho (Night)\",\r\n\t\"Keterburg\",\r\n\t\"Khura'in\",\r\n\t\"Khurain\",\r\n\t\"KokonoeLab\",\r\n\t\"KurainCourt\",\r\n\t\"KurainVillageJFA\",\r\n\t\"LBCastle\",\r\n\t\"LBMisc\",\r\n\t\"LBScotlandYard\",\r\n\t\"Lab 8\",\r\n\t\"Lentomain\",\r\n\t\"Library\",\r\n\t\"LogicChessAAI2\",\r\n\t\"MI - Ashleys Shack\",\r\n\t\"MLP - Apple barn\",\r\n\t\"MLP - CMC Clubhouse\",\r\n\t\"MLP - CMC Clubhouse inside\",\r\n\t\"MLP - Canterlot Castle galaroom\",\r\n\t\"MLP - Canterlot Hallway\",\r\n\t\"MLP - Canterlot Library2\",\r\n\t\"MLP - Canterlot Town\",\r\n\t\"MLP - Canterlot alley\",\r\n\t\"MLP - Canterlot library\",\r\n\t\"MLP - Carousel Boutique\",\r\n\t\"MLP - Clearing\",\r\n\t\"MLP - Curio Shop\",\r\n\t\"MLP - Everfree Forest\",\r\n\t\"MLP - Everfree Forest entrance\",\r\n\t\"MLP - Fluttershy's cottage\",\r\n\t\"MLP - Hospital Room\",\r\n\t\"MLP - Hotelroom\",\r\n\t\"MLP - Library 2F\",\r\n\t\"MLP - Library mainfloor\",\r\n\t\"MLP - Old Castle\",\r\n\t\"MLP - Orchard\",\r\n\t\"MLP - PV Hospital\",\r\n\t\"MLP - PV Street\",\r\n\t\"MLP - Ponyville\",\r\n\t\"MLP - Shining's apartment\",\r\n\t\"MLP - Sugarcube Corner\",\r\n\t\"MLP - Twilight's Lab\",\r\n\t\"MM - Castle\",\r\n\t\"MM - Madokas house\",\r\n\t\"MM - School yard\",\r\n\t\"MM - Street\",\r\n\t\"MM - Street2\",\r\n\t\"MM - classroom\",\r\n\t\"MM - dark hallway\",\r\n\t\"MM - rooftop\",\r\n\t\"MM - room whit Kyubey\",\r\n\t\"MM - school hallway\",\r\n\t\"MM - staircase\",\r\n\t\"MMA-Bedrooms1\",\r\n\t\"MMA-Floor 1\",\r\n\t\"MS - Cathedral\",\r\n\t\"MS - Zakum's Tree\",\r\n\t\"Mansion\",\r\n\t\"MansionAAI2\",\r\n\t\"MansionHQ\",\r\n\t\"Maplecrest - Nightmare\",\r\n\t\"Maplecrest\",\r\n\t\"Market\",\r\n\t\"Mayonaka\",\r\n\t\"MechHangar\",\r\n\t\"Medici Tower\",\r\n\t\"Military Base Exterior\",\r\n\t\"MoeRoomJFA\",\r\n\t\"MuseumAAI2\",\r\n\t\"MuseumTT\",\r\n\t\"Music\",\r\n\t\"NewCourt\",\r\n\t\"New Meridian\",\r\n\t\"Ninetailsvale\",\r\n\t\"Nordon Plains\",\r\n\t\"Nordon Plains Night\",\r\n\t\"OCArcade\",\r\n\t\"OCBebop\",\r\n\t\"OCCourtCafe\",\r\n\t\"OCCourtCounty\",\r\n\t\"OCCourtCruise\",\r\n\t\"OCCourtEndless\",\r\n\t\"OCCourtFinalDestination\",\r\n\t\"OCCourtInverted\",\r\n\t\"OCCourtPirateShip\",\r\n\t\"OCCourtSky\",\r\n\t\"OCCourtSpace\",\r\n\t\"OCCourtSpaceShip\",\r\n\t\"OCCourtTouhou\",\r\n\t\"OCCourtZetta\",\r\n\t\"OCDungeon\",\r\n\t\"OCHospital\",\r\n\t\"OCRoad\",\r\n\t\"OCTownPirate\",\r\n\t\"OCTownShanty\",\r\n\t\"OCWhiteRoom\",\r\n\t\"OfficeHouseHQ\",\r\n\t\"OfficeNightAA\",\r\n\t\"Osaka (Night)\",\r\n\t\"Osaka\",\r\n\t\"OutsidePlaneAAI2\",\r\n\t\"P4UBasement\",\r\n\t\"P4ULab\",\r\n\t\"P4Ubaseball\",\r\n\t\"P4Ubeach\",\r\n\t\"P4Ubuilding\",\r\n\t\"P4Uconcert\",\r\n\t\"P4Ugarden\",\r\n\t\"P4Ugraveyard\",\r\n\t\"P4Uhell\",\r\n\t\"P4Ujail\",\r\n\t\"P4Umisc\",\r\n\t\"P4Unight\",\r\n\t\"P4Uoffices\",\r\n\t\"P4Urailway\",\r\n\t\"P4Urestaurants\",\r\n\t\"P4Urooms\",\r\n\t\"P4Uruins\",\r\n\t\"P4Uschool\",\r\n\t\"P4Ustage1\",\r\n\t\"P4Ustage2\",\r\n\t\"P4Ustation\",\r\n\t\"P4Ustore\",\r\n\t\"P4Utent\",\r\n\t\"P4Utransport\",\r\n\t\"P4Utv\",\r\n\t\"P4Uvelvetroom\",\r\n\t\"PICAAI2\",\r\n\t\"PLvsAAAlchemistHouse\",\r\n\t\"PLvsAABellTower\",\r\n\t\"PLvsAACastle\",\r\n\t\"PLvsAACourtEnglish\",\r\n\t\"PLvsAACourtLabyrinthia\",\r\n\t\"PLvsAACourthouse\",\r\n\t\"PLvsAADefendantLobbyEnglish\",\r\n\t\"PLvsAADefendantLobbyLabyrinthia\",\r\n\t\"PLvsAAEclaireBakery\",\r\n\t\"PLvsAAForest\",\r\n\t\"PLvsAAGreatArchive\",\r\n\t\"PLvsAALabyrinthiaInner\",\r\n\t\"PLvsAALabyrinthiaOuter\",\r\n\t\"PLvsAALondon\",\r\n\t\"PLvsAARougeTavern\",\r\n\t\"PLvsAARuins\",\r\n\t\"PLvsAAStorytellerTower\",\r\n\t\"PLvsAAWagon\",\r\n\t\"PLvsAAWorkshop\",\r\n\t\"PMMMRP\",\r\n\t\"PMMMWitch\",\r\n\t\"ParkingLotAA\",\r\n\t\"PeonyCastle\",\r\n\t\"Persona Afternoon\",\r\n\t\"Persona DH\",\r\n\t\"Persona Morning\",\r\n\t\"Persona Night\",\r\n\t\"PersonaRP\",\r\n\t\"PhoenixOfficeAA\",\r\n\t\"PirateShip\",\r\n\t\"PlaneAAI\",\r\n\t\"PlaneLoungeAAI\",\r\n\t\"PlaneLoungeLandAAI\",\r\n\t\"PlatPark\",\r\n\t\"PlatRemnant\",\r\n\t\"PlatunaArea1\",\r\n\t\"PlatunaArea1HQ\",\r\n\t\"PlatunaArea2\",\r\n\t\"PlatunaArea2HQ\",\r\n\t\"PlatunaMain\",\r\n\t\"PlatunamainHQ\",\r\n\t\"PrecinctAA\",\r\n\t\"PrisonAAI2\",\r\n\t\"PrisonCourtyardAAI2\",\r\n\t\"RG - 104\",\r\n\t\"RG - A-East\",\r\n\t\"RG - AMX\",\r\n\t\"RG - Bus Terminal\",\r\n\t\"RG - Cadoi City\",\r\n\t\"RG - Concert\",\r\n\t\"RG - Dogenzaka\",\r\n\t\"RG - God Pad\",\r\n\t\"RG - Miyashita Underpass\",\r\n\t\"RG - Station Underpass\",\r\n\t\"RG - Trail\",\r\n\t\"RG - Udagawa\",\r\n\t\"RaysDeLite\",\r\n\t\"Retreat\",\r\n\t\"RetreatHQ\",\r\n\t\"RiverVista\",\r\n\t\"Road\",\r\n\t\"Role Play\",\r\n\t\"Ronpa Mansion Area 5\",\r\n\t\"Ronpa Mansion Day\",\r\n\t\"Ronpa Mansion Day2\",\r\n\t\"Ronpa Mansion Day3\",\r\n\t\"Ronpa Mansion Day4\",\r\n\t\"Ronpa Mansion Night\",\r\n\t\"Ronpa Mansion Night2\",\r\n\t\"Ronpa Mansion Night3\",\r\n\t\"Ronpa Mansion Night4\",\r\n\t\"Ronpa mansion Haunted\",\r\n\t\"Ronpers Express\",\r\n\t\"RooftopAAI2\",\r\n\t\"RuinedCastle\",\r\n\t\"RuinedCourt\",\r\n\t\"Ruins Entrance\",\r\n\t\"SDR2 ISLAND\",\r\n\t\"SDR2 ISLAND2\",\r\n\t\"SDR2 ISLAND2 NIGHT\",\r\n\t\"SDR2 ISLAND3\",\r\n\t\"SDR2 ISLAND NIGHT\",\r\n\t\"SI - Bedroom\",\r\n\t\"SI - Class(sunset)\",\r\n\t\"SI - Class\",\r\n\t\"SI - Council1\",\r\n\t\"SI - Council2\",\r\n\t\"SI - Council3\",\r\n\t\"SI - Gym\",\r\n\t\"SI - Gym2\",\r\n\t\"SI - Hall\",\r\n\t\"SI - Hall2\",\r\n\t\"SI - Lockers\",\r\n\t\"SI - Nurse\",\r\n\t\"SI - Office\",\r\n\t\"SI - Pink\",\r\n\t\"SI - Roof\",\r\n\t\"SI - Roof2\",\r\n\t\"SI - School\",\r\n\t\"Seance\",\r\n\t\"SecretRoomsJFA\",\r\n\t\"SecurityCompanyTT\",\r\n\t\"ShipAAI2\",\r\n\t\"SkialForest\",\r\n\t\"Sky\",\r\n\t\"SkyDeck\",\r\n\t\"SoJCourt\",\r\n\t\"SoJDefendantLobby\",\r\n\t\"Somina Castle\",\r\n\t\"Somina Castle Night\",\r\n\t\"SpaceCourt\",\r\n\t\"SpaceCourtBlue\",\r\n\t\"SpaceCourtGreen\",\r\n\t\"SpaceCourtNormal\",\r\n\t\"SpaceCourtOrange\",\r\n\t\"SpaceCourtRainbow\",\r\n\t\"SpaceCourtRed\",\r\n\t\"SpaceCourtYellow\",\r\n\t\"SpacePort\",\r\n\t\"Spaceship\",\r\n\t\"StageAAI\",\r\n\t\"StageDisassembledAAI\",\r\n\t\"SteamBar\",\r\n\t\"SteamGarden\",\r\n\t\"SteamGovt\",\r\n\t\"SteamSquare\",\r\n\t\"SteamStreet\",\r\n\t\"Street\",\r\n\t\"SummerFestival\",\r\n\t\"SummerFestivalEvening\",\r\n\t\"TARDIS\",\r\n\t\"TEOS Lab\",\r\n\t\"TTAtmeyOffice\",\r\n\t\"TTBlueScreensInc\",\r\n\t\"TTDemasqueHideout\",\r\n\t\"TTHazakuraTemple\",\r\n\t\"TTHazakuraTempleInner\",\r\n\t\"TTKBSecurity\",\r\n\t\"TTLordlyTailor\",\r\n\t\"TTTenderLender\",\r\n\t\"TTTresBien\",\r\n\t\"TenderLenderTT\",\r\n\t\"Themis\",\r\n\t\"Titania\",\r\n\t\"TitaniaValley\",\r\n\t\"Togami Mansion\",\r\n\t\"TouhouCourt\",\r\n\t\"Tower\",\r\n\t\"Town\",\r\n\t\"Town Night\",\r\n\t\"Tr0LLc0urt\",\r\n\t\"TrainstationAA\",\r\n\t\"TresBienTT\",\r\n\t\"TrollCourt\",\r\n\t\"Twotorial Village\",\r\n\t\"Twotorial Village Night\",\r\n\t\"VC 1\",\r\n\t\"VLR\",\r\n\t\"VLR2.2\",\r\n\t\"VLR2.3\",\r\n\t\"VLR2\",\r\n\t\"VLR3\",\r\n\t\"VitaminSquareTT\",\r\n\t\"WEN\",\r\n\t\"WaitingRoomAAI\",\r\n\t\"WestAAI\",\r\n\t\"WinterPalaceAAI2\",\r\n\t\"WitchTrialCourt\",\r\n\t\"WitchtrialCourtHQ\",\r\n\t\"Witchwood\",\r\n\t\"WorldEmulator\",\r\n\t\"Wreckage (SG)\",\r\n\t\"Wrightagency\",\r\n\t\"Xmas\",\r\n\t\"Zetta\",\r\n\t\"animation\",\r\n\t\"apollojustice\",\r\n\t\"background\",\r\n\t\"basement\",\r\n\t\"birthday\",\r\n\t\"blackout\",\r\n\t\"chess\",\r\n\t\"chessw1\",\r\n\t\"chessw2\",\r\n\t\"chessw3\",\r\n\t\"chessw4\",\r\n\t\"christmas\",\r\n\t\"circus\",\r\n\t\"classtrial\",\r\n\t\"cofe\",\r\n\t\"courthouseofgods\",\r\n\t\"cruise\",\r\n\t\"cruise court\",\r\n\t\"custom\",\r\n\t\"custom1\",\r\n\t\"custom2\",\r\n\t\"custom3\",\r\n\t\"custom4\",\r\n\t\"custom5\",\r\n\t\"custom6\",\r\n\t\"custom7\",\r\n\t\"custom8\",\r\n\t\"custom9\",\r\n\t\"custom10\",\r\n\t\"daimoncourt\",\r\n\t\"default - Kopie\",\r\n\t\"default\",\r\n\t\"default_christmas\",\r\n\t\"defendantlobby\",\r\n\t\"defendantlobbyapollo\",\r\n\t\"detentioncenter\",\r\n\t\"doppler\",\r\n\t\"dr1stfloor\",\r\n\t\"dr1stfloordorms\",\r\n\t\"dr1stfloorhalls\",\r\n\t\"dr2ndfloor\",\r\n\t\"dr3rdfloor\",\r\n\t\"druq1stfloordorms\",\r\n\t\"druq2ndfloordorms\",\r\n\t\"dualdestinies\",\r\n\t\"dualdestiniesOG\",\r\n\t\"dungeon\",\r\n\t\"endless\",\r\n\t\"englishcourt\",\r\n\t\"forest\",\r\n\t\"gs4\",\r\n\t\"gs4night\",\r\n\t\"gs5\",\r\n\t\"hd\",\r\n\t\"inn\",\r\n\t\"investigationbando\",\r\n\t\"investigationsembassylobby\",\r\n\t\"investigationsgourdlake\",\r\n\t\"investigationsmilesoffice\",\r\n\t\"investigationsplaneair\",\r\n\t\"investigationsroyalcourt\",\r\n\t\"investigationstvroom\",\r\n\t\"investigationswestern\",\r\n\t\"investigationswitchtown\",\r\n\t\"island 1(uranus zone)\",\r\n\t\"lcourt\",\r\n\t\"legacy\",\r\n\t\"lobbyDGS-ENG\",\r\n\t\"lobbyDGS-JAP\",\r\n\t\"lobbyPLvsAA-ENG\",\r\n\t\"lobbyPLvsAA-LAB\",\r\n\t\"lobbySOJ\",\r\n\t\"magatama\",\r\n\t\"magatama1\",\r\n\t\"magatama2\",\r\n\t\"magatama3\",\r\n\t\"magatama4\",\r\n\t\"magatama5\",\r\n\t\"marblefade\",\r\n\t\"matrix\",\r\n\t\"matrixall\",\r\n\t\"matrixangry\",\r\n\t\"matrixangrysad\",\r\n\t\"matrixangrysurprised\",\r\n\t\"matrixhappy\",\r\n\t\"matrixhappyangry\",\r\n\t\"matrixhappysad\",\r\n\t\"matrixhappysurprised\",\r\n\t\"matrixsad\",\r\n\t\"matrixsadsurprised\",\r\n\t\"matrixsurprise\",\r\n\t\"mlp\",\r\n\t\"newcourt\",\r\n\t\"night (no lights)\",\r\n\t\"plvsaa\",\r\n\t\"policestation\",\r\n\t\"prisonvestigation\",\r\n\t\"sdr2classtrial\",\r\n\t\"sky\",\r\n\t\"sshope2ndfloorday(incident)\",\r\n\t\"sshope2ndfloorday\",\r\n\t\"sshope2ndfloornight(incident)\",\r\n\t\"sshope2ndfloornight\",\r\n\t\"sshopeday(incident)\",\r\n\t\"sshopeday\",\r\n\t\"sshopenight(incident)\",\r\n\t\"sshopenight\",\r\n\t\"thief\",\r\n\t\"thiefbash\",\r\n\t\"thiefpoint\",\r\n\t\"thiefpoisoning\",\r\n\t\"thiefprints\",\r\n\t\"thiefstab\",\r\n\t\"thiefsteal\",\r\n\t\"turnaboutstorm - Kopie\",\r\n\t\"turnaboutstorm\",\r\n\t\"vocalcourt\",\r\n\t\"witchtrialcourt\"\r\n];","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0 and Qubrick\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\n// Uses the Gify library:\r\n// https://github.com/rfrench/gify\r\n// The following comment is needed for ESLint:\r\n/* global gify */\r\n\r\nimport background_arr from \"./backgrounds.js\";\r\nimport evidence_arr from \"./evidence.js\";\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function (item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1];\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://s3.wasabisys.com/webao/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.hp = [0, 0];\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\t\tthis.evidences = [];\r\n\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\": {\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\": {\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\": {\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\": {\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\": {\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t};\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn this.presentable ? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#${escapeChat(encodeChat(document.getElementById(\"OOC_name\").value))}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {number} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t * @param {string} evidence the filename of evidence to show\r\n\t * @param {number} flip change to 1 to reverse sprite for position changes\r\n\t * @param {string} flash screen flash effect\r\n\t * @param {string} color text color\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {number} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {number} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {number} side the position\r\n\t * @param {number} hp the health point\r\n\t */\r\n\tsendHP(side, hp) {\r\n\t\tthis.serv.send(`HP#${side}#${hp}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif (this.chars[this.charID].side == \"jud\") {\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.3#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Set to playerID to server chat name\r\n\t\t// TODO: Make a text box for this!\r\n\t\tdocument.getElementById(\"OOC_name\").value = \"web\" + this.playerID;\r\n\r\n\t\t// Load evidence array to select\r\n\t\tconst evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tevidence_arr.forEach(evidence => {\r\n\t\t\tevidence_select.add(new Option(evidence));\r\n\t\t});\r\n\r\n\t\t// Load background array to select\r\n\t\tconst background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tbackground_arr.forEach(background => {\r\n\t\t\tbackground_select.add(new Option(background));\r\n\t\t});\r\n\t\t// Calculate gif duration of shouts\r\n\t\tconst shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"].toLowerCase();\r\n\t\t\tfileExists(shout_src, this.callbackLoadImageResources, shouts[i]);\r\n\t\t}\r\n\r\n\t\t// Calculate gif duration of testimony\r\n\t\tconst testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tconst testimony_src = `${AO_HOST}themes/default/${testimony[i]}.gif`;\r\n\t\t\t// Check image existed\r\n\t\t\tfileExists(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tfileExists(AO_HOST + this.resources[testimony[i]][\"sfx\"].toLowerCase(), this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\r\n\t\t// TODO: Cache some resources\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif (result) {\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src, client.callbackGetResourceLength, resource);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length;\r\n\t}\r\n\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif (result) {\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tconst target = document.getElementById(\"client_inner_chat\");\r\n\t\tconst observer = new MutationObserver(function (mutations) {\r\n\t\t\tmutations.forEach(function (mutation) {\r\n\t\t\t\tconst children = mutation.addedNodes;\r\n\t\t\t\tif (children !== null) {\r\n\t\t\t\t\tchildren.forEach(function (node) {\r\n\t\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else if (node.tagName == \"M\") {\r\n\t\t\t\t\t\t\tif (node.hasAttribute(\"a\")) {\r\n\t\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t});\r\n\t\tconst config = {\r\n\t\t\tattributes: true,\r\n\t\t\tchildList: true\r\n\t\t};\r\n\t\tobserver.observe(target, config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split(\"%\");\r\n\t\tlet args = lines[0].split(\"#\");\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * XXX: a nasty hack made by gameboyprinter.\r\n\t * @param {string} msg chat message to prepare for display \r\n\t */\r\n\tprepChat(msg){\r\n\t\t// TODO: make this less awful\r\n\t\treturn decodeBBCode(escapeHtml(decodeChat(unescapeChat(msg))));\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tconst chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: this.prepChat(args[5]), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 600) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1].toLowerCase();\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener(\"loadedmetadata\", function () {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0].toLowerCase()) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0].toLowerCase()) + \"/char_icon.png\"\r\n\t\t\t};\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tconst arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2].toLowerCase())\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tconst evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor (let i = 1; i <= this.evidences.length; i++) {\r\n\t\t\tevidence_box.innerHTML += ``;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tconst hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tlet flagAudio = false;\r\n\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif (/\\.(?:wav|mp3|mp4|ogg|opus)$/i.test(args[i]) && !flagAudio) {\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\r\n\t\t\tif (flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tconst newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tconst newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i];\r\n\t\t\t\tnewarea.onclick = function () {\r\n\t\t\t\t\tarea_click(this);\r\n\t\t\t\t};\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// We need to check if the last area that we got was actually a category\r\n\t\t// header for music. If it was, then move it over to the music list.\r\n\t\tconst area_box = document.getElementById(\"areas\");\r\n\t\tif (area_box.lastChild.textContent.startsWith(\"=\")) {\r\n\t\t\tconst audio_title = document.createElement(\"OPTION\");\r\n\t\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\t\tarea_box.removeChild(area_box.lastChild);\r\n\t\t}\r\n\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tconst bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif (bg_index == 0) {\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + \"background/\" + escape(args[1].toLowerCase()) + \"/defenseempty.png\";\r\n\t\tif (this.charID == -1) {\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tconst percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({\r\n\t\t\t\t\"width\": percent_hp + \"%\"\r\n\t\t\t}, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({\r\n\t\t\t\t\"width\": percent_hp + \"%\"\r\n\t\t\t}, 500);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tlet tr;\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\ttr = document.createElement(\"TR\");\r\n\t\t\t}\r\n\t\t\tconst td = document.createElement(\"TD\");\r\n\t\t\tlet icon_chosen = \"\";\r\n\t\t\tconst thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}\";\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tconst me = this.me();\r\n\t\tconst emotes = this.emotes;\r\n\t\tconst xhr = new XMLHttpRequest();\r\n\t\txhr.withCredentials = false;\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open(\"GET\", AO_HOST + \"characters/\" + escape(this.me().name.toLowerCase()) + \"/char.ini\", true);\r\n\t\txhr.responseType = \"text\";\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tconst linifile = this.responseText;\r\n\t\t\t\tconst pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tconst emoteinfo = pinifile.Emotions[i].split(\"#\");\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== \"undefined\") {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== \"undefined\") {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// Make sure the asset server is case insensitive, or that everything on it is lowercase\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0].toLowerCase(),\r\n\t\t\t\t\t\tspeaking: emoteinfo[1].toLowerCase(),\r\n\t\t\t\t\t\tsilent: emoteinfo[2].toLowerCase(),\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx.toLowerCase(),\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + `characters/${escape(me.name).toLowerCase()}/emotions/button${i}_off.png`,\r\n\t\t\t\t\t\tbutton_on: AO_HOST + `characters/${escape(me.name).toLowerCase()}/emotions/button${i}_on.png`\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \r\n\t\t\t\t\t\t`\"${emotes[i].desc}\"\r\n\t\t\t\t\t\t`;\r\n\t\t\t\t}\r\n\t\t\t\tpickEmotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + \"sounds/general/sfx-blipmale.wav\");\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + \"sounds/general/sfx-blipmale.wav\");\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + \"sounds/general/sfx-blipmale.wav\");\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname.toLowerCase()}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(`${AO_HOST}characters/${escape(chatmsg.name.toLowerCase())}/${chatmsg.preanim.toLowerCase()}.gif`, this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {number} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay) {\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay);\r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater() {\r\n\t\tif (client.testimonyID > 0) {\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tconst testimonyOverlay = document.getElementById(\"client_testimony\");\r\n\t\t\ttestimonyOverlay.src = client.resources[testimony][\"src\"];\r\n\t\t\ttestimonyOverlay.style.display = \"\";\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tconst request = new XMLHttpRequest();\r\n\t\trequest.open(\"GET\", filename, true);\r\n\t\trequest.responseType = \"arraybuffer\";\r\n\t\trequest.addEventListener(\"load\", function () {\r\n\t\t\tconst gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony() {\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]) {\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]) {\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\tdisposeTestimony() {\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").style.display = \"none\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\tconst nameBox = document.getElementById(\"client_name\");\r\n\t\tconst chatBox = document.getElementById(\"client_chat\");\r\n\t\tconst charSprite = document.getElementById(\"client_char\");\r\n\t\tconst eviBox = document.getElementById(\"client_evi\");\r\n\t\tconst background = document.getElementById(\"client_background\");\r\n\t\tconst shoutSprite = document.getElementById(\"client_shout\");\r\n\t\tconst chatBoxInner = document.getElementById(\"client_inner_chat\");\r\n\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1) {\r\n\t\t\tcharSprite.style.transform = \"scaleX(-1)\";\r\n\t\t} else {\r\n\t\t\tcharSprite.style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tbackground.style.backgroundColor = \"transparent\";\r\n\t\t\t// Hide message and evidence window\r\n\t\t\tnameBox.style.display = \"none\";\r\n\t\t\tchatBox.style.display = \"none\";\r\n\t\t\teviBox.style.opacity = \"0\";\r\n\t\t\teviBox.style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tshoutSprite.src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}characters/${this.chatmsg.name.toLowerCase()}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif (this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2) {\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$(\"#client_gamewindow\").effect(\"shake\", {\r\n\t\t\t\t\t\"direction\": \"up\"\r\n\t\t\t\t});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tbackground.style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$(\"#client_gamewindow\").effect(\"pulsate\");\r\n\t\t\t}\r\n\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif (this.chatmsg.preanimdelay > 0) {\r\n\t\t\t\tshoutSprite.src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.preanim.toLowerCase() + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif (this.chatmsg.evidence > 0) {\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\teviBox.style.backgroundImage = \"url('\" + client.evidences[this.chatmsg.evidence - 1].icon + \"')\";\r\n\r\n\t\t\t\t\tif (this.chatmsg.side == \"def\") {\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\teviBox.style.right = \"1.5em\";\r\n\t\t\t\t\t\teviBox.style.left = \"initial\";\r\n\t\t\t\t\t\t$(\"#client_evi\").animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\teviBox.style.right = \"initial\";\r\n\t\t\t\t\t\teviBox.style.left = \"1.5em\";\r\n\t\t\t\t\t\t$(\"#client_evi\").animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tnameBox.style.display = \"block\";\r\n\t\t\t\tnameBox.style.fontSize = (nameBox.offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tnameBox.innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tchatBox.style.display = \"block\";\r\n\t\t\t\tchatBox.style.fontSize = (chatBox.offsetHeight * 0.25) + \"px\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t};\r\n\t\t\t\tchatBoxInner.style.color = colors[this.chatmsg.color] || \"#ffffff\";\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.chatmsg.preanimdelay == 0) {\r\n\t\t\t\t\tshoutSprite.src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.speaking.toLowerCase() + \".gif\";\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.silent.toLowerCase() + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tchatBoxInner.innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.silent.toLowerCase() + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound.toLowerCase()) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w.\\-_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function (line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip) ? 1 : 0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if a file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction fileExists(url, callback, param) {\r\n\tconst xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function () {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tlet standname;\r\n\tconst bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\tcase \"def\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\";\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\tfileExists(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\tstandname = \"defense\";\r\n\t\tbreak;\r\n\tcase \"pro\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\";\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\tfileExists(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\tcase \"hld\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\";\r\n\t\tstandname = \"defense\";\r\n\t\tbreak;\r\n\tcase \"hlp\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\";\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\tcase \"wit\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\";\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\";\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\tcase \"jud\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\";\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result, position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\") {\r\n\t\tif (result) {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\";\r\n\t\t}\r\n\t} else {\r\n\t\tif (result) {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\";\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 800) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickChar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickChar = pickChar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickEmotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo;\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickEmotion = pickEmotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickEvidence(evidence) {\r\n\tif (client.selectedEvidence !== evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif (client.selectedEvidence > 0) {\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0) {\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelEvidence();\r\n\t}\r\n}\r\nwindow.pickEvidence = pickEvidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addEvidence() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tclient.sendPE(document.getElementById(\"evi_name\").value,\r\n\t\tdocument.getElementById(\"evi_desc\").value,\r\n\t\tevidence_select.selectedIndex == 0 ?\r\n\t\t\tdocument.getElementById(\"evi_filename\").value :\r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text\r\n\t);\r\n\tcancelEvidence();\r\n}\r\nwindow.addEvidence = addEvidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editEvidence() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE(id,\r\n\t\tdocument.getElementById(\"evi_name\").value,\r\n\t\tdocument.getElementById(\"evi_desc\").value,\r\n\t\tevidence_select.selectedIndex == 0 ?\r\n\t\t\tdocument.getElementById(\"evi_filename\").value :\r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text\r\n\t);\r\n\tcancelEvidence();\r\n}\r\nwindow.editEvidence = editEvidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function deleteEvidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelEvidence();\r\n}\r\nwindow.deleteEvidence = deleteEvidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelEvidence() {\r\n\t//Clear evidence data\r\n\tif (client.selectedEvidence > 0) {\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelEvidence = cancelEvidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t//Find if icon alraedy existed in select box\r\n\tconst select_element = document.getElementById(select_box);\r\n\tfor (let i = 1; i < select_element.length; ++i) {\r\n\t\tif (select_element.options[i].value == value) {\r\n\t\t\treturn i;\r\n\t\t}\r\n\t}\r\n\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\r\n\tif (evidence_select.selectedIndex === 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = `url(${AO_HOST}evidence/${evidence_filename.value.toLowerCase()})`;\r\n\t} else {\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = `url(${AO_HOST}evidence/${evidence_select.value.toLowerCase()})`;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif (side == \"jud\") {\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor (let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++) {\r\n\t\tif (side == role_select[i].value) {\r\n\t\t\trole_select.selectedIndex = i;\r\n\t\t\treturn;\r\n\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\",\r\n\t\tbackground_select = document.getElementById(\"bg_select\"),\r\n\t\tbg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value;\r\n\t} else {\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\", filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\"),\r\n\t\trole_command = document.getElementById(\"role_command\").value;\r\n\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\", role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callMod() {\r\n\t$(\"#callmod_dialog\").dialog(\"open\");\r\n}\r\nwindow.callMod = callMod;\r\n\r\n/**\r\n * Declare witness testimony.\r\n */\r\nexport function initWT() {\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initWT = initWT;\r\n\r\n/**\r\n * Declare cross examination.\r\n */\r\nexport function initCE() {\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initCE = initCE;\r\n\r\n/**\r\n * Increment defense health point.\r\n */\r\nexport function addHPD() {\r\n\tclient.sendHP(1, String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Decrement defense health point.\r\n */\r\nexport function redHPD() {\r\n\tclient.sendHP(1, String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Increment prosecution health point.\r\n */\r\nexport function addHPP() {\r\n\tclient.sendHP(2, String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Decrement prosecution health point.\r\n */\r\nexport function redHPP() {\r\n\tclient.sendHP(2, String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + \"background/\" + background_filename.value.toLowerCase() + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + \"background/\" + background_select.value.toLowerCase() + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleEffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleEffect = toggleEffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleFlip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleFlip = toggleFlip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglePresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglePresent = togglePresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function toggleMenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.toggleMenu = toggleMenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleShout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleShout = toggleShout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encode text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t// This approach works by escaping all special characters to Unicode escape sequences.\r\n\t\t// Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function (ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4);\r\n\t\t});\r\n\t} else if (selectedEncoding == \"utf16\") {\r\n\t\t// Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tconst buffer = new ArrayBuffer(estring.length * 2);\r\n\t\tconst result = new Uint16Array(buffer);\r\n\t\tfor (let i = 0, strLen = estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decodes text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t// Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n\t\treturn estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16));\r\n\t\t});\r\n\t} else if (selectedDecoding == \"utf16\") {\r\n\t\t// Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, \"\") // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, \"<$1m>\") // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, \"\") // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, \"\"); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof (String.prototype.trim) === \"undefined\") {\r\n\tString.prototype.trim = function () {\r\n\t\treturn String(this).replace(/^\\s+|\\s+$/g, \"\");\r\n\t};\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function () {\r\n\tlet hash = 0;\r\n\tif (this.length === 0) return hash;\r\n\tfor (let i = 0; i < this.length; i++) {\r\n\t\tconst chr = this.charCodeAt(i);\r\n\t\thash = ((hash << 5) - hash) + chr;\r\n\t\thash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function () {\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources();\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$(function () {\r\n\t$(\"#callmod_dialog\").dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection: \"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection: \"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\tSure: function () {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$(this).dialog(\"close\");\r\n\t\t\t},\r\n\t\t\tCancel: function () {\r\n\t\t\t\t$(this).dialog(\"close\");\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""} \ No newline at end of file -- cgit From 1db7474cbdcf13c586ee3fc446375d8a9d638a10 Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Sat, 8 Sep 2018 21:12:16 -0500 Subject: Fix some more annoyances - Use createTextNode instead of escapeHtml - Add area change messages in IC log - Move "Call Mod" button to menu, replacing "Guide" which was mostly empty except for the BBCode reference (but you can surely look that up somewhere else, at least until more documentation for webAO has been produced) - Compact the evidence editor - Fix bug where the last emote was not displayed in the emotes list Some issues that remain: - Clients still cannot send special Unicode characters, but they can receive them correctly. - Shout animations run for longer than the GIF animation length. - Preanims sometimes play when they are not supposed to. - GoldenLayout panels cannot be dragged around for some reason. - The chatbox does not automatically scroll down. - When the game panel is maximized, the viewport should not exceed the size of the game panel. --- webAO/client.b.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'webAO/client.b.js.map') diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map index 6c826b9..7a38fc7 100644 --- a/webAO/client.b.js.map +++ b/webAO/client.b.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/evidence.js","webpack:///./webAO/backgrounds.js","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","r","value","n","__esModule","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickChar","pickEmotion","pickEvidence","addEvidence","editEvidence","deleteEvidence","cancelEvidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callMod","initWT","initCE","addHPD","redHPD","addHPP","redHPP","updateBackgroundPreview","toggleEffect","toggleFlip","togglePresent","toggleMenu","toggleShout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","mode","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","hp","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","document","getElementById","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","add","Option","evidence_arr","background_select","background_arr","background","shouts","length","fileExists","toLowerCase","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","escapeHtml","decodeChat","unescapeChat","replace","chatmsg","content","innerHTML","preanim","escape","nameplate","prepChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","lastChild","startsWith","audio_title","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","percent_hp","$","animate","width","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","withCredentials","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","testimonyOverlay","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","nameBox","chatBox","charSprite","eviBox","shoutSprite","chatBoxInner","transform","opacity","height","shout","1","2","3","effect","direction","backgroundImage","right","left","fontSize","offsetHeight","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","dialog","sendRT","sendHP","String","background_filename","background_preview","menu","unsafe","estring","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources","autoOpen","resizable","show","hide","modal","buttons","Sure","sendZZ","Cancel"],"mappings":"aACA,IAAAA,KAGA,SAAAC,EAAAC,GAGA,GAAAF,EAAAE,GACA,OAAAF,EAAAE,GAAAC,QAGA,IAAAC,EAAAJ,EAAAE,IACAG,EAAAH,EACAI,GAAA,EACAH,YAUA,OANAI,EAAAL,GAAAM,KAAAJ,EAAAD,QAAAC,IAAAD,QAAAF,GAGAG,EAAAE,GAAA,EAGAF,EAAAD,QAKAF,EAAAQ,EAAAF,EAGAN,EAAAS,EAAAV,EAGAC,EAAAU,EAAA,SAAAR,EAAAS,EAAAC,GACAZ,EAAAa,EAAAX,EAAAS,IACAG,OAAAC,eAAAb,EAAAS,GACAK,cAAA,EACAC,YAAA,EACAC,IAAAN,KAMAZ,EAAAmB,EAAA,SAAAjB,GACAY,OAAAC,eAAAb,EAAA,cAAiDkB,OAAA,KAIjDpB,EAAAqB,EAAA,SAAAlB,GACA,IAAAS,EAAAT,KAAAmB,WACA,WAA2B,OAAAnB,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAH,EAAAU,EAAAE,EAAA,IAAAA,GACAA,GAIAZ,EAAAa,EAAA,SAAAU,EAAAC,GAAsD,OAAAV,OAAAW,UAAAC,eAAAnB,KAAAgB,EAAAC,IAGtDxB,EAAA2B,EAAA,GAIA3B,IAAA4B,EAAA,8FClEC,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,kBACA,oBACA,iBACA,kBACA,kBACA,kBACA,iBACA,kBACA,gBACA,iBACA,oBACA,oBACA,sBACA,oBACA,mBACA,iBACA,kBACA,iBACA,kBACA,oBACA,iBACA,oBACA,gBACA,kBACA,kBACA,iBACA,mBACA,oBACA,kBACA,mBACA,kBACA,oBACA,qBACA,mBACA,oBACA,mBACA,gBACA,kBACA,oBACA,kBACA,qBACA,qBACA,sBACA,uBACA,sBACA,oBACA,qBACA,uBACA,wBACA,mBACA,oBACA,wBACA,yBACA,wBACA,oBACA,qBACA,sBACA,qBACA,qBACA,sBACA,uBACA,qBACA,oBACA,qBACA,wBACA,qBACA,oBACA,cACA,kBACA,eACA,kBACA,eACA,iBACA,gBACA,eACA,gBACA,cACA,eACA,gBACA,eACA,gBACA,cACA,cACA,cACA,eACA,eACA,eACA,eACA,iBACA,iBACA,kBACA,gBACA,eACA,mBACA,kBACA,mBACA,mBACA,kBACA,mBACA,kBACA,mBACA,mBACA,oBACA,kBACA,uBACA,wBACA,qBACA,sBACA,mBACA,mBACA,iBACA,kBACA,mBACA,kBACA,kBACA,oBACA,qBACA,mBACA,iBACA,qBACA,mBACA,sBACA,mBACA,oBACA,kBACA,iBACA,kBACA,cACA,YACA,aACA,aACA,eACA,eACA,gBACA,iBACA,iBACA,iBACA,aACA,iBACA,cACA,eACA,eACA,eACA,eACA,cACA,eACA,eACA,eACA,eACA,sBACA,uBACA,aACA,eACA,cACA,gBACA,cACA,gBACA,oBACA,cACA,cACA,eACA,eACA,iBACA,kBACA,mBACA,cACA,oBACA,aACA,cACA,cACA,mBACA,aACA,cACA,aACA,aACA,cACA,cACA,cACA,cACA,eACA,gBACA,gBACA,gBACA,gBACA,iBACA,qBACA,iBACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,aACA,iBACA,kBACA,iBACA,kBACA,eACA,gBACA,gBACA,eACA,gBACA,gBACA,gBACA,gBACA,sBACA,iBACA,cACA,eACA,oBACA,gBACA,iBACA,iBACA,gBACA,eACA,eACA,eACA,eACA,gBACA,iBACA,iBACA,iBACA,iBACA,eACA,gBACA,cACA,qBACA,sBACA,sBACA,eACA,mBACA,gBACA,cACA,iBACA,kBACA,gBACA,gBACA,mBACA,aACA,cACA,cACA,eACA,gBACA,eACA,gBACA,cACA,aACA,cACA,cACA,cACA,cACA,aACA,cACA,cACA,cACA,iBACA,oBACA,0BACA,oBACA,oBACA,cACA,oBACA,cACA,YACA,kBACA,eACA,YACA,gBACA,eACA,kBACA,gBACA,eACA,gBACA,gBACA,gBACA,iBACA,cACA,eACA,eACA,iBACA,kBACA,iBACA,kBACA,sBACA,gBACA,iBACA,gBACA,iBACA,aACA,cACA,cACA,cACA,sBACA,iBACA,kBACA,cACA,eACA,eACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,cACA,eACA,cACA,eACA,cACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,mBACA,aACA,cACA,oBACA,eACA,gBACA,aACA,cACA,cACA,kBACA,oBACA,qBACA,qBACA,gBACA,aACA,cACA,cACA,cACA,cACA,cACA,eACA,eACA,gBACA,kBACA,mBACA,mBACA,mBACA,iBACA,mBACA,gBACA,oBACA,qBACA,qBACA,qBACA,oBACA,kBACA,oBACA,qBACA,iBACA,kBACA,kBACA,oBACA,iBACA,kBACA,kBACA,qBACA,qBACA,kBACA,kBACA,mBACA,oBACA,iBACA,oBACA,kBACA,gBACA,WACA,YACA,YACA,YACA,YACA,gBACA,cACA,aACA,eACA,aACA,YACA,iBACA,eACA,eACA,mBACA,qBACA,sBACA,sBACA,sBACA,sBACA,sBACA,eACA,aACA,cACA,cACA,cACA,cACA,aACA,aACA,cACA,cACA,eACA,cACA,cACA,cACA,eACA,gBACA,gBACA,iBACA,0BACA,cACA,oBACA,eACA,YACA,aACA,aACA,WACA,YACA,YACA,cACA,aACA,eACA,gBACA,iBACA,YACA,aACA,aACA,aACA,eACA,cACA,cACA,YACA,mBACA,aACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,SACA,iBACA,kBACA,kBACA,kBACA,gBACA,iBACA,iBACA,cACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,oBACA,mBACA,aACA,cACA,cACA,cACA,eACA,eACA,iBACA,cACA,gBACA,eACA,gBACA,gBACA,cACA,oBACA,aACA,aACA,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,iBACA,gBACA,cACA,oBACA,mBACA,oBACA,oBACA,mBACA,iBACA,uBACA,oBACA,iBACA,mBACA,oBACA,mBACA,iBACA,mBACA,kBACA,sBACA,mBACA,oBACA,qBACA,oBACA,mBACA,oBACA,kBACA,kBACA,kBACA,sBACA,kBACA,oBACA,iBACA,kBACA,kBACA,oBACA,gBACA,kBACA,kBACA,mBACA,kBACA,mBACA,mBACA,wBACA,oBACA,mBACA,oBACA,qBACA,oBACA,mBACA,kBACA,iBACA,mBACA,oBACA,qBACA,cACA,eACA,YACA,aACA,YACA,aACA,cACA,cACA,cACA,aACA,cACA,cACA,cACA,cACA,aACA,YACA,aACA,aACA,aACA,iBACA,eACA,gBACA,mBACA,iBACA,eACA,gBACA,gBACA,aACA,WACA,cACA,aACA,cACA,cACA,cACA,aACA,cACA,iBACA,gBACA,iBACA,iBACA,aACA,cACA,cACA,kBACA,aACA,cACA,cACA,YACA,gBACA,eACA,iBACA,oBACA,0BACA,aACA,eACA,aACA,cACA,YACA,aACA,kBACA,kBACA,YACA,mBACA,YACA,aACA,aACA,gBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,cACA,eACA,gBACA,gBACA,gBACA,iBACA,kBACA,YACA,aACA,aACA,aACA,aACA,aACA,aACA,aACA,aACA,cACA,cACA,cACA,aACA,iBACA,kBACA,kBACA,aACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,eACA,eACA,gBACA,cACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,cACA,eACA,gBACA,gBACA,eACA,iBACA,uBACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,aACA,cACA,cACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,cACA,eACA,aACA,aACA,cACA,cACA,gBACA,eACA,mBACA,mBACA,mBACA,qBACA,wBACA,sBACA,kBACA,mBACA,qBACA,oBACA,sBACA,uBACA,mBACA,qBACA,oBACA,kBACA,kBACA,oBACA,uBACA,sBACA,uBACA,qBACA,mBACA,sBACA,iBACA,kBACA,qBACA,wBACA,oBACA,uBACA,oBACA,qBACA,oBACA,mBACA,oBACA,qBACA,oBACA,oBACA,eACA,aACA,cACA,cACA,eACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,cACA,cACA,cACA,eACA,eACA,eACA,cACA,gBACA,gBACA,cACA,eACA,eACA,eACA,gBACA,iBACA,aACA,cACA,cACA,mBACA,eACA,gBACA,gBACA,gBACA,aACA,cACA,cACA,kBACA,mBACA,mBACA,mBACA,oBACA,oBACA,oBACA,qBACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,UACA,gBACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,aACA,cACA,cACA,kBACA,oBACA,eACA,qBACA,sBACA,eACA,eACA,gBACA,cACA,cACA,gBACA,kBACA,oBACA,iBACA,iBACA,iBACA,qBACA,sBACA,oBACA,uBACA,uBACA,kBACA,mBACA,iBACA,kBACA,oBACA,kBACA,kBACA,iBACA,oBACA,mBACA,oBACA,oBACA,oBACA,wBACA,kBACA,mBACA,mBACA,oBACA,cACA,eACA,cACA,eACA,eACA,gBACA,aACA,cACA,sBACA,uBACA,gBACA,iBACA,iBACA,gBACA,cACA,eACA,cACA,eACA,eACA,eACA,cACA,2BACA,iBACA,eACA,gBACA,gBACA,aACA,cACA,iBACA,aACA,eACA,aACA,eACA,gBACA,cACA,cACA,eACA,eACA,cACA,eACA,gBACA,eACA,gBACA,iBACA,gBACA,cACA,cACA,mBACA,eACA,gBACA,cACA,mBACA,gBACA,iBACA,iBACA,qBACA,qBACA,eACA,iBACA,cACA,cACA,cACA,cACA,eACA,qBACA,iBACA,gBACA,mBACA,qBACA,0BACA,oBACA,kBACA,uBACA,oBACA,oBACA,qBACA,oBACA,gBACA,4BACA,qBACA,oBACA,oBACA,wBACA,oBACA,0BACA,mBACA,mBACA,mBACA,mBACA,wBACA,kBACA,wBACA,sBACA,eACA,yBACA,cACA,gBACA,iBACA,cACA,YACA,aACA,aACA,aACA,aACA,aACA,aACA,eACA,iBACA,eACA,gBACA,eACA,gBACA,eACA,gBACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,aACA,cACA,kBACA,gBACA,gBACA,oBACA,qBACA,qBACA,mBACA,mBACA,2BACA,oBACA,oBACA,mBACA,oBACA,qBACA,sBACA,mBACA,wBACA,mBACA,mBACA,kBACA,kBACA,mBACA,oBACA,mBACA,mBACA,iBACA,oBACA,mBACA,kBACA,kBACA,mBACA,qBACA,mBACA,mBACA,mBACA,qBACA,oBACA,oBACA,mBACA,oBACA,kBACA,kBACA,oBACA,sBACA,mBACA,qBACA,mBACA,mBACA,mBACA,YACA,aACA,eACA,cACA,eACA,aACA,kBACA,aACA,cACA,gBACA,eACA,eACA,eACA,aACA,iBACA,cACA,aACA,oBACA,eACA,gBACA,aACA,cACA,cACA,cACA,iBACA,kBACA,iBACA,kBACA,iBACA,kBACA,mBACA,mBACA,aACA,cACA,cACA,cACA,cACA,cACA,cACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,aACA,kBACA,iBACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,WACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,qBACA,kBACA,qBACA,gBACA,iBACA,iBACA,eACA,gBACA,iBACA,eACA,gBACA,iBACA,eACA,cACA,iBACA,aACA,aACA,gBACA,gBACA,mBACA,sBACA,kBACA,mBACA,kBACA,oBACA,mBACA,qBACA,oBACA,kBACA,gBACA,kBACA,mBACA,kBACA,sBACA,oBACA,iBACA,kBACA,iBACA,iBACA,mBACA,kBACA,gBACA,oBACA,kBACA,oBACA,kBACA,WACA,YACA,cACA,cACA,YACA,eACA,eACA,gBACA,gBACA,YACA,aACA,eACA,iBACA,eACA,aACA,WACA,YACA,aACA,cACA,cACA,cACA,cACA,mBACA,oBACA,YACA,aACA,cACA,cACA,cACA,gBACA,eACA,iBACA,cACA,cACA,aACA,cACA,eACA,gBACA,cACA,gBACA,iBACA,iBACA,kBACA,kBACA,mBACA,iBACA,kBACA,cACA,iBACA,aACA,cACA,cACA,cACA,cACA,cACA,cACA,gBACA,iBACA,iBACA,cACA,qBACA,sBACA,sBACA,eACA,gBACA,aACA,cACA,cACA,eACA,eACA,cACA,eACA,eACA,gBACA,iBACA,aACA,cACA,cACA,cACA,eACA,cACA,eACA,YACA,6GCvyCA,aACA,QACA,MACA,eACA,sBACA,WACA,YACA,WACA,mBACA,YACA,WACA,iBACA,YACA,YACA,cACA,aACA,aACA,eACA,YACA,WACA,eACA,WACA,aACA,oBACA,oBACA,mBACA,yBACA,iBACA,sBACA,kBACA,2BACA,mBACA,mBACA,cACA,kBACA,wBACA,sBACA,oBACA,YACA,uBACA,aACA,UACA,eACA,8BACA,yBACA,YACA,mBACA,qBACA,oBACA,oBACA,eACA,mBACA,sBACA,sBACA,cACA,oBACA,aACA,WACA,gBACA,iBACA,iBACA,oBACA,UACA,aACA,sBACA,WACA,kBACA,qBACA,wBACA,2BACA,kBACA,UACA,eACA,kBACA,iBACA,iBACA,oBACA,UACA,kBACA,mBACA,eACA,YACA,mBACA,oBACA,eACA,gBACA,kBACA,iBACA,UACA,mBACA,eACA,qBACA,iBACA,MACA,cACA,aACA,gBACA,QACA,SACA,gBACA,cACA,eACA,mBACA,cACA,cACA,eACA,WACA,gBACA,oBACA,WACA,gBACA,aACA,aACA,OACA,WACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,OACA,OACA,OACA,gBACA,iBACA,mBACA,iBACA,kBACA,uBACA,kBACA,KACA,cACA,kBACA,cACA,cACA,aACA,aACA,aACA,aACA,aACA,cACA,OACA,YACA,aACA,MACA,eACA,SACA,cACA,iBACA,YACA,sBACA,gBACA,YACA,eACA,eACA,kBACA,iBACA,eACA,wBACA,cACA,cACA,gBACA,eACA,cACA,mBACA,iBACA,kBACA,cACA,mBACA,eACA,kBACA,kBACA,kBACA,iBACA,cACA,cACA,eACA,gBACA,aACA,aACA,iBACA,aACA,YACA,cACA,YACA,YACA,iBACA,cACA,eACA,YACA,KACA,UACA,cACA,gBACA,6BACA,gBACA,mBACA,UACA,UACA,kBACA,sBACA,kBACA,gBACA,UACA,UACA,MACA,mBACA,oBACA,wBACA,4BACA,6BACA,kBACA,gBACA,YACA,kBACA,aACA,aACA,eACA,OACA,YACA,WACA,gBACA,kBACA,gBACA,mBACA,sBACA,kBACA,gBACA,gBACA,oBACA,oBACA,qBACA,aACA,oBACA,kBACA,eACA,SACA,UACA,WACA,SACA,SACA,UACA,WACA,UACA,eACA,cACA,cACA,gBACA,SACA,WACA,eACA,mBACA,mBACA,yBACA,0BACA,cACA,eACA,eACA,YACA,uBACA,oBACA,KACA,SACA,kBACA,aACA,WACA,SACA,kBACA,aACA,aACA,kBACA,oBACA,oBACA,eACA,iBACA,sBACA,WACA,cACA,iBACA,YACA,kBACA,kBACA,oBACA,aACA,wBACA,wBACA,oBACA,iBACA,mBACA,eACA,gBACA,kBACA,oBACA,YACA,WACA,UACA,aACA,cACA,mBACA,WACA,SACA,iBACA,QACA,YACA,UACA,iBACA,qBACA,mBACA,sBACA,6BACA,kCACA,0BACA,2BACA,uBACA,wBACA,0BACA,0BACA,iBACA,mBACA,wBACA,iCACA,6BACA,sBACA,kBACA,mBACA,0BACA,mBACA,gBACA,oBACA,kBACA,kBACA,4BACA,yBACA,uBACA,cACA,qBACA,mBACA,cACA,eACA,iBACA,oBACA,eACA,wBACA,sBACA,iBACA,gBACA,cACA,iBACA,oBACA,UACA,cACA,YACA,yBACA,aACA,SACA,WACA,aACA,eACA,yBACA,aACA,aACA,WACA,QACA,WACA,eACA,gBACA,gBACA,sBACA,WACA,UACA,cACA,gBACA,gBACA,iBACA,0BACA,kBACA,oBACA,aACA,eACA,mBACA,gBACA,eACA,YACA,aACA,SACA,eACA,eACA,cACA,gBACA,gBACA,gBACA,QACA,mBACA,cACA,SACA,cACA,WACA,cACA,aACA,YACA,eACA,UACA,UACA,UACA,WACA,aACA,aACA,iBACA,WACA,WACA,YACA,YACA,YACA,aACA,WACA,UACA,eACA,QACA,gBACA,UACA,uBACA,kBACA,eACA,qBACA,yBACA,mBACA,8BACA,kCACA,sBACA,eACA,qBACA,yBACA,yBACA,eACA,oBACA,cACA,yBACA,cACA,iBACA,SACA,YACA,eACA,cACA,oBACA,aACA,kBACA,gBACA,YACA,kBACA,aACA,WACA,iBACA,qBACA,WACA,cACA,eACA,iBACA,eACA,iBACA,cACA,gBACA,aACA,aACA,sBACA,WACA,cACA,WACA,oBACA,kBACA,eACA,iBACA,eACA,2BACA,yBACA,aACA,eACA,aACA,UACA,YACA,aACA,OACA,YACA,uBACA,oBACA,qBACA,qBACA,qBACA,sBACA,uBACA,uBACA,uBACA,wBACA,kBACA,cACA,eACA,cACA,iBACA,cACA,eACA,qBACA,eACA,oBACA,eACA,qBACA,aACA,gBACA,gBACA,gBACA,WACA,YACA,YACA,aACA,eACA,aACA,cACA,YACA,YACA,aACA,cACA,SACA,iBACA,oBACA,WACA,cACA,MACA,UACA,WACA,oBACA,gBACA,sBACA,aACA,iBACA,kBACA,mBACA,mBACA,oBACA,gBACA,mBACA,YACA,YACA,WACA,uBACA,WACA,cACA,YACA,cACA,cACA,SACA,iBACA,wBACA,SACA,WACA,gBACA,mBACA,oBACA,mBACA,wBACA,eACA,iBACA,iBACA,aACA,iBACA,SACA,UACA,gBACA,iBACA,cACA,QACA,OACA,aACA,aACA,iBACA,aACA,aACA,oBACA,0BACA,OACA,MACA,SACA,SACA,OACA,OACA,kBACA,MACA,iBACA,UACA,mBACA,kBACA,oBACA,YACA,gBACA,gBACA,eACA,OACA,QACA,YACA,gBACA,aACA,WACA,WACA,WACA,QACA,UACA,UACA,UACA,UACA,YACA,SACA,aACA,OACA,mBACA,SACA,eACA,SACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WACA,cACA,kBACA,UACA,oBACA,iBACA,uBACA,kBACA,UACA,aACA,kBACA,kBACA,aACA,aACA,oBACA,oBACA,gBACA,kBACA,UACA,UACA,eACA,SACA,MACA,WACA,MACA,KACA,MACA,qBACA,6BACA,0BACA,4BACA,yBACA,2BACA,uBACA,wBACA,0BACA,wBACA,SACA,SACA,eACA,eACA,kBACA,kBACA,WACA,WACA,YACA,YACA,YACA,YACA,YACA,aACA,SACA,YACA,cACA,iBACA,uBACA,cACA,mBACA,iBACA,uBACA,YACA,qBACA,iBACA,MACA,WACA,oBACA,SACA,gBACA,oBACA,iBACA,MACA,8BACA,oBACA,gCACA,sBACA,sBACA,YACA,wBACA,cACA,QACA,YACA,aACA,iBACA,cACA,YACA,aACA,yBACA,iBACA,aACA,6VCwjBeC,eAYAC,YAuCAC,oBAUAC,eASAC,sBAQAC,oBAQAC,qBASAC,oBAWAC,aAWAC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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 2);\n","export default [\r\n\t\"1.gif\",\r\n\t\"1.png\",\r\n\t\"2.png\",\r\n\t\"3.png\",\r\n\t\"4.png\",\r\n\t\"5.gif\",\r\n\t\"5.png\",\r\n\t\"6.gif\",\r\n\t\"6.png\",\r\n\t\"AACastApril.png\",\r\n\t\"AACastBellboy.png\",\r\n\t\"AACastButz.png\",\r\n\t\"AACastButz2.png\",\r\n\t\"AACastButz3.png\",\r\n\t\"AACastCindy.png\",\r\n\t\"AACastCody.png\",\r\n\t\"AACastDarke.png\",\r\n\t\"AACastEma.png\",\r\n\t\"AACastGant.png\",\r\n\t\"AACastGoodman.png\",\r\n\t\"AACastGregory.png\",\r\n\t\"AACastGrossberg.png\",\r\n\t\"AACastGumshoe.png\",\r\n\t\"AACastHammer.png\",\r\n\t\"AACastJake.png\",\r\n\t\"AACastJudge.png\",\r\n\t\"AACastLana.png\",\r\n\t\"AACastLotta.png\",\r\n\t\"AACastManfred.png\",\r\n\t\"AACastMaya.png\",\r\n\t\"AACastMeekins.png\",\r\n\t\"AACastMia.png\",\r\n\t\"AACastMiles.png\",\r\n\t\"AACastMisty.png\",\r\n\t\"AACastNeil.png\",\r\n\t\"AACastOldbag.png\",\r\n\t\"AACastOldbag2.png\",\r\n\t\"AACastPayne.png\",\r\n\t\"AACastPayne2.png\",\r\n\t\"AACastPenny.png\",\r\n\t\"AACastPhoenix.png\",\r\n\t\"AACastPhoenix2.png\",\r\n\t\"AACastPowers.png\",\r\n\t\"AACastPowers2.png\",\r\n\t\"AACastSahwit.png\",\r\n\t\"AACastSal.png\",\r\n\t\"AACastStarr.png\",\r\n\t\"AACastVasquez.png\",\r\n\t\"AACastWhite.png\",\r\n\t\"AAI2CastBlaise.png\",\r\n\t\"AAI2CastBonnie.png\",\r\n\t\"AAI2CastCameron.png\",\r\n\t\"AAI2CastCourtney.png\",\r\n\t\"AAI2CastDelicia.png\",\r\n\t\"AAI2CastDogen.png\",\r\n\t\"AAI2CastElbird.png\",\r\n\t\"AAI2CastGustavia.png\",\r\n\t\"AAI2CastGustavia2.png\",\r\n\t\"AAI2CastJill.png\",\r\n\t\"AAI2CastKarin.png\",\r\n\t\"AAI2CastKatherine.png\",\r\n\t\"AAI2CastKatherine2.png\",\r\n\t\"AAI2CastKnightley.png\",\r\n\t\"AAI2CastMarsh.png\",\r\n\t\"AAI2CastMaster.png\",\r\n\t\"AAI2CastMaster2.png\",\r\n\t\"AAI2CastNicole.png\",\r\n\t\"AAI2CastPierre.png\",\r\n\t\"AAI2CastRaymond.png\",\r\n\t\"AAI2CastRaymond2.png\",\r\n\t\"AAI2CastRoland.png\",\r\n\t\"AAI2CastRooke.png\",\r\n\t\"AAI2CastSahwit.png\",\r\n\t\"AAI2CastSebastian.png\",\r\n\t\"AAI2CastShelly.png\",\r\n\t\"AAI2CastSimon.png\",\r\n\t\"AAI2bag.png\",\r\n\t\"AAI2balloon.png\",\r\n\t\"AAI2bell.png\",\r\n\t\"AAI2blanket.png\",\r\n\t\"AAI2body.png\",\r\n\t\"AAI2button.png\",\r\n\t\"AAI2chess.png\",\r\n\t\"AAI2clip.png\",\r\n\t\"AAI2cuffs.png\",\r\n\t\"AAI2dog.png\",\r\n\t\"AAI2door.png\",\r\n\t\"AAI2floor.png\",\r\n\t\"AAI2gate.png\",\r\n\t\"AAI2glove.png\",\r\n\t\"AAI2gun.png\",\r\n\t\"AAI2key.png\",\r\n\t\"AAI2map.png\",\r\n\t\"AAI2map2.png\",\r\n\t\"AAI2map3.png\",\r\n\t\"AAI2note.png\",\r\n\t\"AAI2rope.png\",\r\n\t\"AAI2shovel.png\",\r\n\t\"AAI2tunnel.png\",\r\n\t\"AAI2uniform.png\",\r\n\t\"AAI2video.png\",\r\n\t\"AAI2well.png\",\r\n\t\"AAICastAkbey.png\",\r\n\t\"AAICastAlba.png\",\r\n\t\"AAICastAlba2.png\",\r\n\t\"AAICastAmano.png\",\r\n\t\"AAICastBadd.png\",\r\n\t\"AAICastBuddy.png\",\r\n\t\"AAICastButz.png\",\r\n\t\"AAICastByrne.png\",\r\n\t\"AAICastCammy.png\",\r\n\t\"AAICastDeacon.png\",\r\n\t\"AAICastDeid.png\",\r\n\t\"AAICastFranziska.png\",\r\n\t\"AAICastFranziska2.png\",\r\n\t\"AAICastGumshoe.png\",\r\n\t\"AAICastGumshoe2.png\",\r\n\t\"AAICastHuang.png\",\r\n\t\"AAICastJudge.png\",\r\n\t\"AAICastKay.png\",\r\n\t\"AAICastKay2.png\",\r\n\t\"AAICastLance.png\",\r\n\t\"AAICastLang.png\",\r\n\t\"AAICastMack.png\",\r\n\t\"AAICastMaggey.png\",\r\n\t\"AAICastManfred.png\",\r\n\t\"AAICastManny.png\",\r\n\t\"AAICastNou.png\",\r\n\t\"AAICastPalaeno.png\",\r\n\t\"AAICastPaups.png\",\r\n\t\"AAICastPortsman.png\",\r\n\t\"AAICastRhoda.png\",\r\n\t\"AAICastShihna.png\",\r\n\t\"AAICastSkye.png\",\r\n\t\"AAICastYew.png\",\r\n\t\"AAICastZinc.png\",\r\n\t\"AAIFIRE.png\",\r\n\t\"AAIad.png\",\r\n\t\"AAIad2.png\",\r\n\t\"AAIad3.png\",\r\n\t\"AAIarrow.png\",\r\n\t\"AAIbadge.png\",\r\n\t\"AAIbadger.png\",\r\n\t\"AAIbadger2.png\",\r\n\t\"AAIbadger3.png\",\r\n\t\"AAIbadger4.png\",\r\n\t\"AAIbag.png\",\r\n\t\"AAIballoon.png\",\r\n\t\"AAIbody.png\",\r\n\t\"AAIbody2.png\",\r\n\t\"AAIbody3.png\",\r\n\t\"AAIbody4.png\",\r\n\t\"AAIbody5.png\",\r\n\t\"AAIbook.png\",\r\n\t\"AAIbook2.png\",\r\n\t\"AAIbook3.png\",\r\n\t\"AAIbook4.png\",\r\n\t\"AAIboxes.png\",\r\n\t\"AAIbusinesscard.png\",\r\n\t\"AAIbusinesscard2.png\",\r\n\t\"AAIcar.png\",\r\n\t\"AAIcargo.png\",\r\n\t\"AAIcart.png\",\r\n\t\"AAIchange.png\",\r\n\t\"AAIclip.png\",\r\n\t\"AAIcravat.png\",\r\n\t\"AAIdecoration.png\",\r\n\t\"AAIdoor.png\",\r\n\t\"AAIfile.png\",\r\n\t\"AAIfile2.png\",\r\n\t\"AAIfile3.png\",\r\n\t\"AAIflowers.png\",\r\n\t\"AAIfountain.png\",\r\n\t\"AAIfountain2.png\",\r\n\t\"AAIgift.png\",\r\n\t\"AAIguitarpick.png\",\r\n\t\"AAIgun.png\",\r\n\t\"AAIgun2.png\",\r\n\t\"AAIgun3.png\",\r\n\t\"AAIhandprint.png\",\r\n\t\"AAIhat.png\",\r\n\t\"AAIhoop.png\",\r\n\t\"AAIink.png\",\r\n\t\"AAIkey.png\",\r\n\t\"AAIkey2.png\",\r\n\t\"AAIkey3.png\",\r\n\t\"AAIkey4.png\",\r\n\t\"AAIkey5.png\",\r\n\t\"AAIknife.png\",\r\n\t\"AAIknife2.png\",\r\n\t\"AAIknife3.png\",\r\n\t\"AAIknife4.png\",\r\n\t\"AAIknife5.png\",\r\n\t\"AAIlantern.png\",\r\n\t\"AAIlittlethief.png\",\r\n\t\"AAIluggage.png\",\r\n\t\"AAImoney.png\",\r\n\t\"AAInote.png\",\r\n\t\"AAInote2.png\",\r\n\t\"AAInote3.png\",\r\n\t\"AAInote4.png\",\r\n\t\"AAInote5.png\",\r\n\t\"AAInote6.png\",\r\n\t\"AAInote7.png\",\r\n\t\"AAInote8.png\",\r\n\t\"AAInote9.png\",\r\n\t\"AAInote10.png\",\r\n\t\"AAInote11.png\",\r\n\t\"AAInote12.png\",\r\n\t\"AAInote13.png\",\r\n\t\"AAInote14.png\",\r\n\t\"AAInote15.png\",\r\n\t\"AAInote16.png\",\r\n\t\"AAInote17.png\",\r\n\t\"AAIpen.png\",\r\n\t\"AAIpendant.png\",\r\n\t\"AAIpendant2.png\",\r\n\t\"AAIperfume.png\",\r\n\t\"AAIperfume2.png\",\r\n\t\"AAIphone.png\",\r\n\t\"AAIphone2.png\",\r\n\t\"AAIphone3.png\",\r\n\t\"AAIphoto.png\",\r\n\t\"AAIphoto2.png\",\r\n\t\"AAIphoto3.png\",\r\n\t\"AAIphoto4.png\",\r\n\t\"AAIplates.png\",\r\n\t\"AAIquercuswound.png\",\r\n\t\"AAIreceipt.png\",\r\n\t\"AAIsafe.png\",\r\n\t\"AAIsafe2.png\",\r\n\t\"AAIsciencekit.png\",\r\n\t\"AAIshards.png\",\r\n\t\"AAIshards2.png\",\r\n\t\"AAIshards3.png\",\r\n\t\"AAIshears.png\",\r\n\t\"AAIshirt.png\",\r\n\t\"AAIsnack.png\",\r\n\t\"AAIspear.png\",\r\n\t\"AAIspill.png\",\r\n\t\"AAIstatue.png\",\r\n\t\"AAIstatue2.png\",\r\n\t\"AAIstatue3.png\",\r\n\t\"AAIstatue4.png\",\r\n\t\"AAIsuspect.png\",\r\n\t\"AAIsword.png\",\r\n\t\"AAIsword2.png\",\r\n\t\"AAItape.png\",\r\n\t\"AAItonosamanju.png\",\r\n\t\"AAItonosamanju2.png\",\r\n\t\"AAItonosamanju3.png\",\r\n\t\"AAIvideo.png\",\r\n\t\"AAIwakasaman.png\",\r\n\t\"AAIwallet.png\",\r\n\t\"AAIwire.png\",\r\n\t\"AATHATCARD.png\",\r\n\t\"AAaffidavit.png\",\r\n\t\"AAairtube.png\",\r\n\t\"AAautopsy.png\",\r\n\t\"AAbluebadger.png\",\r\n\t\"AAbook.png\",\r\n\t\"AAbook2.png\",\r\n\t\"AAbook3.png\",\r\n\t\"AAbullet.png\",\r\n\t\"AAbullet2.png\",\r\n\t\"AAcamera.png\",\r\n\t\"AAcamera2.png\",\r\n\t\"AAcards.png\",\r\n\t\"AAclip.png\",\r\n\t\"AAclip2.png\",\r\n\t\"AAclip3.png\",\r\n\t\"AAclip4.png\",\r\n\t\"AAclip5.png\",\r\n\t\"AAdata.png\",\r\n\t\"AAdata2.png\",\r\n\t\"AAdata3.png\",\r\n\t\"AAdata4.png\",\r\n\t\"AAenvelope.png\",\r\n\t\"AAevidencelaw.png\",\r\n\t\"AAfingerprintpowder.png\",\r\n\t\"AAfirecracker.png\",\r\n\t\"AAfishingpole.png\",\r\n\t\"AAflyer.png\",\r\n\t\"AAglassshards.png\",\r\n\t\"AAglove.png\",\r\n\t\"AAgun.png\",\r\n\t\"AAhandprint.png\",\r\n\t\"AAidcard.png\",\r\n\t\"AAkey.png\",\r\n\t\"AAkeycard.png\",\r\n\t\"AAknife1.png\",\r\n\t\"AAkoptrophy.png\",\r\n\t\"AAleather.png\",\r\n\t\"AAlocker.png\",\r\n\t\"AAlocker2.png\",\r\n\t\"AAlocker3.png\",\r\n\t\"AAluminol.png\",\r\n\t\"AAluminol2.png\",\r\n\t\"AAlunch.png\",\r\n\t\"AAlunch2.png\",\r\n\t\"AAlunch3.png\",\r\n\t\"AAmagatama.png\",\r\n\t\"AAmagatama2.png\",\r\n\t\"AAmayanote.png\",\r\n\t\"AAmayoinote.png\",\r\n\t\"AAmetaldetector.png\",\r\n\t\"AAmissile.png\",\r\n\t\"AAmissile2.png\",\r\n\t\"AAmissle2.png\",\r\n\t\"AAmrmonkey.png\",\r\n\t\"AAnote.png\",\r\n\t\"AAnote2.png\",\r\n\t\"AAnote3.png\",\r\n\t\"AAnote4.png\",\r\n\t\"AAparkingticket.png\",\r\n\t\"AApassport.png\",\r\n\t\"AApassport2.png\",\r\n\t\"AAphone.png\",\r\n\t\"AAphone2.png\",\r\n\t\"AAphone3.png\",\r\n\t\"AAphone4.png\",\r\n\t\"AAphoto.png\",\r\n\t\"AAphoto2.png\",\r\n\t\"AAphoto3.png\",\r\n\t\"AAphoto4.png\",\r\n\t\"AAphoto5.png\",\r\n\t\"AAphoto6.png\",\r\n\t\"AAphoto7.png\",\r\n\t\"AAphoto8.png\",\r\n\t\"AAphoto9.png\",\r\n\t\"AAphoto10.png\",\r\n\t\"AAphoto11.png\",\r\n\t\"AApills.png\",\r\n\t\"AApills2.png\",\r\n\t\"AAplate.png\",\r\n\t\"AAplate2.png\",\r\n\t\"AApolly.png\",\r\n\t\"AAprint.png\",\r\n\t\"AAprint2.png\",\r\n\t\"AAprint3.png\",\r\n\t\"AAprint4.png\",\r\n\t\"AAprint5.png\",\r\n\t\"AAprint6.png\",\r\n\t\"AAprint7.png\",\r\n\t\"AAprint8.png\",\r\n\t\"AApsychelock.png\",\r\n\t\"AAsafe.png\",\r\n\t\"AAscarf.png\",\r\n\t\"AAscrewdriver.png\",\r\n\t\"AAscript.png\",\r\n\t\"AAscript2.png\",\r\n\t\"AAshoe.png\",\r\n\t\"AAshoe2.png\",\r\n\t\"AAspear.png\",\r\n\t\"AAstudiovan.png\",\r\n\t\"AAswitchblade.png\",\r\n\t\"AAswitchblade2.png\",\r\n\t\"AAswitchblade3.png\",\r\n\t\"AAthinker.png\",\r\n\t\"AAvase.png\",\r\n\t\"AAvase2.png\",\r\n\t\"AAvase3.png\",\r\n\t\"AAvase4.png\",\r\n\t\"AAvase5.png\",\r\n\t\"AAvideo.png\",\r\n\t\"AAvideo2.png\",\r\n\t\"AAwallet.png\",\r\n\t\"AAwiretap.png\",\r\n\t\"AJCastAlita.png\",\r\n\t\"AJCastApollo.png\",\r\n\t\"AJCastDaryan.jpg\",\r\n\t\"AJCastDaryan.png\",\r\n\t\"AJCastDrew.png\",\r\n\t\"AJCastEldoon.png\",\r\n\t\"AJCastEma.png\",\r\n\t\"AJCastKlavier.png\",\r\n\t\"AJCastKlavier2.png\",\r\n\t\"AJCastKristoph.png\",\r\n\t\"AJCastLamiroir.png\",\r\n\t\"AJCastLeTouse.png\",\r\n\t\"AJCastMachi.png\",\r\n\t\"AJCastMagnifi.png\",\r\n\t\"AJCastMeraktis.png\",\r\n\t\"AJCastOlga.png\",\r\n\t\"AJCastOlga2.png\",\r\n\t\"AJCastPayne.png\",\r\n\t\"AJCastPhoenix.png\",\r\n\t\"AJCastPlum.png\",\r\n\t\"AJCastShadi.png\",\r\n\t\"AJCastSpark.png\",\r\n\t\"AJCastStickler.png\",\r\n\t\"AJCastThalassa.png\",\r\n\t\"AJCastTrucy.gif\",\r\n\t\"AJCastTrucy.png\",\r\n\t\"AJCastValant.png\",\r\n\t\"AJCastValant2.png\",\r\n\t\"AJCastVera.png\",\r\n\t\"AJCastWinfred.png\",\r\n\t\"AJCastWocky.png\",\r\n\t\"AJCastZak.png\",\r\n\t\"AJad.png\",\r\n\t\"AJad2.png\",\r\n\t\"AJad3.png\",\r\n\t\"AJad4.png\",\r\n\t\"AJad5.png\",\r\n\t\"AJautopsy.png\",\r\n\t\"AJbadge.png\",\r\n\t\"AJbook.png\",\r\n\t\"AJbottle.png\",\r\n\t\"AJbowl.png\",\r\n\t\"AJbox.png\",\r\n\t\"AJbracelet.png\",\r\n\t\"AJbrooch.png\",\r\n\t\"AJbullet.png\",\r\n\t\"AJburntstuff.png\",\r\n\t\"AJbusinesscard.png\",\r\n\t\"AJbusinesscard2.png\",\r\n\t\"AJbusinesscard3.png\",\r\n\t\"AJbusinesscard4.png\",\r\n\t\"AJbusinesscard5.png\",\r\n\t\"AJbusinesscard6.png\",\r\n\t\"AJbutton.png\",\r\n\t\"AJcard.png\",\r\n\t\"AJcard2.png\",\r\n\t\"AJcard3.png\",\r\n\t\"AJcard4.png\",\r\n\t\"AJcard5.png\",\r\n\t\"AJcart.png\",\r\n\t\"AJclip.png\",\r\n\t\"AJclip2.png\",\r\n\t\"AJclip3.png\",\r\n\t\"AJcocoon.png\",\r\n\t\"AJdata1.png\",\r\n\t\"AJdata2.png\",\r\n\t\"AJdata3.png\",\r\n\t\"AJdevice.png\",\r\n\t\"AJdevice2.png\",\r\n\t\"AJdevice3.png\",\r\n\t\"AJearpiece.png\",\r\n\t\"AJfingerprintpowder.png\",\r\n\t\"AJframe.png\",\r\n\t\"AJgoldsnackoo.png\",\r\n\t\"AJguitar.png\",\r\n\t\"AJgun.png\",\r\n\t\"AJgun2.png\",\r\n\t\"AJgun3.png\",\r\n\t\"AJiv.png\",\r\n\t\"AJiv2.png\",\r\n\t\"AJkey.png\",\r\n\t\"AJknife.png\",\r\n\t\"AJlamp.png\",\r\n\t\"AJlocket.png\",\r\n\t\"AJluminol.png\",\r\n\t\"AJmagatama.png\",\r\n\t\"AJmap.png\",\r\n\t\"AJmap2.png\",\r\n\t\"AJmap3.png\",\r\n\t\"AJmap4.png\",\r\n\t\"AJmirror.png\",\r\n\t\"AJmixer.png\",\r\n\t\"AJmrhat.png\",\r\n\t\"AJmug.png\",\r\n\t\"AJnailpolish.png\",\r\n\t\"AJnote.png\",\r\n\t\"AJnote2.png\",\r\n\t\"AJnote3.png\",\r\n\t\"AJnote4.png\",\r\n\t\"AJnote5.png\",\r\n\t\"AJnote6.png\",\r\n\t\"AJnote7.png\",\r\n\t\"AJnote8.png\",\r\n\t\"AJnote9.png\",\r\n\t\"AJnote10.png\",\r\n\t\"AJnote11.png\",\r\n\t\"AJnote12.png\",\r\n\t\"AJnote13.png\",\r\n\t\"AJnote14.png\",\r\n\t\"AJnote15.png\",\r\n\t\"AJnote16.png\",\r\n\t\"AJnote17.png\",\r\n\t\"AJnote18.png\",\r\n\t\"AJnote19.png\",\r\n\t\"AJnote\",\r\n\t\"AJpainting.png\",\r\n\t\"AJpainting2.png\",\r\n\t\"AJpainting3.png\",\r\n\t\"AJpainting4.png\",\r\n\t\"AJpanties.png\",\r\n\t\"AJpanties2.png\",\r\n\t\"AJpanties3.png\",\r\n\t\"AJphone.png\",\r\n\t\"AJphone2.png\",\r\n\t\"AJphoto.png\",\r\n\t\"AJphoto2.png\",\r\n\t\"AJphoto3.png\",\r\n\t\"AJphoto4.png\",\r\n\t\"AJphoto5.png\",\r\n\t\"AJphoto6.png\",\r\n\t\"AJphoto7.png\",\r\n\t\"AJphoto8.png\",\r\n\t\"AJpoisonspray.png\",\r\n\t\"AJsciencekit.png\",\r\n\t\"AJshoe.png\",\r\n\t\"AJshoe2.png\",\r\n\t\"AJshoe3.png\",\r\n\t\"AJsnack.png\",\r\n\t\"AJsnack2.png\",\r\n\t\"AJsnack3.png\",\r\n\t\"AJsnackoos.png\",\r\n\t\"AJstamp.png\",\r\n\t\"AJsyringe.png\",\r\n\t\"AJticket.png\",\r\n\t\"AJticket2.png\",\r\n\t\"AJticket3.png\",\r\n\t\"AJvideo.png\",\r\n\t\"AJxraymachine.png\",\r\n\t\"Compin.png\",\r\n\t\"Credit.png\",\r\n\t\"CustomEvidence1.png\",\r\n\t\"CustomEvidence2.png\",\r\n\t\"CustomEvidence3.png\",\r\n\t\"CustomEvidence4.png\",\r\n\t\"CustomEvidence5.png\",\r\n\t\"CustomEvidence6.png\",\r\n\t\"CustomEvidence7.png\",\r\n\t\"CustomEvidence8.png\",\r\n\t\"CustomEvidence9.png\",\r\n\t\"CustomEvidence10.png\",\r\n\t\"CustomEvidence11.png\",\r\n\t\"CustomEvidence12.png\",\r\n\t\"CustomEvidence13.png\",\r\n\t\"CustomEvidence14.png\",\r\n\t\"CustomEvidence15.png\",\r\n\t\"CustomEvidence16.png\",\r\n\t\"CustomEvidence17.png\",\r\n\t\"CustomEvidence18.png\",\r\n\t\"CustomEvidence19.png\",\r\n\t\"CustomEvidence\",\r\n\t\"DDAutopsy.png\",\r\n\t\"DDBadge.png\",\r\n\t\"DDCaseCandice.png\",\r\n\t\"DDCastApollo.png\",\r\n\t\"DDCastApollo2.png\",\r\n\t\"DDCastApollo3.png\",\r\n\t\"DDCastAthena.png\",\r\n\t\"DDCastAura.png\",\r\n\t\"DDCastBlackquill.png\",\r\n\t\"DDCastCandice.png\",\r\n\t\"DDCastClay.png\",\r\n\t\"DDCastClonco.png\",\r\n\t\"DDCastClonco2.png\",\r\n\t\"DDCastCourte.png\",\r\n\t\"DDCastCrab.png\",\r\n\t\"DDCastDamien.png\",\r\n\t\"DDCastFilch.png\",\r\n\t\"DDCastFulbright.png\",\r\n\t\"DDCastJinxie.png\",\r\n\t\"DDCastJuniper.png\",\r\n\t\"DDCastJuniper2.png\",\r\n\t\"DDCastKlavier.png\",\r\n\t\"DDCastLBelle.png\",\r\n\t\"DDCastLBelle2.png\",\r\n\t\"DDCastMeans.png\",\r\n\t\"DDCastMetis.png\",\r\n\t\"DDCastMiles.png\",\r\n\t\"DDCastNineTails.png\",\r\n\t\"DDCastNorma.png\",\r\n\t\"DDCastOConnor.png\",\r\n\t\"DDCastOrla.png\",\r\n\t\"DDCastPayne.png\",\r\n\t\"DDCastPearl.png\",\r\n\t\"DDCastPhoenix.png\",\r\n\t\"DDCastRex.png\",\r\n\t\"DDCastRimes.png\",\r\n\t\"DDCastRobin.png\",\r\n\t\"DDCastRobin2.png\",\r\n\t\"DDCastSasha.png\",\r\n\t\"DDCastSasha2.png\",\r\n\t\"DDCastSasha3.png\",\r\n\t\"DDCastScuttlebutt.png\",\r\n\t\"DDCastShipley.png\",\r\n\t\"DDCastSniper.png\",\r\n\t\"DDCastSniper2.png\",\r\n\t\"DDCastStarbuck.png\",\r\n\t\"DDCastSummers.png\",\r\n\t\"DDCastTonate.png\",\r\n\t\"DDCastTrucy.png\",\r\n\t\"DDCastYuri.png\",\r\n\t\"DDSTEPladder.png\",\r\n\t\"DDScrewdriver.png\",\r\n\t\"DDStatueStands.png\",\r\n\t\"DDarrow.png\",\r\n\t\"DDbadge2.png\",\r\n\t\"DDbag.png\",\r\n\t\"DDball.png\",\r\n\t\"DDbed.png\",\r\n\t\"DDbomb.png\",\r\n\t\"DDbomb2.png\",\r\n\t\"DDbomb3.png\",\r\n\t\"DDbomb4.png\",\r\n\t\"DDbook.png\",\r\n\t\"DDbook2.png\",\r\n\t\"DDbook3.png\",\r\n\t\"DDbook4.png\",\r\n\t\"DDbook5.png\",\r\n\t\"DDbowl.png\",\r\n\t\"DDbox.png\",\r\n\t\"DDbox2.png\",\r\n\t\"DDbox3.png\",\r\n\t\"DDbox4.png\",\r\n\t\"DDbracelet.png\",\r\n\t\"DDbullet.png\",\r\n\t\"DDbullet2.png\",\r\n\t\"DDbullethole.png\",\r\n\t\"DDcalendar.png\",\r\n\t\"DDcamera.png\",\r\n\t\"DDcamera2.png\",\r\n\t\"DDcamera3.png\",\r\n\t\"DDcart.png\",\r\n\t\"DDcd.png\",\r\n\t\"DDcharm.png\",\r\n\t\"DDclip.png\",\r\n\t\"DDclip2.png\",\r\n\t\"DDclip3.png\",\r\n\t\"DDcloth.png\",\r\n\t\"DDcoin.png\",\r\n\t\"DDcoin2.png\",\r\n\t\"DDcomputer.png\",\r\n\t\"DDcostume.png\",\r\n\t\"DDcostume2.png\",\r\n\t\"DDcostumes.png\",\r\n\t\"DDdata.png\",\r\n\t\"DDdata2.png\",\r\n\t\"DDdata3.png\",\r\n\t\"DDdetonator.png\",\r\n\t\"DDdoor.png\",\r\n\t\"DDdoor2.png\",\r\n\t\"DDdoor3.png\",\r\n\t\"DDdye.png\",\r\n\t\"DDearring.png\",\r\n\t\"DDemblem.png\",\r\n\t\"DDenvelope.png\",\r\n\t\"DDfingerprint.png\",\r\n\t\"DDfingerprintpowder.png\",\r\n\t\"DDfish.png\",\r\n\t\"DDflower.png\",\r\n\t\"DDfood.png\",\r\n\t\"DDfood2.png\",\r\n\t\"DDgun.png\",\r\n\t\"DDhair.png\",\r\n\t\"DDhairspray.png\",\r\n\t\"DDhandprint.png\",\r\n\t\"DDhat.png\",\r\n\t\"DDheadphones.png\",\r\n\t\"DDkey.png\",\r\n\t\"DDkey2.png\",\r\n\t\"DDkey3.png\",\r\n\t\"DDkeycard.png\",\r\n\t\"DDkeycard2.png\",\r\n\t\"DDkeycard3.png\",\r\n\t\"DDkeycard4.png\",\r\n\t\"DDkeycard5.png\",\r\n\t\"DDkeycard6.png\",\r\n\t\"DDkeycard7.png\",\r\n\t\"DDknife.png\",\r\n\t\"DDladder.png\",\r\n\t\"DDladder2.png\",\r\n\t\"DDlighter.png\",\r\n\t\"DDluminol.png\",\r\n\t\"DDmagatama.png\",\r\n\t\"DDmagatama2.png\",\r\n\t\"DDmap.png\",\r\n\t\"DDmap2.png\",\r\n\t\"DDmap3.png\",\r\n\t\"DDmap4.png\",\r\n\t\"DDmap5.png\",\r\n\t\"DDmap6.png\",\r\n\t\"DDmap7.png\",\r\n\t\"DDmap8.png\",\r\n\t\"DDmap9.png\",\r\n\t\"DDmap10.png\",\r\n\t\"DDmap11.png\",\r\n\t\"DDmap12.png\",\r\n\t\"DDmask.png\",\r\n\t\"DDmedicine.png\",\r\n\t\"DDmedicine2.png\",\r\n\t\"DDmedicine3.png\",\r\n\t\"DDnote.png\",\r\n\t\"DDnote2.png\",\r\n\t\"DDnote4.png\",\r\n\t\"DDnote5.png\",\r\n\t\"DDnote6.png\",\r\n\t\"DDnote7.png\",\r\n\t\"DDnote8.png\",\r\n\t\"DDnote9.png\",\r\n\t\"DDnote10.png\",\r\n\t\"DDnote16.png\",\r\n\t\"DDpenguin.png\",\r\n\t\"DDphone.png\",\r\n\t\"DDphone2.png\",\r\n\t\"DDphoto.png\",\r\n\t\"DDphoto2.png\",\r\n\t\"DDphoto3.png\",\r\n\t\"DDphoto4.png\",\r\n\t\"DDphoto5.png\",\r\n\t\"DDphoto6.png\",\r\n\t\"DDphoto7.png\",\r\n\t\"DDphoto10.png\",\r\n\t\"DDphoto11.png\",\r\n\t\"DDphoto12.png\",\r\n\t\"DDphoto13.png\",\r\n\t\"DDphoto14.png\",\r\n\t\"DDphoto15.png\",\r\n\t\"DDplate.png\",\r\n\t\"DDposter.png\",\r\n\t\"DDposter2.png\",\r\n\t\"DDposter3.png\",\r\n\t\"DDpuppet.png\",\r\n\t\"DDrecorder.png\",\r\n\t\"DDscienceglasses.png\",\r\n\t\"DDscroll.png\",\r\n\t\"DDshard.png\",\r\n\t\"DDshard2.png\",\r\n\t\"DDshard3.png\",\r\n\t\"DDshard4.png\",\r\n\t\"DDshard5.png\",\r\n\t\"DDshard6.png\",\r\n\t\"DDshard7.png\",\r\n\t\"DDshoe.png\",\r\n\t\"DDskull.png\",\r\n\t\"DDstaff.png\",\r\n\t\"DDstatue.png\",\r\n\t\"DDstatue2.png\",\r\n\t\"DDstatue3.png\",\r\n\t\"DDstatue4.png\",\r\n\t\"DDstatue5.png\",\r\n\t\"DDstatue6.png\",\r\n\t\"DDstatue7.png\",\r\n\t\"DDstatue8.png\",\r\n\t\"DDstatue9.png\",\r\n\t\"DDsurgery.png\",\r\n\t\"DDsuspect.png\",\r\n\t\"DDsword.png\",\r\n\t\"DDsword2.png\",\r\n\t\"DDtail.png\",\r\n\t\"DDtank.png\",\r\n\t\"DDtank2.png\",\r\n\t\"DDvideo.png\",\r\n\t\"DDwhistle.png\",\r\n\t\"DDwidget.png\",\r\n\t\"DGSCastAuchi.png\",\r\n\t\"DGSCastBarok.png\",\r\n\t\"DGSCastBeppo.png\",\r\n\t\"DGSCastCrogrey.png\",\r\n\t\"DGSCastDemiglaski.png\",\r\n\t\"DGSCastFairplay.png\",\r\n\t\"DGSCastGina.png\",\r\n\t\"DGSCastGreen.png\",\r\n\t\"DGSCastGregson.png\",\r\n\t\"DGSCastHolmes.png\",\r\n\t\"DGSCastHosonaga.png\",\r\n\t\"DGSCastHosonaga2.png\",\r\n\t\"DGSCastHutch.png\",\r\n\t\"DGSCastJWatson.png\",\r\n\t\"DGSCastJezail.png\",\r\n\t\"DGSCastJoan.png\",\r\n\t\"DGSCastJohn.png\",\r\n\t\"DGSCastKazuma.png\",\r\n\t\"DGSCastLadyfirst.png\",\r\n\t\"DGSCastMegundal.png\",\r\n\t\"DGSCastMilverton.png\",\r\n\t\"DGSCastNatsume.png\",\r\n\t\"DGSCastNemmy.png\",\r\n\t\"DGSCastNikomina.png\",\r\n\t\"DGSCastPat.png\",\r\n\t\"DGSCastRola.png\",\r\n\t\"DGSCastRoylott.png\",\r\n\t\"DGSCastRyuunosuke.png\",\r\n\t\"DGSCastSanmon.png\",\r\n\t\"DGSCastStroganov.png\",\r\n\t\"DGSCastSusato.png\",\r\n\t\"DGSCastSuspect.png\",\r\n\t\"DGSCastTaizou.png\",\r\n\t\"DGSCastTully.png\",\r\n\t\"DGSCastVortex.png\",\r\n\t\"DGSCastWagahai.png\",\r\n\t\"DGSCastWatson.png\",\r\n\t\"DGSCastYuujin.png\",\r\n\t\"DGSbadge.png\",\r\n\t\"DGSbag.png\",\r\n\t\"DGSbag2.png\",\r\n\t\"DGSbell.png\",\r\n\t\"DGSbell2.png\",\r\n\t\"DGSbell3.png\",\r\n\t\"DGSbook.png\",\r\n\t\"DGSbook2.png\",\r\n\t\"DGSbook3.png\",\r\n\t\"DGSbook4.png\",\r\n\t\"DGSbook5.png\",\r\n\t\"DGSbook6.png\",\r\n\t\"DGSbook7.png\",\r\n\t\"DGSbook8.png\",\r\n\t\"DGSbook9.png\",\r\n\t\"DGSbook10.png\",\r\n\t\"DGSbullet.png\",\r\n\t\"DGScamera.png\",\r\n\t\"DGScane.png\",\r\n\t\"DGScart.png\",\r\n\t\"DGSclip.png\",\r\n\t\"DGSclip2.png\",\r\n\t\"DGSclip3.png\",\r\n\t\"DGSclip4.png\",\r\n\t\"DGScoin.png\",\r\n\t\"DGSdevice.png\",\r\n\t\"DGSflower.png\",\r\n\t\"DGSfood.png\",\r\n\t\"DGSfood2.png\",\r\n\t\"DGSfood3.png\",\r\n\t\"DGSfood4.png\",\r\n\t\"DGSgloves.png\",\r\n\t\"DGSgloves2.png\",\r\n\t\"DGSgun.png\",\r\n\t\"DGSgun2.png\",\r\n\t\"DGSgun3.png\",\r\n\t\"DGSherbaltea.png\",\r\n\t\"DGSknife.png\",\r\n\t\"DGSknife2.png\",\r\n\t\"DGSknife3.png\",\r\n\t\"DGSknife4.png\",\r\n\t\"DGSmap.png\",\r\n\t\"DGSmap2.png\",\r\n\t\"DGSmap3.png\",\r\n\t\"DGSmusicbox.png\",\r\n\t\"DGSmusicbox2.png\",\r\n\t\"DGSmusicbox3.png\",\r\n\t\"DGSmusicdisk.png\",\r\n\t\"DGSmusicdisk2.png\",\r\n\t\"DGSmusicdisk3.png\",\r\n\t\"DGSmusicdisk4.png\",\r\n\t\"DGSmusicdisk15.png\",\r\n\t\"DGSnote.png\",\r\n\t\"DGSnote2.png\",\r\n\t\"DGSnote3.png\",\r\n\t\"DGSnote4.png\",\r\n\t\"DGSnote5.png\",\r\n\t\"DGSnote6.png\",\r\n\t\"DGSnote7.png\",\r\n\t\"DGSnote8.png\",\r\n\t\"DGSnote9.png\",\r\n\t\"DGSnote10.png\",\r\n\t\"DGSnote11.png\",\r\n\t\"DGSnote12.png\",\r\n\t\"DGSnote13.png\",\r\n\t\"DGSnote14.png\",\r\n\t\"DGSnote15.png\",\r\n\t\"DGSnote16.png\",\r\n\t\"DGSnote17.png\",\r\n\t\"DGSnote18.png\",\r\n\t\"DGSnote19.png\",\r\n\t\"DGSnote\",\r\n\t\"DGSnote21.png\",\r\n\t\"DGSphoto.png\",\r\n\t\"DGSphoto2.png\",\r\n\t\"DGSphoto3.png\",\r\n\t\"DGSphoto4.png\",\r\n\t\"DGSphoto5.png\",\r\n\t\"DGSphoto6.png\",\r\n\t\"DGSphoto7.png\",\r\n\t\"DGSphoto8.png\",\r\n\t\"DGSphoto9.png\",\r\n\t\"DGSphoto10.png\",\r\n\t\"DGSphoto11.png\",\r\n\t\"DGSphoto12.png\",\r\n\t\"DGSphoto13.png\",\r\n\t\"DGSphoto14.png\",\r\n\t\"DGSphoto15.png\",\r\n\t\"DGSphoto16.png\",\r\n\t\"DGSphoto17.png\",\r\n\t\"DGSphoto18.png\",\r\n\t\"DGSphoto19.png\",\r\n\t\"DGSpin.png\",\r\n\t\"DGSpin2.png\",\r\n\t\"DGSpipe.png\",\r\n\t\"DGSpressing.png\",\r\n\t\"DGSsciencekit.png\",\r\n\t\"DGSshard.png\",\r\n\t\"DGSstereoscope.png\",\r\n\t\"DGSstereoscope2.png\",\r\n\t\"DGStiara.png\",\r\n\t\"DGSviola.png\",\r\n\t\"DGSviola2.png\",\r\n\t\"DGSwhip.png\",\r\n\t\"Datapad.png\",\r\n\t\"Interface.png\",\r\n\t\"JFACastAcro.png\",\r\n\t\"JFACastAdrian.png\",\r\n\t\"JFACastAmi.png\",\r\n\t\"JFACastBat.png\",\r\n\t\"JFACastBen.png\",\r\n\t\"JFACastCeleste.png\",\r\n\t\"JFACastDeKiller.png\",\r\n\t\"JFACastDustin.png\",\r\n\t\"JFACastFranziska.png\",\r\n\t\"JFACastGalactica.png\",\r\n\t\"JFACastGrey.png\",\r\n\t\"JFACastHotti.png\",\r\n\t\"JFACastIni.png\",\r\n\t\"JFACastJuan.png\",\r\n\t\"JFACastMaggey.png\",\r\n\t\"JFACastMatt.png\",\r\n\t\"JFACastMimi.png\",\r\n\t\"JFACastMoe.png\",\r\n\t\"JFACastMorgan.png\",\r\n\t\"JFACastPearl.png\",\r\n\t\"JFACastRegina.png\",\r\n\t\"JFACastRussel.png\",\r\n\t\"JFACastShelly.png\",\r\n\t\"JFACastWellington.png\",\r\n\t\"JFATHATCARD.png\",\r\n\t\"JFATHATCARD2.png\",\r\n\t\"JFAautograph.png\",\r\n\t\"JFAautograph2.png\",\r\n\t\"JFAball.png\",\r\n\t\"JFAball2.png\",\r\n\t\"JFAbear.png\",\r\n\t\"JFAbear2.png\",\r\n\t\"JFAbear3.png\",\r\n\t\"JFAbottle.png\",\r\n\t\"JFAbox.png\",\r\n\t\"JFAbox2.png\",\r\n\t\"JFAbusinesscard.png\",\r\n\t\"JFAbusinesscard2.png\",\r\n\t\"JFAbutton.png\",\r\n\t\"JFAbutton2.png\",\r\n\t\"JFAbutton3.png\",\r\n\t\"JFAcamera.png\",\r\n\t\"JFAcard.png\",\r\n\t\"JFAcard2.png\",\r\n\t\"JFAclip.png\",\r\n\t\"JFAclip2.png\",\r\n\t\"JFAclip3.png\",\r\n\t\"JFAclip4.png\",\r\n\t\"JFAcoat.png\",\r\n\t\"JFAfrequencydetector.png\",\r\n\t\"JFAglasses.png\",\r\n\t\"JFAglove.png\",\r\n\t\"JFAgrapes.png\",\r\n\t\"JFAguitar.png\",\r\n\t\"JFAgun.png\",\r\n\t\"JFAgun2.png\",\r\n\t\"JFAhammond.png\",\r\n\t\"JFAhat.png\",\r\n\t\"JFAjuice.png\",\r\n\t\"JFAkey.png\",\r\n\t\"JFAknife.png\",\r\n\t\"JFAknife2.png\",\r\n\t\"JFAleon.png\",\r\n\t\"JFAmilk.png\",\r\n\t\"JFAmilk2.png\",\r\n\t\"JFAmoney.png\",\r\n\t\"JFAnote.png\",\r\n\t\"JFAnote2.png\",\r\n\t\"JFApepper.png\",\r\n\t\"JFAphoto.png\",\r\n\t\"JFAposter.png\",\r\n\t\"JFAreceipt.png\",\r\n\t\"JFAregent.png\",\r\n\t\"JFAring.png\",\r\n\t\"JFArobe.png\",\r\n\t\"JFArobescrap.png\",\r\n\t\"JFAscarf.png\",\r\n\t\"JFAscreen.png\",\r\n\t\"JFAshoe.png\",\r\n\t\"JFAspycamera.png\",\r\n\t\"JFAticket.png\",\r\n\t\"JFAticket2.png\",\r\n\t\"JFAtracker.png\",\r\n\t\"JFAtransceiver.png\",\r\n\t\"JFAtransmitter.png\",\r\n\t\"JFAtrilo.png\",\r\n\t\"JFAuniform.png\",\r\n\t\"JFAurn1.png\",\r\n\t\"JFAurn2.png\",\r\n\t\"JFAvest.png\",\r\n\t\"JFAwhip.png\",\r\n\t\"MiscAKMS.png\",\r\n\t\"MiscAsthmaPump.png\",\r\n\t\"MiscBaggie.png\",\r\n\t\"MiscBeach.png\",\r\n\t\"MiscBlueRuby.png\",\r\n\t\"MiscCandy Cane.png\",\r\n\t\"MiscCandy Cane Dark.png\",\r\n\t\"MiscCorkscrew.png\",\r\n\t\"MiscCrowbar.png\",\r\n\t\"MiscDragonPepper.png\",\r\n\t\"MiscFlintlock.png\",\r\n\t\"MiscGenerator.png\",\r\n\t\"MiscGrapeJuice.png\",\r\n\t\"MiscGreen Hut.png\",\r\n\t\"MiscGrill.png\",\r\n\t\"MiscHalf-Eaten Burger.png\",\r\n\t\"MiscHangGlider.png\",\r\n\t\"MiscLockpicks.png\",\r\n\t\"MiscMapBiolab.png\",\r\n\t\"MiscMapCourthouse.png\",\r\n\t\"MiscMapLobby1.png\",\r\n\t\"MiscMichigan J Frog.png\",\r\n\t\"MiscMystery1.png\",\r\n\t\"MiscMystery2.png\",\r\n\t\"MiscMystery3.png\",\r\n\t\"MiscOldTrain.png\",\r\n\t\"MiscRaffleTickets.png\",\r\n\t\"MiscSpatula.png\",\r\n\t\"MiscSpecimenAlpha.png\",\r\n\t\"MiscTimeCrystal.png\",\r\n\t\"MiscTins.png\",\r\n\t\"MiscUnknown People.png\",\r\n\t\"MiscVDF.png\",\r\n\t\"MiscVodka.png\",\r\n\t\"MiscZombie.png\",\r\n\t\"Scanner.png\",\r\n\t\"SoJad.png\",\r\n\t\"SoJad2.png\",\r\n\t\"SoJad3.png\",\r\n\t\"SoJad4.png\",\r\n\t\"SoJad5.png\",\r\n\t\"SoJad6.png\",\r\n\t\"SoJad7.png\",\r\n\t\"SoJarrow.png\",\r\n\t\"SoJautopsy.png\",\r\n\t\"SoJbadge.png\",\r\n\t\"SoJbadge2.png\",\r\n\t\"SoJblimp.png\",\r\n\t\"SoJblimp2.png\",\r\n\t\"SoJblood.png\",\r\n\t\"SoJboiler.png\",\r\n\t\"SoJbook.png\",\r\n\t\"SoJbook2.png\",\r\n\t\"SoJbook3.png\",\r\n\t\"SoJbook4.png\",\r\n\t\"SoJbook5.png\",\r\n\t\"SoJbook6.png\",\r\n\t\"SoJbook7.png\",\r\n\t\"SoJbook8.png\",\r\n\t\"SoJbook9.png\",\r\n\t\"SoJbook10.png\",\r\n\t\"SoJbook11.png\",\r\n\t\"SoJbook12.png\",\r\n\t\"SoJbook13.png\",\r\n\t\"SoJbook14.png\",\r\n\t\"SoJbox.png\",\r\n\t\"SoJbox2.png\",\r\n\t\"SoJbracelet.png\",\r\n\t\"SoJbucket.png\",\r\n\t\"SoJcamera.png\",\r\n\t\"SoJcandelabra.png\",\r\n\t\"SoJcandelabra2.png\",\r\n\t\"SoJcandelabra3.png\",\r\n\t\"SoJcastAhlbi.png\",\r\n\t\"SoJcastAmara.png\",\r\n\t\"SoJcastAndistan'dhin.png\",\r\n\t\"SoJcastApollo.png\",\r\n\t\"SoJcastArchie.png\",\r\n\t\"SoJcastArmie.png\",\r\n\t\"SoJcastAthena.png\",\r\n\t\"SoJcastAtishon.png\",\r\n\t\"SoJcastBeh'leeb.png\",\r\n\t\"SoJcastBetty.png\",\r\n\t\"SoJcastBlackquill.png\",\r\n\t\"SoJcastBonny.png\",\r\n\t\"SoJcastBucky.png\",\r\n\t\"SoJcastButz.png\",\r\n\t\"SoJcastDatz.png\",\r\n\t\"SoJcastDatz2.png\",\r\n\t\"SoJcastDhurke.png\",\r\n\t\"SoJcastDumas.png\",\r\n\t\"SoJcastEllen.png\",\r\n\t\"SoJcastEma.png\",\r\n\t\"SoJcastGa'ran.png\",\r\n\t\"SoJcastGeiru.png\",\r\n\t\"SoJcastInga.png\",\r\n\t\"SoJcastMaya.png\",\r\n\t\"SoJcastMiles.png\",\r\n\t\"SoJcastNahyuta.png\",\r\n\t\"SoJcastNayna.png\",\r\n\t\"SoJcastPayne.png\",\r\n\t\"SoJcastPearl.png\",\r\n\t\"SoJcastPhoenix.png\",\r\n\t\"SoJcastPierce.png\",\r\n\t\"SoJcastPuhray.png\",\r\n\t\"SoJcastRayfa.png\",\r\n\t\"SoJcastRetinz.png\",\r\n\t\"SoJcastReus.png\",\r\n\t\"SoJcastRohl.png\",\r\n\t\"SoJcastSelena.png\",\r\n\t\"SoJcastSergeant.png\",\r\n\t\"SoJcastSorin.png\",\r\n\t\"SoJcastTahrust.png\",\r\n\t\"SoJcastTaifu.png\",\r\n\t\"SoJcastTrucy.png\",\r\n\t\"SoJcastUendo.png\",\r\n\t\"SoJcd.png\",\r\n\t\"SoJcd2.png\",\r\n\t\"SoJcharm.png\",\r\n\t\"SoJclip.png\",\r\n\t\"SoJclip2.png\",\r\n\t\"SoJcog.png\",\r\n\t\"SoJcontract.png\",\r\n\t\"SoJdog.png\",\r\n\t\"SoJflag.png\",\r\n\t\"SoJflower.png\",\r\n\t\"SoJfood1.png\",\r\n\t\"SoJfood2.png\",\r\n\t\"SoJfood3.png\",\r\n\t\"SoJgem.png\",\r\n\t\"SoJglasses.png\",\r\n\t\"SoJgoop.png\",\r\n\t\"SoJhat.png\",\r\n\t\"SoJhelicopter.png\",\r\n\t\"SoJhorse.png\",\r\n\t\"SoJhorse2.png\",\r\n\t\"SoJkey.png\",\r\n\t\"SoJkey2.png\",\r\n\t\"SoJkey3.png\",\r\n\t\"SoJkey4.png\",\r\n\t\"SoJkeycard.png\",\r\n\t\"SoJkeycharm.png\",\r\n\t\"SoJlantern.png\",\r\n\t\"SoJlantern2.png\",\r\n\t\"SoJluminol.png\",\r\n\t\"SoJmagatama.png\",\r\n\t\"SoJmagatama2.png\",\r\n\t\"SoJmagatama3.png\",\r\n\t\"SoJmap.png\",\r\n\t\"SoJmap2.png\",\r\n\t\"SoJmap3.png\",\r\n\t\"SoJmap4.png\",\r\n\t\"SoJmap5.png\",\r\n\t\"SoJmap6.png\",\r\n\t\"SoJmap7.png\",\r\n\t\"SoJmrhat.png\",\r\n\t\"SoJnote.png\",\r\n\t\"SoJnote2.png\",\r\n\t\"SoJnote3.png\",\r\n\t\"SoJnote4.png\",\r\n\t\"SoJnote5.png\",\r\n\t\"SoJnote6.png\",\r\n\t\"SoJnote7.png\",\r\n\t\"SoJnote8.png\",\r\n\t\"SoJnote9.png\",\r\n\t\"SoJnote10.png\",\r\n\t\"SoJnote11.png\",\r\n\t\"SoJnote12.png\",\r\n\t\"SoJnote13.png\",\r\n\t\"SoJnote14.png\",\r\n\t\"SoJnote15.png\",\r\n\t\"SoJnote16.png\",\r\n\t\"SoJnote17.png\",\r\n\t\"SoJorb.png\",\r\n\t\"SoJpassport.png\",\r\n\t\"SoJpendant.png\",\r\n\t\"SoJphone.png\",\r\n\t\"SoJphoto.png\",\r\n\t\"SoJphoto2.png\",\r\n\t\"SoJphoto3.png\",\r\n\t\"SoJphoto4.png\",\r\n\t\"SoJphoto5.png\",\r\n\t\"SoJphoto6.png\",\r\n\t\"SoJphoto7.png\",\r\n\t\"SoJphoto8.png\",\r\n\t\"SoJphoto9.png\",\r\n\t\"SoJphoto10.png\",\r\n\t\"SoJphoto11.png\",\r\n\t\"SoJphoto12.png\",\r\n\t\"SoJphoto13.png\",\r\n\t\"SoJphoto14.png\",\r\n\t\"SoJphoto15.png\",\r\n\t\"SoJphoto16.png\",\r\n\t\"SoJphoto17.png\",\r\n\t\"SoJphoto18.png\",\r\n\t\"SoJphoto19.png\",\r\n\t\"SoJphoto\",\r\n\t\"SoJphoto21.png\",\r\n\t\"SoJphoto22.png\",\r\n\t\"SoJphoto23.png\",\r\n\t\"SoJphoto24.png\",\r\n\t\"SoJphoto25.png\",\r\n\t\"SoJphoto26.png\",\r\n\t\"SoJphoto27.png\",\r\n\t\"SoJphoto28.png\",\r\n\t\"SoJprintpowder.png\",\r\n\t\"SoJraincoat.png\",\r\n\t\"SoJscissorlift.png\",\r\n\t\"SoJscroll.png\",\r\n\t\"SoJscroll2.png\",\r\n\t\"SoJsnackoo.png\",\r\n\t\"SoJstand.png\",\r\n\t\"SoJstatue.png\",\r\n\t\"SoJsuspect.png\",\r\n\t\"SoJsword.png\",\r\n\t\"SoJsword2.png\",\r\n\t\"SoJsyringe.png\",\r\n\t\"SoJtape1.png\",\r\n\t\"SoJtext.png\",\r\n\t\"SoJunknown.png\",\r\n\t\"SoJurn.png\",\r\n\t\"SoJusb.png\",\r\n\t\"SoJwallet.png\",\r\n\t\"SoJwidget.png\",\r\n\t\"TTCastAdrian.png\",\r\n\t\"TTCastArmstrong.png\",\r\n\t\"TTCastAtmey.png\",\r\n\t\"TTCastBikini.png\",\r\n\t\"TTCastBruto.png\",\r\n\t\"TTCastBullard.png\",\r\n\t\"TTCastDahlia.png\",\r\n\t\"TTCastDeMasque.png\",\r\n\t\"TTCastDesiree.png\",\r\n\t\"TTCastDiego.png\",\r\n\t\"TTCastElg.png\",\r\n\t\"TTCastElise.png\",\r\n\t\"TTCastFawles.png\",\r\n\t\"TTCastGodot.png\",\r\n\t\"TTCastGrossberg.png\",\r\n\t\"TTCastGumshoe.png\",\r\n\t\"TTCastIris.png\",\r\n\t\"TTCastIris2.png\",\r\n\t\"TTCastKudo.png\",\r\n\t\"TTCastLisa.png\",\r\n\t\"TTCastMaggey.png\",\r\n\t\"TTCastMiles.png\",\r\n\t\"TTCastRon.png\",\r\n\t\"TTCastSwallow.png\",\r\n\t\"TTCastTigre.png\",\r\n\t\"TTCastValerie.png\",\r\n\t\"TTCastViola.png\",\r\n\t\"TTad.png\",\r\n\t\"TTad2.png\",\r\n\t\"TTapron.png\",\r\n\t\"TTbadge.png\",\r\n\t\"TTbag.png\",\r\n\t\"TTblood1.png\",\r\n\t\"TTblood2.png\",\r\n\t\"TTbottle1.png\",\r\n\t\"TTbottle2.png\",\r\n\t\"TTbox.png\",\r\n\t\"TTbox2.png\",\r\n\t\"TTbutton.png\",\r\n\t\"TTcalendar.png\",\r\n\t\"TTcamera.png\",\r\n\t\"TTcard.png\",\r\n\t\"TTcd.png\",\r\n\t\"TTcd2.png\",\r\n\t\"TTclip.png\",\r\n\t\"TTclip2.png\",\r\n\t\"TTclip3.png\",\r\n\t\"TTclip4.png\",\r\n\t\"TTclip5.png\",\r\n\t\"TTcoldkiller.png\",\r\n\t\"TTcoldkiller2.png\",\r\n\t\"TTcup.png\",\r\n\t\"TTdata.png\",\r\n\t\"TTdata2.png\",\r\n\t\"TTdata3.png\",\r\n\t\"TTdata4.png\",\r\n\t\"TTdrawing.png\",\r\n\t\"TTemblem.png\",\r\n\t\"TTemployee.png\",\r\n\t\"TTfood1.png\",\r\n\t\"TTfood2.png\",\r\n\t\"TThood.png\",\r\n\t\"TTjewel.png\",\r\n\t\"TTjewel2.png\",\r\n\t\"TTkeycard.png\",\r\n\t\"TTknife.png\",\r\n\t\"TTlantern.png\",\r\n\t\"TTlantern2.png\",\r\n\t\"TTmagazine.png\",\r\n\t\"TTmagazine2.png\",\r\n\t\"TTmatchbook.png\",\r\n\t\"TTmatchbook2.png\",\r\n\t\"TTmedicine.png\",\r\n\t\"TTmedicine2.png\",\r\n\t\"TTmoped.png\",\r\n\t\"TTnecklace.png\",\r\n\t\"TTnote.png\",\r\n\t\"TTnote2.png\",\r\n\t\"TTnote3.png\",\r\n\t\"TTnote4.png\",\r\n\t\"TTnote5.png\",\r\n\t\"TTnote6.png\",\r\n\t\"TTnote7.png\",\r\n\t\"TTperfume.png\",\r\n\t\"TTphotoold.png\",\r\n\t\"TTsapphire.png\",\r\n\t\"TTscarf.png\",\r\n\t\"TTschichishito.png\",\r\n\t\"TTschichishito2.png\",\r\n\t\"TTschichishito3.png\",\r\n\t\"TTscroll.png\",\r\n\t\"TTscroll2.png\",\r\n\t\"TTseal.png\",\r\n\t\"TTseal2.png\",\r\n\t\"TTstaff.png\",\r\n\t\"TTstaff2.png\",\r\n\t\"TTstaff3.png\",\r\n\t\"TTstain.png\",\r\n\t\"TTstatue.png\",\r\n\t\"TTticket.png\",\r\n\t\"TTticket2.png\",\r\n\t\"TTumbrella.png\",\r\n\t\"TTvase.png\",\r\n\t\"TTvase2.png\",\r\n\t\"TTvase3.png\",\r\n\t\"TTvase4.png\",\r\n\t\"TTwallet.png\",\r\n\t\"TTwatch.png\",\r\n\t\"Vivaster.png\",\r\n\t\"empty.png\",\r\n\t\"lawyerbadge.png\"\r\n];","export default [\r\n\t\"1st server\",\r\n\t\"999.1\",\r\n\t\"999\",\r\n\t\"999Apartment\",\r\n\t\"999CaptainsQuarters\",\r\n\t\"999Cargo\",\r\n\t\"999Casino\",\r\n\t\"999Cdeck\",\r\n\t\"999CentralStairs\",\r\n\t\"999Chapel\",\r\n\t\"999Chart\",\r\n\t\"999Confinement\",\r\n\t\"999DoorsA\",\r\n\t\"999DoorsB\",\r\n\t\"999Hospital\",\r\n\t\"999Kitchen\",\r\n\t\"999Library\",\r\n\t\"999Operating\",\r\n\t\"999Shower\",\r\n\t\"999Steam\",\r\n\t\"999Steeldoor\",\r\n\t\"999Study\",\r\n\t\"999Torture\",\r\n\t\"9991stClassCabinA\",\r\n\t\"9991stClassCabinB\",\r\n\t\"9992ndClassCabin\",\r\n\t\"AA - Edgewort's Office\",\r\n\t\"AA - Gantsroom\",\r\n\t\"AA - Gatewater room\",\r\n\t\"AA - Gourd Lake\",\r\n\t\"AA - Gourd Lake Entrance\",\r\n\t\"AA - Hotel Lobby\",\r\n\t\"AA - Hotticlinic\",\r\n\t\"AA - Kurain\",\r\n\t\"AA - Parkinglot\",\r\n\t\"AA - Police Deparment\",\r\n\t\"AA - Police Station\",\r\n\t\"AA - Records Room\",\r\n\t\"AA - Sc13\",\r\n\t\"AA - Wright's Office\",\r\n\t\"AABluecorp\",\r\n\t\"AACourt\",\r\n\t\"AACourtAnime\",\r\n\t\"AACourtChristmasDecorations\",\r\n\t\"AACourtChristmasLights\",\r\n\t\"AACourtHD\",\r\n\t\"AADefendantLobby\",\r\n\t\"AADefendantLobbyHD\",\r\n\t\"AADetentionCenter\",\r\n\t\"AAEdgeworthOffice\",\r\n\t\"AAGantOffice\",\r\n\t\"AAGatewaterHotel\",\r\n\t\"AAGlobalStudiosEast\",\r\n\t\"AAGlobalStudiosWest\",\r\n\t\"AAGourdLake\",\r\n\t\"AAGrossbergOffice\",\r\n\t\"AAI2Circus\",\r\n\t\"AAI2City\",\r\n\t\"AAI2GourdLake\",\r\n\t\"AAI2LogicChess\",\r\n\t\"AAI2MuseumPast\",\r\n\t\"AAI2MuseumPresent\",\r\n\t\"AAI2PIC\",\r\n\t\"AAI2Prison\",\r\n\t\"AAICohdopianEmbassy\",\r\n\t\"AAICourt\",\r\n\t\"AAICourtFlipped\",\r\n\t\"AAIEdgeworthOffice\",\r\n\t\"AAIGatewaterLandStage\",\r\n\t\"AAIGatewaterLandWildWest\",\r\n\t\"AAIiFlyAirlines\",\r\n\t\"AALobby\",\r\n\t\"AAParkingLot\",\r\n\t\"AAPoliceStation\",\r\n\t\"AATrainStation\",\r\n\t\"AAWrightOffice\",\r\n\t\"AJBorschtBowlClub\",\r\n\t\"AJCourt\",\r\n\t\"AJCourtBirthday\",\r\n\t\"AJCourtHalloween\",\r\n\t\"AJCourtNight\",\r\n\t\"AJCourtTV\",\r\n\t\"AJDefendantLobby\",\r\n\t\"AJDetentionCenter\",\r\n\t\"AJDrewStudio\",\r\n\t\"AJHottiClinic\",\r\n\t\"AJKlavierOffice\",\r\n\t\"AJKristophCell\",\r\n\t\"AJLobby\",\r\n\t\"AJMeraktisClinic\",\r\n\t\"AJPeoplePark\",\r\n\t\"AJSunshineColiseum\",\r\n\t\"AJWrightOffice\",\r\n\t\"Ace\",\r\n\t\"AcroRoomJFA\",\r\n\t\"AirportJFA\",\r\n\t\"AlbaOfficeAAI\",\r\n\t\"Anime\",\r\n\t\"Arcade\",\r\n\t\"AtmeyOfficeTT\",\r\n\t\"Atrium (SG)\",\r\n\t\"AutumnForest\",\r\n\t\"BB - Flowerfield\",\r\n\t\"BB - Market\",\r\n\t\"BB - Street\",\r\n\t\"BandoLandAAI\",\r\n\t\"Basement\",\r\n\t\"Battlegrounds\",\r\n\t\"BerryBigCircusJFA\",\r\n\t\"Blackout\",\r\n\t\"BlueScreensTT\",\r\n\t\"BluecorpAA\",\r\n\t\"BridgeNest\",\r\n\t\"Brig\",\r\n\t\"Building\",\r\n\t\"CC1\",\r\n\t\"CC2\",\r\n\t\"CC3\",\r\n\t\"CC4\",\r\n\t\"CC5\",\r\n\t\"CC6\",\r\n\t\"CC7\",\r\n\t\"CC8\",\r\n\t\"CC9\",\r\n\t\"CC10\",\r\n\t\"CC11\",\r\n\t\"CC12\",\r\n\t\"CO - Big door\",\r\n\t\"CO - Finalroom\",\r\n\t\"CO - Meetingroom\",\r\n\t\"CO - Whitedoor\",\r\n\t\"CO - Whitelobby\",\r\n\t\"CO - Whitelowerfloor\",\r\n\t\"CO - White room\",\r\n\t\"CP\",\r\n\t\"CPRP2 Chap1\",\r\n\t\"CPRP2 Chap2and3\",\r\n\t\"CPRP2 Chap4\",\r\n\t\"CPRP2 Chap5\",\r\n\t\"CPRP Chap1\",\r\n\t\"CPRP Chap2\",\r\n\t\"CPRP Chap3\",\r\n\t\"CPRP Chap4\",\r\n\t\"CPRP Chap5\",\r\n\t\"CVStMystere\",\r\n\t\"Cafe\",\r\n\t\"CafeCourt\",\r\n\t\"CaffeeCase\",\r\n\t\"Cal\",\r\n\t\"CargoHoldAAI\",\r\n\t\"Casino\",\r\n\t\"CasinoCourt\",\r\n\t\"Cathedral (SG)\",\r\n\t\"Christmas\",\r\n\t\"Christmas Courtroom\",\r\n\t\"CinemaFamousi\",\r\n\t\"Classroom\",\r\n\t\"Co - Lobby 1\",\r\n\t\"Co - Lobby 2\",\r\n\t\"CochenOfficeAAI\",\r\n\t\"ColosseumFerox\",\r\n\t\"Control Room\",\r\n\t\"Control Room Interior\",\r\n\t\"CountyCourt\",\r\n\t\"CourtroomAA\",\r\n\t\"CourtroomAAHD\",\r\n\t\"CourtroomAAI\",\r\n\t\"CourtroomAJ\",\r\n\t\"CourtroomAJNight\",\r\n\t\"CourtroomAnime\",\r\n\t\"CourtroomCounty\",\r\n\t\"CourtroomDD\",\r\n\t\"CourtroomEnglish\",\r\n\t\"CourtroomNew\",\r\n\t\"CourtroomRuined\",\r\n\t\"CourtroomThemis\",\r\n\t\"CourtroomTouhou\",\r\n\t\"CourtroomWitch\",\r\n\t\"CruiseCourt\",\r\n\t\"CustomEight\",\r\n\t\"CustomEleven\",\r\n\t\"CustomFifteen\",\r\n\t\"CustomFive\",\r\n\t\"CustomFour\",\r\n\t\"CustomFourteen\",\r\n\t\"CustomNine\",\r\n\t\"CustomOne\",\r\n\t\"CustomSeven\",\r\n\t\"CustomSix\",\r\n\t\"CustomTen\",\r\n\t\"CustomThirteen\",\r\n\t\"CustomThree\",\r\n\t\"CustomTwelve\",\r\n\t\"CustomTwo\",\r\n\t\"DC\",\r\n\t\"DDCourt\",\r\n\t\"DDCourtGray\",\r\n\t\"DDCourtRuined\",\r\n\t\"DDCourtRuinedInvestigation\",\r\n\t\"DDCourtThemis\",\r\n\t\"DDDefendantLobby\",\r\n\t\"DDGyaxa\",\r\n\t\"DDLobby\",\r\n\t\"DDNinetailsVale\",\r\n\t\"DDShipshapeAquarium\",\r\n\t\"DDThemisAcademy\",\r\n\t\"DFreightTrain\",\r\n\t\"DGS-ENG\",\r\n\t\"DGS-JAP\",\r\n\t\"DGS\",\r\n\t\"DGSCourtJapanese\",\r\n\t\"DGSCourtOldBailey\",\r\n\t\"DGSCourtOldBaileyJury\",\r\n\t\"DGSDefendantLobbyJapanese\",\r\n\t\"DGSDefendantLobbyOldBailey\",\r\n\t\"DGSEnglishCourt\",\r\n\t\"DGSJapanCourt\",\r\n\t\"DGSLondon\",\r\n\t\"DGSenglishcourt\",\r\n\t\"DRAE-Area1\",\r\n\t\"DRAE-Area2\",\r\n\t\"DRClassTrial\",\r\n\t\"DRRP\",\r\n\t\"Dark Cave\",\r\n\t\"Darkness\",\r\n\t\"Datrone Heart\",\r\n\t\"Datrone HeartHQ\",\r\n\t\"DeLiteHouseTT\",\r\n\t\"Despair vs. Hope\",\r\n\t\"DetentionCenterAAI2\",\r\n\t\"DimensionalGate\",\r\n\t\"DogenCellAAI2\",\r\n\t\"DualDestinies\",\r\n\t\"Dungeon Courtroom\",\r\n\t\"EdgeworthOfficeAA\",\r\n\t\"EdgeworthOfficeAAI\",\r\n\t\"EmbassyAAI\",\r\n\t\"Endless Courtroom\",\r\n\t\"EngardeManorJFA\",\r\n\t\"EnglishCourt\",\r\n\t\"Errors\",\r\n\t\"Errors2\",\r\n\t\"FECastle\",\r\n\t\"FECave\",\r\n\t\"FEFort\",\r\n\t\"FEPlain\",\r\n\t\"FETavern\",\r\n\t\"Factory\",\r\n\t\"FieldFortune\",\r\n\t\"FilmSetAAI2\",\r\n\t\"Flowerfield\",\r\n\t\"ForensicCourt\",\r\n\t\"Forest\",\r\n\t\"GS4Night\",\r\n\t\"GantOfficeAA\",\r\n\t\"GetwaterHotelJFA\",\r\n\t\"GetwaterStageJFA\",\r\n\t\"GlobalStudiosIndoorsAA\",\r\n\t\"GlobalStudiosOutdoorsAA\",\r\n\t\"GourdLakeAA\",\r\n\t\"GrandChokmah\",\r\n\t\"GrandStadium\",\r\n\t\"Graveyard\",\r\n\t\"GreatWitchtrialCourt\",\r\n\t\"GrossbergOfficeAA\",\r\n\t\"HD\",\r\n\t\"HQFarm\",\r\n\t\"HQHalloweenTown\",\r\n\t\"HQHolodeck\",\r\n\t\"HQShrine\",\r\n\t\"HQTown\",\r\n\t\"HQVolcanoCherry\",\r\n\t\"HallOfFame\",\r\n\t\"HarborTown\",\r\n\t\"HarvestFestival\",\r\n\t\"HazakuraTemple1TT\",\r\n\t\"HazakuraTemple2TT\",\r\n\t\"Headquarters\",\r\n\t\"Headquarters 2\",\r\n\t\"Hell Correspondence\",\r\n\t\"Hospital\",\r\n\t\"HotelRoomAA\",\r\n\t\"HottiClinicJFA\",\r\n\t\"Innsmouth\",\r\n\t\"InsidePlaneAAI2\",\r\n\t\"Interiors (Day)\",\r\n\t\"Interiors (Night)\",\r\n\t\"JFAAirport\",\r\n\t\"JFABerryBigCircusEast\",\r\n\t\"JFABerryBigCircusWest\",\r\n\t\"JFAGatewaterHotel\",\r\n\t\"JFAHottiClinic\",\r\n\t\"JFAKurainVillage\",\r\n\t\"JFAMattHouse\",\r\n\t\"JapaneseCourt\",\r\n\t\"Kamurocho (Day)\",\r\n\t\"Kamurocho (Night)\",\r\n\t\"Keterburg\",\r\n\t\"Khura'in\",\r\n\t\"Khurain\",\r\n\t\"KokonoeLab\",\r\n\t\"KurainCourt\",\r\n\t\"KurainVillageJFA\",\r\n\t\"LBCastle\",\r\n\t\"LBMisc\",\r\n\t\"LBScotlandYard\",\r\n\t\"Lab 8\",\r\n\t\"Lentomain\",\r\n\t\"Library\",\r\n\t\"LogicChessAAI2\",\r\n\t\"MI - Ashleys Shack\",\r\n\t\"MLP - Apple barn\",\r\n\t\"MLP - CMC Clubhouse\",\r\n\t\"MLP - CMC Clubhouse inside\",\r\n\t\"MLP - Canterlot Castle galaroom\",\r\n\t\"MLP - Canterlot Hallway\",\r\n\t\"MLP - Canterlot Library2\",\r\n\t\"MLP - Canterlot Town\",\r\n\t\"MLP - Canterlot alley\",\r\n\t\"MLP - Canterlot library\",\r\n\t\"MLP - Carousel Boutique\",\r\n\t\"MLP - Clearing\",\r\n\t\"MLP - Curio Shop\",\r\n\t\"MLP - Everfree Forest\",\r\n\t\"MLP - Everfree Forest entrance\",\r\n\t\"MLP - Fluttershy's cottage\",\r\n\t\"MLP - Hospital Room\",\r\n\t\"MLP - Hotelroom\",\r\n\t\"MLP - Library 2F\",\r\n\t\"MLP - Library mainfloor\",\r\n\t\"MLP - Old Castle\",\r\n\t\"MLP - Orchard\",\r\n\t\"MLP - PV Hospital\",\r\n\t\"MLP - PV Street\",\r\n\t\"MLP - Ponyville\",\r\n\t\"MLP - Shining's apartment\",\r\n\t\"MLP - Sugarcube Corner\",\r\n\t\"MLP - Twilight's Lab\",\r\n\t\"MM - Castle\",\r\n\t\"MM - Madokas house\",\r\n\t\"MM - School yard\",\r\n\t\"MM - Street\",\r\n\t\"MM - Street2\",\r\n\t\"MM - classroom\",\r\n\t\"MM - dark hallway\",\r\n\t\"MM - rooftop\",\r\n\t\"MM - room whit Kyubey\",\r\n\t\"MM - school hallway\",\r\n\t\"MM - staircase\",\r\n\t\"MMA-Bedrooms1\",\r\n\t\"MMA-Floor 1\",\r\n\t\"MS - Cathedral\",\r\n\t\"MS - Zakum's Tree\",\r\n\t\"Mansion\",\r\n\t\"MansionAAI2\",\r\n\t\"MansionHQ\",\r\n\t\"Maplecrest - Nightmare\",\r\n\t\"Maplecrest\",\r\n\t\"Market\",\r\n\t\"Mayonaka\",\r\n\t\"MechHangar\",\r\n\t\"Medici Tower\",\r\n\t\"Military Base Exterior\",\r\n\t\"MoeRoomJFA\",\r\n\t\"MuseumAAI2\",\r\n\t\"MuseumTT\",\r\n\t\"Music\",\r\n\t\"NewCourt\",\r\n\t\"New Meridian\",\r\n\t\"Ninetailsvale\",\r\n\t\"Nordon Plains\",\r\n\t\"Nordon Plains Night\",\r\n\t\"OCArcade\",\r\n\t\"OCBebop\",\r\n\t\"OCCourtCafe\",\r\n\t\"OCCourtCounty\",\r\n\t\"OCCourtCruise\",\r\n\t\"OCCourtEndless\",\r\n\t\"OCCourtFinalDestination\",\r\n\t\"OCCourtInverted\",\r\n\t\"OCCourtPirateShip\",\r\n\t\"OCCourtSky\",\r\n\t\"OCCourtSpace\",\r\n\t\"OCCourtSpaceShip\",\r\n\t\"OCCourtTouhou\",\r\n\t\"OCCourtZetta\",\r\n\t\"OCDungeon\",\r\n\t\"OCHospital\",\r\n\t\"OCRoad\",\r\n\t\"OCTownPirate\",\r\n\t\"OCTownShanty\",\r\n\t\"OCWhiteRoom\",\r\n\t\"OfficeHouseHQ\",\r\n\t\"OfficeNightAA\",\r\n\t\"Osaka (Night)\",\r\n\t\"Osaka\",\r\n\t\"OutsidePlaneAAI2\",\r\n\t\"P4UBasement\",\r\n\t\"P4ULab\",\r\n\t\"P4Ubaseball\",\r\n\t\"P4Ubeach\",\r\n\t\"P4Ubuilding\",\r\n\t\"P4Uconcert\",\r\n\t\"P4Ugarden\",\r\n\t\"P4Ugraveyard\",\r\n\t\"P4Uhell\",\r\n\t\"P4Ujail\",\r\n\t\"P4Umisc\",\r\n\t\"P4Unight\",\r\n\t\"P4Uoffices\",\r\n\t\"P4Urailway\",\r\n\t\"P4Urestaurants\",\r\n\t\"P4Urooms\",\r\n\t\"P4Uruins\",\r\n\t\"P4Uschool\",\r\n\t\"P4Ustage1\",\r\n\t\"P4Ustage2\",\r\n\t\"P4Ustation\",\r\n\t\"P4Ustore\",\r\n\t\"P4Utent\",\r\n\t\"P4Utransport\",\r\n\t\"P4Utv\",\r\n\t\"P4Uvelvetroom\",\r\n\t\"PICAAI2\",\r\n\t\"PLvsAAAlchemistHouse\",\r\n\t\"PLvsAABellTower\",\r\n\t\"PLvsAACastle\",\r\n\t\"PLvsAACourtEnglish\",\r\n\t\"PLvsAACourtLabyrinthia\",\r\n\t\"PLvsAACourthouse\",\r\n\t\"PLvsAADefendantLobbyEnglish\",\r\n\t\"PLvsAADefendantLobbyLabyrinthia\",\r\n\t\"PLvsAAEclaireBakery\",\r\n\t\"PLvsAAForest\",\r\n\t\"PLvsAAGreatArchive\",\r\n\t\"PLvsAALabyrinthiaInner\",\r\n\t\"PLvsAALabyrinthiaOuter\",\r\n\t\"PLvsAALondon\",\r\n\t\"PLvsAARougeTavern\",\r\n\t\"PLvsAARuins\",\r\n\t\"PLvsAAStorytellerTower\",\r\n\t\"PLvsAAWagon\",\r\n\t\"PLvsAAWorkshop\",\r\n\t\"PMMMRP\",\r\n\t\"PMMMWitch\",\r\n\t\"ParkingLotAA\",\r\n\t\"PeonyCastle\",\r\n\t\"Persona Afternoon\",\r\n\t\"Persona DH\",\r\n\t\"Persona Morning\",\r\n\t\"Persona Night\",\r\n\t\"PersonaRP\",\r\n\t\"PhoenixOfficeAA\",\r\n\t\"PirateShip\",\r\n\t\"PlaneAAI\",\r\n\t\"PlaneLoungeAAI\",\r\n\t\"PlaneLoungeLandAAI\",\r\n\t\"PlatPark\",\r\n\t\"PlatRemnant\",\r\n\t\"PlatunaArea1\",\r\n\t\"PlatunaArea1HQ\",\r\n\t\"PlatunaArea2\",\r\n\t\"PlatunaArea2HQ\",\r\n\t\"PlatunaMain\",\r\n\t\"PlatunamainHQ\",\r\n\t\"PrecinctAA\",\r\n\t\"PrisonAAI2\",\r\n\t\"PrisonCourtyardAAI2\",\r\n\t\"RG - 104\",\r\n\t\"RG - A-East\",\r\n\t\"RG - AMX\",\r\n\t\"RG - Bus Terminal\",\r\n\t\"RG - Cadoi City\",\r\n\t\"RG - Concert\",\r\n\t\"RG - Dogenzaka\",\r\n\t\"RG - God Pad\",\r\n\t\"RG - Miyashita Underpass\",\r\n\t\"RG - Station Underpass\",\r\n\t\"RG - Trail\",\r\n\t\"RG - Udagawa\",\r\n\t\"RaysDeLite\",\r\n\t\"Retreat\",\r\n\t\"RetreatHQ\",\r\n\t\"RiverVista\",\r\n\t\"Road\",\r\n\t\"Role Play\",\r\n\t\"Ronpa Mansion Area 5\",\r\n\t\"Ronpa Mansion Day\",\r\n\t\"Ronpa Mansion Day2\",\r\n\t\"Ronpa Mansion Day3\",\r\n\t\"Ronpa Mansion Day4\",\r\n\t\"Ronpa Mansion Night\",\r\n\t\"Ronpa Mansion Night2\",\r\n\t\"Ronpa Mansion Night3\",\r\n\t\"Ronpa Mansion Night4\",\r\n\t\"Ronpa mansion Haunted\",\r\n\t\"Ronpers Express\",\r\n\t\"RooftopAAI2\",\r\n\t\"RuinedCastle\",\r\n\t\"RuinedCourt\",\r\n\t\"Ruins Entrance\",\r\n\t\"SDR2 ISLAND\",\r\n\t\"SDR2 ISLAND2\",\r\n\t\"SDR2 ISLAND2 NIGHT\",\r\n\t\"SDR2 ISLAND3\",\r\n\t\"SDR2 ISLAND NIGHT\",\r\n\t\"SI - Bedroom\",\r\n\t\"SI - Class(sunset)\",\r\n\t\"SI - Class\",\r\n\t\"SI - Council1\",\r\n\t\"SI - Council2\",\r\n\t\"SI - Council3\",\r\n\t\"SI - Gym\",\r\n\t\"SI - Gym2\",\r\n\t\"SI - Hall\",\r\n\t\"SI - Hall2\",\r\n\t\"SI - Lockers\",\r\n\t\"SI - Nurse\",\r\n\t\"SI - Office\",\r\n\t\"SI - Pink\",\r\n\t\"SI - Roof\",\r\n\t\"SI - Roof2\",\r\n\t\"SI - School\",\r\n\t\"Seance\",\r\n\t\"SecretRoomsJFA\",\r\n\t\"SecurityCompanyTT\",\r\n\t\"ShipAAI2\",\r\n\t\"SkialForest\",\r\n\t\"Sky\",\r\n\t\"SkyDeck\",\r\n\t\"SoJCourt\",\r\n\t\"SoJDefendantLobby\",\r\n\t\"Somina Castle\",\r\n\t\"Somina Castle Night\",\r\n\t\"SpaceCourt\",\r\n\t\"SpaceCourtBlue\",\r\n\t\"SpaceCourtGreen\",\r\n\t\"SpaceCourtNormal\",\r\n\t\"SpaceCourtOrange\",\r\n\t\"SpaceCourtRainbow\",\r\n\t\"SpaceCourtRed\",\r\n\t\"SpaceCourtYellow\",\r\n\t\"SpacePort\",\r\n\t\"Spaceship\",\r\n\t\"StageAAI\",\r\n\t\"StageDisassembledAAI\",\r\n\t\"SteamBar\",\r\n\t\"SteamGarden\",\r\n\t\"SteamGovt\",\r\n\t\"SteamSquare\",\r\n\t\"SteamStreet\",\r\n\t\"Street\",\r\n\t\"SummerFestival\",\r\n\t\"SummerFestivalEvening\",\r\n\t\"TARDIS\",\r\n\t\"TEOS Lab\",\r\n\t\"TTAtmeyOffice\",\r\n\t\"TTBlueScreensInc\",\r\n\t\"TTDemasqueHideout\",\r\n\t\"TTHazakuraTemple\",\r\n\t\"TTHazakuraTempleInner\",\r\n\t\"TTKBSecurity\",\r\n\t\"TTLordlyTailor\",\r\n\t\"TTTenderLender\",\r\n\t\"TTTresBien\",\r\n\t\"TenderLenderTT\",\r\n\t\"Themis\",\r\n\t\"Titania\",\r\n\t\"TitaniaValley\",\r\n\t\"Togami Mansion\",\r\n\t\"TouhouCourt\",\r\n\t\"Tower\",\r\n\t\"Town\",\r\n\t\"Town Night\",\r\n\t\"Tr0LLc0urt\",\r\n\t\"TrainstationAA\",\r\n\t\"TresBienTT\",\r\n\t\"TrollCourt\",\r\n\t\"Twotorial Village\",\r\n\t\"Twotorial Village Night\",\r\n\t\"VC 1\",\r\n\t\"VLR\",\r\n\t\"VLR2.2\",\r\n\t\"VLR2.3\",\r\n\t\"VLR2\",\r\n\t\"VLR3\",\r\n\t\"VitaminSquareTT\",\r\n\t\"WEN\",\r\n\t\"WaitingRoomAAI\",\r\n\t\"WestAAI\",\r\n\t\"WinterPalaceAAI2\",\r\n\t\"WitchTrialCourt\",\r\n\t\"WitchtrialCourtHQ\",\r\n\t\"Witchwood\",\r\n\t\"WorldEmulator\",\r\n\t\"Wreckage (SG)\",\r\n\t\"Wrightagency\",\r\n\t\"Xmas\",\r\n\t\"Zetta\",\r\n\t\"animation\",\r\n\t\"apollojustice\",\r\n\t\"background\",\r\n\t\"basement\",\r\n\t\"birthday\",\r\n\t\"blackout\",\r\n\t\"chess\",\r\n\t\"chessw1\",\r\n\t\"chessw2\",\r\n\t\"chessw3\",\r\n\t\"chessw4\",\r\n\t\"christmas\",\r\n\t\"circus\",\r\n\t\"classtrial\",\r\n\t\"cofe\",\r\n\t\"courthouseofgods\",\r\n\t\"cruise\",\r\n\t\"cruise court\",\r\n\t\"custom\",\r\n\t\"custom1\",\r\n\t\"custom2\",\r\n\t\"custom3\",\r\n\t\"custom4\",\r\n\t\"custom5\",\r\n\t\"custom6\",\r\n\t\"custom7\",\r\n\t\"custom8\",\r\n\t\"custom9\",\r\n\t\"custom10\",\r\n\t\"daimoncourt\",\r\n\t\"default - Kopie\",\r\n\t\"default\",\r\n\t\"default_christmas\",\r\n\t\"defendantlobby\",\r\n\t\"defendantlobbyapollo\",\r\n\t\"detentioncenter\",\r\n\t\"doppler\",\r\n\t\"dr1stfloor\",\r\n\t\"dr1stfloordorms\",\r\n\t\"dr1stfloorhalls\",\r\n\t\"dr2ndfloor\",\r\n\t\"dr3rdfloor\",\r\n\t\"druq1stfloordorms\",\r\n\t\"druq2ndfloordorms\",\r\n\t\"dualdestinies\",\r\n\t\"dualdestiniesOG\",\r\n\t\"dungeon\",\r\n\t\"endless\",\r\n\t\"englishcourt\",\r\n\t\"forest\",\r\n\t\"gs4\",\r\n\t\"gs4night\",\r\n\t\"gs5\",\r\n\t\"hd\",\r\n\t\"inn\",\r\n\t\"investigationbando\",\r\n\t\"investigationsembassylobby\",\r\n\t\"investigationsgourdlake\",\r\n\t\"investigationsmilesoffice\",\r\n\t\"investigationsplaneair\",\r\n\t\"investigationsroyalcourt\",\r\n\t\"investigationstvroom\",\r\n\t\"investigationswestern\",\r\n\t\"investigationswitchtown\",\r\n\t\"island 1(uranus zone)\",\r\n\t\"lcourt\",\r\n\t\"legacy\",\r\n\t\"lobbyDGS-ENG\",\r\n\t\"lobbyDGS-JAP\",\r\n\t\"lobbyPLvsAA-ENG\",\r\n\t\"lobbyPLvsAA-LAB\",\r\n\t\"lobbySOJ\",\r\n\t\"magatama\",\r\n\t\"magatama1\",\r\n\t\"magatama2\",\r\n\t\"magatama3\",\r\n\t\"magatama4\",\r\n\t\"magatama5\",\r\n\t\"marblefade\",\r\n\t\"matrix\",\r\n\t\"matrixall\",\r\n\t\"matrixangry\",\r\n\t\"matrixangrysad\",\r\n\t\"matrixangrysurprised\",\r\n\t\"matrixhappy\",\r\n\t\"matrixhappyangry\",\r\n\t\"matrixhappysad\",\r\n\t\"matrixhappysurprised\",\r\n\t\"matrixsad\",\r\n\t\"matrixsadsurprised\",\r\n\t\"matrixsurprise\",\r\n\t\"mlp\",\r\n\t\"newcourt\",\r\n\t\"night (no lights)\",\r\n\t\"plvsaa\",\r\n\t\"policestation\",\r\n\t\"prisonvestigation\",\r\n\t\"sdr2classtrial\",\r\n\t\"sky\",\r\n\t\"sshope2ndfloorday(incident)\",\r\n\t\"sshope2ndfloorday\",\r\n\t\"sshope2ndfloornight(incident)\",\r\n\t\"sshope2ndfloornight\",\r\n\t\"sshopeday(incident)\",\r\n\t\"sshopeday\",\r\n\t\"sshopenight(incident)\",\r\n\t\"sshopenight\",\r\n\t\"thief\",\r\n\t\"thiefbash\",\r\n\t\"thiefpoint\",\r\n\t\"thiefpoisoning\",\r\n\t\"thiefprints\",\r\n\t\"thiefstab\",\r\n\t\"thiefsteal\",\r\n\t\"turnaboutstorm - Kopie\",\r\n\t\"turnaboutstorm\",\r\n\t\"vocalcourt\",\r\n\t\"witchtrialcourt\"\r\n];","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0 and Qubrick\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\n// Uses the Gify library:\r\n// https://github.com/rfrench/gify\r\n// The following comment is needed for ESLint:\r\n/* global gify */\r\n\r\nimport background_arr from \"./backgrounds.js\";\r\nimport evidence_arr from \"./evidence.js\";\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function (item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1];\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://s3.wasabisys.com/webao/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.hp = [0, 0];\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\t\tthis.evidences = [];\r\n\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\": {\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\": {\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\": {\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\": {\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\": {\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t};\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn this.presentable ? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#${escapeChat(encodeChat(document.getElementById(\"OOC_name\").value))}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {number} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t * @param {string} evidence the filename of evidence to show\r\n\t * @param {number} flip change to 1 to reverse sprite for position changes\r\n\t * @param {string} flash screen flash effect\r\n\t * @param {string} color text color\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {number} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {number} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {number} side the position\r\n\t * @param {number} hp the health point\r\n\t */\r\n\tsendHP(side, hp) {\r\n\t\tthis.serv.send(`HP#${side}#${hp}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif (this.chars[this.charID].side == \"jud\") {\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.3#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Set to playerID to server chat name\r\n\t\t// TODO: Make a text box for this!\r\n\t\tdocument.getElementById(\"OOC_name\").value = \"web\" + this.playerID;\r\n\r\n\t\t// Load evidence array to select\r\n\t\tconst evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tevidence_arr.forEach(evidence => {\r\n\t\t\tevidence_select.add(new Option(evidence));\r\n\t\t});\r\n\r\n\t\t// Load background array to select\r\n\t\tconst background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tbackground_arr.forEach(background => {\r\n\t\t\tbackground_select.add(new Option(background));\r\n\t\t});\r\n\t\t// Calculate gif duration of shouts\r\n\t\tconst shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"].toLowerCase();\r\n\t\t\tfileExists(shout_src, this.callbackLoadImageResources, shouts[i]);\r\n\t\t}\r\n\r\n\t\t// Calculate gif duration of testimony\r\n\t\tconst testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tconst testimony_src = `${AO_HOST}themes/default/${testimony[i]}.gif`;\r\n\t\t\t// Check image existed\r\n\t\t\tfileExists(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tfileExists(AO_HOST + this.resources[testimony[i]][\"sfx\"].toLowerCase(), this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\r\n\t\t// TODO: Cache some resources\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif (result) {\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src, client.callbackGetResourceLength, resource);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length;\r\n\t}\r\n\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif (result) {\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tconst target = document.getElementById(\"client_inner_chat\");\r\n\t\tconst observer = new MutationObserver(function (mutations) {\r\n\t\t\tmutations.forEach(function (mutation) {\r\n\t\t\t\tconst children = mutation.addedNodes;\r\n\t\t\t\tif (children !== null) {\r\n\t\t\t\t\tchildren.forEach(function (node) {\r\n\t\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else if (node.tagName == \"M\") {\r\n\t\t\t\t\t\t\tif (node.hasAttribute(\"a\")) {\r\n\t\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t});\r\n\t\tconst config = {\r\n\t\t\tattributes: true,\r\n\t\t\tchildList: true\r\n\t\t};\r\n\t\tobserver.observe(target, config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split(\"%\");\r\n\t\tlet args = lines[0].split(\"#\");\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * XXX: a nasty hack made by gameboyprinter.\r\n\t * @param {string} msg chat message to prepare for display \r\n\t */\r\n\tprepChat(msg){\r\n\t\t// TODO: make this less awful\r\n\t\treturn decodeBBCode(escapeHtml(decodeChat(unescapeChat(msg))));\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tconst chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: this.prepChat(args[5]), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 600) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1].toLowerCase();\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener(\"loadedmetadata\", function () {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0].toLowerCase()) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0].toLowerCase()) + \"/char_icon.png\"\r\n\t\t\t};\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tconst arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2].toLowerCase())\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tconst evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor (let i = 1; i <= this.evidences.length; i++) {\r\n\t\t\tevidence_box.innerHTML += ``;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tconst hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tlet flagAudio = false;\r\n\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif (/\\.(?:wav|mp3|mp4|ogg|opus)$/i.test(args[i]) && !flagAudio) {\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\r\n\t\t\tif (flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tconst newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tconst newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i];\r\n\t\t\t\tnewarea.onclick = function () {\r\n\t\t\t\t\tarea_click(this);\r\n\t\t\t\t};\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// We need to check if the last area that we got was actually a category\r\n\t\t// header for music. If it was, then move it over to the music list.\r\n\t\tconst area_box = document.getElementById(\"areas\");\r\n\t\tif (area_box.lastChild.textContent.startsWith(\"=\")) {\r\n\t\t\tconst audio_title = document.createElement(\"OPTION\");\r\n\t\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\t\tarea_box.removeChild(area_box.lastChild);\r\n\t\t}\r\n\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tconst bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif (bg_index == 0) {\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + \"background/\" + escape(args[1].toLowerCase()) + \"/defenseempty.png\";\r\n\t\tif (this.charID == -1) {\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tconst percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({\r\n\t\t\t\t\"width\": percent_hp + \"%\"\r\n\t\t\t}, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({\r\n\t\t\t\t\"width\": percent_hp + \"%\"\r\n\t\t\t}, 500);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tlet tr;\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\ttr = document.createElement(\"TR\");\r\n\t\t\t}\r\n\t\t\tconst td = document.createElement(\"TD\");\r\n\t\t\tlet icon_chosen = \"\";\r\n\t\t\tconst thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}\";\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tconst me = this.me();\r\n\t\tconst emotes = this.emotes;\r\n\t\tconst xhr = new XMLHttpRequest();\r\n\t\txhr.withCredentials = false;\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open(\"GET\", AO_HOST + \"characters/\" + escape(this.me().name.toLowerCase()) + \"/char.ini\", true);\r\n\t\txhr.responseType = \"text\";\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tconst linifile = this.responseText;\r\n\t\t\t\tconst pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tconst emoteinfo = pinifile.Emotions[i].split(\"#\");\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== \"undefined\") {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== \"undefined\") {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// Make sure the asset server is case insensitive, or that everything on it is lowercase\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0].toLowerCase(),\r\n\t\t\t\t\t\tspeaking: emoteinfo[1].toLowerCase(),\r\n\t\t\t\t\t\tsilent: emoteinfo[2].toLowerCase(),\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx.toLowerCase(),\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + `characters/${escape(me.name).toLowerCase()}/emotions/button${i}_off.png`,\r\n\t\t\t\t\t\tbutton_on: AO_HOST + `characters/${escape(me.name).toLowerCase()}/emotions/button${i}_on.png`\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \r\n\t\t\t\t\t\t`\"${emotes[i].desc}\"\r\n\t\t\t\t\t\t`;\r\n\t\t\t\t}\r\n\t\t\t\tpickEmotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + \"sounds/general/sfx-blipmale.wav\");\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + \"sounds/general/sfx-blipmale.wav\");\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + \"sounds/general/sfx-blipmale.wav\");\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname.toLowerCase()}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(`${AO_HOST}characters/${escape(chatmsg.name.toLowerCase())}/${chatmsg.preanim.toLowerCase()}.gif`, this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {number} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay) {\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay);\r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater() {\r\n\t\tif (client.testimonyID > 0) {\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tconst testimonyOverlay = document.getElementById(\"client_testimony\");\r\n\t\t\ttestimonyOverlay.src = client.resources[testimony][\"src\"];\r\n\t\t\ttestimonyOverlay.style.display = \"\";\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tconst request = new XMLHttpRequest();\r\n\t\trequest.open(\"GET\", filename, true);\r\n\t\trequest.responseType = \"arraybuffer\";\r\n\t\trequest.addEventListener(\"load\", function () {\r\n\t\t\tconst gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony() {\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]) {\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]) {\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\tdisposeTestimony() {\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").style.display = \"none\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\tconst nameBox = document.getElementById(\"client_name\");\r\n\t\tconst chatBox = document.getElementById(\"client_chat\");\r\n\t\tconst charSprite = document.getElementById(\"client_char\");\r\n\t\tconst eviBox = document.getElementById(\"client_evi\");\r\n\t\tconst background = document.getElementById(\"client_background\");\r\n\t\tconst shoutSprite = document.getElementById(\"client_shout\");\r\n\t\tconst chatBoxInner = document.getElementById(\"client_inner_chat\");\r\n\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1) {\r\n\t\t\tcharSprite.style.transform = \"scaleX(-1)\";\r\n\t\t} else {\r\n\t\t\tcharSprite.style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tbackground.style.backgroundColor = \"transparent\";\r\n\t\t\t// Hide message and evidence window\r\n\t\t\tnameBox.style.display = \"none\";\r\n\t\t\tchatBox.style.display = \"none\";\r\n\t\t\teviBox.style.opacity = \"0\";\r\n\t\t\teviBox.style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tshoutSprite.src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}characters/${this.chatmsg.name.toLowerCase()}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif (this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2) {\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$(\"#client_gamewindow\").effect(\"shake\", {\r\n\t\t\t\t\t\"direction\": \"up\"\r\n\t\t\t\t});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tbackground.style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$(\"#client_gamewindow\").effect(\"pulsate\");\r\n\t\t\t}\r\n\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif (this.chatmsg.preanimdelay > 0) {\r\n\t\t\t\tshoutSprite.src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.preanim.toLowerCase() + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif (this.chatmsg.evidence > 0) {\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\teviBox.style.backgroundImage = \"url('\" + client.evidences[this.chatmsg.evidence - 1].icon + \"')\";\r\n\r\n\t\t\t\t\tif (this.chatmsg.side == \"def\") {\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\teviBox.style.right = \"1.5em\";\r\n\t\t\t\t\t\teviBox.style.left = \"initial\";\r\n\t\t\t\t\t\t$(\"#client_evi\").animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\teviBox.style.right = \"initial\";\r\n\t\t\t\t\t\teviBox.style.left = \"1.5em\";\r\n\t\t\t\t\t\t$(\"#client_evi\").animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tnameBox.style.display = \"block\";\r\n\t\t\t\tnameBox.style.fontSize = (nameBox.offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tnameBox.innerHTML = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\r\n\r\n\t\t\t\tchatBox.style.display = \"block\";\r\n\t\t\t\tchatBox.style.fontSize = (chatBox.offsetHeight * 0.25) + \"px\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t};\r\n\t\t\t\tchatBoxInner.style.color = colors[this.chatmsg.color] || \"#ffffff\";\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.chatmsg.preanimdelay == 0) {\r\n\t\t\t\t\tshoutSprite.src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.speaking.toLowerCase() + \".gif\";\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.silent.toLowerCase() + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tchatBoxInner.innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.silent.toLowerCase() + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound.toLowerCase()) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w.\\-_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function (line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip) ? 1 : 0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if a file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction fileExists(url, callback, param) {\r\n\tconst xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function () {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tlet standname;\r\n\tconst bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\tcase \"def\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\";\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\tfileExists(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\tstandname = \"defense\";\r\n\t\tbreak;\r\n\tcase \"pro\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\";\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\tfileExists(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\tcase \"hld\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\";\r\n\t\tstandname = \"defense\";\r\n\t\tbreak;\r\n\tcase \"hlp\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\";\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\tcase \"wit\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\";\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\";\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\tcase \"jud\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\";\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result, position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\") {\r\n\t\tif (result) {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\";\r\n\t\t}\r\n\t} else {\r\n\t\tif (result) {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\";\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 800) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickChar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickChar = pickChar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickEmotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo;\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickEmotion = pickEmotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickEvidence(evidence) {\r\n\tif (client.selectedEvidence !== evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif (client.selectedEvidence > 0) {\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0) {\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelEvidence();\r\n\t}\r\n}\r\nwindow.pickEvidence = pickEvidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addEvidence() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tclient.sendPE(document.getElementById(\"evi_name\").value,\r\n\t\tdocument.getElementById(\"evi_desc\").value,\r\n\t\tevidence_select.selectedIndex == 0 ?\r\n\t\t\tdocument.getElementById(\"evi_filename\").value :\r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text\r\n\t);\r\n\tcancelEvidence();\r\n}\r\nwindow.addEvidence = addEvidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editEvidence() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE(id,\r\n\t\tdocument.getElementById(\"evi_name\").value,\r\n\t\tdocument.getElementById(\"evi_desc\").value,\r\n\t\tevidence_select.selectedIndex == 0 ?\r\n\t\t\tdocument.getElementById(\"evi_filename\").value :\r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text\r\n\t);\r\n\tcancelEvidence();\r\n}\r\nwindow.editEvidence = editEvidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function deleteEvidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelEvidence();\r\n}\r\nwindow.deleteEvidence = deleteEvidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelEvidence() {\r\n\t//Clear evidence data\r\n\tif (client.selectedEvidence > 0) {\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelEvidence = cancelEvidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t//Find if icon alraedy existed in select box\r\n\tconst select_element = document.getElementById(select_box);\r\n\tfor (let i = 1; i < select_element.length; ++i) {\r\n\t\tif (select_element.options[i].value == value) {\r\n\t\t\treturn i;\r\n\t\t}\r\n\t}\r\n\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\r\n\tif (evidence_select.selectedIndex === 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = `url(${AO_HOST}evidence/${evidence_filename.value.toLowerCase()})`;\r\n\t} else {\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = `url(${AO_HOST}evidence/${evidence_select.value.toLowerCase()})`;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif (side == \"jud\") {\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor (let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++) {\r\n\t\tif (side == role_select[i].value) {\r\n\t\t\trole_select.selectedIndex = i;\r\n\t\t\treturn;\r\n\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\",\r\n\t\tbackground_select = document.getElementById(\"bg_select\"),\r\n\t\tbg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value;\r\n\t} else {\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\", filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\"),\r\n\t\trole_command = document.getElementById(\"role_command\").value;\r\n\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\", role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callMod() {\r\n\t$(\"#callmod_dialog\").dialog(\"open\");\r\n}\r\nwindow.callMod = callMod;\r\n\r\n/**\r\n * Declare witness testimony.\r\n */\r\nexport function initWT() {\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initWT = initWT;\r\n\r\n/**\r\n * Declare cross examination.\r\n */\r\nexport function initCE() {\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initCE = initCE;\r\n\r\n/**\r\n * Increment defense health point.\r\n */\r\nexport function addHPD() {\r\n\tclient.sendHP(1, String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Decrement defense health point.\r\n */\r\nexport function redHPD() {\r\n\tclient.sendHP(1, String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Increment prosecution health point.\r\n */\r\nexport function addHPP() {\r\n\tclient.sendHP(2, String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Decrement prosecution health point.\r\n */\r\nexport function redHPP() {\r\n\tclient.sendHP(2, String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + \"background/\" + background_filename.value.toLowerCase() + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + \"background/\" + background_select.value.toLowerCase() + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleEffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleEffect = toggleEffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleFlip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleFlip = toggleFlip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglePresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglePresent = togglePresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function toggleMenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.toggleMenu = toggleMenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleShout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleShout = toggleShout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encode text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t// This approach works by escaping all special characters to Unicode escape sequences.\r\n\t\t// Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function (ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4);\r\n\t\t});\r\n\t} else if (selectedEncoding == \"utf16\") {\r\n\t\t// Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tconst buffer = new ArrayBuffer(estring.length * 2);\r\n\t\tconst result = new Uint16Array(buffer);\r\n\t\tfor (let i = 0, strLen = estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decodes text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t// Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n\t\treturn estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16));\r\n\t\t});\r\n\t} else if (selectedDecoding == \"utf16\") {\r\n\t\t// Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, \"\") // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, \"<$1m>\") // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, \"\") // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, \"\"); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof (String.prototype.trim) === \"undefined\") {\r\n\tString.prototype.trim = function () {\r\n\t\treturn String(this).replace(/^\\s+|\\s+$/g, \"\");\r\n\t};\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function () {\r\n\tlet hash = 0;\r\n\tif (this.length === 0) return hash;\r\n\tfor (let i = 0; i < this.length; i++) {\r\n\t\tconst chr = this.charCodeAt(i);\r\n\t\thash = ((hash << 5) - hash) + chr;\r\n\t\thash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function () {\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources();\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$(function () {\r\n\t$(\"#callmod_dialog\").dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection: \"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection: \"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\tSure: function () {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$(this).dialog(\"close\");\r\n\t\t\t},\r\n\t\t\tCancel: function () {\r\n\t\t\t\t$(this).dialog(\"close\");\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/evidence.js","webpack:///./webAO/backgrounds.js","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","r","value","n","__esModule","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickChar","pickEmotion","pickEvidence","addEvidence","editEvidence","deleteEvidence","cancelEvidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callMod","initWT","initCE","addHPD","redHPD","addHPP","redHPP","updateBackgroundPreview","toggleEffect","toggleFlip","togglePresent","toggleMenu","toggleShout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","mode","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","hp","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","document","getElementById","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","add","Option","evidence_arr","background_select","background_arr","background","shouts","length","fileExists","toLowerCase","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","unescapeChat","decodeChat","replace","chatmsg","content","innerHTML","preanim","escape","nameplate","prepChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","lastChild","startsWith","audio_title","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","percent_hp","$","animate","width","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","emotesList","xhr","XMLHttpRequest","withCredentials","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","testimonyOverlay","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","nameBox","chatBox","charSprite","eviBox","shoutSprite","chatBoxInner","transform","opacity","height","shout","1","2","3","effect","direction","backgroundImage","right","left","fontSize","offsetHeight","hasChildNodes","createTextNode","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","area","areaHr","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","dialog","sendRT","sendHP","String","background_filename","background_preview","menu","estring","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources","autoOpen","resizable","show","hide","modal","buttons","Sure","sendZZ","Cancel"],"mappings":"aACA,IAAAA,KAGA,SAAAC,EAAAC,GAGA,GAAAF,EAAAE,GACA,OAAAF,EAAAE,GAAAC,QAGA,IAAAC,EAAAJ,EAAAE,IACAG,EAAAH,EACAI,GAAA,EACAH,YAUA,OANAI,EAAAL,GAAAM,KAAAJ,EAAAD,QAAAC,IAAAD,QAAAF,GAGAG,EAAAE,GAAA,EAGAF,EAAAD,QAKAF,EAAAQ,EAAAF,EAGAN,EAAAS,EAAAV,EAGAC,EAAAU,EAAA,SAAAR,EAAAS,EAAAC,GACAZ,EAAAa,EAAAX,EAAAS,IACAG,OAAAC,eAAAb,EAAAS,GACAK,cAAA,EACAC,YAAA,EACAC,IAAAN,KAMAZ,EAAAmB,EAAA,SAAAjB,GACAY,OAAAC,eAAAb,EAAA,cAAiDkB,OAAA,KAIjDpB,EAAAqB,EAAA,SAAAlB,GACA,IAAAS,EAAAT,KAAAmB,WACA,WAA2B,OAAAnB,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAH,EAAAU,EAAAE,EAAA,IAAAA,GACAA,GAIAZ,EAAAa,EAAA,SAAAU,EAAAC,GAAsD,OAAAV,OAAAW,UAAAC,eAAAnB,KAAAgB,EAAAC,IAGtDxB,EAAA2B,EAAA,GAIA3B,IAAA4B,EAAA,8FClEC,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,kBACA,oBACA,iBACA,kBACA,kBACA,kBACA,iBACA,kBACA,gBACA,iBACA,oBACA,oBACA,sBACA,oBACA,mBACA,iBACA,kBACA,iBACA,kBACA,oBACA,iBACA,oBACA,gBACA,kBACA,kBACA,iBACA,mBACA,oBACA,kBACA,mBACA,kBACA,oBACA,qBACA,mBACA,oBACA,mBACA,gBACA,kBACA,oBACA,kBACA,qBACA,qBACA,sBACA,uBACA,sBACA,oBACA,qBACA,uBACA,wBACA,mBACA,oBACA,wBACA,yBACA,wBACA,oBACA,qBACA,sBACA,qBACA,qBACA,sBACA,uBACA,qBACA,oBACA,qBACA,wBACA,qBACA,oBACA,cACA,kBACA,eACA,kBACA,eACA,iBACA,gBACA,eACA,gBACA,cACA,eACA,gBACA,eACA,gBACA,cACA,cACA,cACA,eACA,eACA,eACA,eACA,iBACA,iBACA,kBACA,gBACA,eACA,mBACA,kBACA,mBACA,mBACA,kBACA,mBACA,kBACA,mBACA,mBACA,oBACA,kBACA,uBACA,wBACA,qBACA,sBACA,mBACA,mBACA,iBACA,kBACA,mBACA,kBACA,kBACA,oBACA,qBACA,mBACA,iBACA,qBACA,mBACA,sBACA,mBACA,oBACA,kBACA,iBACA,kBACA,cACA,YACA,aACA,aACA,eACA,eACA,gBACA,iBACA,iBACA,iBACA,aACA,iBACA,cACA,eACA,eACA,eACA,eACA,cACA,eACA,eACA,eACA,eACA,sBACA,uBACA,aACA,eACA,cACA,gBACA,cACA,gBACA,oBACA,cACA,cACA,eACA,eACA,iBACA,kBACA,mBACA,cACA,oBACA,aACA,cACA,cACA,mBACA,aACA,cACA,aACA,aACA,cACA,cACA,cACA,cACA,eACA,gBACA,gBACA,gBACA,gBACA,iBACA,qBACA,iBACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,aACA,iBACA,kBACA,iBACA,kBACA,eACA,gBACA,gBACA,eACA,gBACA,gBACA,gBACA,gBACA,sBACA,iBACA,cACA,eACA,oBACA,gBACA,iBACA,iBACA,gBACA,eACA,eACA,eACA,eACA,gBACA,iBACA,iBACA,iBACA,iBACA,eACA,gBACA,cACA,qBACA,sBACA,sBACA,eACA,mBACA,gBACA,cACA,iBACA,kBACA,gBACA,gBACA,mBACA,aACA,cACA,cACA,eACA,gBACA,eACA,gBACA,cACA,aACA,cACA,cACA,cACA,cACA,aACA,cACA,cACA,cACA,iBACA,oBACA,0BACA,oBACA,oBACA,cACA,oBACA,cACA,YACA,kBACA,eACA,YACA,gBACA,eACA,kBACA,gBACA,eACA,gBACA,gBACA,gBACA,iBACA,cACA,eACA,eACA,iBACA,kBACA,iBACA,kBACA,sBACA,gBACA,iBACA,gBACA,iBACA,aACA,cACA,cACA,cACA,sBACA,iBACA,kBACA,cACA,eACA,eACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,cACA,eACA,cACA,eACA,cACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,mBACA,aACA,cACA,oBACA,eACA,gBACA,aACA,cACA,cACA,kBACA,oBACA,qBACA,qBACA,gBACA,aACA,cACA,cACA,cACA,cACA,cACA,eACA,eACA,gBACA,kBACA,mBACA,mBACA,mBACA,iBACA,mBACA,gBACA,oBACA,qBACA,qBACA,qBACA,oBACA,kBACA,oBACA,qBACA,iBACA,kBACA,kBACA,oBACA,iBACA,kBACA,kBACA,qBACA,qBACA,kBACA,kBACA,mBACA,oBACA,iBACA,oBACA,kBACA,gBACA,WACA,YACA,YACA,YACA,YACA,gBACA,cACA,aACA,eACA,aACA,YACA,iBACA,eACA,eACA,mBACA,qBACA,sBACA,sBACA,sBACA,sBACA,sBACA,eACA,aACA,cACA,cACA,cACA,cACA,aACA,aACA,cACA,cACA,eACA,cACA,cACA,cACA,eACA,gBACA,gBACA,iBACA,0BACA,cACA,oBACA,eACA,YACA,aACA,aACA,WACA,YACA,YACA,cACA,aACA,eACA,gBACA,iBACA,YACA,aACA,aACA,aACA,eACA,cACA,cACA,YACA,mBACA,aACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,SACA,iBACA,kBACA,kBACA,kBACA,gBACA,iBACA,iBACA,cACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,oBACA,mBACA,aACA,cACA,cACA,cACA,eACA,eACA,iBACA,cACA,gBACA,eACA,gBACA,gBACA,cACA,oBACA,aACA,aACA,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,iBACA,gBACA,cACA,oBACA,mBACA,oBACA,oBACA,mBACA,iBACA,uBACA,oBACA,iBACA,mBACA,oBACA,mBACA,iBACA,mBACA,kBACA,sBACA,mBACA,oBACA,qBACA,oBACA,mBACA,oBACA,kBACA,kBACA,kBACA,sBACA,kBACA,oBACA,iBACA,kBACA,kBACA,oBACA,gBACA,kBACA,kBACA,mBACA,kBACA,mBACA,mBACA,wBACA,oBACA,mBACA,oBACA,qBACA,oBACA,mBACA,kBACA,iBACA,mBACA,oBACA,qBACA,cACA,eACA,YACA,aACA,YACA,aACA,cACA,cACA,cACA,aACA,cACA,cACA,cACA,cACA,aACA,YACA,aACA,aACA,aACA,iBACA,eACA,gBACA,mBACA,iBACA,eACA,gBACA,gBACA,aACA,WACA,cACA,aACA,cACA,cACA,cACA,aACA,cACA,iBACA,gBACA,iBACA,iBACA,aACA,cACA,cACA,kBACA,aACA,cACA,cACA,YACA,gBACA,eACA,iBACA,oBACA,0BACA,aACA,eACA,aACA,cACA,YACA,aACA,kBACA,kBACA,YACA,mBACA,YACA,aACA,aACA,gBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,cACA,eACA,gBACA,gBACA,gBACA,iBACA,kBACA,YACA,aACA,aACA,aACA,aACA,aACA,aACA,aACA,aACA,cACA,cACA,cACA,aACA,iBACA,kBACA,kBACA,aACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,eACA,eACA,gBACA,cACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,cACA,eACA,gBACA,gBACA,eACA,iBACA,uBACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,aACA,cACA,cACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,cACA,eACA,aACA,aACA,cACA,cACA,gBACA,eACA,mBACA,mBACA,mBACA,qBACA,wBACA,sBACA,kBACA,mBACA,qBACA,oBACA,sBACA,uBACA,mBACA,qBACA,oBACA,kBACA,kBACA,oBACA,uBACA,sBACA,uBACA,qBACA,mBACA,sBACA,iBACA,kBACA,qBACA,wBACA,oBACA,uBACA,oBACA,qBACA,oBACA,mBACA,oBACA,qBACA,oBACA,oBACA,eACA,aACA,cACA,cACA,eACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,cACA,cACA,cACA,eACA,eACA,eACA,cACA,gBACA,gBACA,cACA,eACA,eACA,eACA,gBACA,iBACA,aACA,cACA,cACA,mBACA,eACA,gBACA,gBACA,gBACA,aACA,cACA,cACA,kBACA,mBACA,mBACA,mBACA,oBACA,oBACA,oBACA,qBACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,UACA,gBACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,aACA,cACA,cACA,kBACA,oBACA,eACA,qBACA,sBACA,eACA,eACA,gBACA,cACA,cACA,gBACA,kBACA,oBACA,iBACA,iBACA,iBACA,qBACA,sBACA,oBACA,uBACA,uBACA,kBACA,mBACA,iBACA,kBACA,oBACA,kBACA,kBACA,iBACA,oBACA,mBACA,oBACA,oBACA,oBACA,wBACA,kBACA,mBACA,mBACA,oBACA,cACA,eACA,cACA,eACA,eACA,gBACA,aACA,cACA,sBACA,uBACA,gBACA,iBACA,iBACA,gBACA,cACA,eACA,cACA,eACA,eACA,eACA,cACA,2BACA,iBACA,eACA,gBACA,gBACA,aACA,cACA,iBACA,aACA,eACA,aACA,eACA,gBACA,cACA,cACA,eACA,eACA,cACA,eACA,gBACA,eACA,gBACA,iBACA,gBACA,cACA,cACA,mBACA,eACA,gBACA,cACA,mBACA,gBACA,iBACA,iBACA,qBACA,qBACA,eACA,iBACA,cACA,cACA,cACA,cACA,eACA,qBACA,iBACA,gBACA,mBACA,qBACA,0BACA,oBACA,kBACA,uBACA,oBACA,oBACA,qBACA,oBACA,gBACA,4BACA,qBACA,oBACA,oBACA,wBACA,oBACA,0BACA,mBACA,mBACA,mBACA,mBACA,wBACA,kBACA,wBACA,sBACA,eACA,yBACA,cACA,gBACA,iBACA,cACA,YACA,aACA,aACA,aACA,aACA,aACA,aACA,eACA,iBACA,eACA,gBACA,eACA,gBACA,eACA,gBACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,aACA,cACA,kBACA,gBACA,gBACA,oBACA,qBACA,qBACA,mBACA,mBACA,2BACA,oBACA,oBACA,mBACA,oBACA,qBACA,sBACA,mBACA,wBACA,mBACA,mBACA,kBACA,kBACA,mBACA,oBACA,mBACA,mBACA,iBACA,oBACA,mBACA,kBACA,kBACA,mBACA,qBACA,mBACA,mBACA,mBACA,qBACA,oBACA,oBACA,mBACA,oBACA,kBACA,kBACA,oBACA,sBACA,mBACA,qBACA,mBACA,mBACA,mBACA,YACA,aACA,eACA,cACA,eACA,aACA,kBACA,aACA,cACA,gBACA,eACA,eACA,eACA,aACA,iBACA,cACA,aACA,oBACA,eACA,gBACA,aACA,cACA,cACA,cACA,iBACA,kBACA,iBACA,kBACA,iBACA,kBACA,mBACA,mBACA,aACA,cACA,cACA,cACA,cACA,cACA,cACA,eACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,aACA,kBACA,iBACA,eACA,eACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,WACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,iBACA,qBACA,kBACA,qBACA,gBACA,iBACA,iBACA,eACA,gBACA,iBACA,eACA,gBACA,iBACA,eACA,cACA,iBACA,aACA,aACA,gBACA,gBACA,mBACA,sBACA,kBACA,mBACA,kBACA,oBACA,mBACA,qBACA,oBACA,kBACA,gBACA,kBACA,mBACA,kBACA,sBACA,oBACA,iBACA,kBACA,iBACA,iBACA,mBACA,kBACA,gBACA,oBACA,kBACA,oBACA,kBACA,WACA,YACA,cACA,cACA,YACA,eACA,eACA,gBACA,gBACA,YACA,aACA,eACA,iBACA,eACA,aACA,WACA,YACA,aACA,cACA,cACA,cACA,cACA,mBACA,oBACA,YACA,aACA,cACA,cACA,cACA,gBACA,eACA,iBACA,cACA,cACA,aACA,cACA,eACA,gBACA,cACA,gBACA,iBACA,iBACA,kBACA,kBACA,mBACA,iBACA,kBACA,cACA,iBACA,aACA,cACA,cACA,cACA,cACA,cACA,cACA,gBACA,iBACA,iBACA,cACA,qBACA,sBACA,sBACA,eACA,gBACA,aACA,cACA,cACA,eACA,eACA,cACA,eACA,eACA,gBACA,iBACA,aACA,cACA,cACA,cACA,eACA,cACA,eACA,YACA,6GCvyCA,aACA,QACA,MACA,eACA,sBACA,WACA,YACA,WACA,mBACA,YACA,WACA,iBACA,YACA,YACA,cACA,aACA,aACA,eACA,YACA,WACA,eACA,WACA,aACA,oBACA,oBACA,mBACA,yBACA,iBACA,sBACA,kBACA,2BACA,mBACA,mBACA,cACA,kBACA,wBACA,sBACA,oBACA,YACA,uBACA,aACA,UACA,eACA,8BACA,yBACA,YACA,mBACA,qBACA,oBACA,oBACA,eACA,mBACA,sBACA,sBACA,cACA,oBACA,aACA,WACA,gBACA,iBACA,iBACA,oBACA,UACA,aACA,sBACA,WACA,kBACA,qBACA,wBACA,2BACA,kBACA,UACA,eACA,kBACA,iBACA,iBACA,oBACA,UACA,kBACA,mBACA,eACA,YACA,mBACA,oBACA,eACA,gBACA,kBACA,iBACA,UACA,mBACA,eACA,qBACA,iBACA,MACA,cACA,aACA,gBACA,QACA,SACA,gBACA,cACA,eACA,mBACA,cACA,cACA,eACA,WACA,gBACA,oBACA,WACA,gBACA,aACA,aACA,OACA,WACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,OACA,OACA,OACA,gBACA,iBACA,mBACA,iBACA,kBACA,uBACA,kBACA,KACA,cACA,kBACA,cACA,cACA,aACA,aACA,aACA,aACA,aACA,cACA,OACA,YACA,aACA,MACA,eACA,SACA,cACA,iBACA,YACA,sBACA,gBACA,YACA,eACA,eACA,kBACA,iBACA,eACA,wBACA,cACA,cACA,gBACA,eACA,cACA,mBACA,iBACA,kBACA,cACA,mBACA,eACA,kBACA,kBACA,kBACA,iBACA,cACA,cACA,eACA,gBACA,aACA,aACA,iBACA,aACA,YACA,cACA,YACA,YACA,iBACA,cACA,eACA,YACA,KACA,UACA,cACA,gBACA,6BACA,gBACA,mBACA,UACA,UACA,kBACA,sBACA,kBACA,gBACA,UACA,UACA,MACA,mBACA,oBACA,wBACA,4BACA,6BACA,kBACA,gBACA,YACA,kBACA,aACA,aACA,eACA,OACA,YACA,WACA,gBACA,kBACA,gBACA,mBACA,sBACA,kBACA,gBACA,gBACA,oBACA,oBACA,qBACA,aACA,oBACA,kBACA,eACA,SACA,UACA,WACA,SACA,SACA,UACA,WACA,UACA,eACA,cACA,cACA,gBACA,SACA,WACA,eACA,mBACA,mBACA,yBACA,0BACA,cACA,eACA,eACA,YACA,uBACA,oBACA,KACA,SACA,kBACA,aACA,WACA,SACA,kBACA,aACA,aACA,kBACA,oBACA,oBACA,eACA,iBACA,sBACA,WACA,cACA,iBACA,YACA,kBACA,kBACA,oBACA,aACA,wBACA,wBACA,oBACA,iBACA,mBACA,eACA,gBACA,kBACA,oBACA,YACA,WACA,UACA,aACA,cACA,mBACA,WACA,SACA,iBACA,QACA,YACA,UACA,iBACA,qBACA,mBACA,sBACA,6BACA,kCACA,0BACA,2BACA,uBACA,wBACA,0BACA,0BACA,iBACA,mBACA,wBACA,iCACA,6BACA,sBACA,kBACA,mBACA,0BACA,mBACA,gBACA,oBACA,kBACA,kBACA,4BACA,yBACA,uBACA,cACA,qBACA,mBACA,cACA,eACA,iBACA,oBACA,eACA,wBACA,sBACA,iBACA,gBACA,cACA,iBACA,oBACA,UACA,cACA,YACA,yBACA,aACA,SACA,WACA,aACA,eACA,yBACA,aACA,aACA,WACA,QACA,WACA,eACA,gBACA,gBACA,sBACA,WACA,UACA,cACA,gBACA,gBACA,iBACA,0BACA,kBACA,oBACA,aACA,eACA,mBACA,gBACA,eACA,YACA,aACA,SACA,eACA,eACA,cACA,gBACA,gBACA,gBACA,QACA,mBACA,cACA,SACA,cACA,WACA,cACA,aACA,YACA,eACA,UACA,UACA,UACA,WACA,aACA,aACA,iBACA,WACA,WACA,YACA,YACA,YACA,aACA,WACA,UACA,eACA,QACA,gBACA,UACA,uBACA,kBACA,eACA,qBACA,yBACA,mBACA,8BACA,kCACA,sBACA,eACA,qBACA,yBACA,yBACA,eACA,oBACA,cACA,yBACA,cACA,iBACA,SACA,YACA,eACA,cACA,oBACA,aACA,kBACA,gBACA,YACA,kBACA,aACA,WACA,iBACA,qBACA,WACA,cACA,eACA,iBACA,eACA,iBACA,cACA,gBACA,aACA,aACA,sBACA,WACA,cACA,WACA,oBACA,kBACA,eACA,iBACA,eACA,2BACA,yBACA,aACA,eACA,aACA,UACA,YACA,aACA,OACA,YACA,uBACA,oBACA,qBACA,qBACA,qBACA,sBACA,uBACA,uBACA,uBACA,wBACA,kBACA,cACA,eACA,cACA,iBACA,cACA,eACA,qBACA,eACA,oBACA,eACA,qBACA,aACA,gBACA,gBACA,gBACA,WACA,YACA,YACA,aACA,eACA,aACA,cACA,YACA,YACA,aACA,cACA,SACA,iBACA,oBACA,WACA,cACA,MACA,UACA,WACA,oBACA,gBACA,sBACA,aACA,iBACA,kBACA,mBACA,mBACA,oBACA,gBACA,mBACA,YACA,YACA,WACA,uBACA,WACA,cACA,YACA,cACA,cACA,SACA,iBACA,wBACA,SACA,WACA,gBACA,mBACA,oBACA,mBACA,wBACA,eACA,iBACA,iBACA,aACA,iBACA,SACA,UACA,gBACA,iBACA,cACA,QACA,OACA,aACA,aACA,iBACA,aACA,aACA,oBACA,0BACA,OACA,MACA,SACA,SACA,OACA,OACA,kBACA,MACA,iBACA,UACA,mBACA,kBACA,oBACA,YACA,gBACA,gBACA,eACA,OACA,QACA,YACA,gBACA,aACA,WACA,WACA,WACA,QACA,UACA,UACA,UACA,UACA,YACA,SACA,aACA,OACA,mBACA,SACA,eACA,SACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WACA,cACA,kBACA,UACA,oBACA,iBACA,uBACA,kBACA,UACA,aACA,kBACA,kBACA,aACA,aACA,oBACA,oBACA,gBACA,kBACA,UACA,UACA,eACA,SACA,MACA,WACA,MACA,KACA,MACA,qBACA,6BACA,0BACA,4BACA,yBACA,2BACA,uBACA,wBACA,0BACA,wBACA,SACA,SACA,eACA,eACA,kBACA,kBACA,WACA,WACA,YACA,YACA,YACA,YACA,YACA,aACA,SACA,YACA,cACA,iBACA,uBACA,cACA,mBACA,iBACA,uBACA,YACA,qBACA,iBACA,MACA,WACA,oBACA,SACA,gBACA,oBACA,iBACA,MACA,8BACA,oBACA,gCACA,sBACA,sBACA,YACA,wBACA,cACA,QACA,YACA,aACA,iBACA,cACA,YACA,aACA,yBACA,iBACA,aACA,6VCokBeC,eAYAC,YAuCAC,oBAUAC,eAcAC,sBAQAC,oBAQAC,qBASAC,oBAWAC,aAWAC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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 2);\n","export default [\r\n\t\"1.gif\",\r\n\t\"1.png\",\r\n\t\"2.png\",\r\n\t\"3.png\",\r\n\t\"4.png\",\r\n\t\"5.gif\",\r\n\t\"5.png\",\r\n\t\"6.gif\",\r\n\t\"6.png\",\r\n\t\"AACastApril.png\",\r\n\t\"AACastBellboy.png\",\r\n\t\"AACastButz.png\",\r\n\t\"AACastButz2.png\",\r\n\t\"AACastButz3.png\",\r\n\t\"AACastCindy.png\",\r\n\t\"AACastCody.png\",\r\n\t\"AACastDarke.png\",\r\n\t\"AACastEma.png\",\r\n\t\"AACastGant.png\",\r\n\t\"AACastGoodman.png\",\r\n\t\"AACastGregory.png\",\r\n\t\"AACastGrossberg.png\",\r\n\t\"AACastGumshoe.png\",\r\n\t\"AACastHammer.png\",\r\n\t\"AACastJake.png\",\r\n\t\"AACastJudge.png\",\r\n\t\"AACastLana.png\",\r\n\t\"AACastLotta.png\",\r\n\t\"AACastManfred.png\",\r\n\t\"AACastMaya.png\",\r\n\t\"AACastMeekins.png\",\r\n\t\"AACastMia.png\",\r\n\t\"AACastMiles.png\",\r\n\t\"AACastMisty.png\",\r\n\t\"AACastNeil.png\",\r\n\t\"AACastOldbag.png\",\r\n\t\"AACastOldbag2.png\",\r\n\t\"AACastPayne.png\",\r\n\t\"AACastPayne2.png\",\r\n\t\"AACastPenny.png\",\r\n\t\"AACastPhoenix.png\",\r\n\t\"AACastPhoenix2.png\",\r\n\t\"AACastPowers.png\",\r\n\t\"AACastPowers2.png\",\r\n\t\"AACastSahwit.png\",\r\n\t\"AACastSal.png\",\r\n\t\"AACastStarr.png\",\r\n\t\"AACastVasquez.png\",\r\n\t\"AACastWhite.png\",\r\n\t\"AAI2CastBlaise.png\",\r\n\t\"AAI2CastBonnie.png\",\r\n\t\"AAI2CastCameron.png\",\r\n\t\"AAI2CastCourtney.png\",\r\n\t\"AAI2CastDelicia.png\",\r\n\t\"AAI2CastDogen.png\",\r\n\t\"AAI2CastElbird.png\",\r\n\t\"AAI2CastGustavia.png\",\r\n\t\"AAI2CastGustavia2.png\",\r\n\t\"AAI2CastJill.png\",\r\n\t\"AAI2CastKarin.png\",\r\n\t\"AAI2CastKatherine.png\",\r\n\t\"AAI2CastKatherine2.png\",\r\n\t\"AAI2CastKnightley.png\",\r\n\t\"AAI2CastMarsh.png\",\r\n\t\"AAI2CastMaster.png\",\r\n\t\"AAI2CastMaster2.png\",\r\n\t\"AAI2CastNicole.png\",\r\n\t\"AAI2CastPierre.png\",\r\n\t\"AAI2CastRaymond.png\",\r\n\t\"AAI2CastRaymond2.png\",\r\n\t\"AAI2CastRoland.png\",\r\n\t\"AAI2CastRooke.png\",\r\n\t\"AAI2CastSahwit.png\",\r\n\t\"AAI2CastSebastian.png\",\r\n\t\"AAI2CastShelly.png\",\r\n\t\"AAI2CastSimon.png\",\r\n\t\"AAI2bag.png\",\r\n\t\"AAI2balloon.png\",\r\n\t\"AAI2bell.png\",\r\n\t\"AAI2blanket.png\",\r\n\t\"AAI2body.png\",\r\n\t\"AAI2button.png\",\r\n\t\"AAI2chess.png\",\r\n\t\"AAI2clip.png\",\r\n\t\"AAI2cuffs.png\",\r\n\t\"AAI2dog.png\",\r\n\t\"AAI2door.png\",\r\n\t\"AAI2floor.png\",\r\n\t\"AAI2gate.png\",\r\n\t\"AAI2glove.png\",\r\n\t\"AAI2gun.png\",\r\n\t\"AAI2key.png\",\r\n\t\"AAI2map.png\",\r\n\t\"AAI2map2.png\",\r\n\t\"AAI2map3.png\",\r\n\t\"AAI2note.png\",\r\n\t\"AAI2rope.png\",\r\n\t\"AAI2shovel.png\",\r\n\t\"AAI2tunnel.png\",\r\n\t\"AAI2uniform.png\",\r\n\t\"AAI2video.png\",\r\n\t\"AAI2well.png\",\r\n\t\"AAICastAkbey.png\",\r\n\t\"AAICastAlba.png\",\r\n\t\"AAICastAlba2.png\",\r\n\t\"AAICastAmano.png\",\r\n\t\"AAICastBadd.png\",\r\n\t\"AAICastBuddy.png\",\r\n\t\"AAICastButz.png\",\r\n\t\"AAICastByrne.png\",\r\n\t\"AAICastCammy.png\",\r\n\t\"AAICastDeacon.png\",\r\n\t\"AAICastDeid.png\",\r\n\t\"AAICastFranziska.png\",\r\n\t\"AAICastFranziska2.png\",\r\n\t\"AAICastGumshoe.png\",\r\n\t\"AAICastGumshoe2.png\",\r\n\t\"AAICastHuang.png\",\r\n\t\"AAICastJudge.png\",\r\n\t\"AAICastKay.png\",\r\n\t\"AAICastKay2.png\",\r\n\t\"AAICastLance.png\",\r\n\t\"AAICastLang.png\",\r\n\t\"AAICastMack.png\",\r\n\t\"AAICastMaggey.png\",\r\n\t\"AAICastManfred.png\",\r\n\t\"AAICastManny.png\",\r\n\t\"AAICastNou.png\",\r\n\t\"AAICastPalaeno.png\",\r\n\t\"AAICastPaups.png\",\r\n\t\"AAICastPortsman.png\",\r\n\t\"AAICastRhoda.png\",\r\n\t\"AAICastShihna.png\",\r\n\t\"AAICastSkye.png\",\r\n\t\"AAICastYew.png\",\r\n\t\"AAICastZinc.png\",\r\n\t\"AAIFIRE.png\",\r\n\t\"AAIad.png\",\r\n\t\"AAIad2.png\",\r\n\t\"AAIad3.png\",\r\n\t\"AAIarrow.png\",\r\n\t\"AAIbadge.png\",\r\n\t\"AAIbadger.png\",\r\n\t\"AAIbadger2.png\",\r\n\t\"AAIbadger3.png\",\r\n\t\"AAIbadger4.png\",\r\n\t\"AAIbag.png\",\r\n\t\"AAIballoon.png\",\r\n\t\"AAIbody.png\",\r\n\t\"AAIbody2.png\",\r\n\t\"AAIbody3.png\",\r\n\t\"AAIbody4.png\",\r\n\t\"AAIbody5.png\",\r\n\t\"AAIbook.png\",\r\n\t\"AAIbook2.png\",\r\n\t\"AAIbook3.png\",\r\n\t\"AAIbook4.png\",\r\n\t\"AAIboxes.png\",\r\n\t\"AAIbusinesscard.png\",\r\n\t\"AAIbusinesscard2.png\",\r\n\t\"AAIcar.png\",\r\n\t\"AAIcargo.png\",\r\n\t\"AAIcart.png\",\r\n\t\"AAIchange.png\",\r\n\t\"AAIclip.png\",\r\n\t\"AAIcravat.png\",\r\n\t\"AAIdecoration.png\",\r\n\t\"AAIdoor.png\",\r\n\t\"AAIfile.png\",\r\n\t\"AAIfile2.png\",\r\n\t\"AAIfile3.png\",\r\n\t\"AAIflowers.png\",\r\n\t\"AAIfountain.png\",\r\n\t\"AAIfountain2.png\",\r\n\t\"AAIgift.png\",\r\n\t\"AAIguitarpick.png\",\r\n\t\"AAIgun.png\",\r\n\t\"AAIgun2.png\",\r\n\t\"AAIgun3.png\",\r\n\t\"AAIhandprint.png\",\r\n\t\"AAIhat.png\",\r\n\t\"AAIhoop.png\",\r\n\t\"AAIink.png\",\r\n\t\"AAIkey.png\",\r\n\t\"AAIkey2.png\",\r\n\t\"AAIkey3.png\",\r\n\t\"AAIkey4.png\",\r\n\t\"AAIkey5.png\",\r\n\t\"AAIknife.png\",\r\n\t\"AAIknife2.png\",\r\n\t\"AAIknife3.png\",\r\n\t\"AAIknife4.png\",\r\n\t\"AAIknife5.png\",\r\n\t\"AAIlantern.png\",\r\n\t\"AAIlittlethief.png\",\r\n\t\"AAIluggage.png\",\r\n\t\"AAImoney.png\",\r\n\t\"AAInote.png\",\r\n\t\"AAInote2.png\",\r\n\t\"AAInote3.png\",\r\n\t\"AAInote4.png\",\r\n\t\"AAInote5.png\",\r\n\t\"AAInote6.png\",\r\n\t\"AAInote7.png\",\r\n\t\"AAInote8.png\",\r\n\t\"AAInote9.png\",\r\n\t\"AAInote10.png\",\r\n\t\"AAInote11.png\",\r\n\t\"AAInote12.png\",\r\n\t\"AAInote13.png\",\r\n\t\"AAInote14.png\",\r\n\t\"AAInote15.png\",\r\n\t\"AAInote16.png\",\r\n\t\"AAInote17.png\",\r\n\t\"AAIpen.png\",\r\n\t\"AAIpendant.png\",\r\n\t\"AAIpendant2.png\",\r\n\t\"AAIperfume.png\",\r\n\t\"AAIperfume2.png\",\r\n\t\"AAIphone.png\",\r\n\t\"AAIphone2.png\",\r\n\t\"AAIphone3.png\",\r\n\t\"AAIphoto.png\",\r\n\t\"AAIphoto2.png\",\r\n\t\"AAIphoto3.png\",\r\n\t\"AAIphoto4.png\",\r\n\t\"AAIplates.png\",\r\n\t\"AAIquercuswound.png\",\r\n\t\"AAIreceipt.png\",\r\n\t\"AAIsafe.png\",\r\n\t\"AAIsafe2.png\",\r\n\t\"AAIsciencekit.png\",\r\n\t\"AAIshards.png\",\r\n\t\"AAIshards2.png\",\r\n\t\"AAIshards3.png\",\r\n\t\"AAIshears.png\",\r\n\t\"AAIshirt.png\",\r\n\t\"AAIsnack.png\",\r\n\t\"AAIspear.png\",\r\n\t\"AAIspill.png\",\r\n\t\"AAIstatue.png\",\r\n\t\"AAIstatue2.png\",\r\n\t\"AAIstatue3.png\",\r\n\t\"AAIstatue4.png\",\r\n\t\"AAIsuspect.png\",\r\n\t\"AAIsword.png\",\r\n\t\"AAIsword2.png\",\r\n\t\"AAItape.png\",\r\n\t\"AAItonosamanju.png\",\r\n\t\"AAItonosamanju2.png\",\r\n\t\"AAItonosamanju3.png\",\r\n\t\"AAIvideo.png\",\r\n\t\"AAIwakasaman.png\",\r\n\t\"AAIwallet.png\",\r\n\t\"AAIwire.png\",\r\n\t\"AATHATCARD.png\",\r\n\t\"AAaffidavit.png\",\r\n\t\"AAairtube.png\",\r\n\t\"AAautopsy.png\",\r\n\t\"AAbluebadger.png\",\r\n\t\"AAbook.png\",\r\n\t\"AAbook2.png\",\r\n\t\"AAbook3.png\",\r\n\t\"AAbullet.png\",\r\n\t\"AAbullet2.png\",\r\n\t\"AAcamera.png\",\r\n\t\"AAcamera2.png\",\r\n\t\"AAcards.png\",\r\n\t\"AAclip.png\",\r\n\t\"AAclip2.png\",\r\n\t\"AAclip3.png\",\r\n\t\"AAclip4.png\",\r\n\t\"AAclip5.png\",\r\n\t\"AAdata.png\",\r\n\t\"AAdata2.png\",\r\n\t\"AAdata3.png\",\r\n\t\"AAdata4.png\",\r\n\t\"AAenvelope.png\",\r\n\t\"AAevidencelaw.png\",\r\n\t\"AAfingerprintpowder.png\",\r\n\t\"AAfirecracker.png\",\r\n\t\"AAfishingpole.png\",\r\n\t\"AAflyer.png\",\r\n\t\"AAglassshards.png\",\r\n\t\"AAglove.png\",\r\n\t\"AAgun.png\",\r\n\t\"AAhandprint.png\",\r\n\t\"AAidcard.png\",\r\n\t\"AAkey.png\",\r\n\t\"AAkeycard.png\",\r\n\t\"AAknife1.png\",\r\n\t\"AAkoptrophy.png\",\r\n\t\"AAleather.png\",\r\n\t\"AAlocker.png\",\r\n\t\"AAlocker2.png\",\r\n\t\"AAlocker3.png\",\r\n\t\"AAluminol.png\",\r\n\t\"AAluminol2.png\",\r\n\t\"AAlunch.png\",\r\n\t\"AAlunch2.png\",\r\n\t\"AAlunch3.png\",\r\n\t\"AAmagatama.png\",\r\n\t\"AAmagatama2.png\",\r\n\t\"AAmayanote.png\",\r\n\t\"AAmayoinote.png\",\r\n\t\"AAmetaldetector.png\",\r\n\t\"AAmissile.png\",\r\n\t\"AAmissile2.png\",\r\n\t\"AAmissle2.png\",\r\n\t\"AAmrmonkey.png\",\r\n\t\"AAnote.png\",\r\n\t\"AAnote2.png\",\r\n\t\"AAnote3.png\",\r\n\t\"AAnote4.png\",\r\n\t\"AAparkingticket.png\",\r\n\t\"AApassport.png\",\r\n\t\"AApassport2.png\",\r\n\t\"AAphone.png\",\r\n\t\"AAphone2.png\",\r\n\t\"AAphone3.png\",\r\n\t\"AAphone4.png\",\r\n\t\"AAphoto.png\",\r\n\t\"AAphoto2.png\",\r\n\t\"AAphoto3.png\",\r\n\t\"AAphoto4.png\",\r\n\t\"AAphoto5.png\",\r\n\t\"AAphoto6.png\",\r\n\t\"AAphoto7.png\",\r\n\t\"AAphoto8.png\",\r\n\t\"AAphoto9.png\",\r\n\t\"AAphoto10.png\",\r\n\t\"AAphoto11.png\",\r\n\t\"AApills.png\",\r\n\t\"AApills2.png\",\r\n\t\"AAplate.png\",\r\n\t\"AAplate2.png\",\r\n\t\"AApolly.png\",\r\n\t\"AAprint.png\",\r\n\t\"AAprint2.png\",\r\n\t\"AAprint3.png\",\r\n\t\"AAprint4.png\",\r\n\t\"AAprint5.png\",\r\n\t\"AAprint6.png\",\r\n\t\"AAprint7.png\",\r\n\t\"AAprint8.png\",\r\n\t\"AApsychelock.png\",\r\n\t\"AAsafe.png\",\r\n\t\"AAscarf.png\",\r\n\t\"AAscrewdriver.png\",\r\n\t\"AAscript.png\",\r\n\t\"AAscript2.png\",\r\n\t\"AAshoe.png\",\r\n\t\"AAshoe2.png\",\r\n\t\"AAspear.png\",\r\n\t\"AAstudiovan.png\",\r\n\t\"AAswitchblade.png\",\r\n\t\"AAswitchblade2.png\",\r\n\t\"AAswitchblade3.png\",\r\n\t\"AAthinker.png\",\r\n\t\"AAvase.png\",\r\n\t\"AAvase2.png\",\r\n\t\"AAvase3.png\",\r\n\t\"AAvase4.png\",\r\n\t\"AAvase5.png\",\r\n\t\"AAvideo.png\",\r\n\t\"AAvideo2.png\",\r\n\t\"AAwallet.png\",\r\n\t\"AAwiretap.png\",\r\n\t\"AJCastAlita.png\",\r\n\t\"AJCastApollo.png\",\r\n\t\"AJCastDaryan.jpg\",\r\n\t\"AJCastDaryan.png\",\r\n\t\"AJCastDrew.png\",\r\n\t\"AJCastEldoon.png\",\r\n\t\"AJCastEma.png\",\r\n\t\"AJCastKlavier.png\",\r\n\t\"AJCastKlavier2.png\",\r\n\t\"AJCastKristoph.png\",\r\n\t\"AJCastLamiroir.png\",\r\n\t\"AJCastLeTouse.png\",\r\n\t\"AJCastMachi.png\",\r\n\t\"AJCastMagnifi.png\",\r\n\t\"AJCastMeraktis.png\",\r\n\t\"AJCastOlga.png\",\r\n\t\"AJCastOlga2.png\",\r\n\t\"AJCastPayne.png\",\r\n\t\"AJCastPhoenix.png\",\r\n\t\"AJCastPlum.png\",\r\n\t\"AJCastShadi.png\",\r\n\t\"AJCastSpark.png\",\r\n\t\"AJCastStickler.png\",\r\n\t\"AJCastThalassa.png\",\r\n\t\"AJCastTrucy.gif\",\r\n\t\"AJCastTrucy.png\",\r\n\t\"AJCastValant.png\",\r\n\t\"AJCastValant2.png\",\r\n\t\"AJCastVera.png\",\r\n\t\"AJCastWinfred.png\",\r\n\t\"AJCastWocky.png\",\r\n\t\"AJCastZak.png\",\r\n\t\"AJad.png\",\r\n\t\"AJad2.png\",\r\n\t\"AJad3.png\",\r\n\t\"AJad4.png\",\r\n\t\"AJad5.png\",\r\n\t\"AJautopsy.png\",\r\n\t\"AJbadge.png\",\r\n\t\"AJbook.png\",\r\n\t\"AJbottle.png\",\r\n\t\"AJbowl.png\",\r\n\t\"AJbox.png\",\r\n\t\"AJbracelet.png\",\r\n\t\"AJbrooch.png\",\r\n\t\"AJbullet.png\",\r\n\t\"AJburntstuff.png\",\r\n\t\"AJbusinesscard.png\",\r\n\t\"AJbusinesscard2.png\",\r\n\t\"AJbusinesscard3.png\",\r\n\t\"AJbusinesscard4.png\",\r\n\t\"AJbusinesscard5.png\",\r\n\t\"AJbusinesscard6.png\",\r\n\t\"AJbutton.png\",\r\n\t\"AJcard.png\",\r\n\t\"AJcard2.png\",\r\n\t\"AJcard3.png\",\r\n\t\"AJcard4.png\",\r\n\t\"AJcard5.png\",\r\n\t\"AJcart.png\",\r\n\t\"AJclip.png\",\r\n\t\"AJclip2.png\",\r\n\t\"AJclip3.png\",\r\n\t\"AJcocoon.png\",\r\n\t\"AJdata1.png\",\r\n\t\"AJdata2.png\",\r\n\t\"AJdata3.png\",\r\n\t\"AJdevice.png\",\r\n\t\"AJdevice2.png\",\r\n\t\"AJdevice3.png\",\r\n\t\"AJearpiece.png\",\r\n\t\"AJfingerprintpowder.png\",\r\n\t\"AJframe.png\",\r\n\t\"AJgoldsnackoo.png\",\r\n\t\"AJguitar.png\",\r\n\t\"AJgun.png\",\r\n\t\"AJgun2.png\",\r\n\t\"AJgun3.png\",\r\n\t\"AJiv.png\",\r\n\t\"AJiv2.png\",\r\n\t\"AJkey.png\",\r\n\t\"AJknife.png\",\r\n\t\"AJlamp.png\",\r\n\t\"AJlocket.png\",\r\n\t\"AJluminol.png\",\r\n\t\"AJmagatama.png\",\r\n\t\"AJmap.png\",\r\n\t\"AJmap2.png\",\r\n\t\"AJmap3.png\",\r\n\t\"AJmap4.png\",\r\n\t\"AJmirror.png\",\r\n\t\"AJmixer.png\",\r\n\t\"AJmrhat.png\",\r\n\t\"AJmug.png\",\r\n\t\"AJnailpolish.png\",\r\n\t\"AJnote.png\",\r\n\t\"AJnote2.png\",\r\n\t\"AJnote3.png\",\r\n\t\"AJnote4.png\",\r\n\t\"AJnote5.png\",\r\n\t\"AJnote6.png\",\r\n\t\"AJnote7.png\",\r\n\t\"AJnote8.png\",\r\n\t\"AJnote9.png\",\r\n\t\"AJnote10.png\",\r\n\t\"AJnote11.png\",\r\n\t\"AJnote12.png\",\r\n\t\"AJnote13.png\",\r\n\t\"AJnote14.png\",\r\n\t\"AJnote15.png\",\r\n\t\"AJnote16.png\",\r\n\t\"AJnote17.png\",\r\n\t\"AJnote18.png\",\r\n\t\"AJnote19.png\",\r\n\t\"AJnote\",\r\n\t\"AJpainting.png\",\r\n\t\"AJpainting2.png\",\r\n\t\"AJpainting3.png\",\r\n\t\"AJpainting4.png\",\r\n\t\"AJpanties.png\",\r\n\t\"AJpanties2.png\",\r\n\t\"AJpanties3.png\",\r\n\t\"AJphone.png\",\r\n\t\"AJphone2.png\",\r\n\t\"AJphoto.png\",\r\n\t\"AJphoto2.png\",\r\n\t\"AJphoto3.png\",\r\n\t\"AJphoto4.png\",\r\n\t\"AJphoto5.png\",\r\n\t\"AJphoto6.png\",\r\n\t\"AJphoto7.png\",\r\n\t\"AJphoto8.png\",\r\n\t\"AJpoisonspray.png\",\r\n\t\"AJsciencekit.png\",\r\n\t\"AJshoe.png\",\r\n\t\"AJshoe2.png\",\r\n\t\"AJshoe3.png\",\r\n\t\"AJsnack.png\",\r\n\t\"AJsnack2.png\",\r\n\t\"AJsnack3.png\",\r\n\t\"AJsnackoos.png\",\r\n\t\"AJstamp.png\",\r\n\t\"AJsyringe.png\",\r\n\t\"AJticket.png\",\r\n\t\"AJticket2.png\",\r\n\t\"AJticket3.png\",\r\n\t\"AJvideo.png\",\r\n\t\"AJxraymachine.png\",\r\n\t\"Compin.png\",\r\n\t\"Credit.png\",\r\n\t\"CustomEvidence1.png\",\r\n\t\"CustomEvidence2.png\",\r\n\t\"CustomEvidence3.png\",\r\n\t\"CustomEvidence4.png\",\r\n\t\"CustomEvidence5.png\",\r\n\t\"CustomEvidence6.png\",\r\n\t\"CustomEvidence7.png\",\r\n\t\"CustomEvidence8.png\",\r\n\t\"CustomEvidence9.png\",\r\n\t\"CustomEvidence10.png\",\r\n\t\"CustomEvidence11.png\",\r\n\t\"CustomEvidence12.png\",\r\n\t\"CustomEvidence13.png\",\r\n\t\"CustomEvidence14.png\",\r\n\t\"CustomEvidence15.png\",\r\n\t\"CustomEvidence16.png\",\r\n\t\"CustomEvidence17.png\",\r\n\t\"CustomEvidence18.png\",\r\n\t\"CustomEvidence19.png\",\r\n\t\"CustomEvidence\",\r\n\t\"DDAutopsy.png\",\r\n\t\"DDBadge.png\",\r\n\t\"DDCaseCandice.png\",\r\n\t\"DDCastApollo.png\",\r\n\t\"DDCastApollo2.png\",\r\n\t\"DDCastApollo3.png\",\r\n\t\"DDCastAthena.png\",\r\n\t\"DDCastAura.png\",\r\n\t\"DDCastBlackquill.png\",\r\n\t\"DDCastCandice.png\",\r\n\t\"DDCastClay.png\",\r\n\t\"DDCastClonco.png\",\r\n\t\"DDCastClonco2.png\",\r\n\t\"DDCastCourte.png\",\r\n\t\"DDCastCrab.png\",\r\n\t\"DDCastDamien.png\",\r\n\t\"DDCastFilch.png\",\r\n\t\"DDCastFulbright.png\",\r\n\t\"DDCastJinxie.png\",\r\n\t\"DDCastJuniper.png\",\r\n\t\"DDCastJuniper2.png\",\r\n\t\"DDCastKlavier.png\",\r\n\t\"DDCastLBelle.png\",\r\n\t\"DDCastLBelle2.png\",\r\n\t\"DDCastMeans.png\",\r\n\t\"DDCastMetis.png\",\r\n\t\"DDCastMiles.png\",\r\n\t\"DDCastNineTails.png\",\r\n\t\"DDCastNorma.png\",\r\n\t\"DDCastOConnor.png\",\r\n\t\"DDCastOrla.png\",\r\n\t\"DDCastPayne.png\",\r\n\t\"DDCastPearl.png\",\r\n\t\"DDCastPhoenix.png\",\r\n\t\"DDCastRex.png\",\r\n\t\"DDCastRimes.png\",\r\n\t\"DDCastRobin.png\",\r\n\t\"DDCastRobin2.png\",\r\n\t\"DDCastSasha.png\",\r\n\t\"DDCastSasha2.png\",\r\n\t\"DDCastSasha3.png\",\r\n\t\"DDCastScuttlebutt.png\",\r\n\t\"DDCastShipley.png\",\r\n\t\"DDCastSniper.png\",\r\n\t\"DDCastSniper2.png\",\r\n\t\"DDCastStarbuck.png\",\r\n\t\"DDCastSummers.png\",\r\n\t\"DDCastTonate.png\",\r\n\t\"DDCastTrucy.png\",\r\n\t\"DDCastYuri.png\",\r\n\t\"DDSTEPladder.png\",\r\n\t\"DDScrewdriver.png\",\r\n\t\"DDStatueStands.png\",\r\n\t\"DDarrow.png\",\r\n\t\"DDbadge2.png\",\r\n\t\"DDbag.png\",\r\n\t\"DDball.png\",\r\n\t\"DDbed.png\",\r\n\t\"DDbomb.png\",\r\n\t\"DDbomb2.png\",\r\n\t\"DDbomb3.png\",\r\n\t\"DDbomb4.png\",\r\n\t\"DDbook.png\",\r\n\t\"DDbook2.png\",\r\n\t\"DDbook3.png\",\r\n\t\"DDbook4.png\",\r\n\t\"DDbook5.png\",\r\n\t\"DDbowl.png\",\r\n\t\"DDbox.png\",\r\n\t\"DDbox2.png\",\r\n\t\"DDbox3.png\",\r\n\t\"DDbox4.png\",\r\n\t\"DDbracelet.png\",\r\n\t\"DDbullet.png\",\r\n\t\"DDbullet2.png\",\r\n\t\"DDbullethole.png\",\r\n\t\"DDcalendar.png\",\r\n\t\"DDcamera.png\",\r\n\t\"DDcamera2.png\",\r\n\t\"DDcamera3.png\",\r\n\t\"DDcart.png\",\r\n\t\"DDcd.png\",\r\n\t\"DDcharm.png\",\r\n\t\"DDclip.png\",\r\n\t\"DDclip2.png\",\r\n\t\"DDclip3.png\",\r\n\t\"DDcloth.png\",\r\n\t\"DDcoin.png\",\r\n\t\"DDcoin2.png\",\r\n\t\"DDcomputer.png\",\r\n\t\"DDcostume.png\",\r\n\t\"DDcostume2.png\",\r\n\t\"DDcostumes.png\",\r\n\t\"DDdata.png\",\r\n\t\"DDdata2.png\",\r\n\t\"DDdata3.png\",\r\n\t\"DDdetonator.png\",\r\n\t\"DDdoor.png\",\r\n\t\"DDdoor2.png\",\r\n\t\"DDdoor3.png\",\r\n\t\"DDdye.png\",\r\n\t\"DDearring.png\",\r\n\t\"DDemblem.png\",\r\n\t\"DDenvelope.png\",\r\n\t\"DDfingerprint.png\",\r\n\t\"DDfingerprintpowder.png\",\r\n\t\"DDfish.png\",\r\n\t\"DDflower.png\",\r\n\t\"DDfood.png\",\r\n\t\"DDfood2.png\",\r\n\t\"DDgun.png\",\r\n\t\"DDhair.png\",\r\n\t\"DDhairspray.png\",\r\n\t\"DDhandprint.png\",\r\n\t\"DDhat.png\",\r\n\t\"DDheadphones.png\",\r\n\t\"DDkey.png\",\r\n\t\"DDkey2.png\",\r\n\t\"DDkey3.png\",\r\n\t\"DDkeycard.png\",\r\n\t\"DDkeycard2.png\",\r\n\t\"DDkeycard3.png\",\r\n\t\"DDkeycard4.png\",\r\n\t\"DDkeycard5.png\",\r\n\t\"DDkeycard6.png\",\r\n\t\"DDkeycard7.png\",\r\n\t\"DDknife.png\",\r\n\t\"DDladder.png\",\r\n\t\"DDladder2.png\",\r\n\t\"DDlighter.png\",\r\n\t\"DDluminol.png\",\r\n\t\"DDmagatama.png\",\r\n\t\"DDmagatama2.png\",\r\n\t\"DDmap.png\",\r\n\t\"DDmap2.png\",\r\n\t\"DDmap3.png\",\r\n\t\"DDmap4.png\",\r\n\t\"DDmap5.png\",\r\n\t\"DDmap6.png\",\r\n\t\"DDmap7.png\",\r\n\t\"DDmap8.png\",\r\n\t\"DDmap9.png\",\r\n\t\"DDmap10.png\",\r\n\t\"DDmap11.png\",\r\n\t\"DDmap12.png\",\r\n\t\"DDmask.png\",\r\n\t\"DDmedicine.png\",\r\n\t\"DDmedicine2.png\",\r\n\t\"DDmedicine3.png\",\r\n\t\"DDnote.png\",\r\n\t\"DDnote2.png\",\r\n\t\"DDnote4.png\",\r\n\t\"DDnote5.png\",\r\n\t\"DDnote6.png\",\r\n\t\"DDnote7.png\",\r\n\t\"DDnote8.png\",\r\n\t\"DDnote9.png\",\r\n\t\"DDnote10.png\",\r\n\t\"DDnote16.png\",\r\n\t\"DDpenguin.png\",\r\n\t\"DDphone.png\",\r\n\t\"DDphone2.png\",\r\n\t\"DDphoto.png\",\r\n\t\"DDphoto2.png\",\r\n\t\"DDphoto3.png\",\r\n\t\"DDphoto4.png\",\r\n\t\"DDphoto5.png\",\r\n\t\"DDphoto6.png\",\r\n\t\"DDphoto7.png\",\r\n\t\"DDphoto10.png\",\r\n\t\"DDphoto11.png\",\r\n\t\"DDphoto12.png\",\r\n\t\"DDphoto13.png\",\r\n\t\"DDphoto14.png\",\r\n\t\"DDphoto15.png\",\r\n\t\"DDplate.png\",\r\n\t\"DDposter.png\",\r\n\t\"DDposter2.png\",\r\n\t\"DDposter3.png\",\r\n\t\"DDpuppet.png\",\r\n\t\"DDrecorder.png\",\r\n\t\"DDscienceglasses.png\",\r\n\t\"DDscroll.png\",\r\n\t\"DDshard.png\",\r\n\t\"DDshard2.png\",\r\n\t\"DDshard3.png\",\r\n\t\"DDshard4.png\",\r\n\t\"DDshard5.png\",\r\n\t\"DDshard6.png\",\r\n\t\"DDshard7.png\",\r\n\t\"DDshoe.png\",\r\n\t\"DDskull.png\",\r\n\t\"DDstaff.png\",\r\n\t\"DDstatue.png\",\r\n\t\"DDstatue2.png\",\r\n\t\"DDstatue3.png\",\r\n\t\"DDstatue4.png\",\r\n\t\"DDstatue5.png\",\r\n\t\"DDstatue6.png\",\r\n\t\"DDstatue7.png\",\r\n\t\"DDstatue8.png\",\r\n\t\"DDstatue9.png\",\r\n\t\"DDsurgery.png\",\r\n\t\"DDsuspect.png\",\r\n\t\"DDsword.png\",\r\n\t\"DDsword2.png\",\r\n\t\"DDtail.png\",\r\n\t\"DDtank.png\",\r\n\t\"DDtank2.png\",\r\n\t\"DDvideo.png\",\r\n\t\"DDwhistle.png\",\r\n\t\"DDwidget.png\",\r\n\t\"DGSCastAuchi.png\",\r\n\t\"DGSCastBarok.png\",\r\n\t\"DGSCastBeppo.png\",\r\n\t\"DGSCastCrogrey.png\",\r\n\t\"DGSCastDemiglaski.png\",\r\n\t\"DGSCastFairplay.png\",\r\n\t\"DGSCastGina.png\",\r\n\t\"DGSCastGreen.png\",\r\n\t\"DGSCastGregson.png\",\r\n\t\"DGSCastHolmes.png\",\r\n\t\"DGSCastHosonaga.png\",\r\n\t\"DGSCastHosonaga2.png\",\r\n\t\"DGSCastHutch.png\",\r\n\t\"DGSCastJWatson.png\",\r\n\t\"DGSCastJezail.png\",\r\n\t\"DGSCastJoan.png\",\r\n\t\"DGSCastJohn.png\",\r\n\t\"DGSCastKazuma.png\",\r\n\t\"DGSCastLadyfirst.png\",\r\n\t\"DGSCastMegundal.png\",\r\n\t\"DGSCastMilverton.png\",\r\n\t\"DGSCastNatsume.png\",\r\n\t\"DGSCastNemmy.png\",\r\n\t\"DGSCastNikomina.png\",\r\n\t\"DGSCastPat.png\",\r\n\t\"DGSCastRola.png\",\r\n\t\"DGSCastRoylott.png\",\r\n\t\"DGSCastRyuunosuke.png\",\r\n\t\"DGSCastSanmon.png\",\r\n\t\"DGSCastStroganov.png\",\r\n\t\"DGSCastSusato.png\",\r\n\t\"DGSCastSuspect.png\",\r\n\t\"DGSCastTaizou.png\",\r\n\t\"DGSCastTully.png\",\r\n\t\"DGSCastVortex.png\",\r\n\t\"DGSCastWagahai.png\",\r\n\t\"DGSCastWatson.png\",\r\n\t\"DGSCastYuujin.png\",\r\n\t\"DGSbadge.png\",\r\n\t\"DGSbag.png\",\r\n\t\"DGSbag2.png\",\r\n\t\"DGSbell.png\",\r\n\t\"DGSbell2.png\",\r\n\t\"DGSbell3.png\",\r\n\t\"DGSbook.png\",\r\n\t\"DGSbook2.png\",\r\n\t\"DGSbook3.png\",\r\n\t\"DGSbook4.png\",\r\n\t\"DGSbook5.png\",\r\n\t\"DGSbook6.png\",\r\n\t\"DGSbook7.png\",\r\n\t\"DGSbook8.png\",\r\n\t\"DGSbook9.png\",\r\n\t\"DGSbook10.png\",\r\n\t\"DGSbullet.png\",\r\n\t\"DGScamera.png\",\r\n\t\"DGScane.png\",\r\n\t\"DGScart.png\",\r\n\t\"DGSclip.png\",\r\n\t\"DGSclip2.png\",\r\n\t\"DGSclip3.png\",\r\n\t\"DGSclip4.png\",\r\n\t\"DGScoin.png\",\r\n\t\"DGSdevice.png\",\r\n\t\"DGSflower.png\",\r\n\t\"DGSfood.png\",\r\n\t\"DGSfood2.png\",\r\n\t\"DGSfood3.png\",\r\n\t\"DGSfood4.png\",\r\n\t\"DGSgloves.png\",\r\n\t\"DGSgloves2.png\",\r\n\t\"DGSgun.png\",\r\n\t\"DGSgun2.png\",\r\n\t\"DGSgun3.png\",\r\n\t\"DGSherbaltea.png\",\r\n\t\"DGSknife.png\",\r\n\t\"DGSknife2.png\",\r\n\t\"DGSknife3.png\",\r\n\t\"DGSknife4.png\",\r\n\t\"DGSmap.png\",\r\n\t\"DGSmap2.png\",\r\n\t\"DGSmap3.png\",\r\n\t\"DGSmusicbox.png\",\r\n\t\"DGSmusicbox2.png\",\r\n\t\"DGSmusicbox3.png\",\r\n\t\"DGSmusicdisk.png\",\r\n\t\"DGSmusicdisk2.png\",\r\n\t\"DGSmusicdisk3.png\",\r\n\t\"DGSmusicdisk4.png\",\r\n\t\"DGSmusicdisk15.png\",\r\n\t\"DGSnote.png\",\r\n\t\"DGSnote2.png\",\r\n\t\"DGSnote3.png\",\r\n\t\"DGSnote4.png\",\r\n\t\"DGSnote5.png\",\r\n\t\"DGSnote6.png\",\r\n\t\"DGSnote7.png\",\r\n\t\"DGSnote8.png\",\r\n\t\"DGSnote9.png\",\r\n\t\"DGSnote10.png\",\r\n\t\"DGSnote11.png\",\r\n\t\"DGSnote12.png\",\r\n\t\"DGSnote13.png\",\r\n\t\"DGSnote14.png\",\r\n\t\"DGSnote15.png\",\r\n\t\"DGSnote16.png\",\r\n\t\"DGSnote17.png\",\r\n\t\"DGSnote18.png\",\r\n\t\"DGSnote19.png\",\r\n\t\"DGSnote\",\r\n\t\"DGSnote21.png\",\r\n\t\"DGSphoto.png\",\r\n\t\"DGSphoto2.png\",\r\n\t\"DGSphoto3.png\",\r\n\t\"DGSphoto4.png\",\r\n\t\"DGSphoto5.png\",\r\n\t\"DGSphoto6.png\",\r\n\t\"DGSphoto7.png\",\r\n\t\"DGSphoto8.png\",\r\n\t\"DGSphoto9.png\",\r\n\t\"DGSphoto10.png\",\r\n\t\"DGSphoto11.png\",\r\n\t\"DGSphoto12.png\",\r\n\t\"DGSphoto13.png\",\r\n\t\"DGSphoto14.png\",\r\n\t\"DGSphoto15.png\",\r\n\t\"DGSphoto16.png\",\r\n\t\"DGSphoto17.png\",\r\n\t\"DGSphoto18.png\",\r\n\t\"DGSphoto19.png\",\r\n\t\"DGSpin.png\",\r\n\t\"DGSpin2.png\",\r\n\t\"DGSpipe.png\",\r\n\t\"DGSpressing.png\",\r\n\t\"DGSsciencekit.png\",\r\n\t\"DGSshard.png\",\r\n\t\"DGSstereoscope.png\",\r\n\t\"DGSstereoscope2.png\",\r\n\t\"DGStiara.png\",\r\n\t\"DGSviola.png\",\r\n\t\"DGSviola2.png\",\r\n\t\"DGSwhip.png\",\r\n\t\"Datapad.png\",\r\n\t\"Interface.png\",\r\n\t\"JFACastAcro.png\",\r\n\t\"JFACastAdrian.png\",\r\n\t\"JFACastAmi.png\",\r\n\t\"JFACastBat.png\",\r\n\t\"JFACastBen.png\",\r\n\t\"JFACastCeleste.png\",\r\n\t\"JFACastDeKiller.png\",\r\n\t\"JFACastDustin.png\",\r\n\t\"JFACastFranziska.png\",\r\n\t\"JFACastGalactica.png\",\r\n\t\"JFACastGrey.png\",\r\n\t\"JFACastHotti.png\",\r\n\t\"JFACastIni.png\",\r\n\t\"JFACastJuan.png\",\r\n\t\"JFACastMaggey.png\",\r\n\t\"JFACastMatt.png\",\r\n\t\"JFACastMimi.png\",\r\n\t\"JFACastMoe.png\",\r\n\t\"JFACastMorgan.png\",\r\n\t\"JFACastPearl.png\",\r\n\t\"JFACastRegina.png\",\r\n\t\"JFACastRussel.png\",\r\n\t\"JFACastShelly.png\",\r\n\t\"JFACastWellington.png\",\r\n\t\"JFATHATCARD.png\",\r\n\t\"JFATHATCARD2.png\",\r\n\t\"JFAautograph.png\",\r\n\t\"JFAautograph2.png\",\r\n\t\"JFAball.png\",\r\n\t\"JFAball2.png\",\r\n\t\"JFAbear.png\",\r\n\t\"JFAbear2.png\",\r\n\t\"JFAbear3.png\",\r\n\t\"JFAbottle.png\",\r\n\t\"JFAbox.png\",\r\n\t\"JFAbox2.png\",\r\n\t\"JFAbusinesscard.png\",\r\n\t\"JFAbusinesscard2.png\",\r\n\t\"JFAbutton.png\",\r\n\t\"JFAbutton2.png\",\r\n\t\"JFAbutton3.png\",\r\n\t\"JFAcamera.png\",\r\n\t\"JFAcard.png\",\r\n\t\"JFAcard2.png\",\r\n\t\"JFAclip.png\",\r\n\t\"JFAclip2.png\",\r\n\t\"JFAclip3.png\",\r\n\t\"JFAclip4.png\",\r\n\t\"JFAcoat.png\",\r\n\t\"JFAfrequencydetector.png\",\r\n\t\"JFAglasses.png\",\r\n\t\"JFAglove.png\",\r\n\t\"JFAgrapes.png\",\r\n\t\"JFAguitar.png\",\r\n\t\"JFAgun.png\",\r\n\t\"JFAgun2.png\",\r\n\t\"JFAhammond.png\",\r\n\t\"JFAhat.png\",\r\n\t\"JFAjuice.png\",\r\n\t\"JFAkey.png\",\r\n\t\"JFAknife.png\",\r\n\t\"JFAknife2.png\",\r\n\t\"JFAleon.png\",\r\n\t\"JFAmilk.png\",\r\n\t\"JFAmilk2.png\",\r\n\t\"JFAmoney.png\",\r\n\t\"JFAnote.png\",\r\n\t\"JFAnote2.png\",\r\n\t\"JFApepper.png\",\r\n\t\"JFAphoto.png\",\r\n\t\"JFAposter.png\",\r\n\t\"JFAreceipt.png\",\r\n\t\"JFAregent.png\",\r\n\t\"JFAring.png\",\r\n\t\"JFArobe.png\",\r\n\t\"JFArobescrap.png\",\r\n\t\"JFAscarf.png\",\r\n\t\"JFAscreen.png\",\r\n\t\"JFAshoe.png\",\r\n\t\"JFAspycamera.png\",\r\n\t\"JFAticket.png\",\r\n\t\"JFAticket2.png\",\r\n\t\"JFAtracker.png\",\r\n\t\"JFAtransceiver.png\",\r\n\t\"JFAtransmitter.png\",\r\n\t\"JFAtrilo.png\",\r\n\t\"JFAuniform.png\",\r\n\t\"JFAurn1.png\",\r\n\t\"JFAurn2.png\",\r\n\t\"JFAvest.png\",\r\n\t\"JFAwhip.png\",\r\n\t\"MiscAKMS.png\",\r\n\t\"MiscAsthmaPump.png\",\r\n\t\"MiscBaggie.png\",\r\n\t\"MiscBeach.png\",\r\n\t\"MiscBlueRuby.png\",\r\n\t\"MiscCandy Cane.png\",\r\n\t\"MiscCandy Cane Dark.png\",\r\n\t\"MiscCorkscrew.png\",\r\n\t\"MiscCrowbar.png\",\r\n\t\"MiscDragonPepper.png\",\r\n\t\"MiscFlintlock.png\",\r\n\t\"MiscGenerator.png\",\r\n\t\"MiscGrapeJuice.png\",\r\n\t\"MiscGreen Hut.png\",\r\n\t\"MiscGrill.png\",\r\n\t\"MiscHalf-Eaten Burger.png\",\r\n\t\"MiscHangGlider.png\",\r\n\t\"MiscLockpicks.png\",\r\n\t\"MiscMapBiolab.png\",\r\n\t\"MiscMapCourthouse.png\",\r\n\t\"MiscMapLobby1.png\",\r\n\t\"MiscMichigan J Frog.png\",\r\n\t\"MiscMystery1.png\",\r\n\t\"MiscMystery2.png\",\r\n\t\"MiscMystery3.png\",\r\n\t\"MiscOldTrain.png\",\r\n\t\"MiscRaffleTickets.png\",\r\n\t\"MiscSpatula.png\",\r\n\t\"MiscSpecimenAlpha.png\",\r\n\t\"MiscTimeCrystal.png\",\r\n\t\"MiscTins.png\",\r\n\t\"MiscUnknown People.png\",\r\n\t\"MiscVDF.png\",\r\n\t\"MiscVodka.png\",\r\n\t\"MiscZombie.png\",\r\n\t\"Scanner.png\",\r\n\t\"SoJad.png\",\r\n\t\"SoJad2.png\",\r\n\t\"SoJad3.png\",\r\n\t\"SoJad4.png\",\r\n\t\"SoJad5.png\",\r\n\t\"SoJad6.png\",\r\n\t\"SoJad7.png\",\r\n\t\"SoJarrow.png\",\r\n\t\"SoJautopsy.png\",\r\n\t\"SoJbadge.png\",\r\n\t\"SoJbadge2.png\",\r\n\t\"SoJblimp.png\",\r\n\t\"SoJblimp2.png\",\r\n\t\"SoJblood.png\",\r\n\t\"SoJboiler.png\",\r\n\t\"SoJbook.png\",\r\n\t\"SoJbook2.png\",\r\n\t\"SoJbook3.png\",\r\n\t\"SoJbook4.png\",\r\n\t\"SoJbook5.png\",\r\n\t\"SoJbook6.png\",\r\n\t\"SoJbook7.png\",\r\n\t\"SoJbook8.png\",\r\n\t\"SoJbook9.png\",\r\n\t\"SoJbook10.png\",\r\n\t\"SoJbook11.png\",\r\n\t\"SoJbook12.png\",\r\n\t\"SoJbook13.png\",\r\n\t\"SoJbook14.png\",\r\n\t\"SoJbox.png\",\r\n\t\"SoJbox2.png\",\r\n\t\"SoJbracelet.png\",\r\n\t\"SoJbucket.png\",\r\n\t\"SoJcamera.png\",\r\n\t\"SoJcandelabra.png\",\r\n\t\"SoJcandelabra2.png\",\r\n\t\"SoJcandelabra3.png\",\r\n\t\"SoJcastAhlbi.png\",\r\n\t\"SoJcastAmara.png\",\r\n\t\"SoJcastAndistan'dhin.png\",\r\n\t\"SoJcastApollo.png\",\r\n\t\"SoJcastArchie.png\",\r\n\t\"SoJcastArmie.png\",\r\n\t\"SoJcastAthena.png\",\r\n\t\"SoJcastAtishon.png\",\r\n\t\"SoJcastBeh'leeb.png\",\r\n\t\"SoJcastBetty.png\",\r\n\t\"SoJcastBlackquill.png\",\r\n\t\"SoJcastBonny.png\",\r\n\t\"SoJcastBucky.png\",\r\n\t\"SoJcastButz.png\",\r\n\t\"SoJcastDatz.png\",\r\n\t\"SoJcastDatz2.png\",\r\n\t\"SoJcastDhurke.png\",\r\n\t\"SoJcastDumas.png\",\r\n\t\"SoJcastEllen.png\",\r\n\t\"SoJcastEma.png\",\r\n\t\"SoJcastGa'ran.png\",\r\n\t\"SoJcastGeiru.png\",\r\n\t\"SoJcastInga.png\",\r\n\t\"SoJcastMaya.png\",\r\n\t\"SoJcastMiles.png\",\r\n\t\"SoJcastNahyuta.png\",\r\n\t\"SoJcastNayna.png\",\r\n\t\"SoJcastPayne.png\",\r\n\t\"SoJcastPearl.png\",\r\n\t\"SoJcastPhoenix.png\",\r\n\t\"SoJcastPierce.png\",\r\n\t\"SoJcastPuhray.png\",\r\n\t\"SoJcastRayfa.png\",\r\n\t\"SoJcastRetinz.png\",\r\n\t\"SoJcastReus.png\",\r\n\t\"SoJcastRohl.png\",\r\n\t\"SoJcastSelena.png\",\r\n\t\"SoJcastSergeant.png\",\r\n\t\"SoJcastSorin.png\",\r\n\t\"SoJcastTahrust.png\",\r\n\t\"SoJcastTaifu.png\",\r\n\t\"SoJcastTrucy.png\",\r\n\t\"SoJcastUendo.png\",\r\n\t\"SoJcd.png\",\r\n\t\"SoJcd2.png\",\r\n\t\"SoJcharm.png\",\r\n\t\"SoJclip.png\",\r\n\t\"SoJclip2.png\",\r\n\t\"SoJcog.png\",\r\n\t\"SoJcontract.png\",\r\n\t\"SoJdog.png\",\r\n\t\"SoJflag.png\",\r\n\t\"SoJflower.png\",\r\n\t\"SoJfood1.png\",\r\n\t\"SoJfood2.png\",\r\n\t\"SoJfood3.png\",\r\n\t\"SoJgem.png\",\r\n\t\"SoJglasses.png\",\r\n\t\"SoJgoop.png\",\r\n\t\"SoJhat.png\",\r\n\t\"SoJhelicopter.png\",\r\n\t\"SoJhorse.png\",\r\n\t\"SoJhorse2.png\",\r\n\t\"SoJkey.png\",\r\n\t\"SoJkey2.png\",\r\n\t\"SoJkey3.png\",\r\n\t\"SoJkey4.png\",\r\n\t\"SoJkeycard.png\",\r\n\t\"SoJkeycharm.png\",\r\n\t\"SoJlantern.png\",\r\n\t\"SoJlantern2.png\",\r\n\t\"SoJluminol.png\",\r\n\t\"SoJmagatama.png\",\r\n\t\"SoJmagatama2.png\",\r\n\t\"SoJmagatama3.png\",\r\n\t\"SoJmap.png\",\r\n\t\"SoJmap2.png\",\r\n\t\"SoJmap3.png\",\r\n\t\"SoJmap4.png\",\r\n\t\"SoJmap5.png\",\r\n\t\"SoJmap6.png\",\r\n\t\"SoJmap7.png\",\r\n\t\"SoJmrhat.png\",\r\n\t\"SoJnote.png\",\r\n\t\"SoJnote2.png\",\r\n\t\"SoJnote3.png\",\r\n\t\"SoJnote4.png\",\r\n\t\"SoJnote5.png\",\r\n\t\"SoJnote6.png\",\r\n\t\"SoJnote7.png\",\r\n\t\"SoJnote8.png\",\r\n\t\"SoJnote9.png\",\r\n\t\"SoJnote10.png\",\r\n\t\"SoJnote11.png\",\r\n\t\"SoJnote12.png\",\r\n\t\"SoJnote13.png\",\r\n\t\"SoJnote14.png\",\r\n\t\"SoJnote15.png\",\r\n\t\"SoJnote16.png\",\r\n\t\"SoJnote17.png\",\r\n\t\"SoJorb.png\",\r\n\t\"SoJpassport.png\",\r\n\t\"SoJpendant.png\",\r\n\t\"SoJphone.png\",\r\n\t\"SoJphoto.png\",\r\n\t\"SoJphoto2.png\",\r\n\t\"SoJphoto3.png\",\r\n\t\"SoJphoto4.png\",\r\n\t\"SoJphoto5.png\",\r\n\t\"SoJphoto6.png\",\r\n\t\"SoJphoto7.png\",\r\n\t\"SoJphoto8.png\",\r\n\t\"SoJphoto9.png\",\r\n\t\"SoJphoto10.png\",\r\n\t\"SoJphoto11.png\",\r\n\t\"SoJphoto12.png\",\r\n\t\"SoJphoto13.png\",\r\n\t\"SoJphoto14.png\",\r\n\t\"SoJphoto15.png\",\r\n\t\"SoJphoto16.png\",\r\n\t\"SoJphoto17.png\",\r\n\t\"SoJphoto18.png\",\r\n\t\"SoJphoto19.png\",\r\n\t\"SoJphoto\",\r\n\t\"SoJphoto21.png\",\r\n\t\"SoJphoto22.png\",\r\n\t\"SoJphoto23.png\",\r\n\t\"SoJphoto24.png\",\r\n\t\"SoJphoto25.png\",\r\n\t\"SoJphoto26.png\",\r\n\t\"SoJphoto27.png\",\r\n\t\"SoJphoto28.png\",\r\n\t\"SoJprintpowder.png\",\r\n\t\"SoJraincoat.png\",\r\n\t\"SoJscissorlift.png\",\r\n\t\"SoJscroll.png\",\r\n\t\"SoJscroll2.png\",\r\n\t\"SoJsnackoo.png\",\r\n\t\"SoJstand.png\",\r\n\t\"SoJstatue.png\",\r\n\t\"SoJsuspect.png\",\r\n\t\"SoJsword.png\",\r\n\t\"SoJsword2.png\",\r\n\t\"SoJsyringe.png\",\r\n\t\"SoJtape1.png\",\r\n\t\"SoJtext.png\",\r\n\t\"SoJunknown.png\",\r\n\t\"SoJurn.png\",\r\n\t\"SoJusb.png\",\r\n\t\"SoJwallet.png\",\r\n\t\"SoJwidget.png\",\r\n\t\"TTCastAdrian.png\",\r\n\t\"TTCastArmstrong.png\",\r\n\t\"TTCastAtmey.png\",\r\n\t\"TTCastBikini.png\",\r\n\t\"TTCastBruto.png\",\r\n\t\"TTCastBullard.png\",\r\n\t\"TTCastDahlia.png\",\r\n\t\"TTCastDeMasque.png\",\r\n\t\"TTCastDesiree.png\",\r\n\t\"TTCastDiego.png\",\r\n\t\"TTCastElg.png\",\r\n\t\"TTCastElise.png\",\r\n\t\"TTCastFawles.png\",\r\n\t\"TTCastGodot.png\",\r\n\t\"TTCastGrossberg.png\",\r\n\t\"TTCastGumshoe.png\",\r\n\t\"TTCastIris.png\",\r\n\t\"TTCastIris2.png\",\r\n\t\"TTCastKudo.png\",\r\n\t\"TTCastLisa.png\",\r\n\t\"TTCastMaggey.png\",\r\n\t\"TTCastMiles.png\",\r\n\t\"TTCastRon.png\",\r\n\t\"TTCastSwallow.png\",\r\n\t\"TTCastTigre.png\",\r\n\t\"TTCastValerie.png\",\r\n\t\"TTCastViola.png\",\r\n\t\"TTad.png\",\r\n\t\"TTad2.png\",\r\n\t\"TTapron.png\",\r\n\t\"TTbadge.png\",\r\n\t\"TTbag.png\",\r\n\t\"TTblood1.png\",\r\n\t\"TTblood2.png\",\r\n\t\"TTbottle1.png\",\r\n\t\"TTbottle2.png\",\r\n\t\"TTbox.png\",\r\n\t\"TTbox2.png\",\r\n\t\"TTbutton.png\",\r\n\t\"TTcalendar.png\",\r\n\t\"TTcamera.png\",\r\n\t\"TTcard.png\",\r\n\t\"TTcd.png\",\r\n\t\"TTcd2.png\",\r\n\t\"TTclip.png\",\r\n\t\"TTclip2.png\",\r\n\t\"TTclip3.png\",\r\n\t\"TTclip4.png\",\r\n\t\"TTclip5.png\",\r\n\t\"TTcoldkiller.png\",\r\n\t\"TTcoldkiller2.png\",\r\n\t\"TTcup.png\",\r\n\t\"TTdata.png\",\r\n\t\"TTdata2.png\",\r\n\t\"TTdata3.png\",\r\n\t\"TTdata4.png\",\r\n\t\"TTdrawing.png\",\r\n\t\"TTemblem.png\",\r\n\t\"TTemployee.png\",\r\n\t\"TTfood1.png\",\r\n\t\"TTfood2.png\",\r\n\t\"TThood.png\",\r\n\t\"TTjewel.png\",\r\n\t\"TTjewel2.png\",\r\n\t\"TTkeycard.png\",\r\n\t\"TTknife.png\",\r\n\t\"TTlantern.png\",\r\n\t\"TTlantern2.png\",\r\n\t\"TTmagazine.png\",\r\n\t\"TTmagazine2.png\",\r\n\t\"TTmatchbook.png\",\r\n\t\"TTmatchbook2.png\",\r\n\t\"TTmedicine.png\",\r\n\t\"TTmedicine2.png\",\r\n\t\"TTmoped.png\",\r\n\t\"TTnecklace.png\",\r\n\t\"TTnote.png\",\r\n\t\"TTnote2.png\",\r\n\t\"TTnote3.png\",\r\n\t\"TTnote4.png\",\r\n\t\"TTnote5.png\",\r\n\t\"TTnote6.png\",\r\n\t\"TTnote7.png\",\r\n\t\"TTperfume.png\",\r\n\t\"TTphotoold.png\",\r\n\t\"TTsapphire.png\",\r\n\t\"TTscarf.png\",\r\n\t\"TTschichishito.png\",\r\n\t\"TTschichishito2.png\",\r\n\t\"TTschichishito3.png\",\r\n\t\"TTscroll.png\",\r\n\t\"TTscroll2.png\",\r\n\t\"TTseal.png\",\r\n\t\"TTseal2.png\",\r\n\t\"TTstaff.png\",\r\n\t\"TTstaff2.png\",\r\n\t\"TTstaff3.png\",\r\n\t\"TTstain.png\",\r\n\t\"TTstatue.png\",\r\n\t\"TTticket.png\",\r\n\t\"TTticket2.png\",\r\n\t\"TTumbrella.png\",\r\n\t\"TTvase.png\",\r\n\t\"TTvase2.png\",\r\n\t\"TTvase3.png\",\r\n\t\"TTvase4.png\",\r\n\t\"TTwallet.png\",\r\n\t\"TTwatch.png\",\r\n\t\"Vivaster.png\",\r\n\t\"empty.png\",\r\n\t\"lawyerbadge.png\"\r\n];","export default [\r\n\t\"1st server\",\r\n\t\"999.1\",\r\n\t\"999\",\r\n\t\"999Apartment\",\r\n\t\"999CaptainsQuarters\",\r\n\t\"999Cargo\",\r\n\t\"999Casino\",\r\n\t\"999Cdeck\",\r\n\t\"999CentralStairs\",\r\n\t\"999Chapel\",\r\n\t\"999Chart\",\r\n\t\"999Confinement\",\r\n\t\"999DoorsA\",\r\n\t\"999DoorsB\",\r\n\t\"999Hospital\",\r\n\t\"999Kitchen\",\r\n\t\"999Library\",\r\n\t\"999Operating\",\r\n\t\"999Shower\",\r\n\t\"999Steam\",\r\n\t\"999Steeldoor\",\r\n\t\"999Study\",\r\n\t\"999Torture\",\r\n\t\"9991stClassCabinA\",\r\n\t\"9991stClassCabinB\",\r\n\t\"9992ndClassCabin\",\r\n\t\"AA - Edgewort's Office\",\r\n\t\"AA - Gantsroom\",\r\n\t\"AA - Gatewater room\",\r\n\t\"AA - Gourd Lake\",\r\n\t\"AA - Gourd Lake Entrance\",\r\n\t\"AA - Hotel Lobby\",\r\n\t\"AA - Hotticlinic\",\r\n\t\"AA - Kurain\",\r\n\t\"AA - Parkinglot\",\r\n\t\"AA - Police Deparment\",\r\n\t\"AA - Police Station\",\r\n\t\"AA - Records Room\",\r\n\t\"AA - Sc13\",\r\n\t\"AA - Wright's Office\",\r\n\t\"AABluecorp\",\r\n\t\"AACourt\",\r\n\t\"AACourtAnime\",\r\n\t\"AACourtChristmasDecorations\",\r\n\t\"AACourtChristmasLights\",\r\n\t\"AACourtHD\",\r\n\t\"AADefendantLobby\",\r\n\t\"AADefendantLobbyHD\",\r\n\t\"AADetentionCenter\",\r\n\t\"AAEdgeworthOffice\",\r\n\t\"AAGantOffice\",\r\n\t\"AAGatewaterHotel\",\r\n\t\"AAGlobalStudiosEast\",\r\n\t\"AAGlobalStudiosWest\",\r\n\t\"AAGourdLake\",\r\n\t\"AAGrossbergOffice\",\r\n\t\"AAI2Circus\",\r\n\t\"AAI2City\",\r\n\t\"AAI2GourdLake\",\r\n\t\"AAI2LogicChess\",\r\n\t\"AAI2MuseumPast\",\r\n\t\"AAI2MuseumPresent\",\r\n\t\"AAI2PIC\",\r\n\t\"AAI2Prison\",\r\n\t\"AAICohdopianEmbassy\",\r\n\t\"AAICourt\",\r\n\t\"AAICourtFlipped\",\r\n\t\"AAIEdgeworthOffice\",\r\n\t\"AAIGatewaterLandStage\",\r\n\t\"AAIGatewaterLandWildWest\",\r\n\t\"AAIiFlyAirlines\",\r\n\t\"AALobby\",\r\n\t\"AAParkingLot\",\r\n\t\"AAPoliceStation\",\r\n\t\"AATrainStation\",\r\n\t\"AAWrightOffice\",\r\n\t\"AJBorschtBowlClub\",\r\n\t\"AJCourt\",\r\n\t\"AJCourtBirthday\",\r\n\t\"AJCourtHalloween\",\r\n\t\"AJCourtNight\",\r\n\t\"AJCourtTV\",\r\n\t\"AJDefendantLobby\",\r\n\t\"AJDetentionCenter\",\r\n\t\"AJDrewStudio\",\r\n\t\"AJHottiClinic\",\r\n\t\"AJKlavierOffice\",\r\n\t\"AJKristophCell\",\r\n\t\"AJLobby\",\r\n\t\"AJMeraktisClinic\",\r\n\t\"AJPeoplePark\",\r\n\t\"AJSunshineColiseum\",\r\n\t\"AJWrightOffice\",\r\n\t\"Ace\",\r\n\t\"AcroRoomJFA\",\r\n\t\"AirportJFA\",\r\n\t\"AlbaOfficeAAI\",\r\n\t\"Anime\",\r\n\t\"Arcade\",\r\n\t\"AtmeyOfficeTT\",\r\n\t\"Atrium (SG)\",\r\n\t\"AutumnForest\",\r\n\t\"BB - Flowerfield\",\r\n\t\"BB - Market\",\r\n\t\"BB - Street\",\r\n\t\"BandoLandAAI\",\r\n\t\"Basement\",\r\n\t\"Battlegrounds\",\r\n\t\"BerryBigCircusJFA\",\r\n\t\"Blackout\",\r\n\t\"BlueScreensTT\",\r\n\t\"BluecorpAA\",\r\n\t\"BridgeNest\",\r\n\t\"Brig\",\r\n\t\"Building\",\r\n\t\"CC1\",\r\n\t\"CC2\",\r\n\t\"CC3\",\r\n\t\"CC4\",\r\n\t\"CC5\",\r\n\t\"CC6\",\r\n\t\"CC7\",\r\n\t\"CC8\",\r\n\t\"CC9\",\r\n\t\"CC10\",\r\n\t\"CC11\",\r\n\t\"CC12\",\r\n\t\"CO - Big door\",\r\n\t\"CO - Finalroom\",\r\n\t\"CO - Meetingroom\",\r\n\t\"CO - Whitedoor\",\r\n\t\"CO - Whitelobby\",\r\n\t\"CO - Whitelowerfloor\",\r\n\t\"CO - White room\",\r\n\t\"CP\",\r\n\t\"CPRP2 Chap1\",\r\n\t\"CPRP2 Chap2and3\",\r\n\t\"CPRP2 Chap4\",\r\n\t\"CPRP2 Chap5\",\r\n\t\"CPRP Chap1\",\r\n\t\"CPRP Chap2\",\r\n\t\"CPRP Chap3\",\r\n\t\"CPRP Chap4\",\r\n\t\"CPRP Chap5\",\r\n\t\"CVStMystere\",\r\n\t\"Cafe\",\r\n\t\"CafeCourt\",\r\n\t\"CaffeeCase\",\r\n\t\"Cal\",\r\n\t\"CargoHoldAAI\",\r\n\t\"Casino\",\r\n\t\"CasinoCourt\",\r\n\t\"Cathedral (SG)\",\r\n\t\"Christmas\",\r\n\t\"Christmas Courtroom\",\r\n\t\"CinemaFamousi\",\r\n\t\"Classroom\",\r\n\t\"Co - Lobby 1\",\r\n\t\"Co - Lobby 2\",\r\n\t\"CochenOfficeAAI\",\r\n\t\"ColosseumFerox\",\r\n\t\"Control Room\",\r\n\t\"Control Room Interior\",\r\n\t\"CountyCourt\",\r\n\t\"CourtroomAA\",\r\n\t\"CourtroomAAHD\",\r\n\t\"CourtroomAAI\",\r\n\t\"CourtroomAJ\",\r\n\t\"CourtroomAJNight\",\r\n\t\"CourtroomAnime\",\r\n\t\"CourtroomCounty\",\r\n\t\"CourtroomDD\",\r\n\t\"CourtroomEnglish\",\r\n\t\"CourtroomNew\",\r\n\t\"CourtroomRuined\",\r\n\t\"CourtroomThemis\",\r\n\t\"CourtroomTouhou\",\r\n\t\"CourtroomWitch\",\r\n\t\"CruiseCourt\",\r\n\t\"CustomEight\",\r\n\t\"CustomEleven\",\r\n\t\"CustomFifteen\",\r\n\t\"CustomFive\",\r\n\t\"CustomFour\",\r\n\t\"CustomFourteen\",\r\n\t\"CustomNine\",\r\n\t\"CustomOne\",\r\n\t\"CustomSeven\",\r\n\t\"CustomSix\",\r\n\t\"CustomTen\",\r\n\t\"CustomThirteen\",\r\n\t\"CustomThree\",\r\n\t\"CustomTwelve\",\r\n\t\"CustomTwo\",\r\n\t\"DC\",\r\n\t\"DDCourt\",\r\n\t\"DDCourtGray\",\r\n\t\"DDCourtRuined\",\r\n\t\"DDCourtRuinedInvestigation\",\r\n\t\"DDCourtThemis\",\r\n\t\"DDDefendantLobby\",\r\n\t\"DDGyaxa\",\r\n\t\"DDLobby\",\r\n\t\"DDNinetailsVale\",\r\n\t\"DDShipshapeAquarium\",\r\n\t\"DDThemisAcademy\",\r\n\t\"DFreightTrain\",\r\n\t\"DGS-ENG\",\r\n\t\"DGS-JAP\",\r\n\t\"DGS\",\r\n\t\"DGSCourtJapanese\",\r\n\t\"DGSCourtOldBailey\",\r\n\t\"DGSCourtOldBaileyJury\",\r\n\t\"DGSDefendantLobbyJapanese\",\r\n\t\"DGSDefendantLobbyOldBailey\",\r\n\t\"DGSEnglishCourt\",\r\n\t\"DGSJapanCourt\",\r\n\t\"DGSLondon\",\r\n\t\"DGSenglishcourt\",\r\n\t\"DRAE-Area1\",\r\n\t\"DRAE-Area2\",\r\n\t\"DRClassTrial\",\r\n\t\"DRRP\",\r\n\t\"Dark Cave\",\r\n\t\"Darkness\",\r\n\t\"Datrone Heart\",\r\n\t\"Datrone HeartHQ\",\r\n\t\"DeLiteHouseTT\",\r\n\t\"Despair vs. Hope\",\r\n\t\"DetentionCenterAAI2\",\r\n\t\"DimensionalGate\",\r\n\t\"DogenCellAAI2\",\r\n\t\"DualDestinies\",\r\n\t\"Dungeon Courtroom\",\r\n\t\"EdgeworthOfficeAA\",\r\n\t\"EdgeworthOfficeAAI\",\r\n\t\"EmbassyAAI\",\r\n\t\"Endless Courtroom\",\r\n\t\"EngardeManorJFA\",\r\n\t\"EnglishCourt\",\r\n\t\"Errors\",\r\n\t\"Errors2\",\r\n\t\"FECastle\",\r\n\t\"FECave\",\r\n\t\"FEFort\",\r\n\t\"FEPlain\",\r\n\t\"FETavern\",\r\n\t\"Factory\",\r\n\t\"FieldFortune\",\r\n\t\"FilmSetAAI2\",\r\n\t\"Flowerfield\",\r\n\t\"ForensicCourt\",\r\n\t\"Forest\",\r\n\t\"GS4Night\",\r\n\t\"GantOfficeAA\",\r\n\t\"GetwaterHotelJFA\",\r\n\t\"GetwaterStageJFA\",\r\n\t\"GlobalStudiosIndoorsAA\",\r\n\t\"GlobalStudiosOutdoorsAA\",\r\n\t\"GourdLakeAA\",\r\n\t\"GrandChokmah\",\r\n\t\"GrandStadium\",\r\n\t\"Graveyard\",\r\n\t\"GreatWitchtrialCourt\",\r\n\t\"GrossbergOfficeAA\",\r\n\t\"HD\",\r\n\t\"HQFarm\",\r\n\t\"HQHalloweenTown\",\r\n\t\"HQHolodeck\",\r\n\t\"HQShrine\",\r\n\t\"HQTown\",\r\n\t\"HQVolcanoCherry\",\r\n\t\"HallOfFame\",\r\n\t\"HarborTown\",\r\n\t\"HarvestFestival\",\r\n\t\"HazakuraTemple1TT\",\r\n\t\"HazakuraTemple2TT\",\r\n\t\"Headquarters\",\r\n\t\"Headquarters 2\",\r\n\t\"Hell Correspondence\",\r\n\t\"Hospital\",\r\n\t\"HotelRoomAA\",\r\n\t\"HottiClinicJFA\",\r\n\t\"Innsmouth\",\r\n\t\"InsidePlaneAAI2\",\r\n\t\"Interiors (Day)\",\r\n\t\"Interiors (Night)\",\r\n\t\"JFAAirport\",\r\n\t\"JFABerryBigCircusEast\",\r\n\t\"JFABerryBigCircusWest\",\r\n\t\"JFAGatewaterHotel\",\r\n\t\"JFAHottiClinic\",\r\n\t\"JFAKurainVillage\",\r\n\t\"JFAMattHouse\",\r\n\t\"JapaneseCourt\",\r\n\t\"Kamurocho (Day)\",\r\n\t\"Kamurocho (Night)\",\r\n\t\"Keterburg\",\r\n\t\"Khura'in\",\r\n\t\"Khurain\",\r\n\t\"KokonoeLab\",\r\n\t\"KurainCourt\",\r\n\t\"KurainVillageJFA\",\r\n\t\"LBCastle\",\r\n\t\"LBMisc\",\r\n\t\"LBScotlandYard\",\r\n\t\"Lab 8\",\r\n\t\"Lentomain\",\r\n\t\"Library\",\r\n\t\"LogicChessAAI2\",\r\n\t\"MI - Ashleys Shack\",\r\n\t\"MLP - Apple barn\",\r\n\t\"MLP - CMC Clubhouse\",\r\n\t\"MLP - CMC Clubhouse inside\",\r\n\t\"MLP - Canterlot Castle galaroom\",\r\n\t\"MLP - Canterlot Hallway\",\r\n\t\"MLP - Canterlot Library2\",\r\n\t\"MLP - Canterlot Town\",\r\n\t\"MLP - Canterlot alley\",\r\n\t\"MLP - Canterlot library\",\r\n\t\"MLP - Carousel Boutique\",\r\n\t\"MLP - Clearing\",\r\n\t\"MLP - Curio Shop\",\r\n\t\"MLP - Everfree Forest\",\r\n\t\"MLP - Everfree Forest entrance\",\r\n\t\"MLP - Fluttershy's cottage\",\r\n\t\"MLP - Hospital Room\",\r\n\t\"MLP - Hotelroom\",\r\n\t\"MLP - Library 2F\",\r\n\t\"MLP - Library mainfloor\",\r\n\t\"MLP - Old Castle\",\r\n\t\"MLP - Orchard\",\r\n\t\"MLP - PV Hospital\",\r\n\t\"MLP - PV Street\",\r\n\t\"MLP - Ponyville\",\r\n\t\"MLP - Shining's apartment\",\r\n\t\"MLP - Sugarcube Corner\",\r\n\t\"MLP - Twilight's Lab\",\r\n\t\"MM - Castle\",\r\n\t\"MM - Madokas house\",\r\n\t\"MM - School yard\",\r\n\t\"MM - Street\",\r\n\t\"MM - Street2\",\r\n\t\"MM - classroom\",\r\n\t\"MM - dark hallway\",\r\n\t\"MM - rooftop\",\r\n\t\"MM - room whit Kyubey\",\r\n\t\"MM - school hallway\",\r\n\t\"MM - staircase\",\r\n\t\"MMA-Bedrooms1\",\r\n\t\"MMA-Floor 1\",\r\n\t\"MS - Cathedral\",\r\n\t\"MS - Zakum's Tree\",\r\n\t\"Mansion\",\r\n\t\"MansionAAI2\",\r\n\t\"MansionHQ\",\r\n\t\"Maplecrest - Nightmare\",\r\n\t\"Maplecrest\",\r\n\t\"Market\",\r\n\t\"Mayonaka\",\r\n\t\"MechHangar\",\r\n\t\"Medici Tower\",\r\n\t\"Military Base Exterior\",\r\n\t\"MoeRoomJFA\",\r\n\t\"MuseumAAI2\",\r\n\t\"MuseumTT\",\r\n\t\"Music\",\r\n\t\"NewCourt\",\r\n\t\"New Meridian\",\r\n\t\"Ninetailsvale\",\r\n\t\"Nordon Plains\",\r\n\t\"Nordon Plains Night\",\r\n\t\"OCArcade\",\r\n\t\"OCBebop\",\r\n\t\"OCCourtCafe\",\r\n\t\"OCCourtCounty\",\r\n\t\"OCCourtCruise\",\r\n\t\"OCCourtEndless\",\r\n\t\"OCCourtFinalDestination\",\r\n\t\"OCCourtInverted\",\r\n\t\"OCCourtPirateShip\",\r\n\t\"OCCourtSky\",\r\n\t\"OCCourtSpace\",\r\n\t\"OCCourtSpaceShip\",\r\n\t\"OCCourtTouhou\",\r\n\t\"OCCourtZetta\",\r\n\t\"OCDungeon\",\r\n\t\"OCHospital\",\r\n\t\"OCRoad\",\r\n\t\"OCTownPirate\",\r\n\t\"OCTownShanty\",\r\n\t\"OCWhiteRoom\",\r\n\t\"OfficeHouseHQ\",\r\n\t\"OfficeNightAA\",\r\n\t\"Osaka (Night)\",\r\n\t\"Osaka\",\r\n\t\"OutsidePlaneAAI2\",\r\n\t\"P4UBasement\",\r\n\t\"P4ULab\",\r\n\t\"P4Ubaseball\",\r\n\t\"P4Ubeach\",\r\n\t\"P4Ubuilding\",\r\n\t\"P4Uconcert\",\r\n\t\"P4Ugarden\",\r\n\t\"P4Ugraveyard\",\r\n\t\"P4Uhell\",\r\n\t\"P4Ujail\",\r\n\t\"P4Umisc\",\r\n\t\"P4Unight\",\r\n\t\"P4Uoffices\",\r\n\t\"P4Urailway\",\r\n\t\"P4Urestaurants\",\r\n\t\"P4Urooms\",\r\n\t\"P4Uruins\",\r\n\t\"P4Uschool\",\r\n\t\"P4Ustage1\",\r\n\t\"P4Ustage2\",\r\n\t\"P4Ustation\",\r\n\t\"P4Ustore\",\r\n\t\"P4Utent\",\r\n\t\"P4Utransport\",\r\n\t\"P4Utv\",\r\n\t\"P4Uvelvetroom\",\r\n\t\"PICAAI2\",\r\n\t\"PLvsAAAlchemistHouse\",\r\n\t\"PLvsAABellTower\",\r\n\t\"PLvsAACastle\",\r\n\t\"PLvsAACourtEnglish\",\r\n\t\"PLvsAACourtLabyrinthia\",\r\n\t\"PLvsAACourthouse\",\r\n\t\"PLvsAADefendantLobbyEnglish\",\r\n\t\"PLvsAADefendantLobbyLabyrinthia\",\r\n\t\"PLvsAAEclaireBakery\",\r\n\t\"PLvsAAForest\",\r\n\t\"PLvsAAGreatArchive\",\r\n\t\"PLvsAALabyrinthiaInner\",\r\n\t\"PLvsAALabyrinthiaOuter\",\r\n\t\"PLvsAALondon\",\r\n\t\"PLvsAARougeTavern\",\r\n\t\"PLvsAARuins\",\r\n\t\"PLvsAAStorytellerTower\",\r\n\t\"PLvsAAWagon\",\r\n\t\"PLvsAAWorkshop\",\r\n\t\"PMMMRP\",\r\n\t\"PMMMWitch\",\r\n\t\"ParkingLotAA\",\r\n\t\"PeonyCastle\",\r\n\t\"Persona Afternoon\",\r\n\t\"Persona DH\",\r\n\t\"Persona Morning\",\r\n\t\"Persona Night\",\r\n\t\"PersonaRP\",\r\n\t\"PhoenixOfficeAA\",\r\n\t\"PirateShip\",\r\n\t\"PlaneAAI\",\r\n\t\"PlaneLoungeAAI\",\r\n\t\"PlaneLoungeLandAAI\",\r\n\t\"PlatPark\",\r\n\t\"PlatRemnant\",\r\n\t\"PlatunaArea1\",\r\n\t\"PlatunaArea1HQ\",\r\n\t\"PlatunaArea2\",\r\n\t\"PlatunaArea2HQ\",\r\n\t\"PlatunaMain\",\r\n\t\"PlatunamainHQ\",\r\n\t\"PrecinctAA\",\r\n\t\"PrisonAAI2\",\r\n\t\"PrisonCourtyardAAI2\",\r\n\t\"RG - 104\",\r\n\t\"RG - A-East\",\r\n\t\"RG - AMX\",\r\n\t\"RG - Bus Terminal\",\r\n\t\"RG - Cadoi City\",\r\n\t\"RG - Concert\",\r\n\t\"RG - Dogenzaka\",\r\n\t\"RG - God Pad\",\r\n\t\"RG - Miyashita Underpass\",\r\n\t\"RG - Station Underpass\",\r\n\t\"RG - Trail\",\r\n\t\"RG - Udagawa\",\r\n\t\"RaysDeLite\",\r\n\t\"Retreat\",\r\n\t\"RetreatHQ\",\r\n\t\"RiverVista\",\r\n\t\"Road\",\r\n\t\"Role Play\",\r\n\t\"Ronpa Mansion Area 5\",\r\n\t\"Ronpa Mansion Day\",\r\n\t\"Ronpa Mansion Day2\",\r\n\t\"Ronpa Mansion Day3\",\r\n\t\"Ronpa Mansion Day4\",\r\n\t\"Ronpa Mansion Night\",\r\n\t\"Ronpa Mansion Night2\",\r\n\t\"Ronpa Mansion Night3\",\r\n\t\"Ronpa Mansion Night4\",\r\n\t\"Ronpa mansion Haunted\",\r\n\t\"Ronpers Express\",\r\n\t\"RooftopAAI2\",\r\n\t\"RuinedCastle\",\r\n\t\"RuinedCourt\",\r\n\t\"Ruins Entrance\",\r\n\t\"SDR2 ISLAND\",\r\n\t\"SDR2 ISLAND2\",\r\n\t\"SDR2 ISLAND2 NIGHT\",\r\n\t\"SDR2 ISLAND3\",\r\n\t\"SDR2 ISLAND NIGHT\",\r\n\t\"SI - Bedroom\",\r\n\t\"SI - Class(sunset)\",\r\n\t\"SI - Class\",\r\n\t\"SI - Council1\",\r\n\t\"SI - Council2\",\r\n\t\"SI - Council3\",\r\n\t\"SI - Gym\",\r\n\t\"SI - Gym2\",\r\n\t\"SI - Hall\",\r\n\t\"SI - Hall2\",\r\n\t\"SI - Lockers\",\r\n\t\"SI - Nurse\",\r\n\t\"SI - Office\",\r\n\t\"SI - Pink\",\r\n\t\"SI - Roof\",\r\n\t\"SI - Roof2\",\r\n\t\"SI - School\",\r\n\t\"Seance\",\r\n\t\"SecretRoomsJFA\",\r\n\t\"SecurityCompanyTT\",\r\n\t\"ShipAAI2\",\r\n\t\"SkialForest\",\r\n\t\"Sky\",\r\n\t\"SkyDeck\",\r\n\t\"SoJCourt\",\r\n\t\"SoJDefendantLobby\",\r\n\t\"Somina Castle\",\r\n\t\"Somina Castle Night\",\r\n\t\"SpaceCourt\",\r\n\t\"SpaceCourtBlue\",\r\n\t\"SpaceCourtGreen\",\r\n\t\"SpaceCourtNormal\",\r\n\t\"SpaceCourtOrange\",\r\n\t\"SpaceCourtRainbow\",\r\n\t\"SpaceCourtRed\",\r\n\t\"SpaceCourtYellow\",\r\n\t\"SpacePort\",\r\n\t\"Spaceship\",\r\n\t\"StageAAI\",\r\n\t\"StageDisassembledAAI\",\r\n\t\"SteamBar\",\r\n\t\"SteamGarden\",\r\n\t\"SteamGovt\",\r\n\t\"SteamSquare\",\r\n\t\"SteamStreet\",\r\n\t\"Street\",\r\n\t\"SummerFestival\",\r\n\t\"SummerFestivalEvening\",\r\n\t\"TARDIS\",\r\n\t\"TEOS Lab\",\r\n\t\"TTAtmeyOffice\",\r\n\t\"TTBlueScreensInc\",\r\n\t\"TTDemasqueHideout\",\r\n\t\"TTHazakuraTemple\",\r\n\t\"TTHazakuraTempleInner\",\r\n\t\"TTKBSecurity\",\r\n\t\"TTLordlyTailor\",\r\n\t\"TTTenderLender\",\r\n\t\"TTTresBien\",\r\n\t\"TenderLenderTT\",\r\n\t\"Themis\",\r\n\t\"Titania\",\r\n\t\"TitaniaValley\",\r\n\t\"Togami Mansion\",\r\n\t\"TouhouCourt\",\r\n\t\"Tower\",\r\n\t\"Town\",\r\n\t\"Town Night\",\r\n\t\"Tr0LLc0urt\",\r\n\t\"TrainstationAA\",\r\n\t\"TresBienTT\",\r\n\t\"TrollCourt\",\r\n\t\"Twotorial Village\",\r\n\t\"Twotorial Village Night\",\r\n\t\"VC 1\",\r\n\t\"VLR\",\r\n\t\"VLR2.2\",\r\n\t\"VLR2.3\",\r\n\t\"VLR2\",\r\n\t\"VLR3\",\r\n\t\"VitaminSquareTT\",\r\n\t\"WEN\",\r\n\t\"WaitingRoomAAI\",\r\n\t\"WestAAI\",\r\n\t\"WinterPalaceAAI2\",\r\n\t\"WitchTrialCourt\",\r\n\t\"WitchtrialCourtHQ\",\r\n\t\"Witchwood\",\r\n\t\"WorldEmulator\",\r\n\t\"Wreckage (SG)\",\r\n\t\"Wrightagency\",\r\n\t\"Xmas\",\r\n\t\"Zetta\",\r\n\t\"animation\",\r\n\t\"apollojustice\",\r\n\t\"background\",\r\n\t\"basement\",\r\n\t\"birthday\",\r\n\t\"blackout\",\r\n\t\"chess\",\r\n\t\"chessw1\",\r\n\t\"chessw2\",\r\n\t\"chessw3\",\r\n\t\"chessw4\",\r\n\t\"christmas\",\r\n\t\"circus\",\r\n\t\"classtrial\",\r\n\t\"cofe\",\r\n\t\"courthouseofgods\",\r\n\t\"cruise\",\r\n\t\"cruise court\",\r\n\t\"custom\",\r\n\t\"custom1\",\r\n\t\"custom2\",\r\n\t\"custom3\",\r\n\t\"custom4\",\r\n\t\"custom5\",\r\n\t\"custom6\",\r\n\t\"custom7\",\r\n\t\"custom8\",\r\n\t\"custom9\",\r\n\t\"custom10\",\r\n\t\"daimoncourt\",\r\n\t\"default - Kopie\",\r\n\t\"default\",\r\n\t\"default_christmas\",\r\n\t\"defendantlobby\",\r\n\t\"defendantlobbyapollo\",\r\n\t\"detentioncenter\",\r\n\t\"doppler\",\r\n\t\"dr1stfloor\",\r\n\t\"dr1stfloordorms\",\r\n\t\"dr1stfloorhalls\",\r\n\t\"dr2ndfloor\",\r\n\t\"dr3rdfloor\",\r\n\t\"druq1stfloordorms\",\r\n\t\"druq2ndfloordorms\",\r\n\t\"dualdestinies\",\r\n\t\"dualdestiniesOG\",\r\n\t\"dungeon\",\r\n\t\"endless\",\r\n\t\"englishcourt\",\r\n\t\"forest\",\r\n\t\"gs4\",\r\n\t\"gs4night\",\r\n\t\"gs5\",\r\n\t\"hd\",\r\n\t\"inn\",\r\n\t\"investigationbando\",\r\n\t\"investigationsembassylobby\",\r\n\t\"investigationsgourdlake\",\r\n\t\"investigationsmilesoffice\",\r\n\t\"investigationsplaneair\",\r\n\t\"investigationsroyalcourt\",\r\n\t\"investigationstvroom\",\r\n\t\"investigationswestern\",\r\n\t\"investigationswitchtown\",\r\n\t\"island 1(uranus zone)\",\r\n\t\"lcourt\",\r\n\t\"legacy\",\r\n\t\"lobbyDGS-ENG\",\r\n\t\"lobbyDGS-JAP\",\r\n\t\"lobbyPLvsAA-ENG\",\r\n\t\"lobbyPLvsAA-LAB\",\r\n\t\"lobbySOJ\",\r\n\t\"magatama\",\r\n\t\"magatama1\",\r\n\t\"magatama2\",\r\n\t\"magatama3\",\r\n\t\"magatama4\",\r\n\t\"magatama5\",\r\n\t\"marblefade\",\r\n\t\"matrix\",\r\n\t\"matrixall\",\r\n\t\"matrixangry\",\r\n\t\"matrixangrysad\",\r\n\t\"matrixangrysurprised\",\r\n\t\"matrixhappy\",\r\n\t\"matrixhappyangry\",\r\n\t\"matrixhappysad\",\r\n\t\"matrixhappysurprised\",\r\n\t\"matrixsad\",\r\n\t\"matrixsadsurprised\",\r\n\t\"matrixsurprise\",\r\n\t\"mlp\",\r\n\t\"newcourt\",\r\n\t\"night (no lights)\",\r\n\t\"plvsaa\",\r\n\t\"policestation\",\r\n\t\"prisonvestigation\",\r\n\t\"sdr2classtrial\",\r\n\t\"sky\",\r\n\t\"sshope2ndfloorday(incident)\",\r\n\t\"sshope2ndfloorday\",\r\n\t\"sshope2ndfloornight(incident)\",\r\n\t\"sshope2ndfloornight\",\r\n\t\"sshopeday(incident)\",\r\n\t\"sshopeday\",\r\n\t\"sshopenight(incident)\",\r\n\t\"sshopenight\",\r\n\t\"thief\",\r\n\t\"thiefbash\",\r\n\t\"thiefpoint\",\r\n\t\"thiefpoisoning\",\r\n\t\"thiefprints\",\r\n\t\"thiefstab\",\r\n\t\"thiefsteal\",\r\n\t\"turnaboutstorm - Kopie\",\r\n\t\"turnaboutstorm\",\r\n\t\"vocalcourt\",\r\n\t\"witchtrialcourt\"\r\n];","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0 and Qubrick\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\n// Uses the Gify library:\r\n// https://github.com/rfrench/gify\r\n// The following comment is needed for ESLint:\r\n/* global gify */\r\n\r\nimport background_arr from \"./backgrounds.js\";\r\nimport evidence_arr from \"./evidence.js\";\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function (item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1];\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://s3.wasabisys.com/webao/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.hp = [0, 0];\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\t\tthis.evidences = [];\r\n\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\": {\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\": {\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\": {\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\": {\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\": {\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t};\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn this.presentable ? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#${escapeChat(encodeChat(document.getElementById(\"OOC_name\").value))}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {number} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t * @param {string} evidence the filename of evidence to show\r\n\t * @param {number} flip change to 1 to reverse sprite for position changes\r\n\t * @param {string} flash screen flash effect\r\n\t * @param {string} color text color\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {number} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {number} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {number} side the position\r\n\t * @param {number} hp the health point\r\n\t */\r\n\tsendHP(side, hp) {\r\n\t\tthis.serv.send(`HP#${side}#${hp}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif (this.chars[this.charID].side == \"jud\") {\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.3#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Set to playerID to server chat name\r\n\t\t// TODO: Make a text box for this!\r\n\t\tdocument.getElementById(\"OOC_name\").value = \"web\" + this.playerID;\r\n\r\n\t\t// Load evidence array to select\r\n\t\tconst evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tevidence_arr.forEach(evidence => {\r\n\t\t\tevidence_select.add(new Option(evidence));\r\n\t\t});\r\n\r\n\t\t// Load background array to select\r\n\t\tconst background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tbackground_arr.forEach(background => {\r\n\t\t\tbackground_select.add(new Option(background));\r\n\t\t});\r\n\t\t// Calculate gif duration of shouts\r\n\t\tconst shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"].toLowerCase();\r\n\t\t\tfileExists(shout_src, this.callbackLoadImageResources, shouts[i]);\r\n\t\t}\r\n\r\n\t\t// Calculate gif duration of testimony\r\n\t\tconst testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tconst testimony_src = `${AO_HOST}themes/default/${testimony[i]}.gif`;\r\n\t\t\t// Check image existed\r\n\t\t\tfileExists(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tfileExists(AO_HOST + this.resources[testimony[i]][\"sfx\"].toLowerCase(), this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\r\n\t\t// TODO: Cache some resources\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif (result) {\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src, client.callbackGetResourceLength, resource);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length;\r\n\t}\r\n\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif (result) {\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tconst target = document.getElementById(\"client_inner_chat\");\r\n\t\tconst observer = new MutationObserver(function (mutations) {\r\n\t\t\tmutations.forEach(function (mutation) {\r\n\t\t\t\tconst children = mutation.addedNodes;\r\n\t\t\t\tif (children !== null) {\r\n\t\t\t\t\tchildren.forEach(function (node) {\r\n\t\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else if (node.tagName == \"M\") {\r\n\t\t\t\t\t\t\tif (node.hasAttribute(\"a\")) {\r\n\t\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t});\r\n\t\tconst config = {\r\n\t\t\tattributes: true,\r\n\t\t\tchildList: true\r\n\t\t};\r\n\t\tobserver.observe(target, config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split(\"%\");\r\n\t\tlet args = lines[0].split(\"#\");\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * XXX: a nasty hack made by gameboyprinter.\r\n\t * @param {string} msg chat message to prepare for display \r\n\t */\r\n\tprepChat(msg){\r\n\t\t// TODO: make this less awful\r\n\t\treturn decodeBBCode(unescapeChat(decodeChat(msg)));\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tconst chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: this.prepChat(args[5]), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 600) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1].toLowerCase();\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener(\"loadedmetadata\", function () {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0].toLowerCase()) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0].toLowerCase()) + \"/char_icon.png\"\r\n\t\t\t};\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tconst arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": decodeChat(unescapeChat(arg[0])),\r\n\t\t\t\t\"desc\": decodeChat(unescapeChat(arg[1])),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2].toLowerCase())\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tconst evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor (let i = 1; i <= this.evidences.length; i++) {\r\n\t\t\tevidence_box.innerHTML += ``;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tconst hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tlet flagAudio = false;\r\n\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif (/\\.(?:wav|mp3|mp4|ogg|opus)$/i.test(args[i]) && !flagAudio) {\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\r\n\t\t\tif (flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tconst newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tconst newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i];\r\n\t\t\t\tnewarea.onclick = function () {\r\n\t\t\t\t\tarea_click(this);\r\n\t\t\t\t};\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// We need to check if the last area that we got was actually a category\r\n\t\t// header for music. If it was, then move it over to the music list.\r\n\t\tconst area_box = document.getElementById(\"areas\");\r\n\t\tif (area_box.lastChild.textContent.startsWith(\"=\")) {\r\n\t\t\tconst audio_title = document.createElement(\"OPTION\");\r\n\t\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\t\tarea_box.removeChild(area_box.lastChild);\r\n\t\t}\r\n\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tconst bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif (bg_index == 0) {\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + \"background/\" + escape(args[1].toLowerCase()) + \"/defenseempty.png\";\r\n\t\tif (this.charID == -1) {\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tconst percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({\r\n\t\t\t\t\"width\": percent_hp + \"%\"\r\n\t\t\t}, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({\r\n\t\t\t\t\"width\": percent_hp + \"%\"\r\n\t\t\t}, 500);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tlet tr;\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\ttr = document.createElement(\"TR\");\r\n\t\t\t}\r\n\t\t\tconst td = document.createElement(\"TD\");\r\n\t\t\tlet icon_chosen = \"\";\r\n\t\t\tconst thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}\";\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"\";\r\n\t\tconst me = this.me();\r\n\t\tconst emotes = this.emotes;\r\n\t\tconst emotesList = document.getElementById(\"client_emo\");\r\n\t\temotesList.innerHTML = \"\"; // Clear emote box\r\n\t\temotesList.style.display = \"\";\r\n\t\tconst xhr = new XMLHttpRequest();\r\n\t\txhr.withCredentials = false;\r\n\t\txhr.open(\"GET\", AO_HOST + \"characters/\" + escape(this.me().name.toLowerCase()) + \"/char.ini\", true);\r\n\t\txhr.responseType = \"text\";\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tconst linifile = this.responseText;\r\n\t\t\t\tconst pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i <= pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tconst emoteinfo = pinifile.Emotions[i].split(\"#\");\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== \"undefined\") {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== \"undefined\") {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// Make sure the asset server is case insensitive, or that everything on it is lowercase\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0].toLowerCase(),\r\n\t\t\t\t\t\tspeaking: emoteinfo[1].toLowerCase(),\r\n\t\t\t\t\t\tsilent: emoteinfo[2].toLowerCase(),\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx.toLowerCase(),\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + `characters/${escape(me.name).toLowerCase()}/emotions/button${i}_off.png`,\r\n\t\t\t\t\t\tbutton_on: AO_HOST + `characters/${escape(me.name).toLowerCase()}/emotions/button${i}_on.png`\r\n\t\t\t\t\t};\r\n\t\t\t\t\temotesList.innerHTML += \r\n\t\t\t\t\t\t`\"${emotes[i].desc}\"\r\n\t\t\t\t\t\t`;\r\n\t\t\t\t}\r\n\t\t\t\tpickEmotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + \"sounds/general/sfx-blipmale.wav\");\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + \"sounds/general/sfx-blipmale.wav\");\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + \"sounds/general/sfx-blipmale.wav\");\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname.toLowerCase()}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t// If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(`${AO_HOST}characters/${escape(chatmsg.name.toLowerCase())}/${chatmsg.preanim.toLowerCase()}.gif`, this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {number} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay) {\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay);\r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater() {\r\n\t\tif (client.testimonyID > 0) {\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tconst testimonyOverlay = document.getElementById(\"client_testimony\");\r\n\t\t\ttestimonyOverlay.src = client.resources[testimony][\"src\"];\r\n\t\t\ttestimonyOverlay.style.display = \"\";\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tconst request = new XMLHttpRequest();\r\n\t\trequest.open(\"GET\", filename, true);\r\n\t\trequest.responseType = \"arraybuffer\";\r\n\t\trequest.addEventListener(\"load\", function () {\r\n\t\t\tconst gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony() {\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]) {\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]) {\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\tdisposeTestimony() {\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").style.display = \"none\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\tconst nameBox = document.getElementById(\"client_name\");\r\n\t\tconst chatBox = document.getElementById(\"client_chat\");\r\n\t\tconst charSprite = document.getElementById(\"client_char\");\r\n\t\tconst eviBox = document.getElementById(\"client_evi\");\r\n\t\tconst background = document.getElementById(\"client_background\");\r\n\t\tconst shoutSprite = document.getElementById(\"client_shout\");\r\n\t\tconst chatBoxInner = document.getElementById(\"client_inner_chat\");\r\n\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1) {\r\n\t\t\tcharSprite.style.transform = \"scaleX(-1)\";\r\n\t\t} else {\r\n\t\t\tcharSprite.style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tbackground.style.backgroundColor = \"transparent\";\r\n\t\t\t// Hide message and evidence window\r\n\t\t\tnameBox.style.display = \"none\";\r\n\t\t\tchatBox.style.display = \"none\";\r\n\t\t\teviBox.style.opacity = \"0\";\r\n\t\t\teviBox.style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tshoutSprite.src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}characters/${this.chatmsg.name.toLowerCase()}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif (this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2) {\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$(\"#client_gamewindow\").effect(\"shake\", {\r\n\t\t\t\t\t\"direction\": \"up\"\r\n\t\t\t\t});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tbackground.style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$(\"#client_gamewindow\").effect(\"pulsate\");\r\n\t\t\t}\r\n\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif (this.chatmsg.preanimdelay > 0) {\r\n\t\t\t\tshoutSprite.src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.preanim.toLowerCase() + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif (this.chatmsg.evidence > 0) {\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\teviBox.style.backgroundImage = \"url('\" + client.evidences[this.chatmsg.evidence - 1].icon + \"')\";\r\n\r\n\t\t\t\t\tif (this.chatmsg.side == \"def\") {\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\teviBox.style.right = \"1.5em\";\r\n\t\t\t\t\t\teviBox.style.left = \"initial\";\r\n\t\t\t\t\t\t$(\"#client_evi\").animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\teviBox.style.right = \"initial\";\r\n\t\t\t\t\t\teviBox.style.left = \"1.5em\";\r\n\t\t\t\t\t\t$(\"#client_evi\").animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tnameBox.style.display = \"block\";\r\n\t\t\t\tnameBox.style.fontSize = (nameBox.offsetHeight * 0.7) + \"px\";\r\n\r\n\t\t\t\twhile (nameBox.hasChildNodes()) {\r\n\t\t\t\t\tnameBox.removeChild(nameBox.firstChild);\r\n\t\t\t\t}\r\n\t\t\t\tnameBox.appendChild(document.createTextNode(this.chatmsg.nameplate));\r\n\r\n\t\t\t\tchatBox.style.display = \"block\";\r\n\t\t\t\tchatBox.style.fontSize = (chatBox.offsetHeight * 0.25) + \"px\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t};\r\n\t\t\t\tchatBoxInner.style.color = colors[this.chatmsg.color] || \"#ffffff\";\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.chatmsg.preanimdelay == 0) {\r\n\t\t\t\t\tshoutSprite.src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.speaking.toLowerCase() + \".gif\";\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.silent.toLowerCase() + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\r\n\t\t\t\t\twhile (chatBoxInner.hasChildNodes()) {\r\n\t\t\t\t\t\tchatBoxInner.removeChild(chatBoxInner.firstChild);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tchatBoxInner.appendChild(document.createTextNode(this.textnow));\r\n\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.silent.toLowerCase() + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound.toLowerCase()) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w.\\-_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function (line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip) ? 1 : 0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tconst playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the area list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tconst area = el.textContent;\r\n\tclient.sendMusicChange(area);\r\n\r\n\tconst areaHr = document.createElement(\"div\");\r\n\tareaHr.className = \"hrtext\";\r\n\tareaHr.textContent = `switched to ${el.textContent}`;\r\n\tdocument.getElementById(\"client_log\").appendChild(areaHr);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if a file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction fileExists(url, callback, param) {\r\n\tconst xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function () {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tlet standname;\r\n\tconst bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\tcase \"def\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\";\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\tfileExists(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\tstandname = \"defense\";\r\n\t\tbreak;\r\n\tcase \"pro\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\";\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\tfileExists(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\tcase \"hld\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\";\r\n\t\tstandname = \"defense\";\r\n\t\tbreak;\r\n\tcase \"hlp\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\";\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\tcase \"wit\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\";\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\";\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\tcase \"jud\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\";\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result, position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\") {\r\n\t\tif (result) {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\";\r\n\t\t}\r\n\t} else {\r\n\t\tif (result) {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\";\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 800) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickChar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickChar = pickChar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickEmotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo;\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickEmotion = pickEmotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickEvidence(evidence) {\r\n\tif (client.selectedEvidence !== evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif (client.selectedEvidence > 0) {\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0) {\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelEvidence();\r\n\t}\r\n}\r\nwindow.pickEvidence = pickEvidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addEvidence() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tclient.sendPE(document.getElementById(\"evi_name\").value,\r\n\t\tdocument.getElementById(\"evi_desc\").value,\r\n\t\tevidence_select.selectedIndex == 0 ?\r\n\t\t\tdocument.getElementById(\"evi_filename\").value :\r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text\r\n\t);\r\n\tcancelEvidence();\r\n}\r\nwindow.addEvidence = addEvidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editEvidence() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE(id,\r\n\t\tdocument.getElementById(\"evi_name\").value,\r\n\t\tdocument.getElementById(\"evi_desc\").value,\r\n\t\tevidence_select.selectedIndex == 0 ?\r\n\t\t\tdocument.getElementById(\"evi_filename\").value :\r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text\r\n\t);\r\n\tcancelEvidence();\r\n}\r\nwindow.editEvidence = editEvidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function deleteEvidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelEvidence();\r\n}\r\nwindow.deleteEvidence = deleteEvidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelEvidence() {\r\n\t//Clear evidence data\r\n\tif (client.selectedEvidence > 0) {\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelEvidence = cancelEvidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t//Find if icon alraedy existed in select box\r\n\tconst select_element = document.getElementById(select_box);\r\n\tfor (let i = 1; i < select_element.length; ++i) {\r\n\t\tif (select_element.options[i].value == value) {\r\n\t\t\treturn i;\r\n\t\t}\r\n\t}\r\n\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\r\n\tif (evidence_select.selectedIndex === 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = `url(${AO_HOST}evidence/${evidence_filename.value.toLowerCase()})`;\r\n\t} else {\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = `url(${AO_HOST}evidence/${evidence_select.value.toLowerCase()})`;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif (side == \"jud\") {\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor (let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++) {\r\n\t\tif (side == role_select[i].value) {\r\n\t\t\trole_select.selectedIndex = i;\r\n\t\t\treturn;\r\n\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\",\r\n\t\tbackground_select = document.getElementById(\"bg_select\"),\r\n\t\tbg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value;\r\n\t} else {\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\", filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\"),\r\n\t\trole_command = document.getElementById(\"role_command\").value;\r\n\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\", role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callMod() {\r\n\t$(\"#callmod_dialog\").dialog(\"open\");\r\n}\r\nwindow.callMod = callMod;\r\n\r\n/**\r\n * Declare witness testimony.\r\n */\r\nexport function initWT() {\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initWT = initWT;\r\n\r\n/**\r\n * Declare cross examination.\r\n */\r\nexport function initCE() {\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initCE = initCE;\r\n\r\n/**\r\n * Increment defense health point.\r\n */\r\nexport function addHPD() {\r\n\tclient.sendHP(1, String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Decrement defense health point.\r\n */\r\nexport function redHPD() {\r\n\tclient.sendHP(1, String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Increment prosecution health point.\r\n */\r\nexport function addHPP() {\r\n\tclient.sendHP(2, String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Decrement prosecution health point.\r\n */\r\nexport function redHPP() {\r\n\tclient.sendHP(2, String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + \"background/\" + background_filename.value.toLowerCase() + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + \"background/\" + background_select.value.toLowerCase() + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleEffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleEffect = toggleEffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleFlip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleFlip = toggleFlip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglePresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglePresent = togglePresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function toggleMenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.toggleMenu = toggleMenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleShout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleShout = toggleShout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encode text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t// This approach works by escaping all special characters to Unicode escape sequences.\r\n\t\t// Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function (ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4);\r\n\t\t});\r\n\t} else if (selectedEncoding == \"utf16\") {\r\n\t\t// Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tconst buffer = new ArrayBuffer(estring.length * 2);\r\n\t\tconst result = new Uint16Array(buffer);\r\n\t\tfor (let i = 0, strLen = estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decodes text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t// Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n\t\treturn estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16));\r\n\t\t});\r\n\t} else if (selectedDecoding == \"utf16\") {\r\n\t\t// Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"
\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, \"\") // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, \"<$1m>\") // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, \"\") // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, \"\"); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof (String.prototype.trim) === \"undefined\") {\r\n\tString.prototype.trim = function () {\r\n\t\treturn String(this).replace(/^\\s+|\\s+$/g, \"\");\r\n\t};\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function () {\r\n\tlet hash = 0;\r\n\tif (this.length === 0) return hash;\r\n\tfor (let i = 0; i < this.length; i++) {\r\n\t\tconst chr = this.charCodeAt(i);\r\n\t\thash = ((hash << 5) - hash) + chr;\r\n\t\thash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function () {\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources();\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$(function () {\r\n\t$(\"#callmod_dialog\").dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection: \"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection: \"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\tSure: function () {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$(this).dialog(\"close\");\r\n\t\t\t},\r\n\t\t\tCancel: function () {\r\n\t\t\t\t$(this).dialog(\"close\");\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""} \ No newline at end of file -- cgit