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 --- .eslintrc.js | 5 +- package.json | 1 - webAO/backgrounds.js | 719 +++++++++++++++++++++++++ webAO/backgrounds.min.js | 1 - webAO/client.b.js | 2 +- webAO/client.b.js.map | 2 +- webAO/client.css | 39 +- webAO/client.html | 143 +++-- webAO/client.js | 249 +++++---- webAO/evidence.js | 1322 ++++++++++++++++++++++++++++++++++++++++++++++ webAO/evidences.min.js | 1 - webAO/ui.b.js | 2 +- webAO/ui.b.js.map | 2 +- webAO/ui.js | 133 +++-- 14 files changed, 2340 insertions(+), 281 deletions(-) create mode 100644 webAO/backgrounds.js delete mode 100644 webAO/backgrounds.min.js create mode 100644 webAO/evidence.js delete mode 100644 webAO/evidences.min.js diff --git a/.eslintrc.js b/.eslintrc.js index c3c75e8..3b5d12a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,8 +15,7 @@ module.exports = { "tab" ], "linebreak-style": [ - "error", - "unix" + "off" ], "quotes": [ "warn", @@ -31,6 +30,6 @@ module.exports = { ], "no-unused-vars": [ "warn" - ] + ], } }; \ No newline at end of file diff --git a/package.json b/package.json index 711e7cf..aed873d 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,6 @@ "description": "Web-based Attorney Online client", "main": "client.js", "scripts": { - "babel": "babel ui.js -o ui.b.js", "webpack": "webpack", "deploy": "cross-env NODE_ENV=production webpack -p", "test": "echo \"Error: no test specified\" && exit 1" diff --git a/webAO/backgrounds.js b/webAO/backgrounds.js new file mode 100644 index 0000000..4a3a703 --- /dev/null +++ b/webAO/backgrounds.js @@ -0,0 +1,719 @@ +export default [ + "1st server", + "999.1", + "999", + "999Apartment", + "999CaptainsQuarters", + "999Cargo", + "999Casino", + "999Cdeck", + "999CentralStairs", + "999Chapel", + "999Chart", + "999Confinement", + "999DoorsA", + "999DoorsB", + "999Hospital", + "999Kitchen", + "999Library", + "999Operating", + "999Shower", + "999Steam", + "999Steeldoor", + "999Study", + "999Torture", + "9991stClassCabinA", + "9991stClassCabinB", + "9992ndClassCabin", + "AA - Edgewort's Office", + "AA - Gantsroom", + "AA - Gatewater room", + "AA - Gourd Lake", + "AA - Gourd Lake Entrance", + "AA - Hotel Lobby", + "AA - Hotticlinic", + "AA - Kurain", + "AA - Parkinglot", + "AA - Police Deparment", + "AA - Police Station", + "AA - Records Room", + "AA - Sc13", + "AA - Wright's Office", + "AABluecorp", + "AACourt", + "AACourtAnime", + "AACourtChristmasDecorations", + "AACourtChristmasLights", + "AACourtHD", + "AADefendantLobby", + "AADefendantLobbyHD", + "AADetentionCenter", + "AAEdgeworthOffice", + "AAGantOffice", + "AAGatewaterHotel", + "AAGlobalStudiosEast", + "AAGlobalStudiosWest", + "AAGourdLake", + "AAGrossbergOffice", + "AAI2Circus", + "AAI2City", + "AAI2GourdLake", + "AAI2LogicChess", + "AAI2MuseumPast", + "AAI2MuseumPresent", + "AAI2PIC", + "AAI2Prison", + "AAICohdopianEmbassy", + "AAICourt", + "AAICourtFlipped", + "AAIEdgeworthOffice", + "AAIGatewaterLandStage", + "AAIGatewaterLandWildWest", + "AAIiFlyAirlines", + "AALobby", + "AAParkingLot", + "AAPoliceStation", + "AATrainStation", + "AAWrightOffice", + "AJBorschtBowlClub", + "AJCourt", + "AJCourtBirthday", + "AJCourtHalloween", + "AJCourtNight", + "AJCourtTV", + "AJDefendantLobby", + "AJDetentionCenter", + "AJDrewStudio", + "AJHottiClinic", + "AJKlavierOffice", + "AJKristophCell", + "AJLobby", + "AJMeraktisClinic", + "AJPeoplePark", + "AJSunshineColiseum", + "AJWrightOffice", + "Ace", + "AcroRoomJFA", + "AirportJFA", + "AlbaOfficeAAI", + "Anime", + "Arcade", + "AtmeyOfficeTT", + "Atrium (SG)", + "AutumnForest", + "BB - Flowerfield", + "BB - Market", + "BB - Street", + "BandoLandAAI", + "Basement", + "Battlegrounds", + "BerryBigCircusJFA", + "Blackout", + "BlueScreensTT", + "BluecorpAA", + "BridgeNest", + "Brig", + "Building", + "CC1", + "CC2", + "CC3", + "CC4", + "CC5", + "CC6", + "CC7", + "CC8", + "CC9", + "CC10", + "CC11", + "CC12", + "CO - Big door", + "CO - Finalroom", + "CO - Meetingroom", + "CO - Whitedoor", + "CO - Whitelobby", + "CO - Whitelowerfloor", + "CO - White room", + "CP", + "CPRP2 Chap1", + "CPRP2 Chap2and3", + "CPRP2 Chap4", + "CPRP2 Chap5", + "CPRP Chap1", + "CPRP Chap2", + "CPRP Chap3", + "CPRP Chap4", + "CPRP Chap5", + "CVStMystere", + "Cafe", + "CafeCourt", + "CaffeeCase", + "Cal", + "CargoHoldAAI", + "Casino", + "CasinoCourt", + "Cathedral (SG)", + "Christmas", + "Christmas Courtroom", + "CinemaFamousi", + "Classroom", + "Co - Lobby 1", + "Co - Lobby 2", + "CochenOfficeAAI", + "ColosseumFerox", + "Control Room", + "Control Room Interior", + "CountyCourt", + "CourtroomAA", + "CourtroomAAHD", + "CourtroomAAI", + "CourtroomAJ", + "CourtroomAJNight", + "CourtroomAnime", + "CourtroomCounty", + "CourtroomDD", + "CourtroomEnglish", + "CourtroomNew", + "CourtroomRuined", + "CourtroomThemis", + "CourtroomTouhou", + "CourtroomWitch", + "CruiseCourt", + "CustomEight", + "CustomEleven", + "CustomFifteen", + "CustomFive", + "CustomFour", + "CustomFourteen", + "CustomNine", + "CustomOne", + "CustomSeven", + "CustomSix", + "CustomTen", + "CustomThirteen", + "CustomThree", + "CustomTwelve", + "CustomTwo", + "DC", + "DDCourt", + "DDCourtGray", + "DDCourtRuined", + "DDCourtRuinedInvestigation", + "DDCourtThemis", + "DDDefendantLobby", + "DDGyaxa", + "DDLobby", + "DDNinetailsVale", + "DDShipshapeAquarium", + "DDThemisAcademy", + "DFreightTrain", + "DGS-ENG", + "DGS-JAP", + "DGS", + "DGSCourtJapanese", + "DGSCourtOldBailey", + "DGSCourtOldBaileyJury", + "DGSDefendantLobbyJapanese", + "DGSDefendantLobbyOldBailey", + "DGSEnglishCourt", + "DGSJapanCourt", + "DGSLondon", + "DGSenglishcourt", + "DRAE-Area1", + "DRAE-Area2", + "DRClassTrial", + "DRRP", + "Dark Cave", + "Darkness", + "Datrone Heart", + "Datrone HeartHQ", + "DeLiteHouseTT", + "Despair vs. Hope", + "DetentionCenterAAI2", + "DimensionalGate", + "DogenCellAAI2", + "DualDestinies", + "Dungeon Courtroom", + "EdgeworthOfficeAA", + "EdgeworthOfficeAAI", + "EmbassyAAI", + "Endless Courtroom", + "EngardeManorJFA", + "EnglishCourt", + "Errors", + "Errors2", + "FECastle", + "FECave", + "FEFort", + "FEPlain", + "FETavern", + "Factory", + "FieldFortune", + "FilmSetAAI2", + "Flowerfield", + "ForensicCourt", + "Forest", + "GS4Night", + "GantOfficeAA", + "GetwaterHotelJFA", + "GetwaterStageJFA", + "GlobalStudiosIndoorsAA", + "GlobalStudiosOutdoorsAA", + "GourdLakeAA", + "GrandChokmah", + "GrandStadium", + "Graveyard", + "GreatWitchtrialCourt", + "GrossbergOfficeAA", + "HD", + "HQFarm", + "HQHalloweenTown", + "HQHolodeck", + "HQShrine", + "HQTown", + "HQVolcanoCherry", + "HallOfFame", + "HarborTown", + "HarvestFestival", + "HazakuraTemple1TT", + "HazakuraTemple2TT", + "Headquarters", + "Headquarters 2", + "Hell Correspondence", + "Hospital", + "HotelRoomAA", + "HottiClinicJFA", + "Innsmouth", + "InsidePlaneAAI2", + "Interiors (Day)", + "Interiors (Night)", + "JFAAirport", + "JFABerryBigCircusEast", + "JFABerryBigCircusWest", + "JFAGatewaterHotel", + "JFAHottiClinic", + "JFAKurainVillage", + "JFAMattHouse", + "JapaneseCourt", + "Kamurocho (Day)", + "Kamurocho (Night)", + "Keterburg", + "Khura'in", + "Khurain", + "KokonoeLab", + "KurainCourt", + "KurainVillageJFA", + "LBCastle", + "LBMisc", + "LBScotlandYard", + "Lab 8", + "Lentomain", + "Library", + "LogicChessAAI2", + "MI - Ashleys Shack", + "MLP - Apple barn", + "MLP - CMC Clubhouse", + "MLP - CMC Clubhouse inside", + "MLP - Canterlot Castle galaroom", + "MLP - Canterlot Hallway", + "MLP - Canterlot Library2", + "MLP - Canterlot Town", + "MLP - Canterlot alley", + "MLP - Canterlot library", + "MLP - Carousel Boutique", + "MLP - Clearing", + "MLP - Curio Shop", + "MLP - Everfree Forest", + "MLP - Everfree Forest entrance", + "MLP - Fluttershy's cottage", + "MLP - Hospital Room", + "MLP - Hotelroom", + "MLP - Library 2F", + "MLP - Library mainfloor", + "MLP - Old Castle", + "MLP - Orchard", + "MLP - PV Hospital", + "MLP - PV Street", + "MLP - Ponyville", + "MLP - Shining's apartment", + "MLP - Sugarcube Corner", + "MLP - Twilight's Lab", + "MM - Castle", + "MM - Madokas house", + "MM - School yard", + "MM - Street", + "MM - Street2", + "MM - classroom", + "MM - dark hallway", + "MM - rooftop", + "MM - room whit Kyubey", + "MM - school hallway", + "MM - staircase", + "MMA-Bedrooms1", + "MMA-Floor 1", + "MS - Cathedral", + "MS - Zakum's Tree", + "Mansion", + "MansionAAI2", + "MansionHQ", + "Maplecrest - Nightmare", + "Maplecrest", + "Market", + "Mayonaka", + "MechHangar", + "Medici Tower", + "Military Base Exterior", + "MoeRoomJFA", + "MuseumAAI2", + "MuseumTT", + "Music", + "NewCourt", + "New Meridian", + "Ninetailsvale", + "Nordon Plains", + "Nordon Plains Night", + "OCArcade", + "OCBebop", + "OCCourtCafe", + "OCCourtCounty", + "OCCourtCruise", + "OCCourtEndless", + "OCCourtFinalDestination", + "OCCourtInverted", + "OCCourtPirateShip", + "OCCourtSky", + "OCCourtSpace", + "OCCourtSpaceShip", + "OCCourtTouhou", + "OCCourtZetta", + "OCDungeon", + "OCHospital", + "OCRoad", + "OCTownPirate", + "OCTownShanty", + "OCWhiteRoom", + "OfficeHouseHQ", + "OfficeNightAA", + "Osaka (Night)", + "Osaka", + "OutsidePlaneAAI2", + "P4UBasement", + "P4ULab", + "P4Ubaseball", + "P4Ubeach", + "P4Ubuilding", + "P4Uconcert", + "P4Ugarden", + "P4Ugraveyard", + "P4Uhell", + "P4Ujail", + "P4Umisc", + "P4Unight", + "P4Uoffices", + "P4Urailway", + "P4Urestaurants", + "P4Urooms", + "P4Uruins", + "P4Uschool", + "P4Ustage1", + "P4Ustage2", + "P4Ustation", + "P4Ustore", + "P4Utent", + "P4Utransport", + "P4Utv", + "P4Uvelvetroom", + "PICAAI2", + "PLvsAAAlchemistHouse", + "PLvsAABellTower", + "PLvsAACastle", + "PLvsAACourtEnglish", + "PLvsAACourtLabyrinthia", + "PLvsAACourthouse", + "PLvsAADefendantLobbyEnglish", + "PLvsAADefendantLobbyLabyrinthia", + "PLvsAAEclaireBakery", + "PLvsAAForest", + "PLvsAAGreatArchive", + "PLvsAALabyrinthiaInner", + "PLvsAALabyrinthiaOuter", + "PLvsAALondon", + "PLvsAARougeTavern", + "PLvsAARuins", + "PLvsAAStorytellerTower", + "PLvsAAWagon", + "PLvsAAWorkshop", + "PMMMRP", + "PMMMWitch", + "ParkingLotAA", + "PeonyCastle", + "Persona Afternoon", + "Persona DH", + "Persona Morning", + "Persona Night", + "PersonaRP", + "PhoenixOfficeAA", + "PirateShip", + "PlaneAAI", + "PlaneLoungeAAI", + "PlaneLoungeLandAAI", + "PlatPark", + "PlatRemnant", + "PlatunaArea1", + "PlatunaArea1HQ", + "PlatunaArea2", + "PlatunaArea2HQ", + "PlatunaMain", + "PlatunamainHQ", + "PrecinctAA", + "PrisonAAI2", + "PrisonCourtyardAAI2", + "RG - 104", + "RG - A-East", + "RG - AMX", + "RG - Bus Terminal", + "RG - Cadoi City", + "RG - Concert", + "RG - Dogenzaka", + "RG - God Pad", + "RG - Miyashita Underpass", + "RG - Station Underpass", + "RG - Trail", + "RG - Udagawa", + "RaysDeLite", + "Retreat", + "RetreatHQ", + "RiverVista", + "Road", + "Role Play", + "Ronpa Mansion Area 5", + "Ronpa Mansion Day", + "Ronpa Mansion Day2", + "Ronpa Mansion Day3", + "Ronpa Mansion Day4", + "Ronpa Mansion Night", + "Ronpa Mansion Night2", + "Ronpa Mansion Night3", + "Ronpa Mansion Night4", + "Ronpa mansion Haunted", + "Ronpers Express", + "RooftopAAI2", + "RuinedCastle", + "RuinedCourt", + "Ruins Entrance", + "SDR2 ISLAND", + "SDR2 ISLAND2", + "SDR2 ISLAND2 NIGHT", + "SDR2 ISLAND3", + "SDR2 ISLAND NIGHT", + "SI - Bedroom", + "SI - Class(sunset)", + "SI - Class", + "SI - Council1", + "SI - Council2", + "SI - Council3", + "SI - Gym", + "SI - Gym2", + "SI - Hall", + "SI - Hall2", + "SI - Lockers", + "SI - Nurse", + "SI - Office", + "SI - Pink", + "SI - Roof", + "SI - Roof2", + "SI - School", + "Seance", + "SecretRoomsJFA", + "SecurityCompanyTT", + "ShipAAI2", + "SkialForest", + "Sky", + "SkyDeck", + "SoJCourt", + "SoJDefendantLobby", + "Somina Castle", + "Somina Castle Night", + "SpaceCourt", + "SpaceCourtBlue", + "SpaceCourtGreen", + "SpaceCourtNormal", + "SpaceCourtOrange", + "SpaceCourtRainbow", + "SpaceCourtRed", + "SpaceCourtYellow", + "SpacePort", + "Spaceship", + "StageAAI", + "StageDisassembledAAI", + "SteamBar", + "SteamGarden", + "SteamGovt", + "SteamSquare", + "SteamStreet", + "Street", + "SummerFestival", + "SummerFestivalEvening", + "TARDIS", + "TEOS Lab", + "TTAtmeyOffice", + "TTBlueScreensInc", + "TTDemasqueHideout", + "TTHazakuraTemple", + "TTHazakuraTempleInner", + "TTKBSecurity", + "TTLordlyTailor", + "TTTenderLender", + "TTTresBien", + "TenderLenderTT", + "Themis", + "Titania", + "TitaniaValley", + "Togami Mansion", + "TouhouCourt", + "Tower", + "Town", + "Town Night", + "Tr0LLc0urt", + "TrainstationAA", + "TresBienTT", + "TrollCourt", + "Twotorial Village", + "Twotorial Village Night", + "VC 1", + "VLR", + "VLR2.2", + "VLR2.3", + "VLR2", + "VLR3", + "VitaminSquareTT", + "WEN", + "WaitingRoomAAI", + "WestAAI", + "WinterPalaceAAI2", + "WitchTrialCourt", + "WitchtrialCourtHQ", + "Witchwood", + "WorldEmulator", + "Wreckage (SG)", + "Wrightagency", + "Xmas", + "Zetta", + "animation", + "apollojustice", + "background", + "basement", + "birthday", + "blackout", + "chess", + "chessw1", + "chessw2", + "chessw3", + "chessw4", + "christmas", + "circus", + "classtrial", + "cofe", + "courthouseofgods", + "cruise", + "cruise court", + "custom", + "custom1", + "custom2", + "custom3", + "custom4", + "custom5", + "custom6", + "custom7", + "custom8", + "custom9", + "custom10", + "daimoncourt", + "default - Kopie", + "default", + "default_christmas", + "defendantlobby", + "defendantlobbyapollo", + "detentioncenter", + "doppler", + "dr1stfloor", + "dr1stfloordorms", + "dr1stfloorhalls", + "dr2ndfloor", + "dr3rdfloor", + "druq1stfloordorms", + "druq2ndfloordorms", + "dualdestinies", + "dualdestiniesOG", + "dungeon", + "endless", + "englishcourt", + "forest", + "gs4", + "gs4night", + "gs5", + "hd", + "inn", + "investigationbando", + "investigationsembassylobby", + "investigationsgourdlake", + "investigationsmilesoffice", + "investigationsplaneair", + "investigationsroyalcourt", + "investigationstvroom", + "investigationswestern", + "investigationswitchtown", + "island 1(uranus zone)", + "lcourt", + "legacy", + "lobbyDGS-ENG", + "lobbyDGS-JAP", + "lobbyPLvsAA-ENG", + "lobbyPLvsAA-LAB", + "lobbySOJ", + "magatama", + "magatama1", + "magatama2", + "magatama3", + "magatama4", + "magatama5", + "marblefade", + "matrix", + "matrixall", + "matrixangry", + "matrixangrysad", + "matrixangrysurprised", + "matrixhappy", + "matrixhappyangry", + "matrixhappysad", + "matrixhappysurprised", + "matrixsad", + "matrixsadsurprised", + "matrixsurprise", + "mlp", + "newcourt", + "night (no lights)", + "plvsaa", + "policestation", + "prisonvestigation", + "sdr2classtrial", + "sky", + "sshope2ndfloorday(incident)", + "sshope2ndfloorday", + "sshope2ndfloornight(incident)", + "sshope2ndfloornight", + "sshopeday(incident)", + "sshopeday", + "sshopenight(incident)", + "sshopenight", + "thief", + "thiefbash", + "thiefpoint", + "thiefpoisoning", + "thiefprints", + "thiefstab", + "thiefsteal", + "turnaboutstorm - Kopie", + "turnaboutstorm", + "vocalcourt", + "witchtrialcourt" +]; \ No newline at end of file diff --git a/webAO/backgrounds.min.js b/webAO/backgrounds.min.js deleted file mode 100644 index fc615e5..0000000 --- a/webAO/backgrounds.min.js +++ /dev/null @@ -1 +0,0 @@ -var background_arr=["1st server","999.1","999","999Apartment","999CaptainsQuarters","999Cargo","999Casino","999Cdeck","999CentralStairs","999Chapel","999Chart","999Confinement","999DoorsA","999DoorsB","999Hospital","999Kitchen","999Library","999Operating","999Shower","999Steam","999Steeldoor","999Study","999Torture","9991stClassCabinA","9991stClassCabinB","9992ndClassCabin","AA - Edgewort's Office","AA - Gantsroom","AA - Gatewater room","AA - Gourd Lake","AA - Gourd Lake Entrance","AA - Hotel Lobby","AA - Hotticlinic","AA - Kurain","AA - Parkinglot","AA - Police Deparment","AA - Police Station","AA - Records Room","AA - Sc13","AA - Wright's Office","AABluecorp","AACourt","AACourtAnime","AACourtChristmasDecorations","AACourtChristmasLights","AACourtHD","AADefendantLobby","AADefendantLobbyHD","AADetentionCenter","AAEdgeworthOffice","AAGantOffice","AAGatewaterHotel","AAGlobalStudiosEast","AAGlobalStudiosWest","AAGourdLake","AAGrossbergOffice","AAI2Circus","AAI2City","AAI2GourdLake","AAI2LogicChess","AAI2MuseumPast","AAI2MuseumPresent","AAI2PIC","AAI2Prison","AAICohdopianEmbassy","AAICourt","AAICourtFlipped","AAIEdgeworthOffice","AAIGatewaterLandStage","AAIGatewaterLandWildWest","AAIiFlyAirlines","AALobby","AAParkingLot","AAPoliceStation","AATrainStation","AAWrightOffice","AJBorschtBowlClub","AJCourt","AJCourtBirthday","AJCourtHalloween","AJCourtNight","AJCourtTV","AJDefendantLobby","AJDetentionCenter","AJDrewStudio","AJHottiClinic","AJKlavierOffice","AJKristophCell","AJLobby","AJMeraktisClinic","AJPeoplePark","AJSunshineColiseum","AJWrightOffice","Ace","AcroRoomJFA","AirportJFA","AlbaOfficeAAI","Anime","Arcade","AtmeyOfficeTT","Atrium (SG)","AutumnForest","BB - Flowerfield","BB - Market","BB - Street","BandoLandAAI","Basement","Battlegrounds","BerryBigCircusJFA","Blackout","BlueScreensTT","BluecorpAA","BridgeNest","Brig","Building","CC1","CC2","CC3","CC4","CC5","CC6","CC7","CC8","CC9","CC10","CC11","CC12","CO - Big door","CO - Finalroom","CO - Meetingroom","CO - Whitedoor","CO - Whitelobby","CO - Whitelowerfloor","CO - White room","CP","CPRP2 Chap1","CPRP2 Chap2and3","CPRP2 Chap4","CPRP2 Chap5","CPRP Chap1","CPRP Chap2","CPRP Chap3","CPRP Chap4","CPRP Chap5","CVStMystere","Cafe","CafeCourt","CaffeeCase","Cal","CargoHoldAAI","Casino","CasinoCourt","Cathedral (SG)","Christmas","Christmas Courtroom","CinemaFamousi","Classroom","Co - Lobby 1","Co - Lobby 2","CochenOfficeAAI","ColosseumFerox","Control Room","Control Room Interior","CountyCourt","CourtroomAA","CourtroomAAHD","CourtroomAAI","CourtroomAJ","CourtroomAJNight","CourtroomAnime","CourtroomCounty","CourtroomDD","CourtroomEnglish","CourtroomNew","CourtroomRuined","CourtroomThemis","CourtroomTouhou","CourtroomWitch","CruiseCourt","CustomEight","CustomEleven","CustomFifteen","CustomFive","CustomFour","CustomFourteen","CustomNine","CustomOne","CustomSeven","CustomSix","CustomTen","CustomThirteen","CustomThree","CustomTwelve","CustomTwo","DC","DDCourt","DDCourtGray","DDCourtRuined","DDCourtRuinedInvestigation","DDCourtThemis","DDDefendantLobby","DDGyaxa","DDLobby","DDNinetailsVale","DDShipshapeAquarium","DDThemisAcademy","DFreightTrain","DGS-ENG","DGS-JAP","DGS","DGSCourtJapanese","DGSCourtOldBailey","DGSCourtOldBaileyJury","DGSDefendantLobbyJapanese","DGSDefendantLobbyOldBailey","DGSEnglishCourt","DGSJapanCourt","DGSLondon","DGSenglishcourt","DRAE-Area1","DRAE-Area2","DRClassTrial","DRRP","Dark Cave","Darkness","Datrone Heart","Datrone HeartHQ","DeLiteHouseTT","Despair vs. Hope","DetentionCenterAAI2","DimensionalGate","DogenCellAAI2","DualDestinies","Dungeon Courtroom","EdgeworthOfficeAA","EdgeworthOfficeAAI","EmbassyAAI","Endless Courtroom","EngardeManorJFA","EnglishCourt","Errors","Errors2","FECastle","FECave","FEFort","FEPlain","FETavern","Factory","FieldFortune","FilmSetAAI2","Flowerfield","ForensicCourt","Forest","GS4Night","GantOfficeAA","GetwaterHotelJFA","GetwaterStageJFA","GlobalStudiosIndoorsAA","GlobalStudiosOutdoorsAA","GourdLakeAA","GrandChokmah","GrandStadium","Graveyard","GreatWitchtrialCourt","GrossbergOfficeAA","HD","HQFarm","HQHalloweenTown","HQHolodeck","HQShrine","HQTown","HQVolcanoCherry","HallOfFame","HarborTown","HarvestFestival","HazakuraTemple1TT","HazakuraTemple2TT","Headquarters","Headquarters 2","Hell Correspondence","Hospital","HotelRoomAA","HottiClinicJFA","Innsmouth","InsidePlaneAAI2","Interiors (Day)","Interiors (Night)","JFAAirport","JFABerryBigCircusEast","JFABerryBigCircusWest","JFAGatewaterHotel","JFAHottiClinic","JFAKurainVillage","JFAMattHouse","JapaneseCourt","Kamurocho (Day)","Kamurocho (Night)","Keterburg","Khura'in","Khurain","KokonoeLab","KurainCourt","KurainVillageJFA","LBCastle","LBMisc","LBScotlandYard","Lab 8","Lentomain","Library","LogicChessAAI2","MI - Ashleys Shack","MLP - Apple barn","MLP - CMC Clubhouse","MLP - CMC Clubhouse inside","MLP - Canterlot Castle galaroom","MLP - Canterlot Hallway","MLP - Canterlot Library2","MLP - Canterlot Town","MLP - Canterlot alley","MLP - Canterlot library","MLP - Carousel Boutique","MLP - Clearing","MLP - Curio Shop","MLP - Everfree Forest","MLP - Everfree Forest entrance","MLP - Fluttershy's cottage","MLP - Hospital Room","MLP - Hotelroom","MLP - Library 2F","MLP - Library mainfloor","MLP - Old Castle","MLP - Orchard","MLP - PV Hospital","MLP - PV Street","MLP - Ponyville","MLP - Shining's apartment","MLP - Sugarcube Corner","MLP - Twilight's Lab","MM - Castle","MM - Madokas house","MM - School yard","MM - Street","MM - Street2","MM - classroom","MM - dark hallway","MM - rooftop","MM - room whit Kyubey","MM - school hallway","MM - staircase","MMA-Bedrooms1","MMA-Floor 1","MS - Cathedral","MS - Zakum's Tree","Mansion","MansionAAI2","MansionHQ","Maplecrest - Nightmare","Maplecrest","Market","Mayonaka","MechHangar","Medici Tower","Military Base Exterior","MoeRoomJFA","MuseumAAI2","MuseumTT","Music","NewCourt","New Meridian","Ninetailsvale","Nordon Plains","Nordon Plains Night","OCArcade","OCBebop","OCCourtCafe","OCCourtCounty","OCCourtCruise","OCCourtEndless","OCCourtFinalDestination","OCCourtInverted","OCCourtPirateShip","OCCourtSky","OCCourtSpace","OCCourtSpaceShip","OCCourtTouhou","OCCourtZetta","OCDungeon","OCHospital","OCRoad","OCTownPirate","OCTownShanty","OCWhiteRoom","OfficeHouseHQ","OfficeNightAA","Osaka (Night)","Osaka","OutsidePlaneAAI2","P4UBasement","P4ULab","P4Ubaseball","P4Ubeach","P4Ubuilding","P4Uconcert","P4Ugarden","P4Ugraveyard","P4Uhell","P4Ujail","P4Umisc","P4Unight","P4Uoffices","P4Urailway","P4Urestaurants","P4Urooms","P4Uruins","P4Uschool","P4Ustage1","P4Ustage2","P4Ustation","P4Ustore","P4Utent","P4Utransport","P4Utv","P4Uvelvetroom","PICAAI2","PLvsAAAlchemistHouse","PLvsAABellTower","PLvsAACastle","PLvsAACourtEnglish","PLvsAACourtLabyrinthia","PLvsAACourthouse","PLvsAADefendantLobbyEnglish","PLvsAADefendantLobbyLabyrinthia","PLvsAAEclaireBakery","PLvsAAForest","PLvsAAGreatArchive","PLvsAALabyrinthiaInner","PLvsAALabyrinthiaOuter","PLvsAALondon","PLvsAARougeTavern","PLvsAARuins","PLvsAAStorytellerTower","PLvsAAWagon","PLvsAAWorkshop","PMMMRP","PMMMWitch","ParkingLotAA","PeonyCastle","Persona Afternoon","Persona DH","Persona Morning","Persona Night","PersonaRP","PhoenixOfficeAA","PirateShip","PlaneAAI","PlaneLoungeAAI","PlaneLoungeLandAAI","PlatPark","PlatRemnant","PlatunaArea1","PlatunaArea1HQ","PlatunaArea2","PlatunaArea2HQ","PlatunaMain","PlatunamainHQ","PrecinctAA","PrisonAAI2","PrisonCourtyardAAI2","RG - 104","RG - A-East","RG - AMX","RG - Bus Terminal","RG - Cadoi City","RG - Concert","RG - Dogenzaka","RG - God Pad","RG - Miyashita Underpass","RG - Station Underpass","RG - Trail","RG - Udagawa","RaysDeLite","Retreat","RetreatHQ","RiverVista","Road","Role Play","Ronpa Mansion Area 5","Ronpa Mansion Day","Ronpa Mansion Day2","Ronpa Mansion Day3","Ronpa Mansion Day4","Ronpa Mansion Night","Ronpa Mansion Night2","Ronpa Mansion Night3","Ronpa Mansion Night4","Ronpa mansion Haunted","Ronpers Express","RooftopAAI2","RuinedCastle","RuinedCourt","Ruins Entrance","SDR2 ISLAND","SDR2 ISLAND2","SDR2 ISLAND2 NIGHT","SDR2 ISLAND3","SDR2 ISLAND NIGHT","SI - Bedroom","SI - Class(sunset)","SI - Class","SI - Council1","SI - Council2","SI - Council3","SI - Gym","SI - Gym2","SI - Hall","SI - Hall2","SI - Lockers","SI - Nurse","SI - Office","SI - Pink","SI - Roof","SI - Roof2","SI - School","Seance","SecretRoomsJFA","SecurityCompanyTT","ShipAAI2","SkialForest","Sky","SkyDeck","SoJCourt","SoJDefendantLobby","Somina Castle","Somina Castle Night","SpaceCourt","SpaceCourtBlue","SpaceCourtGreen","SpaceCourtNormal","SpaceCourtOrange","SpaceCourtRainbow","SpaceCourtRed","SpaceCourtYellow","SpacePort","Spaceship","StageAAI","StageDisassembledAAI","SteamBar","SteamGarden","SteamGovt","SteamSquare","SteamStreet","Street","SummerFestival","SummerFestivalEvening","TARDIS","TEOS Lab","TTAtmeyOffice","TTBlueScreensInc","TTDemasqueHideout","TTHazakuraTemple","TTHazakuraTempleInner","TTKBSecurity","TTLordlyTailor","TTTenderLender","TTTresBien","TenderLenderTT","Themis","Titania","TitaniaValley","Togami Mansion","TouhouCourt","Tower","Town","Town Night","Tr0LLc0urt","TrainstationAA","TresBienTT","TrollCourt","Twotorial Village","Twotorial Village Night","VC 1","VLR","VLR2.2","VLR2.3","VLR2","VLR3","VitaminSquareTT","WEN","WaitingRoomAAI","WestAAI","WinterPalaceAAI2","WitchTrialCourt","WitchtrialCourtHQ","Witchwood","WorldEmulator","Wreckage (SG)","Wrightagency","Xmas","Zetta","animation","apollojustice","background","basement","birthday","blackout","chess","chessw1","chessw2","chessw3","chessw4","christmas","circus","classtrial","cofe","courthouseofgods","cruise","cruise court","custom","custom1","custom2","custom3","custom4","custom5","custom6","custom7","custom8","custom9","custom10","daimoncourt","default - Kopie","default","default_christmas","defendantlobby","defendantlobbyapollo","detentioncenter","doppler","dr1stfloor","dr1stfloordorms","dr1stfloorhalls","dr2ndfloor","dr3rdfloor","druq1stfloordorms","druq2ndfloordorms","dualdestinies","dualdestiniesOG","dungeon","endless","englishcourt","forest","gs4","gs4night","gs5","hd","inn","investigationbando","investigationsembassylobby","investigationsgourdlake","investigationsmilesoffice","investigationsplaneair","investigationsroyalcourt","investigationstvroom","investigationswestern","investigationswitchtown","island 1(uranus zone)","lcourt","legacy","lobbyDGS-ENG","lobbyDGS-JAP","lobbyPLvsAA-ENG","lobbyPLvsAA-LAB","lobbySOJ","magatama","magatama1","magatama2","magatama3","magatama4","magatama5","marblefade","matrix","matrixall","matrixangry","matrixangrysad","matrixangrysurprised","matrixhappy","matrixhappyangry","matrixhappysad","matrixhappysurprised","matrixsad","matrixsadsurprised","matrixsurprise","mlp","newcourt","night (no lights)","plvsaa","policestation","prisonvestigation","sdr2classtrial","sky","sshope2ndfloorday(incident)","sshope2ndfloorday","sshope2ndfloornight(incident)","sshope2ndfloornight","sshopeday(incident)","sshopeday","sshopenight(incident)","sshopenight","thief","thiefbash","thiefpoint","thiefpoisoning","thiefprints","thiefstab","thiefsteal","turnaboutstorm - Kopie","turnaboutstorm","vocalcourt","witchtrialcourt"]; \ No newline at end of file diff --git a/webAO/client.b.js b/webAO/client.b.js index 46ab840..ac6b321 100644 --- a/webAO/client.b.js +++ b/webAO/client.b.js @@ -1,2 +1,2 @@ -!function(e){var t={};function n(i){if(t[i])return t[i].exports;var c=t[i]={i:i,l:!1,exports:{}};return e[i].call(c.exports,c,c.exports,n),c.l=!0,c.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var c in e)n.d(i,c,function(t){return e[t]}.bind(null,c));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=3)}({3:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n").replace(/\[(\/?)b\]/g,"<$1b>").replace(/\[(\/?)i\]/g,"<$1i>").replace(/\[(\/?)s\]/g,"<$1del>").replace(/\[(\/?)u\]/g,"<$1u>").replace(/\[(\/?)sub\]/g,"<$1sub>").replace(/\[(\/?)sup\]/g,"<$1sup>").replace(/\[m=([#a-zA-Z0-9]+)\]/g,'').replace(/\[(\/?)m\]/g,"<$1m>").replace(/\[c=?([#a-zA-Z0-9]+)\]/g,'').replace(/\[\/c\]/g,"")}(ae(ue(de(e[5])))),side:e[6],sound:escape(e[7]),type:e[8],snddelay:e[10],objection:e[11],evidence:e[12],flip:e[13],flash:e[14],color:e[15],isnew:!0},n=0;nt.scrollHeight-60&&(t.scrollTop=t.scrollHeight)}},{key:"handleMC",value:function(e){var t=he.music;(t.pause(),t.src=d+e[1],t.play(),e[2]>=0)?S(this.chars[e[2]].name+" changed music to "+e[1]):S("The music was changed to "+e[1])}},{key:"handleRMC",value:function(e){he.music.pause(),he.music=new Audio(this.musicList[e[1]]);var t=he.music;t.totime=e[1],t.offset=(new Date).getTime()/1e3,t.addEventListener("loadedmetadata",function(){t.currentTime+=parseFloat(t.totime+((new Date).getTime()/1e3-t.offset)).toFixed(3),t.play()},!1)}},{key:"handleCI",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Character "+e[1],this.serv.send("AN#"+(e[1]/10+1)+"#%");for(var t=2;t'}},{key:"handleEM",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Music "+e[1],this.serv.send("AM#"+(e[1]/10+1)+"#%");for(var t=document.getElementById("client_musiclist"),n=2;n .health-bar").animate({width:t+"%"},500)):(this.hp[1]=e[2],$("#client_prosecutor_hp > .health-bar").animate({width:t+"%"},500))}},{key:"handleRT",value:function(e){"testimony1"==e[1]?this.testimonyID=1:this.testimonyID=2,he.initTestimonyUpdater()}},{key:"handleZZ",value:function(e){var t=document.getElementById("client_ooclog");t.innerHTML+="$Alert: "+ue(de(e[1]))+"\r\n",t.scrollTop>t.scrollHeight-60&&(t.scrollTop=t.scrollHeight)}},{key:"handleID",value:function(e){this.playerID=e[1]}},{key:"handlePN",value:function(e){this.serv.send("askchaa#%")}},{key:"handleSI",value:function(e){r?this.serv.send("askchar2#%"):this.serv.send("RC#%")}},{key:"handleCharsCheck",value:function(e){document.getElementById("client_chartable").innerHTML="";for(var t=0;t",n.appendChild(i),t%8==0&&document.getElementById("client_chartable").appendChild(n)}}},{key:"handlePV",value:function(e){this.charID=e[3],document.getElementById("client_charselect").style.display="none";var t=this.me(),n=this.emotes,i=new XMLHttpRequest,c="http://assets.aceattorneyonline.com/base/"==l;i.withCredentials=!1,document.getElementById("client_emo").innerHTML="",i.open("GET",l+"characters/"+escape(this.me().name)+"/char.ini",!0),i.responseType="text",i.onload=function(e){if(200==this.status){var i=this.responseText,o=p.parse(i);t.side=o.Options.side,V(t.side);for(var s=1;s"}P(1)}},i.send()}}]),e}(),f=function(){function e(){c(this,e),this.textnow="",this.chatmsg={isnew:!1,content:"",objection:"0",sound:"",startpreanim:!1,startspeaking:!1,side:null,color:"0",snddelay:0,preanimdelay:0},this.blip=new Audio(l+"sounds/general/sfx-blipmale.wav"),this.blip.volume=.5,this.blipChannels=new Array(6);for(var t=0;t0){var t="";1==me.testimonyID?t="witnesstestimony":2==me.testimonyID&&(t="crossexamination"),new Audio(me.resources[t].sfx).play(),this.testimonyTimer=0,document.getElementById("client_testimony").src=me.resources[t].src,this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60)}}},{key:"getAnimLength",value:function(e,t,n){var i=new XMLHttpRequest;i.open("GET",e,!0),i.responseType="arraybuffer",i.addEventListener("load",function(){var e=gify.getInfo(i.response);console.log(e.duration),t(e.duration,n)}),i.send()}},{key:"updateTestimony",value:function(){var e=this;this.testimonyTimer=this.testimonyTimer+60,1==me.testimonyID?this.testimonyTimer>=me.resources.witnesstestimony.duration?this.disposeTestimony():this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60):2==me.testimonyID?this.testimonyTimer>=me.resources.crossexamination.duration?this.disposeTestimony():this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60):this.disposeTestimony()}},{key:"disposeTestimony",value:function(){me.testimonyID=0,this.testimonyTimer=0,document.getElementById("client_testimony").src="misc/placeholder.gif",clearTimeout(this.testimonyUpdater)}},{key:"updateText",value:function(){var e=this;if(1==this.chatmsg.flip?document.getElementById("client_char").style.transform="scaleX(-1)":document.getElementById("client_char").style.transform="scaleX(1)",this._animating&&(this.updater=setTimeout(function(){return e.updateText()},60)),this.chatmsg.isnew){document.getElementById("client_background").style.backgroundColor="transparent",document.getElementById("client_name").style.display="none",document.getElementById("client_chat").style.display="none",document.getElementById("client_evi").style.opacity="0",document.getElementById("client_evi").style.height="0%";var t={1:"holdit",2:"objection",3:"takethat"}[this.chatmsg.objection];void 0!==t?(document.getElementById("client_shout").src=me.resources[t].src,new Audio(l+"/characters/"+this.chatmsg.name+"/"+t+".wav").play(),this.shoutTimer=850):this.shoutTimer=0,this.chatmsg.isnew=!1,this.chatmsg.startpreanim=!0}if(this.textTimer>=this.shoutTimer&&this.chatmsg.startpreanim)2==this.chatmsg.flash?(this.sfxaudio.pause(),this.sfxplayed=1,this.sfxaudio.src=l+"sounds/general/sfx-stab.wav",this.sfxaudio.play(),$("#client_gamewindow").effect("shake",{direction:"up"})):1==this.chatmsg.flash&&(document.getElementById("client_background").style.backgroundColor="white",this.sfxaudio.pause(),this.sfxplayed=1,this.sfxaudio.src=l+"sounds/general/sfx-realization.wav",this.sfxaudio.play(),$("#client_gamewindow").effect("pulsate")),this.chatmsg.preanimdelay>0&&(document.getElementById("client_shout").src="misc/placeholder.gif",O(this.chatmsg.side),document.getElementById("client_char").src=l+"characters/"+escape(this.chatmsg.name)+"/"+this.chatmsg.preanim+".gif"),this.chatmsg.startpreanim=!1,this.chatmsg.startspeaking=!0;else if(this.textTimer>=this.shoutTimer+this.chatmsg.preanimdelay&&!this.chatmsg.startpreanim)if(this.chatmsg.startspeaking){this.chatmsg.evidence>0&&(document.getElementById("client_evi").style.backgroundImage="url('"+me.evidences[this.chatmsg.evidence-1].icon+"')","def"==this.chatmsg.side?(document.getElementById("client_evi").style.right="1.5em",document.getElementById("client_evi").style.left="initial",$("#client_evi").animate({height:"30%",opacity:1},250)):(document.getElementById("client_evi").style.right="initial",document.getElementById("client_evi").style.left="1.5em",$("#client_evi").animate({height:"30%",opacity:1},250))),$("#client_name").toggle("fade"),$("#client_chat").toggle("drop",{direction:"down"}),0==this.chatmsg.preanimdelay&&(document.getElementById("client_shout").src="misc/placeholder.gif",O(this.chatmsg.side)),document.getElementById("client_char").src=l+"characters/"+escape(this.chatmsg.name)+"/"+this.chatmsg.speaking+".gif",document.getElementById("client_name").style.fontSize=.7*document.getElementById("client_name").offsetHeight+"px",document.getElementById("client_chat").style.fontSize=.25*document.getElementById("client_chat").offsetHeight+"px",document.getElementById("client_name").innerHTML="

"+ae(this.chatmsg.nameplate)+"

";var n="color: "+({0:"#ffffff",1:"#00ff00",2:"#ff0000",3:"#ffaa00",4:"#0000ff",5:"#ffff00",6:"#aa00aa"}[this.chatmsg.color]||"#ffffff");document.getElementById("client_inner_chat").style=n,this.chatmsg.startspeaking=!1,this.textnow==this.chatmsg.content&&(document.getElementById("client_char").src=l+"characters/"+escape(this.chatmsg.name)+"/"+this.chatmsg.silent+".gif",this._animating=!1,clearTimeout(this.updater))}else this.textnow!=this.chatmsg.content&&(" "!=this.chatmsg.content.charAt(this.textnow.length)&&(this.blipChannels[this.currentBlipChannel].play(),this.currentBlipChannel++,this.currentBlipChannel%=this.blipChannels.length),this.textnow=this.chatmsg.content.substring(0,this.textnow.length+1),document.getElementById("client_inner_chat").innerHTML=this.textnow,this.textnow==this.chatmsg.content&&(this.textTimer=0,this._animating=!1,document.getElementById("client_char").src=l+"characters/"+escape(this.chatmsg.name)+"/"+this.chatmsg.silent+".gif",clearTimeout(this.updater)));!this.sfxplayed&&this.chatmsg.snddelay+this.shoutTimer>=this.textTimer&&(this.sfxaudio.pause(),this.sfxplayed=1,"0"!=this.chatmsg.sound&&"1"!=this.chatmsg.sound&&(this.sfxaudio.src=l+"sounds/general/"+escape(this.chatmsg.sound)+".wav",this.sfxaudio.play())),this.textTimer=this.textTimer+60}}]),e}(),p=function(){function e(){c(this,e)}return i(e,null,[{key:"parse",value:function(e){var t={section:/^\s*\[\s*([^\]]*)\s*\]\s*$/,param:/^\s*([\w\.\-\_]+)\s*=\s*(.*?)\s*$/,comment:/^\s*;.*$/},n={},i=null;return e.split(/\r\n|\r|\n/).forEach(function(e){if(!t.comment.test(e)&&0!=e.length)if(t.param.test(e)){var c=e.match(t.param);i?n[i][c[1]]=c[2]:n[c[1]]=c[2]}else if(t.section.test(e)){var o=e.match(t.section);n[o[1]]={},i=o[1]}}),n}}]),e}();function v(e){13==e.keyCode&&(me.sendOOC(document.getElementById("client_oocinputbox").value),document.getElementById("client_oocinputbox").value="")}function _(e){if(13==e.keyCode){var t=me.me(),n=me.myEmote(),i=me.myEvidence(),c=me.flip?1:0,o=document.getElementById("textcolor").value,s="0",a="0";document.getElementById("sendsfx").checked&&(s=n.sfx,a=n.sfxdelay),me.sendIC(n.speaking,t.name,n.silent,document.getElementById("client_inputbox").value,t.side,s,n.zoom,a,h,i,c,u,o)}}function E(e){var t=document.getElementById("client_musiclist").value;me.sendMusicChange(t)}function I(e){var t=e.textContent;me.sendMusicChange(t)}function b(){he.music.volume=document.getElementById("client_mvolume").value/100}function B(){he.sfxaudio.volume=document.getElementById("client_svolume").value/100}function w(){he.setBlipVolume(document.getElementById("client_bvolume").value/100)}function k(e){me.sendLeaveRoom(),document.getElementById("client_charselect").style.display="block",document.getElementById("client_emo").innerHTML=""}function C(e){return e.onerror="",e.src="misc/placeholder.gif",!0}function x(e){return e.onerror="",e.src="/misc/placeholder.png",!0}function T(e,t,n){var i=new XMLHttpRequest;i.onreadystatechange=function(){4==this.readyState&&200==this.status?t(!0,n,e):t(!1,n,e)},i.open("GET",e,!0),i.send()}function O(e){var t,n=he.bgFolder();switch(document.getElementById("client_fg").style.display="none",document.getElementById("client_bench").style.display="none",e){case"def":document.getElementById("client_court").src=n+"defenseempty.png",document.getElementById("client_bench").style.display="block",T(n+"defensedesk.png",M,e),t="defense";break;case"pro":document.getElementById("client_court").src=n+"prosecutorempty.png",document.getElementById("client_bench").style.display="block",T(n+"defensedesk.png",M,e),t="prosecution";break;case"hld":document.getElementById("client_court").src=n+"helperstand.png",t="defense";break;case"hlp":document.getElementById("client_court").src=n+"prohelperstand.png",t="prosecution";break;case"wit":document.getElementById("client_court").src=n+"witnessempty.png",document.getElementById("client_bench").style.display="block",document.getElementById("client_bench").src=n+"estrado.png",t="prosecution";break;case"jud":document.getElementById("client_court").src=n+"judgestand.png",t="prosecution"}5==he.chatmsg.type&&(document.getElementById("client_bench").style.display="none",document.getElementById("client_court").src=l+"themes/default/"+t+"_speedlines.gif")}function M(e,t){var n=he.bgFolder();document.getElementById("client_bench").src="def"==t?e?n+"defensedesk.png":n+"bancodefensa.png":e?n+"prosecutiondesk.png":n+"bancoacusacion.png"}function L(){me.cleanup(),(me=new y(s))&&(a="join",document.getElementById("client_error").style.display="none")}function N(){me.joinServer()}function S(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:new Date,i=document.createElement("p"),c=document.createElement("span");if(c.id="iclog_name",c.appendChild(document.createTextNode(t)),i.appendChild(c),i.appendChild(document.createTextNode(e)),g.getMinutes()!==n.getMinutes()){var o=document.createElement("span");o.id="iclog_time",o.innerText=n.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"}),i.appendChild(o)}var s=document.getElementById("client_log");s.appendChild(i),s.scrollTop>s.scrollHeight-600&&(s.scrollTop=s.scrollHeight),g=new Date}function H(e){e<1e3?me.sendCharacter(e):(document.getElementById("client_charselect").style.display="none",document.getElementById("client_inputbox").style.display="none",document.getElementById("client_emo").style.display="none")}function P(e){-1!=me.selectedEmote&&(document.getElementById("emo_"+me.selectedEmote).src=me.myEmote().button_off),me.selectedEmote=e,document.getElementById("emo_"+e).src=me.myEmote().button_on}function D(e){if(me.selectedEvidence!=e){me.selectedEvidence>0&&(document.getElementById("evi_"+me.selectedEvidence).className="client_button"),document.getElementById("evi_"+e).className="client_button dark",me.selectedEvidence=e,document.getElementById("evi_name").value=me.evidences[e-1].name,document.getElementById("evi_desc").value=me.evidences[e-1].desc;var t=Z("evi_select",me.evidences[e-1].filename);document.getElementById("evi_select").selectedIndex=t,0==t&&(document.getElementById("evi_filename").value=me.evidences[e-1].filename),F(),document.getElementById("evi_add").className="client_button hover_button inactive",document.getElementById("evi_edit").className="client_button hover_button",document.getElementById("evi_cancel").className="client_button hover_button",document.getElementById("evi_del").className="client_button hover_button"}else U()}function R(){var e=document.getElementById("evi_select");me.sendPE(document.getElementById("evi_name").value,document.getElementById("evi_desc").value,0==e.selectedIndex?document.getElementById("evi_filename").value:e.options[e.selectedIndex].text),U()}function A(){var e=document.getElementById("evi_select"),t=parseInt(me.selectedEvidence)-1;me.sendEE(t,document.getElementById("evi_name").value,document.getElementById("evi_desc").value,0==e.selectedIndex?document.getElementById("evi_filename").value:e.options[e.selectedIndex].text),U()}function j(){var e=parseInt(me.selectedEvidence)-1;me.sendDE(e),U()}function U(){me.selectedEvidence>0&&(document.getElementById("evi_"+me.selectedEvidence).className="client_button"),me.selectedEvidence=0,document.getElementById("evi_select").selectedIndex=0,F(),document.getElementById("evi_filename").value="",document.getElementById("evi_name").value="",document.getElementById("evi_desc").value="",document.getElementById("evi_icon").style.backgroundImage="url('misc/empty.png')",document.getElementById("evi_add").className="client_button hover_button",document.getElementById("evi_edit").className="client_button hover_button inactive",document.getElementById("evi_cancel").className="client_button hover_button inactive",document.getElementById("evi_del").className="client_button hover_button inactive"}function Z(e,t){for(var n=document.getElementById(e),i=1;i/g,">").replace(/"/g,""").replace(/'/g,"'")}function le(e){return e.replace(/#/g,"").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}function de(e){return e.replace(//g,"#").replace(//g,"&").replace(//g,"%").replace(//g,"$")}function re(e){var t=document.getElementById("client_encoding").value;if("unicode"==t)return e.replace(/[^\0-~]/g,function(e){return"\\u"+("000"+e.charCodeAt().toString(16)).slice(-4)});if("utf16"==t){for(var n=new ArrayBuffer(2*e.length),i=new Uint16Array(n),c=0,o=e.length;c").replace(/\[(\/?)b\]/g,"<$1b>").replace(/\[(\/?)i\]/g,"<$1i>").replace(/\[(\/?)s\]/g,"<$1del>").replace(/\[(\/?)u\]/g,"<$1u>").replace(/\[(\/?)sub\]/g,"<$1sub>").replace(/\[(\/?)sup\]/g,"<$1sup>").replace(/\[m=([#a-zA-Z0-9]+)\]/g,'').replace(/\[(\/?)m\]/g,"<$1m>").replace(/\[c=?([#a-zA-Z0-9]+)\]/g,'').replace(/\[\/c\]/g,"")}},{key:"handleMS",value:function(e){if(e[4]!=he.chatmsg.content){document.getElementById("client_inner_chat").innerHTML="";for(var n={character:-1,preanim:escape(e[2]),nameplate:e[3],name:e[3],speaking:"(b)"+escape(e[4]),silent:"(a)"+escape(e[4]),content:this.prepChat(e[5]),side:e[6],sound:escape(e[7]),type:e[8],snddelay:e[10],objection:e[11],evidence:e[12],flip:e[13],flash:e[14],color:e[15],isnew:!0},t=0;tn.scrollHeight-600&&(n.scrollTop=n.scrollHeight)}},{key:"handleMC",value:function(e){var n=he.music;(n.pause(),n.src=d+e[1].toLowerCase(),n.play(),e[2]>=0)?F(this.chars[e[2]].name+" changed music to "+e[1]):F("The music was changed to "+e[1])}},{key:"handleRMC",value:function(e){he.music.pause(),he.music=new Audio(this.musicList[e[1]]);var n=he.music;n.totime=e[1],n.offset=(new Date).getTime()/1e3,n.addEventListener("loadedmetadata",function(){n.currentTime+=parseFloat(n.totime+((new Date).getTime()/1e3-n.offset)).toFixed(3),n.play()},!1)}},{key:"handleCI",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Character "+e[1],this.serv.send("AN#"+(e[1]/10+1)+"#%");for(var n=2;n'}},{key:"handleEM",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Music "+e[1],this.serv.send("AM#"+(e[1]/10+1)+"#%");for(var n=document.getElementById("client_musiclist"),t=2;t .health-bar").animate({width:n+"%"},500)):(this.hp[1]=e[2],$("#client_prosecutor_hp > .health-bar").animate({width:n+"%"},500))}},{key:"handleRT",value:function(e){"testimony1"==e[1]?this.testimonyID=1:this.testimonyID=2,he.initTestimonyUpdater()}},{key:"handleZZ",value:function(e){var n=document.getElementById("client_ooclog");n.innerHTML+="$Alert: "+Ae(de(e[1]))+"\r\n",n.scrollTop>n.scrollHeight-60&&(n.scrollTop=n.scrollHeight)}},{key:"handleID",value:function(e){this.playerID=e[1]}},{key:"handlePN",value:function(e){this.serv.send("askchaa#%")}},{key:"handleSI",value:function(e){u?this.serv.send("askchar2#%"):this.serv.send("RC#%")}},{key:"handleCharsCheck",value:function(e){document.getElementById("client_chartable").innerHTML="";for(var n=void 0,t=0;t",n.appendChild(o),t%8==0&&document.getElementById("client_chartable").appendChild(n)}}},{key:"handlePV",value:function(e){this.charID=e[3],document.getElementById("client_charselect").style.display="none";var n=this.me(),t=this.emotes,o=new XMLHttpRequest;o.withCredentials=!1,document.getElementById("client_emo").innerHTML="",o.open("GET",l+"characters/"+escape(this.me().name.toLowerCase())+"/char.ini",!0),o.responseType="text",o.onload=function(e){if(200==this.status){var o=this.responseText,a=f.parse(o);n.side=a.Options.side,K(n.side);for(var s=1;s'}R(1)}},o.send()}}]),e}(),y=function(){function e(){p(this,e),this.textnow="",this.chatmsg={isnew:!1,content:"",objection:"0",sound:"",startpreanim:!1,startspeaking:!1,side:null,color:"0",snddelay:0,preanimdelay:0},this.blip=new Audio(l+"sounds/general/sfx-blipmale.wav"),this.blip.volume=.5,this.blipChannels=new Array(6);for(var n=0;n0){var n="";1==me.testimonyID?n="witnesstestimony":2==me.testimonyID&&(n="crossexamination"),new Audio(me.resources[n].sfx).play(),this.testimonyTimer=0;var t=document.getElementById("client_testimony");t.src=me.resources[n].src,t.style.display="",this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60)}}},{key:"getAnimLength",value:function(e,n,t){var o=new XMLHttpRequest;o.open("GET",e,!0),o.responseType="arraybuffer",o.addEventListener("load",function(){var e=gify.getInfo(o.response);console.log(e.duration),n(e.duration,t)}),o.send()}},{key:"updateTestimony",value:function(){var e=this;this.testimonyTimer=this.testimonyTimer+60,1==me.testimonyID?this.testimonyTimer>=me.resources.witnesstestimony.duration?this.disposeTestimony():this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60):2==me.testimonyID?this.testimonyTimer>=me.resources.crossexamination.duration?this.disposeTestimony():this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60):this.disposeTestimony()}},{key:"disposeTestimony",value:function(){me.testimonyID=0,this.testimonyTimer=0,document.getElementById("client_testimony").style.display="none",clearTimeout(this.testimonyUpdater)}},{key:"updateText",value:function(){var e=this,n=document.getElementById("client_name"),t=document.getElementById("client_chat"),o=document.getElementById("client_char"),a=document.getElementById("client_evi"),s=document.getElementById("client_background"),i=document.getElementById("client_shout"),p=document.getElementById("client_inner_chat");if(1==this.chatmsg.flip?o.style.transform="scaleX(-1)":o.style.transform="scaleX(1)",this._animating&&(this.updater=setTimeout(function(){return e.updateText()},60)),this.chatmsg.isnew){s.style.backgroundColor="transparent",n.style.display="none",t.style.display="none",a.style.opacity="0",a.style.height="0%";var g={1:"holdit",2:"objection",3:"takethat"}[this.chatmsg.objection];void 0!==g?(i.src=me.resources[g].src,new Audio(l+"characters/"+this.chatmsg.name.toLowerCase()+"/"+g+".wav").play(),this.shoutTimer=850):this.shoutTimer=0,this.chatmsg.isnew=!1,this.chatmsg.startpreanim=!0}if(this.textTimer>=this.shoutTimer&&this.chatmsg.startpreanim)2==this.chatmsg.flash?(this.sfxaudio.pause(),this.sfxplayed=1,this.sfxaudio.src=l+"sounds/general/sfx-stab.wav",this.sfxaudio.play(),$("#client_gamewindow").effect("shake",{direction:"up"})):1==this.chatmsg.flash&&(s.style.backgroundColor="white",this.sfxaudio.pause(),this.sfxplayed=1,this.sfxaudio.src=l+"sounds/general/sfx-realization.wav",this.sfxaudio.play(),$("#client_gamewindow").effect("pulsate")),this.chatmsg.preanimdelay>0&&(i.src="misc/placeholder.gif",M(this.chatmsg.side),o.src=l+"characters/"+escape(this.chatmsg.name.toLowerCase())+"/"+this.chatmsg.preanim.toLowerCase()+".gif"),this.chatmsg.startpreanim=!1,this.chatmsg.startspeaking=!0;else if(this.textTimer>=this.shoutTimer+this.chatmsg.preanimdelay&&!this.chatmsg.startpreanim)if(this.chatmsg.startspeaking){this.chatmsg.evidence>0&&(a.style.backgroundImage="url('"+me.evidences[this.chatmsg.evidence-1].icon+"')","def"==this.chatmsg.side?(a.style.right="1.5em",a.style.left="initial",$("#client_evi").animate({height:"30%",opacity:1},250)):(a.style.right="initial",a.style.left="1.5em",$("#client_evi").animate({height:"30%",opacity:1},250))),n.style.display="block",n.style.fontSize=.7*n.offsetHeight+"px",n.innerHTML="

"+ce(this.chatmsg.nameplate)+"

",t.style.display="block",t.style.fontSize=.25*t.offsetHeight+"px";p.style.color={0:"#ffffff",1:"#00ff00",2:"#ff0000",3:"#ffaa00",4:"#0000ff",5:"#ffff00",6:"#aa00aa"}[this.chatmsg.color]||"#ffffff",this.chatmsg.startspeaking=!1,0==this.chatmsg.preanimdelay&&(i.src="misc/placeholder.gif",M(this.chatmsg.side)),o.src=l+"characters/"+escape(this.chatmsg.name.toLowerCase())+"/"+this.chatmsg.speaking.toLowerCase()+".gif",this.textnow==this.chatmsg.content&&(o.src=l+"characters/"+escape(this.chatmsg.name.toLowerCase())+"/"+this.chatmsg.silent.toLowerCase()+".gif",this._animating=!1,clearTimeout(this.updater))}else this.textnow!=this.chatmsg.content&&(" "!=this.chatmsg.content.charAt(this.textnow.length)&&(this.blipChannels[this.currentBlipChannel].play(),this.currentBlipChannel++,this.currentBlipChannel%=this.blipChannels.length),this.textnow=this.chatmsg.content.substring(0,this.textnow.length+1),p.innerHTML=this.textnow,this.textnow==this.chatmsg.content&&(this.textTimer=0,this._animating=!1,o.src=l+"characters/"+escape(this.chatmsg.name.toLowerCase())+"/"+this.chatmsg.silent.toLowerCase()+".gif",clearTimeout(this.updater)));!this.sfxplayed&&this.chatmsg.snddelay+this.shoutTimer>=this.textTimer&&(this.sfxaudio.pause(),this.sfxplayed=1,"0"!=this.chatmsg.sound&&"1"!=this.chatmsg.sound&&(this.sfxaudio.src=l+"sounds/general/"+escape(this.chatmsg.sound.toLowerCase())+".wav",this.sfxaudio.play())),this.textTimer=this.textTimer+60}}]),e}(),f=function(){function e(){p(this,e)}return o(e,null,[{key:"parse",value:function(e){var n={section:/^\s*\[\s*([^\]]*)\s*\]\s*$/,param:/^\s*([\w.\-_]+)\s*=\s*(.*?)\s*$/,comment:/^\s*;.*$/},t={},o=null;return e.split(/\r\n|\r|\n/).forEach(function(e){if(!n.comment.test(e)&&0!=e.length)if(n.param.test(e)){var a=e.match(n.param);o?t[o][a[1]]=a[2]:t[a[1]]=a[2]}else if(n.section.test(e)){var s=e.match(n.section);t[s[1]]={},o=s[1]}}),t}}]),e}();function S(e){13==e.keyCode&&(me.sendOOC(document.getElementById("client_oocinputbox").value),document.getElementById("client_oocinputbox").value="")}function I(e){if(13==e.keyCode){var n=me.me(),t=me.myEmote(),o=me.myEvidence(),a=me.flip?1:0,s=document.getElementById("textcolor").value,i="0",p="0";document.getElementById("sendsfx").checked&&(i=t.sfx,p=t.sfxdelay),me.sendIC(t.speaking,n.name,t.silent,document.getElementById("client_inputbox").value,n.side,i,t.zoom,p,h,o,a,A,s)}}function v(e){var n=document.getElementById("client_musiclist").value;me.sendMusicChange(n)}function J(e){var n=e.textContent;me.sendMusicChange(n)}function b(){he.music.volume=document.getElementById("client_mvolume").value/100}function T(){he.sfxaudio.volume=document.getElementById("client_svolume").value/100}function k(){he.setBlipVolume(document.getElementById("client_bvolume").value/100)}function w(e){me.sendLeaveRoom(),document.getElementById("client_charselect").style.display="block",document.getElementById("client_emo").innerHTML=""}function E(e){return e.onerror="",e.src="misc/placeholder.gif",!0}function B(e){return e.onerror="",e.src="/misc/placeholder.png",!0}function G(e,n,t){var o=new XMLHttpRequest;o.onreadystatechange=function(){4==this.readyState&&200==this.status?n(!0,t,e):n(!1,t,e)},o.open("GET",e,!0),o.send()}function M(e){var n=void 0,t=he.bgFolder();switch(document.getElementById("client_fg").style.display="none",document.getElementById("client_bench").style.display="none",e){case"def":document.getElementById("client_court").src=t+"defenseempty.png",document.getElementById("client_bench").style.display="block",G(t+"defensedesk.png",_,e),n="defense";break;case"pro":document.getElementById("client_court").src=t+"prosecutorempty.png",document.getElementById("client_bench").style.display="block",G(t+"defensedesk.png",_,e),n="prosecution";break;case"hld":document.getElementById("client_court").src=t+"helperstand.png",n="defense";break;case"hlp":document.getElementById("client_court").src=t+"prohelperstand.png",n="prosecution";break;case"wit":document.getElementById("client_court").src=t+"witnessempty.png",document.getElementById("client_bench").style.display="block",document.getElementById("client_bench").src=t+"estrado.png",n="prosecution";break;case"jud":document.getElementById("client_court").src=t+"judgestand.png",n="prosecution"}5==he.chatmsg.type&&(document.getElementById("client_bench").style.display="none",document.getElementById("client_court").src=l+"themes/default/"+n+"_speedlines.gif")}function _(e,n){var t=he.bgFolder();document.getElementById("client_bench").src="def"==n?e?t+"defensedesk.png":t+"bancodefensa.png":e?t+"prosecutiondesk.png":t+"bancoacusacion.png"}function P(){me.cleanup(),(me=new D(r))&&(c="join",document.getElementById("client_error").style.display="none")}function L(){me.joinServer()}function F(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:new Date,o=document.createElement("p"),a=document.createElement("span");if(a.id="iclog_name",a.appendChild(document.createTextNode(n)),o.appendChild(a),o.appendChild(document.createTextNode(e)),C.getMinutes()!==t.getMinutes()){var s=document.createElement("span");s.id="iclog_time",s.innerText=t.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"}),o.appendChild(s)}var i=document.getElementById("client_log");i.appendChild(o),i.scrollTop>i.scrollHeight-800&&(i.scrollTop=i.scrollHeight),C=new Date}function x(e){e<1e3?me.sendCharacter(e):(document.getElementById("client_charselect").style.display="none",document.getElementById("client_inputbox").style.display="none",document.getElementById("client_emo").style.display="none")}function R(e){-1!=me.selectedEmote&&(document.getElementById("emo_"+me.selectedEmote).src=me.myEmote().button_off),me.selectedEmote=e,document.getElementById("emo_"+e).src=me.myEmote().button_on}function O(e){if(me.selectedEvidence!==e){me.selectedEvidence>0&&(document.getElementById("evi_"+me.selectedEvidence).className="client_button"),document.getElementById("evi_"+e).className="client_button dark",me.selectedEvidence=e,document.getElementById("evi_name").value=me.evidences[e-1].name,document.getElementById("evi_desc").value=me.evidences[e-1].desc;var n=W("evi_select",me.evidences[e-1].filename);document.getElementById("evi_select").selectedIndex=n,0==n&&(document.getElementById("evi_filename").value=me.evidences[e-1].filename),j(),document.getElementById("evi_add").className="client_button hover_button inactive",document.getElementById("evi_edit").className="client_button hover_button",document.getElementById("evi_cancel").className="client_button hover_button",document.getElementById("evi_del").className="client_button hover_button"}else V()}function H(){var e=document.getElementById("evi_select");me.sendPE(document.getElementById("evi_name").value,document.getElementById("evi_desc").value,0==e.selectedIndex?document.getElementById("evi_filename").value:e.options[e.selectedIndex].text),V()}function N(){var e=document.getElementById("evi_select"),n=parseInt(me.selectedEvidence)-1;me.sendEE(n,document.getElementById("evi_name").value,document.getElementById("evi_desc").value,0==e.selectedIndex?document.getElementById("evi_filename").value:e.options[e.selectedIndex].text),V()}function U(){var e=parseInt(me.selectedEvidence)-1;me.sendDE(e),V()}function V(){me.selectedEvidence>0&&(document.getElementById("evi_"+me.selectedEvidence).className="client_button"),me.selectedEvidence=0,document.getElementById("evi_select").selectedIndex=0,j(),document.getElementById("evi_filename").value="",document.getElementById("evi_name").value="",document.getElementById("evi_desc").value="",document.getElementById("evi_icon").style.backgroundImage="url('misc/empty.png')",document.getElementById("evi_add").className="client_button hover_button",document.getElementById("evi_edit").className="client_button hover_button inactive",document.getElementById("evi_cancel").className="client_button hover_button inactive",document.getElementById("evi_del").className="client_button hover_button inactive"}function W(e,n){for(var t=document.getElementById(e),o=1;o/g,">").replace(/"/g,""").replace(/'/g,"'")}function le(e){return e.replace(/#/g,"").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}function de(e){return e.replace(//g,"#").replace(//g,"&").replace(//g,"%").replace(//g,"$")}function ue(e){var n=document.getElementById("client_encoding").value;if("unicode"==n)return e.replace(/[^\0-~]/g,function(e){return"\\u"+("000"+e.charCodeAt().toString(16)).slice(-4)});if("utf16"==n){for(var t=new ArrayBuffer(2*e.length),o=new Uint16Array(t),a=0,s=e.length;a 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 diff --git a/webAO/client.css b/webAO/client.css index a76ef6f..79c2d00 100644 --- a/webAO/client.css +++ b/webAO/client.css @@ -16,6 +16,14 @@ img { image-rendering: auto; } +.lm_content :link { + color: #4288f2; +} + +.lm_content :visited { + color: #a65bd4; +} + @keyframes error_blink { 0% { color: white; @@ -87,13 +95,15 @@ img { } #client_chartable { - height: 360px; - width: 320px; - margin: 0 auto; - vertical-align: middle; background: #eeeeee; } +#client_chartable_container { + display: flex; + flex-direction: column; + align-items: center; +} + .demothing { height: 60px; width: 60px; @@ -258,8 +268,6 @@ img { overflow-y: scroll; font-size: medium; background-color: #242424; - border: black; - border-style: solid; text-align: start; line-height: .85em; } @@ -319,6 +327,15 @@ img { background-size: contain; } +.evi_options { + display: inline-block; +} + +.evi_options label { + display: inline-block; + width: 6em; +} + #bg_preview { max-width: 150px; max-height: 112px; @@ -376,6 +393,7 @@ img { .client_button { padding: 1px; + cursor: pointer; } .client_button.hover_button.inactive { @@ -464,15 +482,16 @@ img { } .location-box { - border-style: double; + border-style: solid; background-color: #7B2900; min-width: 120px; margin: 5px; display: inline-block; - padding: 10px; - border-radius: 7px; + padding: 6px; + border-radius: 5px; border-color: white; - border-width: 3px; + border-width: 1px; + cursor: pointer; } .location-box:hover { diff --git a/webAO/client.html b/webAO/client.html index 3db7762..2e5b7d1 100644 --- a/webAO/client.html +++ b/webAO/client.html @@ -9,7 +9,6 @@ - @@ -17,8 +16,6 @@ - - @@ -39,9 +36,9 @@

- Testimony overlay + - +
@@ -74,14 +71,12 @@

- Flip - Flash Shake
- Action Commands + Actions