From 720744a29723a190e02f29084d79aba7fd6f1e0e Mon Sep 17 00:00:00 2001 From: Zack Rauen Date: Fri, 28 Jun 2019 01:36:05 -0400 Subject: [PATCH] emote updates --- data/emotes/bttv.json | 2 +- data/emotes/twitchglobal.json | 2 +- js/main.js | 46 ++-- src/builtins/emotes.js | 218 +++++++++--------- src/data/data.js | 10 +- src/data/emotes/info.js | 38 --- .../config.js => settings/emoteconfig.js} | 0 src/modules/datastore.js | 37 ++- src/modules/localemanager.js | 6 +- 9 files changed, 156 insertions(+), 203 deletions(-) delete mode 100644 src/data/emotes/info.js rename src/data/{emotes/config.js => settings/emoteconfig.js} (100%) diff --git a/data/emotes/bttv.json b/data/emotes/bttv.json index 6d46a1df..4e2a65df 100644 --- a/data/emotes/bttv.json +++ b/data/emotes/bttv.json @@ -1 +1 @@ -{"OhMyGoodness":"//cdn.betterttv.net/emote/54fa925e01e468494b85b54d/1x","PancakeMix":"//cdn.betterttv.net/emote/54fa927801e468494b85b54e/1x","PedoBear":"//cdn.betterttv.net/emote/54fa928f01e468494b85b54f/1x","PokerFace":"//cdn.betterttv.net/emote/54fa92a701e468494b85b550/1x","RageFace":"//cdn.betterttv.net/emote/54fa92d701e468494b85b552/1x","RebeccaBlack":"//cdn.betterttv.net/emote/54fa92ee01e468494b85b553/1x",":tf:":"//cdn.betterttv.net/emote/54fa8f1401e468494b85b537/1x","aPliS":"//cdn.betterttv.net/emote/54fa8f4201e468494b85b538/1x","CiGrip":"//cdn.betterttv.net/emote/54fa8fce01e468494b85b53c/1x","CHAccepted":"//cdn.betterttv.net/emote/54fa8fb201e468494b85b53b/1x","FuckYea":"//cdn.betterttv.net/emote/54fa90d601e468494b85b544/1x","DatSauce":"//cdn.betterttv.net/emote/54fa903b01e468494b85b53f/1x","ForeverAlone":"//cdn.betterttv.net/emote/54fa909b01e468494b85b542/1x","GabeN":"//cdn.betterttv.net/emote/54fa90ba01e468494b85b543/1x","HailHelix":"//cdn.betterttv.net/emote/54fa90f201e468494b85b545/1x","HerbPerve":"//cdn.betterttv.net/emote/54fa913701e468494b85b546/1x","iDog":"//cdn.betterttv.net/emote/54fa919901e468494b85b548/1x","rStrike":"//cdn.betterttv.net/emote/54fa930801e468494b85b554/1x","ShoopDaWhoop":"//cdn.betterttv.net/emote/54fa932201e468494b85b555/1x","SwedSwag":"//cdn.betterttv.net/emote/54fa9cc901e468494b85b565/1x","M&Mjc":"//cdn.betterttv.net/emote/54fab45f633595ca4c713abc/1x","bttvNice":"//cdn.betterttv.net/emote/54fab7d2633595ca4c713abf/1x","TopHam":"//cdn.betterttv.net/emote/54fa934001e468494b85b556/1x","TwaT":"//cdn.betterttv.net/emote/54fa935601e468494b85b557/1x","WhatAYolk":"//cdn.betterttv.net/emote/54fa93d001e468494b85b559/1x","WatChuSay":"//cdn.betterttv.net/emote/54fa99b601e468494b85b55d/1x","Blackappa":"//cdn.betterttv.net/emote/54faa50d01e468494b85b578/1x","DogeWitIt":"//cdn.betterttv.net/emote/54faa52f01e468494b85b579/1x","BadAss":"//cdn.betterttv.net/emote/54faa4f101e468494b85b577/1x","SavageJerky":"//cdn.betterttv.net/emote/54fb603201abde735115ddb5/1x","Zappa":"//cdn.betterttv.net/emote/5622aaef3286c42e57d8e4ab/1x","tehPoleCat":"//cdn.betterttv.net/emote/566ca11a65dbbdab32ec0558/1x","AngelThump":"//cdn.betterttv.net/emote/566ca1a365dbbdab32ec055b/1x","Kaged":"//cdn.betterttv.net/emote/54fbf11001abde735115de66/1x","HHydro":"//cdn.betterttv.net/emote/54fbef6601abde735115de57/1x","TaxiBro":"//cdn.betterttv.net/emote/54fbefeb01abde735115de5b/1x","BroBalt":"//cdn.betterttv.net/emote/54fbf00a01abde735115de5c/1x","ButterSauce":"//cdn.betterttv.net/emote/54fbf02f01abde735115de5d/1x","BaconEffect":"//cdn.betterttv.net/emote/54fbf05a01abde735115de5e/1x","SuchFraud":"//cdn.betterttv.net/emote/54fbf07e01abde735115de5f/1x","CandianRage":"//cdn.betterttv.net/emote/54fbf09c01abde735115de61/1x","She'llBeRight":"//cdn.betterttv.net/emote/54fbefc901abde735115de5a/1x","OhhhKee":"//cdn.betterttv.net/emote/54fbefa901abde735115de59/1x","D:":"//cdn.betterttv.net/emote/55028cd2135896936880fdd7/1x","SexPanda":"//cdn.betterttv.net/emote/5502874d135896936880fdd2/1x","(poolparty)":"//cdn.betterttv.net/emote/5502883d135896936880fdd3/1x",":'(":"//cdn.betterttv.net/emote/55028923135896936880fdd5/1x","(puke)":"//cdn.betterttv.net/emote/550288fe135896936880fdd4/1x","bttvWink":"//cdn.betterttv.net/emote/550292c0135896936880fdef/1x","bttvAngry":"//cdn.betterttv.net/emote/550291a3135896936880fde3/1x","bttvConfused":"//cdn.betterttv.net/emote/550291be135896936880fde4/1x","bttvCool":"//cdn.betterttv.net/emote/550291d4135896936880fde5/1x","bttvHappy":"//cdn.betterttv.net/emote/55029200135896936880fde7/1x","bttvSad":"//cdn.betterttv.net/emote/5502925d135896936880fdea/1x","bttvSleep":"//cdn.betterttv.net/emote/55029272135896936880fdeb/1x","bttvSurprised":"//cdn.betterttv.net/emote/55029288135896936880fdec/1x","bttvTongue":"//cdn.betterttv.net/emote/5502929b135896936880fded/1x","bttvUnsure":"//cdn.betterttv.net/emote/550292ad135896936880fdee/1x","bttvGrin":"//cdn.betterttv.net/emote/550291ea135896936880fde6/1x","bttvHeart":"//cdn.betterttv.net/emote/55029215135896936880fde8/1x","bttvTwink":"//cdn.betterttv.net/emote/55029247135896936880fde9/1x","VisLaud":"//cdn.betterttv.net/emote/550352766f86a5b26c281ba2/1x","(chompy)":"//cdn.betterttv.net/emote/550b225fff8ecee922d2a3b2/1x","SoSerious":"//cdn.betterttv.net/emote/5514afe362e6bd0027aede8a/1x","BatKappa":"//cdn.betterttv.net/emote/550b6b07ff8ecee922d2a3e7/1x","KaRappa":"//cdn.betterttv.net/emote/550b344bff8ecee922d2a3c1/1x","YetiZ":"//cdn.betterttv.net/emote/55189a5062e6bd0027aee082/1x","miniJulia":"//cdn.betterttv.net/emote/552d2fc2236a1aa17a996c5b/1x","FishMoley":"//cdn.betterttv.net/emote/566ca00f65dbbdab32ec0544/1x","Hhhehehe":"//cdn.betterttv.net/emote/566ca02865dbbdab32ec0547/1x","KKona":"//cdn.betterttv.net/emote/566ca04265dbbdab32ec054a/1x","OhGod":"//cdn.betterttv.net/emote/566ca07965dbbdab32ec0552/1x","PoleDoge":"//cdn.betterttv.net/emote/566ca09365dbbdab32ec0555/1x","motnahP":"//cdn.betterttv.net/emote/55288e390fa35376704a4c7a/1x","sosGame":"//cdn.betterttv.net/emote/553b48a21f145f087fc15ca6/1x","CruW":"//cdn.betterttv.net/emote/55471c2789d53f2d12781713/1x","RarePepe":"//cdn.betterttv.net/emote/555015b77676617e17dd2e8e/1x","iamsocal":"//cdn.betterttv.net/emote/54fbef8701abde735115de58/1x","haHAA":"//cdn.betterttv.net/emote/555981336ba1901877765555/1x","FeelsBirthdayMan":"//cdn.betterttv.net/emote/55b6524154eefd53777b2580/1x","RonSmug":"//cdn.betterttv.net/emote/55f324c47f08be9f0a63cce0/1x","KappaCool":"//cdn.betterttv.net/emote/560577560874de34757d2dc0/1x","FeelsBadMan":"//cdn.betterttv.net/emote/566c9fc265dbbdab32ec053b/1x","BasedGod":"//cdn.betterttv.net/emote/566c9eeb65dbbdab32ec052b/1x","bUrself":"//cdn.betterttv.net/emote/566c9f3b65dbbdab32ec052e/1x","ConcernDoge":"//cdn.betterttv.net/emote/566c9f6365dbbdab32ec0532/1x","FapFapFap":"//cdn.betterttv.net/emote/566c9f9265dbbdab32ec0538/1x","FeelsGoodMan":"//cdn.betterttv.net/emote/566c9fde65dbbdab32ec053e/1x","FireSpeed":"//cdn.betterttv.net/emote/566c9ff365dbbdab32ec0541/1x","NaM":"//cdn.betterttv.net/emote/566ca06065dbbdab32ec054e/1x","SourPls":"//cdn.betterttv.net/emote/566ca38765dbbdab32ec0560/1x","LuL":"//cdn.betterttv.net/emote/567b00c61ddbe1786688a633/1x","SaltyCorn":"//cdn.betterttv.net/emote/56901914991f200c34ffa656/1x","FCreep":"//cdn.betterttv.net/emote/56d937f7216793c63ec140cb/1x","monkaS":"//cdn.betterttv.net/emote/56e9f494fff3cc5c35e5287e/1x","VapeNation":"//cdn.betterttv.net/emote/56f5be00d48006ba34f530a4/1x","ariW":"//cdn.betterttv.net/emote/56fa09f18eff3b595e93ac26/1x","notsquishY":"//cdn.betterttv.net/emote/5709ab688eff3b595e93c595/1x","FeelsAmazingMan":"//cdn.betterttv.net/emote/5733ff12e72c3c0814233e20/1x","DuckerZ":"//cdn.betterttv.net/emote/573d38b50ffbf6cc5cc38dc9/1x","SqShy":"//cdn.betterttv.net/emote/59cf182fcbe2693d59d7bf46/1x","Wowee":"//cdn.betterttv.net/emote/58d2e73058d8950a875ad027/1x"} \ No newline at end of file +{"OhMyGoodness":"54fa925e01e468494b85b54d","PancakeMix":"54fa927801e468494b85b54e","PedoBear":"54fa928f01e468494b85b54f","PokerFace":"54fa92a701e468494b85b550","RageFace":"54fa92d701e468494b85b552","RebeccaBlack":"54fa92ee01e468494b85b553",":tf:":"54fa8f1401e468494b85b537","aPliS":"54fa8f4201e468494b85b538","CiGrip":"54fa8fce01e468494b85b53c","CHAccepted":"54fa8fb201e468494b85b53b","FuckYea":"54fa90d601e468494b85b544","DatSauce":"54fa903b01e468494b85b53f","ForeverAlone":"54fa909b01e468494b85b542","GabeN":"54fa90ba01e468494b85b543","HailHelix":"54fa90f201e468494b85b545","HerbPerve":"54fa913701e468494b85b546","iDog":"54fa919901e468494b85b548","rStrike":"54fa930801e468494b85b554","ShoopDaWhoop":"54fa932201e468494b85b555","SwedSwag":"54fa9cc901e468494b85b565","M&Mjc":"54fab45f633595ca4c713abc","bttvNice":"54fab7d2633595ca4c713abf","TopHam":"54fa934001e468494b85b556","TwaT":"54fa935601e468494b85b557","WhatAYolk":"54fa93d001e468494b85b559","WatChuSay":"54fa99b601e468494b85b55d","Blackappa":"54faa50d01e468494b85b578","DogeWitIt":"54faa52f01e468494b85b579","BadAss":"54faa4f101e468494b85b577","SavageJerky":"54fb603201abde735115ddb5","Zappa":"5622aaef3286c42e57d8e4ab","tehPoleCat":"566ca11a65dbbdab32ec0558","AngelThump":"566ca1a365dbbdab32ec055b","Kaged":"54fbf11001abde735115de66","HHydro":"54fbef6601abde735115de57","TaxiBro":"54fbefeb01abde735115de5b","BroBalt":"54fbf00a01abde735115de5c","ButterSauce":"54fbf02f01abde735115de5d","BaconEffect":"54fbf05a01abde735115de5e","SuchFraud":"54fbf07e01abde735115de5f","CandianRage":"54fbf09c01abde735115de61","She'llBeRight":"54fbefc901abde735115de5a","OhhhKee":"54fbefa901abde735115de59","D:":"55028cd2135896936880fdd7","SexPanda":"5502874d135896936880fdd2","(poolparty)":"5502883d135896936880fdd3",":'(":"55028923135896936880fdd5","(puke)":"550288fe135896936880fdd4","bttvWink":"550292c0135896936880fdef","bttvAngry":"550291a3135896936880fde3","bttvConfused":"550291be135896936880fde4","bttvCool":"550291d4135896936880fde5","bttvHappy":"55029200135896936880fde7","bttvSad":"5502925d135896936880fdea","bttvSleep":"55029272135896936880fdeb","bttvSurprised":"55029288135896936880fdec","bttvTongue":"5502929b135896936880fded","bttvUnsure":"550292ad135896936880fdee","bttvGrin":"550291ea135896936880fde6","bttvHeart":"55029215135896936880fde8","bttvTwink":"55029247135896936880fde9","VisLaud":"550352766f86a5b26c281ba2","(chompy)":"550b225fff8ecee922d2a3b2","SoSerious":"5514afe362e6bd0027aede8a","BatKappa":"550b6b07ff8ecee922d2a3e7","KaRappa":"550b344bff8ecee922d2a3c1","YetiZ":"55189a5062e6bd0027aee082","miniJulia":"552d2fc2236a1aa17a996c5b","FishMoley":"566ca00f65dbbdab32ec0544","Hhhehehe":"566ca02865dbbdab32ec0547","KKona":"566ca04265dbbdab32ec054a","OhGod":"566ca07965dbbdab32ec0552","PoleDoge":"566ca09365dbbdab32ec0555","motnahP":"55288e390fa35376704a4c7a","sosGame":"553b48a21f145f087fc15ca6","CruW":"55471c2789d53f2d12781713","RarePepe":"555015b77676617e17dd2e8e","iamsocal":"54fbef8701abde735115de58","haHAA":"555981336ba1901877765555","FeelsBirthdayMan":"55b6524154eefd53777b2580","RonSmug":"55f324c47f08be9f0a63cce0","KappaCool":"560577560874de34757d2dc0","FeelsBadMan":"566c9fc265dbbdab32ec053b","BasedGod":"566c9eeb65dbbdab32ec052b","bUrself":"566c9f3b65dbbdab32ec052e","ConcernDoge":"566c9f6365dbbdab32ec0532","FapFapFap":"566c9f9265dbbdab32ec0538","FeelsGoodMan":"566c9fde65dbbdab32ec053e","FireSpeed":"566c9ff365dbbdab32ec0541","NaM":"566ca06065dbbdab32ec054e","SourPls":"566ca38765dbbdab32ec0560","LuL":"567b00c61ddbe1786688a633","SaltyCorn":"56901914991f200c34ffa656","FCreep":"56d937f7216793c63ec140cb","monkaS":"56e9f494fff3cc5c35e5287e","VapeNation":"56f5be00d48006ba34f530a4","ariW":"56fa09f18eff3b595e93ac26","notsquishY":"5709ab688eff3b595e93c595","FeelsAmazingMan":"5733ff12e72c3c0814233e20","DuckerZ":"573d38b50ffbf6cc5cc38dc9","SqShy":"59cf182fcbe2693d59d7bf46","Wowee":"58d2e73058d8950a875ad027"} \ No newline at end of file diff --git a/data/emotes/twitchglobal.json b/data/emotes/twitchglobal.json index 227aaae0..4bbecb06 100644 --- a/data/emotes/twitchglobal.json +++ b/data/emotes/twitchglobal.json @@ -1 +1 @@ -{"4Head":{"description":"This is the face of a popular Twitch streamer. twitch.tv\/cadburryftw","image_id":354,"first_seen":null},"ANELE":{"description":"This is the face of Twitch Partnerships Lead Anele. twitch.tv\/anele","image_id":3792,"first_seen":null},"ArgieB8":{"description":"ArgieB8 is the face of Twitch Staff member Ignacio Estanga. twitch.tv\/theargietv","image_id":51838,"first_seen":null},"ArsonNoSexy":{"description":"This is the face of streamer ArSon. twitch.tv\/arson","image_id":50,"first_seen":null},"AsianGlow":{"description":"This is the face of Twitch staff member Eliene Sun. twitch.tv\/eleinetv","image_id":74,"first_seen":null},"AthenaPMS":{"description":"This is the face of Twitch staff member & PMS clan founder Amy Brady.","image_id":32035,"first_seen":null},"BabyRage":{"description":"Common meme spurring from Dota 2 professional player and Twitch streamer Arteezy (RTZ) who gets mad when bad things happen in his games, and rages.","image_id":22639,"first_seen":null},"BatChest":{"description":"The BatChest face belongs JhnnyCrwsh, part of the Twitch moderation team. It refers to how his chest hair looks like the Bat Symbol, and came about from a dumb highlight on his channel. twitch.tv\/JhnnyCrwsh","image_id":1905,"first_seen":null},"BCouch":{"description":null,"image_id":83536,"first_seen":null},"BCWarrior":{"description":"This is the face of streamer Zeke. twitch.tv\/ezekiel_iii","image_id":30,"first_seen":null},"BibleThump":{"description":"This is an icon from the game The Binding of Isaac.","image_id":86,"first_seen":null},"BigBrother":{"description":null,"image_id":1904,"first_seen":null},"BionicBunion":{"description":"This is the \"icon\" of Twitch staff member, Russell aka Horror.","image_id":24,"first_seen":null},"BlargNaut":{"description":"This is the face of streamer Aria Blarg. twitch.tv\/ariablarg","image_id":38,"first_seen":null},"bleedPurple":{"description":null,"image_id":62835,"first_seen":null},"BloodTrail":{"description":"This is an icon of the main character in the game Super Meat Boy.","image_id":69,"first_seen":null},"BORT":{"description":"This is the face of Bart, Ambassador at Hi-Rez Studios. He goes by the nickname, Bort","image_id":243,"first_seen":null},"BrainSlug":{"description":"This is a Brain Slug. It controls your thoughts. Originally this was the face of Bwana, part of the Twitch moderation team. It was changed to be an actual Brain Slug due to racist abuse of this emote. More info: twitch.tv\/bwana\/c\/2151897","image_id":881,"first_seen":null},"BrokeBack":{"description":"This is the face of streamer Alan. twitch.tv\/seriousgaming","image_id":4057,"first_seen":null},"BuddhaBar":{"description":"This is the face of Yoh, a JavaScript nerd who works on social features for Twitch.","image_id":27602,"first_seen":null},"ChefFrank":{"description":null,"image_id":90129,"first_seen":null},"cmonBruh":{"description":null,"image_id":84608,"first_seen":null},"CoolCat":{"description":null,"image_id":58127,"first_seen":null},"CorgiDerp":{"description":"This is Lana the corgi.","image_id":49106,"first_seen":null},"CougarHunt":{"description":"This is the face of former Justin.tv staff member, Phil.","image_id":21,"first_seen":null},"DAESuppy":{"description":"This is the face of famous Starcraft 2 player, EG.Suppy.","image_id":973,"first_seen":null},"DansGame":{"description":"This is the face of Dan. twitch.tv\/dansgaming ","image_id":33,"first_seen":null},"DatSheffy":{"description":"This is the face of Twitch staff member Sheffy. twitch.tv\/sheffy","image_id":170,"first_seen":null},"DBstyle":{"description":"This is the face of streamer and composer Dannybstyle. twitch.tv\/dannybstyle","image_id":73,"first_seen":null},"deExcite":{"description":"This is a promotional emote for Deus Ex: Mankind Divided.","image_id":46249,"first_seen":null},"deIlluminati":{"description":"This is a promotional emote for Deus Ex: Mankind Divided.","image_id":46248,"first_seen":null},"DendiFace":{"description":"This is the face of Danil \"Dendi\" Ishutin a professional Dota2 player. The emote is a temporary (https:\/\/twitter.com\/Trancez0r\/status\/534501083796611073) prize given to the winner of the Twitch Doube Trouble tournament. Although Dendi's team didn't actually win the tournament, the prize was graciously(?) given to Dendi by the winner. (https:\/\/twitter.com\/Trancez0r\/status\/534501692285673472). The code itself is reference to what trolls use for the WinWaker emote.","image_id":58135,"first_seen":null},"DogFace":{"description":"DogFace is the face of Kyle Pulver, an indie game developer that added :dogface: to Steam.","image_id":1903,"first_seen":null},"DOOMGuy":{"description":"This is a promotional emote for Bethesda's upcoming reboot of the DOOM franchise.","image_id":54089,"first_seen":null},"duDudu":{"description":"This is a representation of the popular song Sandstorm by Darude. The code is commonly spammed in chat whenever Sandstorm is played.","image_id":62834,"first_seen":null},"EagleEye":{"description":"This is the face of Twitch staff member Jacob.","image_id":20,"first_seen":null},"EleGiggle":{"description":"This is the face of Twitch streamer Elegy of Games. twitch.tv\/elegyofgames","image_id":4339,"first_seen":null},"FailFish":{"description":"This is the face of streamer SpamFish. twitch.tv\/spamfish","image_id":360,"first_seen":null},"FPSMarksman":{"description":"This is the face of Nick Overton, streamer and former Twitch staff member. twitch.tv\/immarksman","image_id":42,"first_seen":null},"FrankerZ":{"description":"This is the face of Frank the dog of Twitch staff member Ernest Le. Brother of RalpherZ.","image_id":65,"first_seen":null},"FreakinStinkin":{"description":"This is the face of GQ, part of the Twitch moderation team. twitch.tv\/thegreatgq","image_id":39,"first_seen":null},"FUNgineer":{"description":"This is the face of Twitch engineer, Jon. twitch.tv\/jbrhymer","image_id":244,"first_seen":null},"FunRun":{"description":"This is the icon of Justin Ignacio aka TheGunrun, Twitch staff member and savior of eSports! twitch.tv\/thegunrun","image_id":48,"first_seen":null},"FuzzyOtterOO":{"description":"This is the icon of Twitch staff member Justin Wong. twitch.tv\/fuzzyotterballs","image_id":168,"first_seen":null},"GingerPower":{"description":"This is the face of Dylan Reichstadt. He works for Twitch in quality assurance. twitch.tv\/dylanlive","image_id":32,"first_seen":null},"GrammarKing":{"description":"This is the face of Twitch employee\/KBMOD writer Vol1tion. twitch.tv\/vol1tion","image_id":3632,"first_seen":null},"HassaanChop":{"description":"This is the face of Twitch software engineer Hassaan. This emote was at one point known as 'DatHass'.","image_id":20225,"first_seen":null},"HassanChop":{"description":"This is the face of Twitch Staff member Hassan. twitch.tv\/hassan","image_id":68,"first_seen":null},"HeyGuys":{"description":"This is the face of Selen, director of recruiting at Twitch.","image_id":30259,"first_seen":null},"HotPokket":{"description":"This is the face of streamer Pokket. twitch.tv\/pokket","image_id":357,"first_seen":null},"HumbleLife":{"description":"This icon was added for Extra Life 2014 where gamers raise money for Children's Miracle Network Hospitals. Find out more at extra-life.org.","image_id":46881,"first_seen":null},"ItsBoshyTime":{"description":"This is an icon from the game I Wanna Be the Boshy.","image_id":169,"first_seen":null},"Jebaited":{"description":"This is the face of Jebailey.","image_id":90,"first_seen":null},"JKanStyle":{"description":"This is the face of Justin Kan, co-founder of Justin.tv and Twitch.","image_id":15,"first_seen":null},"JonCarnage":{"description":"This is the face of Twitch staff member and caster Jon Carnage.","image_id":26,"first_seen":null},"KAPOW":{"description":"This is a promotional emote for the game Infinite Crisis.","image_id":9803,"first_seen":null},"Kappa":{"description":"This is the face of Josh, a former Justin.tv employee. Kappa is generally used to indicate sarcasm or trolling.","image_id":25,"first_seen":null},"KappaClaus":{"description":"This is Kappa with a Santa hat added for Christmas 2015.","image_id":74510,"first_seen":null},"KappaPride":{"description":"On June 26, 2015, the Supreme Court of the United States ruled that same-sex couples can marry nationwide. You can read the full decision at: http:\/\/www.supremecourt.gov\/opinions\/14pdf\/14-556_3204.pdf The rainbow coloring is a symbol of the LGBT pride movement.","image_id":55338,"first_seen":null},"KappaRoss":{"description":"In honor of the late Bob Ross's 73rd birthday and the official launch of the Creative directory, Twitch created this emote - a mashup of Kappa and Bob's distinctive hair. Twitch also ran a non-stop marathon of all 403 episodes of \"The Joy of Painting\" on twitch.tv\/bobross","image_id":70433,"first_seen":null},"KappaWealth":{"description":null,"image_id":81997,"first_seen":null},"Keepo":{"description":"Keepo is Kappa stylized as the hero Meepo from DotA\/DotA 2.","image_id":1902,"first_seen":null},"KevinTurtle":{"description":"This is the face of Klutch, part of the Twitch partnership team. twitch.tv\/klutch","image_id":40,"first_seen":null},"Kippa":{"description":null,"image_id":1901,"first_seen":null},"Kreygasm":{"description":"This is the face of streamer Kreyg. twitch.tv\/kreyg","image_id":41,"first_seen":null},"Mau5":{"description":"The Mau5 emote belongs to music producer Deadmau5. twitch.tv\/deadmau5","image_id":30134,"first_seen":null},"mcaT":{"description":"This is the logo of the music label Monstercat. twitch.tv\/monstercat monstercat.com","image_id":35063,"first_seen":null},"MikeHogu":{"description":null,"image_id":81636,"first_seen":null},"MingLee":{"description":"The face of Chris Mead, the Director of Partnerships EMEA at Twitch.","image_id":68856,"first_seen":null},"MrDestructoid":{"description":"This is the mascot of the gaming website Destructoid. twitch.tv\/destructoid","image_id":28,"first_seen":null},"MVGame":{"description":"This is the face of streamer MAN. twitch.tv\/manvsgame","image_id":29,"first_seen":null},"NinjaTroll":{"description":"This is the face of streamer Ninja. twitch.tv\/ninja","image_id":45,"first_seen":null},"NomNom":{"description":null,"image_id":90075,"first_seen":null},"NoNoSpot":{"description":"This is the face of streamer Towelliee. twitch.tv\/towelliee","image_id":44,"first_seen":null},"NotATK":{"description":null,"image_id":34875,"first_seen":null},"NotLikeThis":{"description":"This is the face of Twitch staff member Ben Swartz. twitch.tv\/bensw","image_id":58765,"first_seen":null},"OhMyDog":{"description":"This is the face of the dog, Tank.","image_id":81103,"first_seen":null},"OMGScoots":{"description":"This is the face of SirScoots, a well known member of the eSports community.","image_id":91,"first_seen":null},"OneHand":{"description":"This is the face of streamer EdwardStarcraft.","image_id":66,"first_seen":null},"OpieOP":{"description":"This is the face of Jason Babo. Strategic Partnerships at TwitchTV and a Web Developer. twitch.tv\/opie","image_id":356,"first_seen":null},"OptimizePrime":{"description":"This is the face of Emmett Shear, co-founder of Justin.tv and CEO of Twitch.","image_id":16,"first_seen":null},"OSfrog":{"description":"This is a promotional emote for the Old Spice Nature Adventure where Twitch chat controlled a man's adventures in nature.","image_id":81248,"first_seen":null},"OSkomodo":{"description":null,"image_id":81273,"first_seen":null},"OSsloth":{"description":"This is a promotional emote for the Old Spice Nature Adventure where Twitch chat controlled a man's adventures in nature.","image_id":81249,"first_seen":null},"panicBasket":{"description":"This emote was voted into existence by the Twitch Townhall attendees during PAX Prime 2014. It is inspired by the phrase \"PICNIC\" (based on PANIC) spammed in chat when a stream goes offline during a broadcast.","image_id":22998,"first_seen":null},"PanicVis":{"description":"This is the emote of Visual, part of the Twitch moderation team. Twitch.tv\/visual","image_id":3668,"first_seen":null},"PartyTime":{"description":"This is the face of Pluto, a partnership manager for Twitch. twitch.tv\/pluto","image_id":76171,"first_seen":null},"PazPazowitz":{"description":"This is the faces of Justin.tv streamer Paz. justin.tv\/paz","image_id":19,"first_seen":null},"PeoplesChamp":{"description":"The PeoplesChamp emote belongs to Bobby 'Scar' of the smash community and of MeleeItOnMe. twitch.tv\/meleeitonme","image_id":3412,"first_seen":null},"PermaSmug":{"description":"This is the face of Aaron Krasnov, a product manager at Twitch, captured during their AHGL Dota team photo.","image_id":27509,"first_seen":null},"PeteZaroll":{"description":null,"image_id":81243,"first_seen":null},"PeteZarollTie":{"description":null,"image_id":81244,"first_seen":null},"PicoMause":{"description":"This is the face of streamer PicoMause. twitch.tv\/picomause","image_id":27,"first_seen":null},"PipeHype":{"description":"The PipeHype emote is of Pipe, part of the Twitch support team. twitch.tv\/pipe","image_id":4240,"first_seen":null},"PJSalt":{"description":" PJ stands for PeacefulJay, a Fighting Game Community (FGC) stream: twitch.tv\/peacefuljay and Salt is a term used in the FGC to describe someone who is upset.","image_id":36,"first_seen":null},"PMSTwin":{"description":"This is the face of Twitch staff member & PMS clan founder Amber Dalton.","image_id":92,"first_seen":null},"PogChamp":{"description":"This is the face of streamer Gootecks. twitch.tv\/gootecks","image_id":88,"first_seen":null},"Poooound":{"description":"This is the face of streamer RSQViper. twitch.tv\/RSQViper","image_id":358,"first_seen":null},"PraiseIt":{"description":"This is the icon for the Helix Fossil item in Pokemon games. It became a meme as part of the TwitchPlaysPokemon streams.","image_id":38586,"first_seen":null},"PRChase":{"description":"This is the face of Twitch PR Director, Chase.","image_id":28328,"first_seen":null},"PunchTrees":{"description":"This is an icon of Steve, the ingame persona in the game Minecraft. One of the first objectives in Minecraft is to punch trees to get wood.","image_id":47,"first_seen":null},"PuppeyFace":{"description":"This is the face of Clement \"Puppey\" Ivanov a professional Dota2 player. twitch.tv\/puppey","image_id":58136,"first_seen":null},"RaccAttack":{"description":"This is the avatar of Nick aka BlackLightAttack. Formerly of his personal channel, twitch.tv\/blacklightattack, where raccoons are a recurring theme.","image_id":27679,"first_seen":null},"RalpherZ":{"description":"This is the face of Ralph the dog of Twitch staff member Ernest Le. Brother of FrankerZ.","image_id":1900,"first_seen":null},"RedCoat":{"description":"This is the face of former Justin.tv staff member, Bill.","image_id":22,"first_seen":null},"ResidentSleeper":{"description":"This is the face of Oddler. Oddler was doing a 72 hour Resident Evil marathon when he fell asleep about 66 hours into it. His stream with him sleeping became massively popular and at one point the viewer count even reached 13,000. twitch.tv\/oddler","image_id":245,"first_seen":null},"riPepperonis":{"description":"This is a symbol for \"Rest In Pepperonis\". \"Rest In Pepperonis\" is a middle of the herd term used to describe a death, usually on a video game.","image_id":62833,"first_seen":null},"RitzMitz":{"description":"The emote RitzMitz is of RitzPlays. twitch.tv\/ritzplays","image_id":4338,"first_seen":null},"RuleFive":{"description":"This is the face of streamer Chuk. twitch.tv\/whenchukattacks","image_id":361,"first_seen":null},"SeemsGood":{"description":"The face of staff member Paul Diamond, twitch.tv\/bearcat","image_id":64138,"first_seen":null},"ShadyLulu":{"description":"The face of Twitch Staff member Lauren Etner from Events\/Marketing","image_id":52492,"first_seen":null},"ShazBotstix":{"description":"This is the face of Ben Goldhaber, Twitch staff member and streamer. twitch.tv\/fishstix","image_id":87,"first_seen":null},"ShibeZ":{"description":"This is a Dogecoin. en.wikipedia.org\/wiki\/Dogecoin","image_id":27903,"first_seen":null},"SmoocherZ":{"description":"This is the emote of Jordan Tayer aka Soma, Influencer Relations Manager at Twitch. twitch.tv\/soma","image_id":89945,"first_seen":null},"SMOrc":{"description":"This is an icon from the game Space Marine.","image_id":52,"first_seen":null},"SMSkull":{"description":"This is an icon from the game Space Marine.","image_id":51,"first_seen":null},"SoBayed":{"description":"This is the face of SONOS, Twitch staff member and streamer. twitch.tv\/s0n0s","image_id":1906,"first_seen":null},"SoonerLater":{"description":"This is the face of Sooner, a popular Twitch streamer. twitch.tv\/lolsooner","image_id":355,"first_seen":null},"SriHead":{"description":null,"image_id":14706,"first_seen":null},"SSSsss":{"description":"This is an icon of a Creeper from the game Minecraft. They blow stuff up.","image_id":46,"first_seen":null},"StinkyCheese":{"description":null,"image_id":90076,"first_seen":null},"StoneLightning":{"description":"This is the face of Michael Seibel, co-founder of Justin.tv.","image_id":17,"first_seen":null},"StrawBeary":{"description":"This is the icon of streamer LordKat. twitch.tv\/lordkat","image_id":37,"first_seen":null},"SuperVinlin":{"description":"This is the face of Twitch staff member Kevin Lin.","image_id":31,"first_seen":null},"SwiftRage":{"description":"This is the face of streamer Swiftor. twitch.tv\/swiftor","image_id":34,"first_seen":null},"TF2John":{"description":"This is the face of stream and Twitch staff member, John. twitch.tv\/synwyn","image_id":1899,"first_seen":null},"TheRinger":{"description":"This is the face of Kyle Vogt, co-founder of Justin.tv.","image_id":18,"first_seen":null},"TheTarFu":{"description":"This is the face of streamer Tarfu. twitch.tv\/tarfu","image_id":70,"first_seen":null},"TheThing":{"description":"The emote \"TheThing\" is the face of Geoff \"iNcontroL\" Robinson. twitch.tv\/incontroltv","image_id":7427,"first_seen":null},"ThunBeast":{"description":"ThunBeast belongs to Twitch caster ThunderCast twitch.tv\/Thundercast","image_id":1898,"first_seen":null},"TinyFace":{"description":"This is the face of streamer, Foom. twitch.tv\/king_foom","image_id":67,"first_seen":null},"TooSpicy":{"description":"This is the face of Miguel, part of the Twitch moderation team. twitch.tv\/sournothardcore SourPls","image_id":359,"first_seen":null},"TriHard":{"description":"This is the face of speed runner Trihex. twitch.tv\/trihex","image_id":171,"first_seen":null},"TTours":{"description":null,"image_id":38436,"first_seen":null},"twitchRaid":{"description":null,"image_id":62836,"first_seen":null},"UleetBackup":{"description":"This is the face of streamer Crream. twitch.tv\/crream","image_id":49,"first_seen":null},"UncleNox":{"description":"This is the face of Nox, part of the Twitch moderation team. Rumor is that he does not wear pants. twitch.tv\/nox","image_id":3666,"first_seen":null},"UnSane":{"description":"This is the face of streamer Tom. twitch.tv\/unsanitylive","image_id":71,"first_seen":null},"VaultBoy":{"description":"This is a promotional emote for Bethesda's Fallout franchise. Vault Boy is the mascot for the fictional corporation known as Vault-Tec within the Fallout universe.","image_id":54090,"first_seen":null},"VoHiYo":{"description":"This is the emote of Volary, a member of the Twitch partnerships team. twitch.tv\/volary","image_id":81274,"first_seen":null},"Volcania":{"description":"This is the logo of CelGaming. twitch.tv\/celgaming","image_id":166,"first_seen":null},"WholeWheat":{"description":"This is the face of caster and Twitch staff member djWHEAT. twitch.tv\/djwheat","image_id":1896,"first_seen":null},"WinWaker":{"description":"This is the face of speed runner Narcissa. twitch.tv\/narcissawright","image_id":167,"first_seen":null},"WTRuck":{"description":"WTRuck belongs Eddie Ruckus twitch.tv\/eddieruckus","image_id":1897,"first_seen":null},"WutFace":{"description":"This is the face of Twitch staff member Alex Mendez. twitch.tv\/goldenboyftw","image_id":28087,"first_seen":null},"YouWHY":{"description":"This is the emote of YouPickGames. twitch.tv\/youpickgames","image_id":4337,"first_seen":null}} \ No newline at end of file +{"JKanStyle":15,"OptimizePrime":16,"StoneLightning":17,"TheRinger":18,"RedCoat":22,"Kappa":25,"JonCarnage":26,"MrDestructoid":28,"BCWarrior":30,"GingerPower":32,"DansGame":33,"SwiftRage":34,"PJSalt":36,"KevinTurtle":40,"Kreygasm":41,"SSSsss":46,"PunchTrees":47,"ArsonNoSexy":50,"SMOrc":52,"FrankerZ":65,"OneHand":66,"HassanChop":68,"BloodTrail":69,"DBstyle":73,"AsianGlow":74,"BibleThump":86,"ShazBotstix":87,"PogChamp":88,"PMSTwin":92,"FUNgineer":244,"ResidentSleeper":245,"4Head":354,"HotPokket":357,"FailFish":360,"DAESuppy":973,"WholeWheat":1896,"ThunBeast":1898,"TF2John":1899,"RalpherZ":1900,"Kippa":1901,"Keepo":1902,"BigBrother":1904,"SoBayed":1906,"PeoplesChamp":3412,"GrammarKing":3632,"PanicVis":3668,"ANELE":3792,"BrokeBack":4057,"PipeHype":4240,"YouWHY":4337,"RitzMitz":4338,"EleGiggle":4339,"TheThing":7427,"HassaanChop":20225,"BabyRage":22639,"panicBasket":22998,"PermaSmug":27509,"BuddhaBar":27602,"WutFace":28087,"PRChase":28328,"Mau5":30134,"HeyGuys":30259,"NotATK":34875,"mcaT":35063,"TTours":38436,"PraiseIt":38586,"HumbleLife":46881,"CorgiDerp":49106,"ArgieB8":51838,"ShadyLulu":52492,"KappaPride":55338,"CoolCat":58127,"DendiFace":58135,"NotLikeThis":58765,"riPepperonis":62833,"duDudu":62834,"bleedPurple":62835,"twitchRaid":62836,"SeemsGood":64138,"MingLee":68856,"KappaRoss":70433,"KappaClaus":74510,"OhMyDog":81103,"OSFrog":81248,"SeriousSloth":81249,"KomodoHype":81273,"VoHiYo":81274,"MikeHogu":81636,"KappaWealth":81997,"cmonBruh":84608,"SmoocherZ":89945,"NomNom":90075,"StinkyCheese":90076,"ChefFrank":90129,"FutureMan":98562,"OpieOP":100590,"DoritosChip":102242,"PJSugar":102556,"VoteYea":106293,"VoteNay":106294,"RuleFive":107030,"DxCat":110734,"DrinkPurple":110785,"TinyFace":111119,"PicoMause":111300,"TheTarFu":111351,"DatSheffy":111700,"UnSane":111792,"copyThis":112288,"pastaThat":112289,"imGlitch":112290,"GivePLZ":112291,"TakeNRG":112292,"BlargNaut":114738,"DogFace":114835,"Jebaited":114836,"TooSpicy":114846,"WTRuck":114847,"UncleNox":114856,"RaccAttack":114870,"StrawBeary":114876,"PrimeMe":115075,"BrainSlug":115233,"BatChest":115234,"CurseLit":116625,"Poooound":117484,"FreakinStinkin":117701,"SuperVinlin":118772,"TriHard":120232,"CoolStoryBob":123171,"ItsBoshyTime":133468,"KAPOW":133537,"YouDontSay":134254,"UWot":134255,"RlyTho":134256,"PartyTime":135393,"NinjaGrumpy":138325,"MVGame":142140,"TBAngel":143490,"TheIlluminati":145315,"BlessRNG":153556,"MorphinTime":156787,"ThankEgg":160392,"ArigatoNas":160393,"BegWan":160394,"BigPhish":160395,"InuyoFace":160396,"Kappu":160397,"KonCha":160400,"PunOko":160401,"SabaPing":160402,"TearGlove":160403,"TehePelo":160404,"TwitchLit":166263,"CarlSmile":166266,"CrreamAwk":191313,"Squid1":191762,"Squid2":191763,"Squid3":191764,"Squid4":191767,"TwitchUnity":196892,"TPcrunchyroll":323914,"EntropyWins":376765,"PowerUpR":425671,"PowerUpL":425688,"HSCheers":444572,"HSWP":446979,"DarkMode":461298,"TwitchVotes":479745,"TPFufun":508650,"RedTeam":530888,"GreenTeam":530890,"PurpleStar":624501,"FBtouchdown":626795,"PopCorn":724216,"TombRaid":864205,"EarthDay":959018,"PartyHat":965738,"MercyWing1":1003187,"MercyWing2":1003189,"PinkMercy":1003190,"BisexualPride":1064987,"LesbianPride":1064988,"GayPride":1064991,"TransgenderPride":1064995,"AsexualPride":1130348,"PansexualPride":1130349,"TwitchRPG":1220086,"IntersexPride":1221184,"MaxLOL":1290325,"NonBinaryPride":1297279,"GenderFluidPride":1297281,"FBRun":1441261,"FBPass":1441271,"FBSpiral":1441273,"FBBlock":1441276,"FBCatch":1441281,"FBChallenge":1441285,"FBPenalty":1441289,"PixelBob":1547903,"GunRun":1584743,"HolidayCookie":1713813,"HolidayLog":1713816,"HolidayOrnament":1713818,"HolidayPresent":1713819,"HolidaySanta":1713822,"HolidayTree":1713825,"SoonerLater":2113050,"TwitchSings":300116344,"SingsMic":300116349,"SingsNote":300116350} \ No newline at end of file diff --git a/js/main.js b/js/main.js index 12478f69..85be84dd 100644 --- a/js/main.js +++ b/js/main.js @@ -203,7 +203,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _str /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _structs_builtin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../structs/builtin */ \"./src/structs/builtin.js\");\n/* harmony import */ var data__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! data */ \"./src/data/data.js\");\n/* harmony import */ var modules__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! modules */ \"./src/modules/modules.js\");\n/* harmony import */ var _ui_emote__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../ui/emote */ \"./src/ui/emote.js\");\n/* harmony import */ var _ui_toasts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../ui/toasts */ \"./src/ui/toasts.js\");\n\n\n\n\n // import EmoteMenu from \"./emotemenu\";\n\nconst request = __webpack_require__(/*! request */ \"request\");\n\nconst Emotes = {\n TwitchGlobal: {},\n TwitchSubscriber: {},\n BTTV: {},\n FrankerFaceZ: {},\n BTTV2: {}\n};\nconst bdEmoteSettingIDs = {\n TwitchGlobal: \"twitch\",\n TwitchSubscriber: \"twitch\",\n BTTV: \"bttv\",\n FrankerFaceZ: \"ffz\",\n BTTV2: \"bttv\"\n};\nconst blacklist = [];\nconst overrides = [\"twitch\", \"bttv\", \"ffz\"];\nconst modifiers = [\"flip\", \"spin\", \"pulse\", \"spin2\", \"spin3\", \"1spin\", \"2spin\", \"3spin\", \"tr\", \"bl\", \"br\", \"shake\", \"shake2\", \"shake3\", \"flap\"];\n/* harmony default export */ __webpack_exports__[\"default\"] = (new class EmoteModule extends _structs_builtin__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\n get name() {\n return \"Emotes\";\n }\n\n get collection() {\n return \"settings\";\n }\n\n get category() {\n return \"general\";\n }\n\n get id() {\n return \"emotes\";\n }\n\n get categories() {\n return Object.keys(bdEmoteSettingIDs).filter(k => this.isCategoryEnabled(bdEmoteSettingIDs[k]));\n }\n\n isCategoryEnabled(id) {\n return super.get(\"emotes\", \"categories\", id);\n }\n\n get(id) {\n return super.get(\"emotes\", \"general\", id);\n }\n\n get MessageContentComponent() {\n return modules__WEBPACK_IMPORTED_MODULE_2__[\"WebpackModules\"].getModule(m => m.defaultProps && m.defaultProps.hasOwnProperty(\"disableButtons\"));\n }\n\n get Emotes() {\n return Emotes;\n }\n\n get TwitchGlobal() {\n return Emotes.TwitchGlobal;\n }\n\n get TwitchSubscriber() {\n return Emotes.TwitchSubscriber;\n }\n\n get BTTV() {\n return Emotes.BTTV;\n }\n\n get FrankerFaceZ() {\n return Emotes.FrankerFaceZ;\n }\n\n get BTTV2() {\n return Emotes.BTTV2;\n }\n\n get blacklist() {\n return blacklist;\n }\n\n get favorites() {\n return this.favoriteEmotes;\n }\n\n getCategory(category) {\n return Emotes[category];\n }\n\n initialize() {\n super.initialize();\n this.favoriteEmotes = {};\n const fe = modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].getBDData(\"bdfavemotes\");\n if (fe !== \"\" && fe !== null) this.favoriteEmotes = JSON.parse(window.atob(fe));\n this.saveFavorites();\n this.addFavorite = this.addFavorite.bind(this);\n this.removeFavorite = this.removeFavorite.bind(this); // EmoteConfig;\n // emoteCollection.button = {title: \"Clear Emote Cache\", onClick: () => { this.clearEmoteData(); this.loadEmoteData(EmoteInfo); }};\n }\n\n async enabled() {\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Settings\"].registerCollection(\"emotes\", \"Emotes\", data__WEBPACK_IMPORTED_MODULE_1__[\"EmoteConfig\"], {\n title: modules__WEBPACK_IMPORTED_MODULE_2__[\"Strings\"].Emotes.clearEmotes,\n onClick: () => {\n this.clearEmoteData();\n this.loadEmoteData(data__WEBPACK_IMPORTED_MODULE_1__[\"EmoteInfo\"]);\n }\n }); // Disable emote module for now because it's annoying and slow\n\n await this.getBlacklist();\n await this.loadEmoteData(data__WEBPACK_IMPORTED_MODULE_1__[\"EmoteInfo\"]);\n\n while (!this.MessageContentComponent) await new Promise(resolve => setTimeout(resolve, 100));\n\n this.patchMessageContent();\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Events\"].on(\"emotes-favorite-added\", this.addFavorite);\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Events\"].on(\"emotes-favorite-removed\", this.removeFavorite);\n }\n\n disabled() {\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Events\"].off(\"emotes-favorite-added\", this.addFavorite);\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Events\"].off(\"emotes-favorite-removed\", this.removeFavorite);\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Settings\"].removeCollection(\"emotes\");\n this.emptyEmotes();\n if (!this.cancelEmoteRender) return;\n this.cancelEmoteRender();\n delete this.cancelEmoteRender;\n }\n\n addFavorite(name, url) {\n if (!this.favoriteEmotes.hasOwnProperty(name)) this.favoriteEmotes[name] = url;\n this.saveFavorites();\n }\n\n removeFavorite(name) {\n if (!this.favoriteEmotes.hasOwnProperty(name)) return;\n delete this.favoriteEmotes[name];\n this.saveFavorites();\n }\n\n isFavorite(name) {\n return this.favoriteEmotes.hasOwnProperty(name);\n }\n\n saveFavorites() {\n modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].setBDData(\"bdfavemotes\", window.btoa(JSON.stringify(this.favoriteEmotes)));\n }\n\n emptyEmotes() {\n for (const cat in Emotes) Object.assign(Emotes, {\n [cat]: {}\n });\n }\n\n patchMessageContent() {\n if (this.cancelEmoteRender) return;\n this.cancelEmoteRender = this.after(this.MessageContentComponent.prototype, \"render\", (thisObj, args, retVal) => {\n this.after(retVal.props, \"children\", (t, a, returnValue) => {\n if (this.categories.length == 0) return;\n const markup = returnValue.props.children[1];\n if (!markup.props.children) return;\n const nodes = markup.props.children[1];\n if (!nodes || !nodes.length) return;\n\n for (let n = 0; n < nodes.length; n++) {\n const node = nodes[n];\n if (typeof node !== \"string\") continue;\n const words = node.split(/([^\\s]+)([\\s]|$)/g);\n\n for (let c = 0, clen = this.categories.length; c < clen; c++) {\n for (let w = 0, wlen = words.length; w < wlen; w++) {\n const emote = words[w];\n const emoteSplit = emote.split(\":\");\n const emoteName = emoteSplit[0];\n let emoteModifier = emoteSplit[1] ? emoteSplit[1] : \"\";\n let emoteOverride = emoteModifier.slice(0);\n if (emoteName.length < 4 || blacklist.includes(emoteName)) continue;\n if (!modifiers.includes(emoteModifier) || !modules__WEBPACK_IMPORTED_MODULE_2__[\"Settings\"].get(this.category, \"general\", \"modifiers\")) emoteModifier = \"\";\n if (!overrides.includes(emoteOverride)) emoteOverride = \"\";else emoteModifier = emoteOverride;\n let current = this.categories[c];\n\n if (emoteOverride === \"twitch\") {\n if (Emotes.TwitchGlobal[emoteName]) current = \"TwitchGlobal\";else if (Emotes.TwitchSubscriber[emoteName]) current = \"TwitchSubscriber\";\n } else if (emoteOverride === \"bttv\") {\n if (Emotes.BTTV[emoteName]) current = \"BTTV\";else if (Emotes.BTTV2[emoteName]) current = \"BTTV2\";\n } else if (emoteOverride === \"ffz\") {\n if (Emotes.FrankerFaceZ[emoteName]) current = \"FrankerFaceZ\";\n }\n\n if (!Emotes[current][emoteName] || !modules__WEBPACK_IMPORTED_MODULE_2__[\"Settings\"].get(this.category, \"categories\", bdEmoteSettingIDs[current])) continue;\n const results = nodes[n].match(new RegExp(`([\\\\s]|^)${modules__WEBPACK_IMPORTED_MODULE_2__[\"Utilities\"].escape(emoteModifier ? emoteName + \":\" + emoteModifier : emoteName)}([\\\\s]|$)`));\n if (!results) continue;\n const pre = nodes[n].substring(0, results.index + results[1].length);\n const post = nodes[n].substring(results.index + results[0].length - results[2].length);\n nodes[n] = pre;\n const emoteComponent = modules__WEBPACK_IMPORTED_MODULE_2__[\"DiscordModules\"].React.createElement(_ui_emote__WEBPACK_IMPORTED_MODULE_3__[\"default\"], {\n name: emoteName,\n url: Emotes[current][emoteName],\n modifier: emoteModifier,\n isFavorite: this.isFavorite(emoteName)\n });\n nodes.splice(n + 1, 0, post);\n nodes.splice(n + 1, 0, emoteComponent);\n }\n }\n }\n\n const onlyEmotes = nodes.every(r => {\n if (typeof r == \"string\" && r.replace(/\\s*/, \"\") == \"\") return true;else if (r.type && r.type.name == \"BDEmote\") return true;else if (r.props && r.props.children && r.props.children.props && r.props.children.props.emojiName) return true;\n return false;\n });\n if (!onlyEmotes) return;\n\n for (const node of nodes) {\n if (typeof node != \"object\") continue;\n if (node.type.name == \"BDEmote\") node.props.jumboable = true;else if (node.props && node.props.children && node.props.children.props && node.props.children.props.emojiName) node.props.children.props.jumboable = true;\n }\n });\n });\n }\n\n async loadEmoteData(emoteInfo) {\n this.emotesLoaded = false;\n\n const _fs = __webpack_require__(/*! fs */ \"fs\");\n\n const emoteFile = \"emote_data.json\";\n const file = data__WEBPACK_IMPORTED_MODULE_1__[\"Config\"].dataPath + emoteFile;\n\n const exists = _fs.existsSync(file);\n\n if (exists && this.isCacheValid()) {\n _ui_toasts__WEBPACK_IMPORTED_MODULE_4__[\"default\"].show(\"Loading emotes from cache.\", {\n type: \"info\"\n });\n this.log(\"Loading emotes from local cache.\");\n const data = await new Promise(resolve => {\n _fs.readFile(file, \"utf8\", (err, content) => {\n this.log(\"Emotes loaded from cache.\");\n if (err) content = {};\n resolve(content);\n });\n });\n const parsed = modules__WEBPACK_IMPORTED_MODULE_2__[\"Utilities\"].testJSON(data);\n let isValid = !!parsed;\n if (isValid) Object.assign(Emotes, parsed);\n\n for (const e in emoteInfo) {\n isValid = Object.keys(Emotes[emoteInfo[e].variable]).length > 0;\n }\n\n if (isValid) {\n _ui_toasts__WEBPACK_IMPORTED_MODULE_4__[\"default\"].show(\"Emotes successfully loaded.\", {\n type: \"success\"\n });\n this.emotesLoaded = true;\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Events\"].dispatch(\"emotes-loaded\");\n return;\n }\n\n this.log(\"Cache was corrupt, downloading...\");\n\n _fs.unlinkSync(file);\n }\n\n if (!modules__WEBPACK_IMPORTED_MODULE_2__[\"Settings\"].get(this.category, \"general\", \"download\")) return;\n _ui_toasts__WEBPACK_IMPORTED_MODULE_4__[\"default\"].show(modules__WEBPACK_IMPORTED_MODULE_2__[\"Strings\"].Emotes.downloading, {\n type: \"info\"\n });\n\n for (const e in emoteInfo) {\n await new Promise(r => setTimeout(r, 1000));\n const data = await this.downloadEmotes(emoteInfo[e]);\n Emotes[emoteInfo[e].variable] = data;\n }\n\n _ui_toasts__WEBPACK_IMPORTED_MODULE_4__[\"default\"].show(modules__WEBPACK_IMPORTED_MODULE_2__[\"Strings\"].Emotes.downloaded, {\n type: \"success\"\n });\n\n try {\n _fs.writeFileSync(file, JSON.stringify(Emotes), \"utf8\");\n } catch (err) {\n this.stacktrace(\"Could not save emote data.\", err);\n }\n\n this.emotesLoaded = true;\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Events\"].dispatch(\"emotes-loaded\");\n }\n\n downloadEmotes(emoteMeta) {\n const repoFile = modules__WEBPACK_IMPORTED_MODULE_2__[\"Utilities\"].repoUrl(`data/emotes/${emoteMeta.variable.toLowerCase()}.json`);\n if (emoteMeta.url && !emoteMeta.backup) emoteMeta.backup = repoFile;\n if (!emoteMeta.url) emoteMeta.url = repoFile;\n const options = {\n url: emoteMeta.url,\n timeout: emoteMeta.timeout ? emoteMeta.timeout : 5000,\n json: true\n };\n this.log(`Downloading: ${emoteMeta.variable} (${emoteMeta.url})`);\n return new Promise((resolve, reject) => {\n request.get(options, (error, response, parsedData) => {\n if (error) {\n this.stacktrace(\"Could not download \" + emoteMeta.variable, error);\n\n if (emoteMeta.backup || emoteMeta.url) {\n emoteMeta.url = emoteMeta.backup;\n emoteMeta.backup = null;\n if (emoteMeta.backupParser) emoteMeta.parser = emoteMeta.backupParser;\n return resolve(this.downloadEmotes(emoteMeta));\n }\n\n return reject({});\n }\n\n if (typeof emoteMeta.parser === \"function\") parsedData = emoteMeta.parser(parsedData);\n\n for (const emote in parsedData) {\n if (emote.length < 4 || blacklist.includes(emote)) {\n delete parsedData[emote];\n continue;\n }\n\n parsedData[emote] = emoteMeta.getEmoteURL(parsedData[emote]);\n }\n\n resolve(parsedData);\n this.log(\"Downloaded: \" + emoteMeta.variable);\n });\n });\n }\n\n getBlacklist() {\n return new Promise(resolve => {\n request.get({\n url: modules__WEBPACK_IMPORTED_MODULE_2__[\"Utilities\"].repoUrl(`data/emotes/blacklist.json`),\n json: true\n }, (err, resp, data) => {\n if (err || resp.statusCode != 200) return resolve();\n resolve(blacklist.push(...data));\n });\n });\n }\n\n isCacheValid() {\n const cacheLength = modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].getBDData(\"emoteCacheDays\") || modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].setBDData(\"emoteCacheDays\", 7) || 7;\n const cacheDate = new Date(modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].getBDData(\"emoteCacheDate\") || null);\n const currentDate = new Date();\n const daysBetween = Math.round(Math.abs((currentDate.getTime() - cacheDate.getTime()) / (24 * 60 * 60 * 1000)));\n\n if (daysBetween > cacheLength) {\n modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].setBDData(\"emoteCacheDate\", currentDate.toJSON());\n return false;\n }\n\n return true;\n }\n\n clearEmoteData() {\n const _fs = __webpack_require__(/*! fs */ \"fs\");\n\n const emoteFile = \"emote_data.json\";\n const file = data__WEBPACK_IMPORTED_MODULE_1__[\"Config\"].dataPath + emoteFile;\n\n const exists = _fs.existsSync(file);\n\n if (exists) _fs.unlinkSync(file);\n modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].setBDData(\"emoteCacheDate\", new Date().toJSON());\n\n for (const category in Emotes) Object.assign(Emotes, {\n [category]: {}\n });\n }\n\n}());//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Db3JlLy4vc3JjL2J1aWx0aW5zL2Vtb3Rlcy5qcz82YTA0Il0sIm5hbWVzIjpbInJlcXVlc3QiLCJyZXF1aXJlIiwiRW1vdGVzIiwiVHdpdGNoR2xvYmFsIiwiVHdpdGNoU3Vic2NyaWJlciIsIkJUVFYiLCJGcmFua2VyRmFjZVoiLCJCVFRWMiIsImJkRW1vdGVTZXR0aW5nSURzIiwiYmxhY2tsaXN0Iiwib3ZlcnJpZGVzIiwibW9kaWZpZXJzIiwiRW1vdGVNb2R1bGUiLCJCdWlsdGluIiwibmFtZSIsImNvbGxlY3Rpb24iLCJjYXRlZ29yeSIsImlkIiwiY2F0ZWdvcmllcyIsIk9iamVjdCIsImtleXMiLCJmaWx0ZXIiLCJrIiwiaXNDYXRlZ29yeUVuYWJsZWQiLCJnZXQiLCJNZXNzYWdlQ29udGVudENvbXBvbmVudCIsIldlYnBhY2tNb2R1bGVzIiwiZ2V0TW9kdWxlIiwibSIsImRlZmF1bHRQcm9wcyIsImhhc093blByb3BlcnR5IiwiZmF2b3JpdGVzIiwiZmF2b3JpdGVFbW90ZXMiLCJnZXRDYXRlZ29yeSIsImluaXRpYWxpemUiLCJmZSIsIkRhdGFTdG9yZSIsImdldEJERGF0YSIsIkpTT04iLCJwYXJzZSIsIndpbmRvdyIsImF0b2IiLCJzYXZlRmF2b3JpdGVzIiwiYWRkRmF2b3JpdGUiLCJiaW5kIiwicmVtb3ZlRmF2b3JpdGUiLCJlbmFibGVkIiwiU2V0dGluZ3MiLCJyZWdpc3RlckNvbGxlY3Rpb24iLCJFbW90ZUNvbmZpZyIsInRpdGxlIiwiU3RyaW5ncyIsImNsZWFyRW1vdGVzIiwib25DbGljayIsImNsZWFyRW1vdGVEYXRhIiwibG9hZEVtb3RlRGF0YSIsIkVtb3RlSW5mbyIsImdldEJsYWNrbGlzdCIsIlByb21pc2UiLCJyZXNvbHZlIiwic2V0VGltZW91dCIsInBhdGNoTWVzc2FnZUNvbnRlbnQiLCJFdmVudHMiLCJvbiIsImRpc2FibGVkIiwib2ZmIiwicmVtb3ZlQ29sbGVjdGlvbiIsImVtcHR5RW1vdGVzIiwiY2FuY2VsRW1vdGVSZW5kZXIiLCJ1cmwiLCJpc0Zhdm9yaXRlIiwic2V0QkREYXRhIiwiYnRvYSIsInN0cmluZ2lmeSIsImNhdCIsImFzc2lnbiIsImFmdGVyIiwicHJvdG90eXBlIiwidGhpc09iaiIsImFyZ3MiLCJyZXRWYWwiLCJwcm9wcyIsInQiLCJhIiwicmV0dXJuVmFsdWUiLCJsZW5ndGgiLCJtYXJrdXAiLCJjaGlsZHJlbiIsIm5vZGVzIiwibiIsIm5vZGUiLCJ3b3JkcyIsInNwbGl0IiwiYyIsImNsZW4iLCJ3Iiwid2xlbiIsImVtb3RlIiwiZW1vdGVTcGxpdCIsImVtb3RlTmFtZSIsImVtb3RlTW9kaWZpZXIiLCJlbW90ZU92ZXJyaWRlIiwic2xpY2UiLCJpbmNsdWRlcyIsImN1cnJlbnQiLCJyZXN1bHRzIiwibWF0Y2giLCJSZWdFeHAiLCJVdGlsaXRpZXMiLCJlc2NhcGUiLCJwcmUiLCJzdWJzdHJpbmciLCJpbmRleCIsInBvc3QiLCJlbW90ZUNvbXBvbmVudCIsIkRpc2NvcmRNb2R1bGVzIiwiUmVhY3QiLCJjcmVhdGVFbGVtZW50IiwiQkRFbW90ZSIsIm1vZGlmaWVyIiwic3BsaWNlIiwib25seUVtb3RlcyIsImV2ZXJ5IiwiciIsInJlcGxhY2UiLCJ0eXBlIiwiZW1vamlOYW1lIiwianVtYm9hYmxlIiwiZW1vdGVJbmZvIiwiZW1vdGVzTG9hZGVkIiwiX2ZzIiwiZW1vdGVGaWxlIiwiZmlsZSIsIkNvbmZpZyIsImRhdGFQYXRoIiwiZXhpc3RzIiwiZXhpc3RzU3luYyIsImlzQ2FjaGVWYWxpZCIsIlRvYXN0cyIsInNob3ciLCJsb2ciLCJkYXRhIiwicmVhZEZpbGUiLCJlcnIiLCJjb250ZW50IiwicGFyc2VkIiwidGVzdEpTT04iLCJpc1ZhbGlkIiwiZSIsInZhcmlhYmxlIiwiZGlzcGF0Y2giLCJ1bmxpbmtTeW5jIiwiZG93bmxvYWRpbmciLCJkb3dubG9hZEVtb3RlcyIsImRvd25sb2FkZWQiLCJ3cml0ZUZpbGVTeW5jIiwic3RhY2t0cmFjZSIsImVtb3RlTWV0YSIsInJlcG9GaWxlIiwicmVwb1VybCIsInRvTG93ZXJDYXNlIiwiYmFja3VwIiwib3B0aW9ucyIsInRpbWVvdXQiLCJqc29uIiwicmVqZWN0IiwiZXJyb3IiLCJyZXNwb25zZSIsInBhcnNlZERhdGEiLCJiYWNrdXBQYXJzZXIiLCJwYXJzZXIiLCJnZXRFbW90ZVVSTCIsInJlc3AiLCJzdGF0dXNDb2RlIiwicHVzaCIsImNhY2hlTGVuZ3RoIiwiY2FjaGVEYXRlIiwiRGF0ZSIsImN1cnJlbnREYXRlIiwiZGF5c0JldHdlZW4iLCJNYXRoIiwicm91bmQiLCJhYnMiLCJnZXRUaW1lIiwidG9KU09OIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtDQUVBOztBQUNBLE1BQU1BLE9BQU8sR0FBR0MsbUJBQU8sQ0FBQyx3QkFBRCxDQUF2Qjs7QUFFQSxNQUFNQyxNQUFNLEdBQUc7QUFDWEMsY0FBWSxFQUFFLEVBREg7QUFFWEMsa0JBQWdCLEVBQUUsRUFGUDtBQUdYQyxNQUFJLEVBQUUsRUFISztBQUlYQyxjQUFZLEVBQUUsRUFKSDtBQUtYQyxPQUFLLEVBQUU7QUFMSSxDQUFmO0FBUUEsTUFBTUMsaUJBQWlCLEdBQUc7QUFDdEJMLGNBQVksRUFBRSxRQURRO0FBRXRCQyxrQkFBZ0IsRUFBRSxRQUZJO0FBR3RCQyxNQUFJLEVBQUUsTUFIZ0I7QUFJdEJDLGNBQVksRUFBRSxLQUpRO0FBS3RCQyxPQUFLLEVBQUU7QUFMZSxDQUExQjtBQVFBLE1BQU1FLFNBQVMsR0FBRyxFQUFsQjtBQUNBLE1BQU1DLFNBQVMsR0FBRyxDQUFDLFFBQUQsRUFBVyxNQUFYLEVBQW1CLEtBQW5CLENBQWxCO0FBQ0EsTUFBTUMsU0FBUyxHQUFHLENBQUMsTUFBRCxFQUFTLE1BQVQsRUFBaUIsT0FBakIsRUFBMEIsT0FBMUIsRUFBbUMsT0FBbkMsRUFBNEMsT0FBNUMsRUFBcUQsT0FBckQsRUFBOEQsT0FBOUQsRUFBdUUsSUFBdkUsRUFBNkUsSUFBN0UsRUFBbUYsSUFBbkYsRUFBeUYs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NkksV0FBVyxHQUFHLElBQUlELElBQUosRUFBcEI7QUFDQSxVQUFNRSxXQUFXLEdBQUdDLElBQUksQ0FBQ0MsS0FBTCxDQUFXRCxJQUFJLENBQUNFLEdBQUwsQ0FBUyxDQUFDSixXQUFXLENBQUNLLE9BQVosS0FBd0JQLFNBQVMsQ0FBQ08sT0FBVixFQUF6QixLQUFpRCxLQUFLLEVBQUwsR0FBVSxFQUFWLEdBQWUsSUFBaEUsQ0FBVCxDQUFYLENBQXBCOztBQUNBLFFBQUlKLFdBQVcsR0FBR0osV0FBbEIsRUFBK0I7QUFDM0IzSSx1REFBUyxDQUFDbUMsU0FBVixDQUFvQixnQkFBcEIsRUFBc0MyRyxXQUFXLENBQUNNLE1BQVosRUFBdEM7QUFDQSxhQUFPLEtBQVA7QUFDSDs7QUFDRCxXQUFPLElBQVA7QUFDSDs7QUFFRGxJLGdCQUFjLEdBQUc7QUFDYixVQUFNNEUsR0FBRyxHQUFHakksbUJBQU8sQ0FBQyxjQUFELENBQW5COztBQUNBLFVBQU1rSSxTQUFTLEdBQUcsaUJBQWxCO0FBQ0EsVUFBTUMsSUFBSSxHQUFHQywyQ0FBTSxDQUFDQyxRQUFQLEdBQWtCSCxTQUEvQjs7QUFDQSxVQUFNSSxNQUFNLEdBQUdMLEdBQUcsQ0FBQ00sVUFBSixDQUFlSixJQUFmLENBQWY7O0FBQ0EsUUFBSUcsTUFBSixFQUFZTCxHQUFHLENBQUNxQixVQUFKLENBQWVuQixJQUFmO0FBQ1poRyxxREFBUyxDQUFDbUMsU0FBVixDQUFvQixnQkFBcEIsRUFBdUMsSUFBSTBHLElBQUosRUFBRCxDQUFhTyxNQUFiLEVBQXRDOztBQUNBLFNBQUssTUFBTXhLLFFBQVgsSUFBdUJkLE1BQXZCLEVBQStCaUIsTUFBTSxDQUFDd0QsTUFBUCxDQUFjekUsTUFBZCxFQUFzQjtBQUFDLE9BQUNjLFFBQUQsR0FBWTtBQUFiLEtBQXRCO0FBQ2xDOztBQXJSZ0QsQ0FBdEMsRUFBZiIsImZpbGUiOiIuL3NyYy9idWlsdGlucy9lbW90ZXMuanMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQnVpbHRpbiBmcm9tIFwiLi4vc3RydWN0cy9idWlsdGluXCI7XHJcblxyXG5pbXBvcnQge0NvbmZpZywgRW1vdGVJbmZvLCBFbW90ZUNvbmZpZ30gZnJvbSBcImRhdGFcIjtcclxuaW1wb3J0IHtVdGlsaXRpZXMsIFdlYnBhY2tNb2R1bGVzLCBEYXRhU3RvcmUsIERpc2NvcmRNb2R1bGVzLCBFdmVudHMsIFNldHRpbmdzLCBTdHJpbmdzfSBmcm9tIFwibW9kdWxlc1wiO1xyXG5pbXBvcnQgQkRFbW90ZSBmcm9tIFwiLi4vdWkvZW1vdGVcIjtcclxuaW1wb3J0IFRvYXN0cyBmcm9tIFwiLi4vdWkvdG9hc3RzXCI7XHJcbi8vIGltcG9ydCBFbW90ZU1lbnUgZnJvbSBcIi4vZW1vdGVtZW51XCI7XHJcbmNvbnN0IHJlcXVlc3QgPSByZXF1aXJlKFwicmVxdWVzdFwiKTtcclxuXHJcbmNvbnN0IEVtb3RlcyA9IHtcclxuICAgIFR3aXRjaEdsb2JhbDoge30sXHJcbiAgICBUd2l0Y2hTdWJzY3JpYmVyOiB7fSxcclxuICAgIEJUVFY6IHt9LFxyXG4gICAgRnJhbmtlckZhY2VaOiB7fSxcclxuICAgIEJUVFYyOiB7fVxyXG59O1xyXG5cclxuY29uc3QgYmRFbW90ZVNldHRpbmdJRHMgPSB7XHJcbiAgICBUd2l0Y2hHbG9iYWw6IFwidHdpdGNoXCIsXHJcbiAgICBUd2l0Y2hTdWJzY3JpYmVyOiBcInR3aXRjaFwiLFxyXG4gICAgQlRUVjogXCJidHR2XCIsXHJcbiAgICBGcmFua2VyRmFjZVo6IFwiZmZ6XCIsXHJcbiAgICBCVFRWMjogXCJidHR2XCJcclxufTtcclxuXHJcbmNvbnN0IGJsYWNrbGlzdCA9IFtdO1xyXG5jb25zdCBvdmVycmlkZXMgPSBbXCJ0d2l0Y2hcIiwgXCJidHR2XCIsIFwiZmZ6XCJdO1xyXG5jb25zdCBtb2RpZmllcnMgPSBbXCJmbGlwXCIsIFwic3BpblwiLCBcInB1bHNlXCIsIFwic3BpbjJcIiwgXCJzcGluM1wiLCBcIjFzcGluXCIsIFwiMnNwaW5cIiwgXCIzc3BpblwiLCBcInRyXCIsIFwiYmxcIiwgXCJiclwiLCBcInNoYWtlXCIsIFwic2hha2UyXCIsIFwic2hha2UzXCIsIFwiZmxhcFwiXTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IG5ldyBjbGFzcyBFbW90ZU1vZHVsZSBleHRlbmRzIEJ1aWx0aW4ge1xyXG4gICAgZ2V0IG5hbWUoKSB7cmV0dXJuIFwiRW1vdGVzXCI7fVxyXG4gICAgZ2V0IGNvbGxlY3Rpb24oKSB7cmV0dXJuIFwic2V0dGluZ3NcIjt9XHJcbiAgICBnZXQgY2F0ZWdvcnkoKSB7cmV0dXJuIFwiZ2VuZXJhbFwiO31cclxuICAgIGdldCBpZCgpIHtyZXR1cm4gXCJlbW90ZXNcIjt9XHJcbiAgICBnZXQgY2F0ZWdvcmllcygpIHsgcmV0dXJuIE9iamVjdC5rZXlzKGJkRW1vdGVTZXR0aW5nSURzKS5maWx0ZXIoayA9PiB0aGlzLmlzQ2F0ZWdvcnlFbmFibGVkKGJkRW1vdGVTZXR0aW5nSURzW2tdKSk7IH1cclxuXHJcbiAgICBpc0NhdGVnb3J5RW5hYmxlZChpZCkge3JldHVybiBzdXBlci5nZXQoXCJlbW90ZXNcIiwgXCJjYXRlZ29yaWVzXCIsIGlkKTt9XHJcblxyXG4gICAgZ2V0KGlkKSB7cmV0dXJuIHN1cGVyLmdldChcImVtb3Rlc1wiLCBcImdlbmVyYWxcIiwgaWQpO31cclxuXHJcbiAgICBnZXQgTWVzc2FnZUNvbnRlbnRDb21wb25lbnQoKSB7cmV0dXJuIFdlYnBhY2tNb2R1bGVzLmdldE1vZHVsZShtID0+IG0uZGVmYXVsdFByb3BzICYmIG0uZGVmYXVsdFByb3BzLmhhc093blByb3BlcnR5KFwiZGlzYWJsZUJ1dHRvbnNcIikpO31cclxuXHJcbiAgICBnZXQgRW1vdGVzKCkge3JldHVybiBFbW90ZXM7fVxyXG4gICAgZ2V0IFR3aXRjaEdsb2JhbCgpIHtyZXR1cm4gRW1vdGVzLlR3aXRjaEdsb2JhbDt9XHJcbiAgICBnZXQgVHdpdGNoU3Vic2NyaWJlcigpIHtyZXR1cm4gRW1vdGVzLlR3aXRjaFN1YnNjcmliZXI7fVxyXG4gICAgZ2V0IEJUVFYoKSB7cmV0dXJuIEVtb3Rlcy5CVFRWO31cclxuICAgIGdldCBGcmFua2VyRmFjZVooKSB7cmV0dXJuIEVtb3Rlcy5GcmFua2VyRmFjZVo7fVxyXG4gICAgZ2V0IEJUVFYyKCkge3JldHVybiBFbW90ZXMuQlRUVjI7fVxyXG4gICAgZ2V0IGJsYWNrbGlzdCgpIHtyZXR1cm4gYmxhY2tsaXN0O31cclxuICAgIGdldCBmYXZvcml0ZXMoKSB7cmV0dXJuIHRoaXMuZmF2b3JpdGVFbW90ZXM7fVxyXG5cclxuICAgIGdldENhdGVnb3J5KGNhdGVnb3J5KSB7XHJcbiAgICAgICAgcmV0dXJuIEVtb3Rlc1tjYXRlZ29yeV07XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdGlhbGl6ZSgpIHtcclxuICAgICAgICBzdXBlci5pbml0aWFsaXplKCk7XHJcbiAgICAgICAgdGhpcy5mYXZvcml0ZUVtb3RlcyA9IHt9O1xyXG4gICAgICAgIGNvbnN0IGZlID0gRGF0YVN0b3JlLmdldEJERGF0YShcImJkZmF2ZW1vdGVzXCIpO1xyXG4gICAgICAgIGlmIChmZSAhPT0gXCJcIiAmJiBmZSAhPT0gbnVsbCkgdGhpcy5mYXZvcml0ZUVtb3RlcyA9IEpTT04ucGFyc2Uod2luZG93LmF0b2IoZmUpKTtcclxuICAgICAgICB0aGlzLnNhdmVGYXZvcml0ZXMoKTtcclxuICAgICAgICB0aGlzLmFkZEZhdm9yaXRlID0gdGhpcy5hZGRGYXZvcml0ZS5iaW5kKHRoaXMpO1xyXG4gICAgICAgIHRoaXMucmVtb3ZlRmF2b3JpdGUgPSB0aGlzLnJlbW92ZUZhdm9yaXRlLmJpbmQodGhpcyk7XHJcbiAgICAgICAgLy8gRW1vdGVDb25maWc7XHJcbiAgICAgICAgLy8gZW1vdGVDb2xsZWN0aW9uLmJ1dHRvbiA9IHt0aXRsZTogXCJDbGVhciBFbW90ZSBDYWNoZVwiLCBvbkNsaWNrOiAoKSA9PiB7IHRoaXMuY2xlYXJFbW90ZURhdGEoKTsgdGhpcy5sb2FkRW1vdGVEYXRhKEVtb3RlSW5mbyk7IH19O1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGVuYWJsZWQoKSB7XHJcbiAgICAgICAgU2V0dGluZ3MucmVnaXN0ZXJDb2xsZWN0aW9uKFwiZW1vdGVzXCIsIFwiRW1vdGVzXCIsIEVtb3RlQ29uZmlnLCB7dGl0bGU6IFN0cmluZ3MuRW1vdGVzLmNsZWFyRW1vdGVzLCBvbkNsaWNrOiAoKSA9PiB7IHRoaXMuY2xlYXJFbW90ZURhdGEoKTsgdGhpcy5sb2FkRW1vdGVEYXRhKEVtb3RlSW5mbyk7IH19KTtcclxuICAgICAgICAvLyBEaXNhYmxlIGVtb3RlIG1vZHVsZSBmb3Igbm93IGJlY2F1c2UgaXQncyBhbm5veWluZyBhbmQgc2xvd1xyXG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QmxhY2tsaXN0KCk7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5sb2FkRW1vdGVEYXRhKEVtb3RlSW5mbyk7XHJcblxyXG4gICAgICAgIHdoaWxlICghdGhpcy5NZXNzYWdlQ29udGVudENvbXBvbmVudCkgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDEwMCkpO1xyXG4gICAgICAgIHRoaXMucGF0Y2hNZXNzYWdlQ29udGVudCgpO1xyXG4gICAgICAgIEV2ZW50cy5vbihcImVtb3Rlcy1mYXZvcml0ZS1hZGRlZFwiLCB0aGlzLmFkZEZhdm9yaXRlKTtcclxuICAgICAgICBFdmVudHMub24oXCJlbW90ZXMtZmF2b3JpdGUtcmVtb3ZlZFwiLCB0aGlzLnJlbW92ZUZhdm9yaXRlKTtcclxuICAgIH1cclxuXHJcbiAgICBkaXNhYmxlZCgpIHtcclxuICAgICAgICBFdmVudHMub2ZmKFwiZW1vdGVzLWZhdm9yaXRlLWFkZGVkXCIsIHRoaXMuYWRkRmF2b3JpdGUpO1xyXG4gICAgICAgIEV2ZW50cy5vZmYoXCJlbW90ZXMtZmF2b3JpdGUtcmVtb3ZlZFwiLCB0aGlzLnJlbW92ZUZhdm9yaXRlKTtcclxuICAgICAgICBTZXR0aW5ncy5yZW1vdmVDb2xsZWN0aW9uKFwiZW1vdGVzXCIpO1xyXG4gICAgICAgIHRoaXMuZW1wdHlFbW90ZXMoKTtcclxuICAgICAgICBpZiAoIXRoaXMuY2FuY2VsRW1vdGVSZW5kZXIpIHJldHVybjtcclxuICAgICAgICB0aGlzLmNhbmNlbEVtb3RlUmVuZGVyKCk7XHJcbiAgICAgICAgZGVsZXRlIHRoaXMuY2FuY2VsRW1vdGVSZW5kZXI7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkRmF2b3JpdGUobmFtZSwgdXJsKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmZhdm9yaXRlRW1vdGVzLmhhc093blByb3BlcnR5KG5hbWUpKSB0aGlzLmZhdm9yaXRlRW1vdGVzW25hbWVdID0gdXJsO1xyXG4gICAgICAgIHRoaXMuc2F2ZUZhdm9yaXRlcygpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZUZhdm9yaXRlKG5hbWUpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZmF2b3JpdGVFbW90ZXMuaGFzT3duUHJvcGVydHkobmFtZSkpIHJldHVybjtcclxuICAgICAgICBkZWxldGUgdGhpcy5mYXZvcml0ZUVtb3Rlc1tuYW1lXTtcclxuICAgICAgICB0aGlzLnNhdmVGYXZvcml0ZXMoKTtcclxuICAgIH1cclxuXHJcbiAgICBpc0Zhdm9yaXRlKG5hbWUpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5mYXZvcml0ZUVtb3Rlcy5oYXNPd25Qcm9wZXJ0eShuYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICBzYXZlRmF2b3JpdGVzKCkge1xyXG4gICAgICAgIERhdGFTdG9yZS5zZXRCRERhdGEoXCJiZGZhdmVtb3Rlc1wiLCB3aW5kb3cuYnRvYShKU09OLnN0cmluZ2lmeSh0aGlzLmZhdm9yaXRlRW1vdGVzKSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGVtcHR5RW1vdGVzKCkge1xyXG4gICAgICAgIGZvciAoY29uc3QgY2F0IGluIEVtb3RlcykgT2JqZWN0LmFzc2lnbihFbW90ZXMsIHtbY2F0XToge319KTtcclxuICAgIH1cclxuXHJcbiAgICBwYXRjaE1lc3NhZ2VDb250ZW50KCkge1xyXG4gICAgICAgIGlmICh0aGlzLmNhbmNlbEVtb3RlUmVuZGVyKSByZXR1cm47XHJcbiAgICAgICAgdGhpcy5jYW5jZWxFbW90ZVJlbmRlciA9IHRoaXMuYWZ0ZXIodGhpcy5NZXNzYWdlQ29udGVudENvbXBvbmVudC5wcm90b3R5cGUsIFwicmVuZGVyXCIsICh0aGlzT2JqLCBhcmdzLCByZXRWYWwpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5hZnRlcihyZXRWYWwucHJvcHMsIFwiY2hpbGRyZW5cIiwgKHQsIGEsIHJldHVyblZhbHVlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jYXRlZ29yaWVzLmxlbmd0aCA9PSAwKSByZXR1cm47XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtYXJrdXAgPSByZXR1cm5WYWx1ZS5wcm9wcy5jaGlsZHJlblsxXTtcclxuICAgICAgICAgICAgICAgIGlmICghbWFya3VwLnByb3BzLmNoaWxkcmVuKSByZXR1cm47XHJcbiAgICAgICAgICAgICAgICBjb25zdCBub2RlcyA9IG1hcmt1cC5wcm9wcy5jaGlsZHJlblsxXTtcclxuICAgICAgICAgICAgICAgIGlmICghbm9kZXMgfHwgIW5vZGVzLmxlbmd0aCkgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgbiA9IDA7IG4gPCBub2Rlcy5sZW5ndGg7IG4rKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSBub2Rlc1tuXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mKG5vZGUpICE9PSBcInN0cmluZ1wiKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB3b3JkcyA9IG5vZGUuc3BsaXQoLyhbXlxcc10rKShbXFxzXXwkKS9nKTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBjID0gMCwgY2xlbiA9IHRoaXMuY2F0ZWdvcmllcy5sZW5ndGg7IGMgPCBjbGVuOyBjKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgdyA9IDAsIHdsZW4gPSB3b3Jkcy5sZW5ndGg7IHcgPCB3bGVuOyB3KyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVtb3RlID0gd29yZHNbd107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbW90ZVNwbGl0ID0gZW1vdGUuc3BsaXQoXCI6XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZW1vdGVOYW1lID0gZW1vdGVTcGxpdFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlbW90ZU1vZGlmaWVyID0gZW1vdGVTcGxpdFsxXSA/IGVtb3RlU3BsaXRbMV0gOiBcIlwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGVtb3RlT3ZlcnJpZGUgPSBlbW90ZU1vZGlmaWVyLnNsaWNlKDApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbW90ZU5hbWUubGVuZ3RoIDwgNCB8fCBibGFja2xpc3QuaW5jbHVkZXMoZW1vdGVOYW1lKSkgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1vZGlmaWVycy5pbmNsdWRlcyhlbW90ZU1vZGlmaWVyKSB8fCAhU2V0dGluZ3MuZ2V0KHRoaXMuY2F0ZWdvcnksIFwiZ2VuZXJhbFwiLCBcIm1vZGlmaWVyc1wiKSkgZW1vdGVNb2RpZmllciA9IFwiXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW92ZXJyaWRlcy5pbmNsdWRlcyhlbW90ZU92ZXJyaWRlKSkgZW1vdGVPdmVycmlkZSA9IFwiXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGVtb3RlTW9kaWZpZXIgPSBlbW90ZU92ZXJyaWRlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjdXJyZW50ID0gdGhpcy5jYXRlZ29yaWVzW2NdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVtb3RlT3ZlcnJpZGUgPT09IFwidHdpdGNoXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoRW1vdGVzLlR3aXRjaEdsb2JhbFtlbW90ZU5hbWVdKSBjdXJyZW50ID0gXCJUd2l0Y2hHbG9iYWxcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChFbW90ZXMuVHdpdGNoU3Vic2NyaWJlcltlbW90ZU5hbWVdKSBjdXJyZW50ID0gXCJUd2l0Y2hTdWJzY3JpYmVyXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlbW90ZU92ZXJyaWRlID09PSBcImJ0dHZcIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChFbW90ZXMuQlRUVltlbW90ZU5hbWVdKSBjdXJyZW50ID0gXCJCVFRWXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoRW1vdGVzLkJUVFYyW2Vtb3RlTmFtZV0pIGN1cnJlbnQgPSBcIkJUVFYyXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlbW90ZU92ZXJyaWRlID09PSBcImZmelwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEVtb3Rlcy5GcmFua2VyRmFjZVpbZW1vdGVOYW1lXSkgY3VycmVudCA9IFwiRnJhbmtlckZhY2VaXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFFbW90ZXNbY3VycmVudF1bZW1vdGVOYW1lXSB8fCAhU2V0dGluZ3MuZ2V0KHRoaXMuY2F0ZWdvcnksIFwiY2F0ZWdvcmllc1wiLCBiZEVtb3RlU2V0dGluZ0lEc1tjdXJyZW50XSkpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IG5vZGVzW25dLm1hdGNoKG5ldyBSZWdFeHAoYChbXFxcXHNdfF4pJHtVdGlsaXRpZXMuZXNjYXBlKGVtb3RlTW9kaWZpZXIgPyBlbW90ZU5hbWUgKyBcIjpcIiArIGVtb3RlTW9kaWZpZXIgOiBlbW90ZU5hbWUpfShbXFxcXHNdfCQpYCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZXN1bHRzKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZSA9IG5vZGVzW25dLnN1YnN0cmluZygwLCByZXN1bHRzLmluZGV4ICsgcmVzdWx0c1sxXS5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zdCA9IG5vZGVzW25dLnN1YnN0cmluZyhyZXN1bHRzLmluZGV4ICsgcmVzdWx0c1swXS5sZW5ndGggLSByZXN1bHRzWzJdLmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2Rlc1tuXSA9IHByZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVtb3RlQ29tcG9uZW50ID0gRGlzY29yZE1vZHVsZXMuUmVhY3QuY3JlYXRlRWxlbWVudChCREVtb3RlLCB7bmFtZTogZW1vdGVOYW1lLCB1cmw6IEVtb3Rlc1tjdXJyZW50XVtlbW90ZU5hbWVdLCBtb2RpZmllcjogZW1vdGVNb2RpZmllciwgaXNGYXZvcml0ZTogdGhpcy5pc0Zhdm9yaXRlKGVtb3RlTmFtZSl9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzLnNwbGljZShuICsgMSwgMCwgcG9zdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2Rlcy5zcGxpY2UobiArIDEsIDAsIGVtb3RlQ29tcG9uZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbnN0IG9ubHlFbW90ZXMgPSBub2Rlcy5ldmVyeShyID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mKHIpID09IFwic3RyaW5nXCIgJiYgci5yZXBsYWNlKC9cXHMqLywgXCJcIikgPT0gXCJcIikgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoci50eXBlICYmIHIudHlwZS5uYW1lID09IFwiQkRFbW90ZVwiKSByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChyLnByb3BzICYmIHIucHJvcHMuY2hpbGRyZW4gJiYgci5wcm9wcy5jaGlsZHJlbi5wcm9wcyAmJiByLnByb3BzLmNoaWxkcmVuLnByb3BzLmVtb2ppTmFtZSkgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIW9ubHlFbW90ZXMpIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygbm9kZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mKG5vZGUpICE9IFwib2JqZWN0XCIpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlLnR5cGUubmFtZSA9PSBcIkJERW1vdGVcIikgbm9kZS5wcm9wcy5qdW1ib2FibGUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5vZGUucHJvcHMgJiYgbm9kZS5wcm9wcy5jaGlsZHJlbiAmJiBub2RlLnByb3BzLmNoaWxkcmVuLnByb3BzICYmIG5vZGUucHJvcHMuY2hpbGRyZW4ucHJvcHMuZW1vamlOYW1lKSBub2RlLnByb3BzLmNoaWxkcmVuLnByb3BzLmp1bWJvYWJsZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGxvYWRFbW90ZURhdGEoZW1vdGVJbmZvKSB7XHJcbiAgICAgICAgdGhpcy5lbW90ZXNMb2FkZWQgPSBmYWxzZTtcclxuICAgICAgICBjb25zdCBfZnMgPSByZXF1aXJlKFwiZnNcIik7XHJcbiAgICAgICAgY29uc3QgZW1vdGVGaWxlID0gXCJlbW90ZV9kYXRhLmpzb25cIjtcclxuICAgICAgICBjb25zdCBmaWxlID0gQ29uZmlnLmRhdGFQYXRoICsgZW1vdGVGaWxlO1xyXG4gICAgICAgIGNvbnN0IGV4aXN0cyA9IF9mcy5leGlzdHNTeW5jKGZpbGUpO1xyXG5cclxuICAgICAgICBpZiAoZXhpc3RzICYmIHRoaXMuaXNDYWNoZVZhbGlkKCkpIHtcclxuICAgICAgICAgICAgVG9hc3RzLnNob3coXCJMb2FkaW5nIGVtb3RlcyBmcm9tIGNhY2hlLlwiLCB7dHlwZTogXCJpbmZvXCJ9KTtcclxuICAgICAgICAgICAgdGhpcy5sb2coXCJMb2FkaW5nIGVtb3RlcyBmcm9tIGxvY2FsIGNhY2hlLlwiKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcclxuICAgICAgICAgICAgICAgIF9mcy5yZWFkRmlsZShmaWxlLCBcInV0ZjhcIiwgKGVyciwgY29udGVudCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9nKFwiRW1vdGVzIGxvYWRlZCBmcm9tIGNhY2hlLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyKSBjb250ZW50ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjb250ZW50KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IFV0aWxpdGllcy50ZXN0SlNPTihkYXRhKTtcclxuICAgICAgICAgICAgbGV0IGlzVmFsaWQgPSAhIXBhcnNlZDtcclxuICAgICAgICAgICAgaWYgKGlzVmFsaWQpIE9iamVjdC5hc3NpZ24oRW1vdGVzLCBwYXJzZWQpO1xyXG5cclxuICAgICAgICAgICAgZm9yIChjb25zdCBlIGluIGVtb3RlSW5mbykge1xyXG4gICAgICAgICAgICAgICAgaXNWYWxpZCA9IE9iamVjdC5rZXlzKEVtb3Rlc1tlbW90ZUluZm9bZV0udmFyaWFibGVdKS5sZW5ndGggPiAwO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoaXNWYWxpZCkge1xyXG4gICAgICAgICAgICAgICAgVG9hc3RzLnNob3coXCJFbW90ZXMgc3VjY2Vzc2Z1bGx5IGxvYWRlZC5cIiwge3R5cGU6IFwic3VjY2Vzc1wifSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVtb3Rlc0xvYWRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBFdmVudHMuZGlzcGF0Y2goXCJlbW90ZXMtbG9hZGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmxvZyhcIkNhY2hlIHdhcyBjb3JydXB0LCBkb3dubG9hZGluZy4uLlwiKTtcclxuICAgICAgICAgICAgX2ZzLnVubGlua1N5bmMoZmlsZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIVNldHRpbmdzLmdldCh0aGlzLmNhdGVnb3J5LCBcImdlbmVyYWxcIiwgXCJkb3dubG9hZFwiKSkgcmV0dXJuO1xyXG4gICAgICAgIFRvYXN0cy5zaG93KFN0cmluZ3MuRW1vdGVzLmRvd25sb2FkaW5nLCB7dHlwZTogXCJpbmZvXCJ9KTtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBlIGluIGVtb3RlSW5mbykge1xyXG4gICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZShyID0+IHNldFRpbWVvdXQociwgMTAwMCkpO1xyXG4gICAgICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy5kb3dubG9hZEVtb3RlcyhlbW90ZUluZm9bZV0pO1xyXG4gICAgICAgICAgICBFbW90ZXNbZW1vdGVJbmZvW2VdLnZhcmlhYmxlXSA9IGRhdGE7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBUb2FzdHMuc2hvdyhTdHJpbmdzLkVtb3Rlcy5kb3dubG9hZGVkLCB7dHlwZTogXCJzdWNjZXNzXCJ9KTtcclxuXHJcbiAgICAgICAgdHJ5IHsgX2ZzLndyaXRlRmlsZVN5bmMoZmlsZSwgSlNPTi5zdHJpbmdpZnkoRW1vdGVzKSwgXCJ1dGY4XCIpOyB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikgeyB0aGlzLnN0YWNrdHJhY2UoXCJDb3VsZCBub3Qgc2F2ZSBlbW90ZSBkYXRhLlwiLCBlcnIpOyB9XHJcblxyXG4gICAgICAgIHRoaXMuZW1vdGVzTG9hZGVkID0gdHJ1ZTtcclxuICAgICAgICBFdmVudHMuZGlzcGF0Y2goXCJlbW90ZXMtbG9hZGVkXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGRvd25sb2FkRW1vdGVzKGVtb3RlTWV0YSkge1xyXG4gICAgICAgIGNvbnN0IHJlcG9GaWxlID0gVXRpbGl0aWVzLnJlcG9VcmwoYGRhdGEvZW1vdGVzLyR7ZW1vdGVNZXRhLnZhcmlhYmxlLnRvTG93ZXJDYXNlKCl9Lmpzb25gKTtcclxuICAgICAgICBpZiAoZW1vdGVNZXRhLnVybCAmJiAhZW1vdGVNZXRhLmJhY2t1cCkgZW1vdGVNZXRhLmJhY2t1cCA9IHJlcG9GaWxlO1xyXG4gICAgICAgIGlmICghZW1vdGVNZXRhLnVybCkgZW1vdGVNZXRhLnVybCA9IHJlcG9GaWxlO1xyXG5cclxuICAgICAgICBjb25zdCBvcHRpb25zID0ge1xyXG4gICAgICAgICAgICB1cmw6IGVtb3RlTWV0YS51cmwsXHJcbiAgICAgICAgICAgIHRpbWVvdXQ6IGVtb3RlTWV0YS50aW1lb3V0ID8gZW1vdGVNZXRhLnRpbWVvdXQgOiA1MDAwLFxyXG4gICAgICAgICAgICBqc29uOiB0cnVlXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgdGhpcy5sb2coYERvd25sb2FkaW5nOiAke2Vtb3RlTWV0YS52YXJpYWJsZX0gKCR7ZW1vdGVNZXRhLnVybH0pYCk7XHJcblxyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIHJlcXVlc3QuZ2V0KG9wdGlvbnMsIChlcnJvciwgcmVzcG9uc2UsIHBhcnNlZERhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhY2t0cmFjZShcIkNvdWxkIG5vdCBkb3dubG9hZCBcIiArIGVtb3RlTWV0YS52YXJpYWJsZSwgZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlbW90ZU1ldGEuYmFja3VwIHx8IGVtb3RlTWV0YS51cmwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZW1vdGVNZXRhLnVybCA9IGVtb3RlTWV0YS5iYWNrdXA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVtb3RlTWV0YS5iYWNrdXAgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW1vdGVNZXRhLmJhY2t1cFBhcnNlcikgZW1vdGVNZXRhLnBhcnNlciA9IGVtb3RlTWV0YS5iYWNrdXBQYXJzZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHRoaXMuZG93bmxvYWRFbW90ZXMoZW1vdGVNZXRhKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3Qoe30pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YoZW1vdGVNZXRhLnBhcnNlcikgPT09IFwiZnVuY3Rpb25cIikgcGFyc2VkRGF0YSA9IGVtb3RlTWV0YS5wYXJzZXIocGFyc2VkRGF0YSk7XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBlbW90ZSBpbiBwYXJzZWREYXRhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVtb3RlLmxlbmd0aCA8IDQgfHwgYmxhY2tsaXN0LmluY2x1ZGVzKGVtb3RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgcGFyc2VkRGF0YVtlbW90ZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBwYXJzZWREYXRhW2Vtb3RlXSA9IGVtb3RlTWV0YS5nZXRFbW90ZVVSTChwYXJzZWREYXRhW2Vtb3RlXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKHBhcnNlZERhdGEpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2coXCJEb3dubG9hZGVkOiBcIiArIGVtb3RlTWV0YS52YXJpYWJsZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEJsYWNrbGlzdCgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XHJcbiAgICAgICAgICAgIHJlcXVlc3QuZ2V0KHt1cmw6IFV0aWxpdGllcy5yZXBvVXJsKGBkYXRhL2Vtb3Rlcy9ibGFja2xpc3QuanNvbmApLCBqc29uOiB0cnVlfSwgKGVyciwgcmVzcCwgZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVyciB8fCByZXNwLnN0YXR1c0NvZGUgIT0gMjAwKSByZXR1cm4gcmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShibGFja2xpc3QucHVzaCguLi5kYXRhKSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGlzQ2FjaGVWYWxpZCgpIHtcclxuICAgICAgICBjb25zdCBjYWNoZUxlbmd0aCA9IERhdGFTdG9yZS5nZXRCRERhdGEoXCJlbW90ZUNhY2hlRGF5c1wiKSB8fCBEYXRhU3RvcmUuc2V0QkREYXRhKFwiZW1vdGVDYWNoZURheXNcIiwgNykgfHwgNztcclxuICAgICAgICBjb25zdCBjYWNoZURhdGUgPSBuZXcgRGF0ZShEYXRhU3RvcmUuZ2V0QkREYXRhKFwiZW1vdGVDYWNoZURhdGVcIikgfHwgbnVsbCk7XHJcbiAgICAgICAgY29uc3QgY3VycmVudERhdGUgPSBuZXcgRGF0ZSgpO1xyXG4gICAgICAgIGNvbnN0IGRheXNCZXR3ZWVuID0gTWF0aC5yb3VuZChNYXRoLmFicygoY3VycmVudERhdGUuZ2V0VGltZSgpIC0gY2FjaGVEYXRlLmdldFRpbWUoKSkgLyAoMjQgKiA2MCAqIDYwICogMTAwMCkpKTtcclxuICAgICAgICBpZiAoZGF5c0JldHdlZW4gPiBjYWNoZUxlbmd0aCkge1xyXG4gICAgICAgICAgICBEYXRhU3RvcmUuc2V0QkREYXRhKFwiZW1vdGVDYWNoZURhdGVcIiwgY3VycmVudERhdGUudG9KU09OKCkpO1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGNsZWFyRW1vdGVEYXRhKCkge1xyXG4gICAgICAgIGNvbnN0IF9mcyA9IHJlcXVpcmUoXCJmc1wiKTtcclxuICAgICAgICBjb25zdCBlbW90ZUZpbGUgPSBcImVtb3RlX2RhdGEuanNvblwiO1xyXG4gICAgICAgIGNvbnN0IGZpbGUgPSBDb25maWcuZGF0YVBhdGggKyBlbW90ZUZpbGU7XHJcbiAgICAgICAgY29uc3QgZXhpc3RzID0gX2ZzLmV4aXN0c1N5bmMoZmlsZSk7XHJcbiAgICAgICAgaWYgKGV4aXN0cykgX2ZzLnVubGlua1N5bmMoZmlsZSk7XHJcbiAgICAgICAgRGF0YVN0b3JlLnNldEJERGF0YShcImVtb3RlQ2FjaGVEYXRlXCIsIChuZXcgRGF0ZSgpKS50b0pTT04oKSk7XHJcbiAgICAgICAgZm9yIChjb25zdCBjYXRlZ29yeSBpbiBFbW90ZXMpIE9iamVjdC5hc3NpZ24oRW1vdGVzLCB7W2NhdGVnb3J5XToge319KTtcclxuICAgIH1cclxufTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/builtins/emotes.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _structs_builtin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../structs/builtin */ \"./src/structs/builtin.js\");\n/* harmony import */ var data__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! data */ \"./src/data/data.js\");\n/* harmony import */ var modules__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! modules */ \"./src/modules/modules.js\");\n/* harmony import */ var _ui_emote__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../ui/emote */ \"./src/ui/emote.js\");\n/* harmony import */ var _ui_toasts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../ui/toasts */ \"./src/ui/toasts.js\");\n/* harmony import */ var _structs_string__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../structs/string */ \"./src/structs/string.js\");\n\n\n\n\n\n\n\nconst request = __webpack_require__(/*! request */ \"request\"); // const fs = require(\"fs\");\n\n\nconst EmoteURLs = {\n TwitchGlobal: new _structs_string__WEBPACK_IMPORTED_MODULE_5__[\"default\"](`https://static-cdn.jtvnw.net/emoticons/v1/{{id}}/1.0`),\n TwitchSubscriber: new _structs_string__WEBPACK_IMPORTED_MODULE_5__[\"default\"](`https://static-cdn.jtvnw.net/emoticons/v1/{{id}}/1.0`),\n FrankerFaceZ: new _structs_string__WEBPACK_IMPORTED_MODULE_5__[\"default\"](`https://cdn.frankerfacez.com/emoticon/{{id}}/1`),\n BTTV: new _structs_string__WEBPACK_IMPORTED_MODULE_5__[\"default\"](`https://cdn.betterttv.net/emote/{{id}}/1x`),\n BTTV2: new _structs_string__WEBPACK_IMPORTED_MODULE_5__[\"default\"](`https://cdn.betterttv.net/emote/{{id}}/1x`)\n};\nconst EmoteMetaInfo = {\n TwitchGlobal: {},\n TwitchSubscriber: {},\n BTTV: {},\n FrankerFaceZ: {},\n BTTV2: {}\n};\nconst Emotes = {\n TwitchGlobal: {},\n TwitchSubscriber: {},\n BTTV: {},\n FrankerFaceZ: {},\n BTTV2: {}\n};\nconst bdEmoteSettingIDs = {\n TwitchGlobal: \"twitch\",\n TwitchSubscriber: \"twitch\",\n BTTV: \"bttv\",\n FrankerFaceZ: \"ffz\",\n BTTV2: \"bttv\"\n};\nconst blacklist = [];\nconst overrides = [\"twitch\", \"bttv\", \"ffz\"];\nconst modifiers = [\"flip\", \"spin\", \"pulse\", \"spin2\", \"spin3\", \"1spin\", \"2spin\", \"3spin\", \"tr\", \"bl\", \"br\", \"shake\", \"shake2\", \"shake3\", \"flap\"];\n/* harmony default export */ __webpack_exports__[\"default\"] = (new class EmoteModule extends _structs_builtin__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\n get name() {\n return \"Emotes\";\n }\n\n get collection() {\n return \"settings\";\n }\n\n get category() {\n return \"general\";\n }\n\n get id() {\n return \"emotes\";\n }\n\n get categories() {\n return Object.keys(bdEmoteSettingIDs).filter(k => this.isCategoryEnabled(bdEmoteSettingIDs[k]));\n }\n\n get shouldDownload() {\n return modules__WEBPACK_IMPORTED_MODULE_2__[\"Settings\"].get(\"emotes\", this.category, \"download\");\n }\n\n isCategoryEnabled(id) {\n return super.get(\"emotes\", \"categories\", id);\n }\n\n get(id) {\n return super.get(\"emotes\", \"general\", id);\n }\n\n get MessageContentComponent() {\n return modules__WEBPACK_IMPORTED_MODULE_2__[\"WebpackModules\"].getModule(m => m.defaultProps && m.defaultProps.hasOwnProperty(\"disableButtons\"));\n }\n\n get Emotes() {\n return Emotes;\n }\n\n get TwitchGlobal() {\n return Emotes.TwitchGlobal;\n }\n\n get TwitchSubscriber() {\n return Emotes.TwitchSubscriber;\n }\n\n get BTTV() {\n return Emotes.BTTV;\n }\n\n get FrankerFaceZ() {\n return Emotes.FrankerFaceZ;\n }\n\n get BTTV2() {\n return Emotes.BTTV2;\n }\n\n get blacklist() {\n return blacklist;\n }\n\n get favorites() {\n return this.favoriteEmotes;\n }\n\n getCategory(category) {\n return Emotes[category];\n }\n\n getRemoteFile(category) {\n return new _structs_string__WEBPACK_IMPORTED_MODULE_5__[\"default\"](modules__WEBPACK_IMPORTED_MODULE_2__[\"Utilities\"].repoUrl(`data/emotes/${category.toLowerCase()}.json`));\n }\n\n initialize() {\n super.initialize();\n this.favoriteEmotes = {};\n const fe = modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].getBDData(\"bdfavemotes\");\n if (fe !== \"\" && fe !== null) this.favoriteEmotes = JSON.parse(window.atob(fe));\n this.saveFavorites();\n this.addFavorite = this.addFavorite.bind(this);\n this.removeFavorite = this.removeFavorite.bind(this); // EmoteConfig;\n // emoteCollection.button = {title: \"Clear Emote Cache\", onClick: () => { this.clearEmoteData(); this.loadEmoteData(EmoteInfo); }};\n }\n\n async enabled() {\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Settings\"].registerCollection(\"emotes\", \"Emotes\", data__WEBPACK_IMPORTED_MODULE_1__[\"EmoteConfig\"], {\n title: modules__WEBPACK_IMPORTED_MODULE_2__[\"Strings\"].Emotes.clearEmotes,\n onClick: () => {\n this.clearEmoteData();\n this.loadEmoteData();\n }\n }); // Disable emote module for now because it's annoying and slow\n\n await this.getBlacklist();\n await this.loadEmoteData();\n\n while (!this.MessageContentComponent) await new Promise(resolve => setTimeout(resolve, 100));\n\n this.patchMessageContent();\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Events\"].on(\"emotes-favorite-added\", this.addFavorite);\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Events\"].on(\"emotes-favorite-removed\", this.removeFavorite);\n }\n\n disabled() {\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Events\"].off(\"emotes-favorite-added\", this.addFavorite);\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Events\"].off(\"emotes-favorite-removed\", this.removeFavorite);\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Settings\"].removeCollection(\"emotes\");\n this.emptyEmotes();\n if (!this.cancelEmoteRender) return;\n this.cancelEmoteRender();\n delete this.cancelEmoteRender;\n }\n\n addFavorite(name, url) {\n if (!this.favoriteEmotes.hasOwnProperty(name)) this.favoriteEmotes[name] = url;\n this.saveFavorites();\n }\n\n removeFavorite(name) {\n if (!this.favoriteEmotes.hasOwnProperty(name)) return;\n delete this.favoriteEmotes[name];\n this.saveFavorites();\n }\n\n isFavorite(name) {\n return this.favoriteEmotes.hasOwnProperty(name);\n }\n\n saveFavorites() {\n modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].setBDData(\"bdfavemotes\", window.btoa(JSON.stringify(this.favoriteEmotes)));\n }\n\n emptyEmotes() {\n for (const cat in Emotes) Object.assign(Emotes, {\n [cat]: {}\n });\n }\n\n patchMessageContent() {\n if (this.cancelEmoteRender) return;\n this.cancelEmoteRender = this.after(this.MessageContentComponent.prototype, \"render\", (thisObj, args, retVal) => {\n this.after(retVal.props, \"children\", (t, a, returnValue) => {\n if (this.categories.length == 0) return;\n const markup = returnValue.props.children[1];\n if (!markup.props.children) return;\n const nodes = markup.props.children[1];\n if (!nodes || !nodes.length) return;\n\n for (let n = 0; n < nodes.length; n++) {\n const node = nodes[n];\n if (typeof node !== \"string\") continue;\n const words = node.split(/([^\\s]+)([\\s]|$)/g);\n\n for (let c = 0, clen = this.categories.length; c < clen; c++) {\n for (let w = 0, wlen = words.length; w < wlen; w++) {\n const emote = words[w];\n const emoteSplit = emote.split(\":\");\n const emoteName = emoteSplit[0];\n let emoteModifier = emoteSplit[1] ? emoteSplit[1] : \"\";\n let emoteOverride = emoteModifier.slice(0);\n if (emoteName.length < 4 || blacklist.includes(emoteName)) continue;\n if (!modifiers.includes(emoteModifier) || !modules__WEBPACK_IMPORTED_MODULE_2__[\"Settings\"].get(this.category, \"general\", \"modifiers\")) emoteModifier = \"\";\n if (!overrides.includes(emoteOverride)) emoteOverride = \"\";else emoteModifier = emoteOverride;\n let current = this.categories[c];\n\n if (emoteOverride === \"twitch\") {\n if (Emotes.TwitchGlobal[emoteName]) current = \"TwitchGlobal\";else if (Emotes.TwitchSubscriber[emoteName]) current = \"TwitchSubscriber\";\n } else if (emoteOverride === \"bttv\") {\n if (Emotes.BTTV[emoteName]) current = \"BTTV\";else if (Emotes.BTTV2[emoteName]) current = \"BTTV2\";\n } else if (emoteOverride === \"ffz\") {\n if (Emotes.FrankerFaceZ[emoteName]) current = \"FrankerFaceZ\";\n }\n\n if (!Emotes[current][emoteName] || !modules__WEBPACK_IMPORTED_MODULE_2__[\"Settings\"].get(this.category, \"categories\", bdEmoteSettingIDs[current])) continue;\n const results = nodes[n].match(new RegExp(`([\\\\s]|^)${modules__WEBPACK_IMPORTED_MODULE_2__[\"Utilities\"].escape(emoteModifier ? emoteName + \":\" + emoteModifier : emoteName)}([\\\\s]|$)`));\n if (!results) continue;\n const pre = nodes[n].substring(0, results.index + results[1].length);\n const post = nodes[n].substring(results.index + results[0].length - results[2].length);\n nodes[n] = pre;\n const emoteComponent = modules__WEBPACK_IMPORTED_MODULE_2__[\"DiscordModules\"].React.createElement(_ui_emote__WEBPACK_IMPORTED_MODULE_3__[\"default\"], {\n name: emoteName,\n url: Emotes[current][emoteName],\n modifier: emoteModifier,\n isFavorite: this.isFavorite(emoteName)\n });\n nodes.splice(n + 1, 0, post);\n nodes.splice(n + 1, 0, emoteComponent);\n }\n }\n }\n\n const onlyEmotes = nodes.every(r => {\n if (typeof r == \"string\" && r.replace(/\\s*/, \"\") == \"\") return true;else if (r.type && r.type.name == \"BDEmote\") return true;else if (r.props && r.props.children && r.props.children.props && r.props.children.props.emojiName) return true;\n return false;\n });\n if (!onlyEmotes) return;\n\n for (const node of nodes) {\n if (typeof node != \"object\") continue;\n if (node.type.name == \"BDEmote\") node.props.jumboable = true;else if (node.props && node.props.children && node.props.children.props && node.props.children.props.emojiName) node.props.children.props.jumboable = true;\n }\n });\n });\n }\n\n getBlacklist() {\n return new Promise(resolve => {\n request.get({\n url: modules__WEBPACK_IMPORTED_MODULE_2__[\"Utilities\"].repoUrl(`data/emotes/blacklist.json`),\n json: true\n }, (err, resp, data) => {\n if (err || resp.statusCode != 200) return resolve();\n resolve(blacklist.push(...data));\n });\n });\n }\n\n isCacheValid(category) {\n return new Promise(resolve => {\n const etag = modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].getCacheHash(\"emotes\", category);\n if (!etag) return resolve(false);\n request.head({\n url: this.getRemoteFile(category),\n headers: {\n \"If-None-Match\": etag\n }\n }, (err, resp) => {\n resolve(resp.statusCode == 304);\n });\n });\n }\n\n async loadEmoteData() {\n this.emotesLoaded = false;\n\n for (const category in Emotes) {\n const exists = modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].emotesExist(category);\n const valid = await this.isCacheValid(category);\n const useCache = valid || !valid && exists && !this.shouldDownload;\n let data = null;\n\n if (useCache) {\n this.log(`Loading ${category} emotes from local cache.`);\n const cachedData = modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].getEmoteData(category);\n const hasData = Object.keys(data).length > 0;\n if (hasData) data = cachedData;\n }\n\n if (!data) data = await this.downloadEmotes(category);\n Object.assign(Emotes[category], data);\n } // Toasts.show(Strings.Emotes.downloading, {type: \"info\"});\n // Toasts.show(Strings.Emotes.downloaded, {type: \"success\"});\n\n\n this.emotesLoaded = true;\n modules__WEBPACK_IMPORTED_MODULE_2__[\"Events\"].dispatch(\"emotes-loaded\");\n }\n\n downloadEmotes(category) {\n const url = this.getRemoteFile(category);\n this.log(`Downloading ${category} from ${url}`);\n const options = {\n url: url,\n timeout: 5000,\n json: true\n };\n return new Promise(resolve => {\n request.get(options, (error, response, parsedData) => {\n if (error || response.statusCode != 200) {\n this.stacktrace(`Could not download ${category} emotes.`, error);\n return resolve({});\n }\n\n for (const emote in parsedData) {\n if (emote.length < 4 || blacklist.includes(emote)) {\n delete parsedData[emote];\n continue;\n }\n\n parsedData[emote] = EmoteURLs[category].format({\n id: parsedData[emote]\n });\n }\n\n modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].saveEmoteData(category, parsedData);\n resolve(parsedData);\n this.log(`Downloaded ${category}`);\n });\n });\n }\n\n clearEmoteData() {\n const _fs = __webpack_require__(/*! fs */ \"fs\");\n\n const emoteFile = \"emote_data.json\";\n const file = data__WEBPACK_IMPORTED_MODULE_1__[\"Config\"].dataPath + emoteFile;\n\n const exists = _fs.existsSync(file);\n\n if (exists) _fs.unlinkSync(file);\n modules__WEBPACK_IMPORTED_MODULE_2__[\"DataStore\"].setBDData(\"emoteCacheDate\", new Date().toJSON());\n\n for (const category in Emotes) Object.assign(Emotes, {\n [category]: {}\n });\n }\n\n}()); // (async () => {\n// const emoteData = await new Promise(resolve => {\n// const req = require(\"request\");\n// req.get({url: \"https://twitchemotes.com/api_cache/v3/global.json\", json: true}, (err, resp, parsedData) => {\n// for (const emote in parsedData) {\n// if (emote.length < 4 || window.bemotes.includes(emote)) {\n// delete parsedData[emote];\n// continue;\n// }\n// parsedData[emote] = parsedData[emote].id;\n// }\n// resolve(parsedData);\n// });\n// });\n// const fs = require(\"fs\");\n// fs.writeFileSync(\"Z:\\\\Programming\\\\BetterDiscordStuff\\\\BetterDiscordApp\\\\data\\\\emotes\\\\global.json\", JSON.stringify(emoteData));\n// return emoteData;\n// })();//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Db3JlLy4vc3JjL2J1aWx0aW5zL2Vtb3Rlcy5qcz82YTA0Il0sIm5hbWVzIjpbInJlcXVlc3QiLCJyZXF1aXJlIiwiRW1vdGVVUkxzIiwiVHdpdGNoR2xvYmFsIiwiRm9ybWF0dGFibGVTdHJpbmciLCJUd2l0Y2hTdWJzY3JpYmVyIiwiRnJhbmtlckZhY2VaIiwiQlRUViIsIkJUVFYyIiwiRW1vdGVNZXRhSW5mbyIsIkVtb3RlcyIsImJkRW1vdGVTZXR0aW5nSURzIiwiYmxhY2tsaXN0Iiwib3ZlcnJpZGVzIiwibW9kaWZpZXJzIiwiRW1vdGVNb2R1bGUiLCJCdWlsdGluIiwibmFtZSIsImNvbGxlY3Rpb24iLCJjYXRlZ29yeSIsImlkIiwiY2F0ZWdvcmllcyIsIk9iamVjdCIsImtleXMiLCJmaWx0ZXIiLCJrIiwiaXNDYXRlZ29yeUVuYWJsZWQiLCJzaG91bGREb3dubG9hZCIsIlNldHRpbmdzIiwiZ2V0IiwiTWVzc2FnZUNvbnRlbnRDb21wb25lbnQiLCJXZWJwYWNrTW9kdWxlcyIsImdldE1vZHVsZSIsIm0iLCJkZWZhdWx0UHJvcHMiLCJoYXNPd25Qcm9wZXJ0eSIsImZhdm9yaXRlcyIsImZhdm9yaXRlRW1vdGVzIiwiZ2V0Q2F0ZWdvcnkiLCJnZXRSZW1vdGVGaWxlIiwiVXRpbGl0aWVzIiwicmVwb1VybCIsInRvTG93ZXJDYXNlIiwiaW5pdGlhbGl6ZSIsImZlIiwiRGF0YVN0b3JlIiwiZ2V0QkREYXRhIiwiSlNPTiIsInBhcnNlIiwid2luZG93IiwiYXRvYiIsInNhdmVGYXZvcml0ZXMiLCJhZGRGYXZvcml0ZSIsImJpbmQiLCJyZW1vdmVGYXZvcml0ZSIsImVuYWJsZWQiLCJyZWdpc3RlckNvbGxlY3Rpb24iLCJFbW90ZUNvbmZpZyIsInRpdGxlIiwiU3RyaW5ncyIsImNsZWFyRW1vdGVzIiwib25DbGljayIsImNsZWFyRW1vdGVEYXRhIiwibG9hZEVtb3RlRGF0YSIsImdldEJsYWNrbGlzdCIsIlByb21pc2UiLCJyZXNvbHZlIiwic2V0VGltZW91dCIsInBhdGNoTWVzc2FnZUNvbnRlbnQiLCJFdmVudHMiLCJvbiIsImRpc2FibGVkIiwib2ZmIiwicmVtb3ZlQ29sbGVjdGlvbiIsImVtcHR5RW1vdGVzIiwiY2FuY2VsRW1vdGVSZW5kZXIiLCJ1cmwiLCJpc0Zhdm9yaXRlIiwic2V0QkREYXRhIiwiYnRvYSIsInN0cmluZ2lmeSIsImNhdCIsImFzc2lnbiIsImFmdGVyIiwicHJvdG90eXBlIiwidGhpc09iaiIsImFyZ3MiLCJyZXRWYWwiLCJwcm9wcyIsInQiLCJhIiwicmV0dXJuVmFsdWUiLCJsZW5ndGgiLCJtYXJrdXAiLCJjaGlsZHJlbiIsIm5vZGVzIiwibiIsIm5vZGUiLCJ3b3JkcyIsInNwbGl0IiwiYyIsImNsZW4iLCJ3Iiwid2xlbiIsImVtb3RlIiwiZW1vdGVTcGxpdCIsImVtb3RlTmFtZSIsImVtb3RlTW9kaWZpZXIiLCJlbW90ZU92ZXJyaWRlIiwic2xpY2UiLCJpbmNsdWRlcyIsImN1cnJlbnQiLCJyZXN1bHRzIiwibWF0Y2giLCJSZWdFeHAiLCJlc2NhcGUiLCJwcmUiLCJzdWJzdHJpbmciLCJpbmRleCIsInBvc3QiLCJlbW90ZUNvbXBvbmVudCIsIkRpc2NvcmRNb2R1bGVzIiwiUmVhY3QiLCJjcmVhdGVFbGVtZW50IiwiQkRFbW90ZSIsIm1vZGlmaWVyIiwic3BsaWNlIiwib25seUVtb3RlcyIsImV2ZXJ5IiwiciIsInJlcGxhY2UiLCJ0eXBlIiwiZW1vamlOYW1lIiwianVtYm9hYmxlIiwianNvbiIsImVyciIsInJlc3AiLCJkYXRhIiwic3RhdHVzQ29kZSIsInB1c2giLCJpc0NhY2hlVmFsaWQiLCJldGFnIiwiZ2V0Q2FjaGVIYXNoIiwiaGVhZCIsImhlYWRlcnMiLCJlbW90ZXNMb2FkZWQiLCJleGlzdHMiLCJlbW90ZXNFeGlzdCIsInZhbGlkIiwidXNlQ2FjaGUiLCJsb2ciLCJjYWNoZWREYXRhIiwiZ2V0RW1vdGVEYXRhIiwiaGFzRGF0YSIsImRvd25sb2FkRW1vdGVzIiwiZGlzcGF0Y2giLCJvcHRpb25zIiwidGltZW91dCIsImVycm9yIiwicmVzcG9uc2UiLCJwYXJzZWREYXRhIiwic3RhY2t0cmFjZSIsImZvcm1hdCIsInNhdmVFbW90ZURhdGEiLCJfZnMiLCJlbW90ZUZpbGUiLCJmaWxlIiwiQ29uZmlnIiwiZGF0YVBhdGgiLCJleGlzdHNTeW5jIiwidW5saW5rU3luYyIsIkRhdGUiLCJ0b0pTT04iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUNBLE1BQU1BLE9BQU8sR0FBR0MsbUJBQU8sQ0FBQyx3QkFBRCxDQUF2QixDLENBQ0E7OztBQUVBLE1BQU1DLFNBQVMsR0FBRztBQUNkQyxjQUFZLEVBQUUsSUFBSUMsdURBQUosQ0FBdUIsc0RBQXZCLENBREE7QUFFZEMsa0JBQWdCLEVBQUUsSUFBSUQsdURBQUosQ0FBdUIsc0RBQXZCLENBRko7QUFHZEUsY0FBWSxFQUFFLElBQUlGLHVEQUFKLENBQXVCLGdEQUF2QixDQUhBO0FBSWRHLE1BQUksRUFBRSxJQUFJSCx1REFBSixDQUF1QiwyQ0FBdkIsQ0FKUTtBQUtkSSxPQUFLLEVBQUUsSUFBSUosdURBQUosQ0FBdUIsMkNBQXZCO0FBTE8sQ0FBbEI7QUFRQSxNQUFNSyxhQUFhLEdBQUc7QUFDbEJOLGNBQVksRUFBRSxFQURJO0FBRWxCRSxrQkFBZ0IsRUFBRSxFQUZBO0FBR2xCRSxNQUFJLEVBQUUsRUFIWTtBQUlsQkQsY0FBWSxFQUFFLEVBSkk7QUFLbEJFLE9BQUssRUFBRTtBQUxXLENBQXRCO0FBUUEsTUFBTUUsTUFBTSxHQUFHO0FBQ1hQLGNBQVksRUFBRSxFQURIO0FBRVhFLGtCQUFnQixFQUFFLEVBRlA7QUFHWEUsTUFBSSxFQUFFLEVBSEs7QUFJWEQsY0FBWSxFQUFFLEVBSkg7QUFLWEUsT0FBSyxFQUFFO0FBTEksQ0FBZjtBQVFBLE1BQU1HLGlCQUFpQixHQUFHO0FBQ3RCUixjQUFZLEVBQUUsUUFEUTtBQUV0QkUsa0JBQWdCLEVBQUUs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LE1BQU0sR0FBR2tCLEdBQUcsQ0FBQ0ssVUFBSixDQUFlSCxJQUFmLENBQWY7O0FBQ0EsUUFBSXBCLE1BQUosRUFBWWtCLEdBQUcsQ0FBQ00sVUFBSixDQUFlSixJQUFmO0FBQ1p6SCxxREFBUyxDQUFDaUMsU0FBVixDQUFvQixnQkFBcEIsRUFBdUMsSUFBSTZGLElBQUosRUFBRCxDQUFhQyxNQUFiLEVBQXRDOztBQUNBLFNBQUssTUFBTXpKLFFBQVgsSUFBdUJULE1BQXZCLEVBQStCWSxNQUFNLENBQUM0RCxNQUFQLENBQWN4RSxNQUFkLEVBQXNCO0FBQUMsT0FBQ1MsUUFBRCxHQUFZO0FBQWIsS0FBdEI7QUFDbEM7O0FBcE9nRCxDQUF0QyxFQUFmLEUsQ0F3T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6Ii4vc3JjL2J1aWx0aW5zL2Vtb3Rlcy5qcy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBCdWlsdGluIGZyb20gXCIuLi9zdHJ1Y3RzL2J1aWx0aW5cIjtcclxuXHJcbmltcG9ydCB7Q29uZmlnLCBFbW90ZUNvbmZpZ30gZnJvbSBcImRhdGFcIjtcclxuaW1wb3J0IHtVdGlsaXRpZXMsIFdlYnBhY2tNb2R1bGVzLCBEYXRhU3RvcmUsIERpc2NvcmRNb2R1bGVzLCBFdmVudHMsIFNldHRpbmdzLCBTdHJpbmdzfSBmcm9tIFwibW9kdWxlc1wiO1xyXG5pbXBvcnQgQkRFbW90ZSBmcm9tIFwiLi4vdWkvZW1vdGVcIjtcclxuaW1wb3J0IFRvYXN0cyBmcm9tIFwiLi4vdWkvdG9hc3RzXCI7XHJcbmltcG9ydCBGb3JtYXR0YWJsZVN0cmluZyBmcm9tIFwiLi4vc3RydWN0cy9zdHJpbmdcIjtcclxuY29uc3QgcmVxdWVzdCA9IHJlcXVpcmUoXCJyZXF1ZXN0XCIpO1xyXG4vLyBjb25zdCBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcclxuXHJcbmNvbnN0IEVtb3RlVVJMcyA9IHtcclxuICAgIFR3aXRjaEdsb2JhbDogbmV3IEZvcm1hdHRhYmxlU3RyaW5nKGBodHRwczovL3N0YXRpYy1jZG4uanR2bncubmV0L2Vtb3RpY29ucy92MS97e2lkfX0vMS4wYCksXHJcbiAgICBUd2l0Y2hTdWJzY3JpYmVyOiBuZXcgRm9ybWF0dGFibGVTdHJpbmcoYGh0dHBzOi8vc3RhdGljLWNkbi5qdHZudy5uZXQvZW1vdGljb25zL3YxL3t7aWR9fS8xLjBgKSxcclxuICAgIEZyYW5rZXJGYWNlWjogbmV3IEZvcm1hdHRhYmxlU3RyaW5nKGBodHRwczovL2Nkbi5mcmFua2VyZmFjZXouY29tL2Vtb3RpY29uL3t7aWR9fS8xYCksXHJcbiAgICBCVFRWOiBuZXcgRm9ybWF0dGFibGVTdHJpbmcoYGh0dHBzOi8vY2RuLmJldHRlcnR0di5uZXQvZW1vdGUve3tpZH19LzF4YCksXHJcbiAgICBCVFRWMjogbmV3IEZvcm1hdHRhYmxlU3RyaW5nKGBodHRwczovL2Nkbi5iZXR0ZXJ0dHYubmV0L2Vtb3RlL3t7aWR9fS8xeGApXHJcbn07XHJcblxyXG5jb25zdCBFbW90ZU1ldGFJbmZvID0ge1xyXG4gICAgVHdpdGNoR2xvYmFsOiB7fSxcclxuICAgIFR3aXRjaFN1YnNjcmliZXI6IHt9LFxyXG4gICAgQlRUVjoge30sXHJcbiAgICBGcmFua2VyRmFjZVo6IHt9LFxyXG4gICAgQlRUVjI6IHt9XHJcbn07XHJcblxyXG5jb25zdCBFbW90ZXMgPSB7XHJcbiAgICBUd2l0Y2hHbG9iYWw6IHt9LFxyXG4gICAgVHdpdGNoU3Vic2NyaWJlcjoge30sXHJcbiAgICBCVFRWOiB7fSxcclxuICAgIEZyYW5rZXJGYWNlWjoge30sXHJcbiAgICBCVFRWMjoge31cclxufTtcclxuXHJcbmNvbnN0IGJkRW1vdGVTZXR0aW5nSURzID0ge1xyXG4gICAgVHdpdGNoR2xvYmFsOiBcInR3aXRjaFwiLFxyXG4gICAgVHdpdGNoU3Vic2NyaWJlcjogXCJ0d2l0Y2hcIixcclxuICAgIEJUVFY6IFwiYnR0dlwiLFxyXG4gICAgRnJhbmtlckZhY2VaOiBcImZmelwiLFxyXG4gICAgQlRUVjI6IFwiYnR0dlwiXHJcbn07XHJcblxyXG5jb25zdCBibGFja2xpc3QgPSBbXTtcclxuY29uc3Qgb3ZlcnJpZGVzID0gW1widHdpdGNoXCIsIFwiYnR0dlwiLCBcImZmelwiXTtcclxuY29uc3QgbW9kaWZpZXJzID0gW1wiZmxpcFwiLCBcInNwaW5cIiwgXCJwdWxzZVwiLCBcInNwaW4yXCIsIFwic3BpbjNcIiwgXCIxc3BpblwiLCBcIjJzcGluXCIsIFwiM3NwaW5cIiwgXCJ0clwiLCBcImJsXCIsIFwiYnJcIiwgXCJzaGFrZVwiLCBcInNoYWtlMlwiLCBcInNoYWtlM1wiLCBcImZsYXBcIl07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBuZXcgY2xhc3MgRW1vdGVNb2R1bGUgZXh0ZW5kcyBCdWlsdGluIHtcclxuICAgIGdldCBuYW1lKCkge3JldHVybiBcIkVtb3Rlc1wiO31cclxuICAgIGdldCBjb2xsZWN0aW9uKCkge3JldHVybiBcInNldHRpbmdzXCI7fVxyXG4gICAgZ2V0IGNhdGVnb3J5KCkge3JldHVybiBcImdlbmVyYWxcIjt9XHJcbiAgICBnZXQgaWQoKSB7cmV0dXJuIFwiZW1vdGVzXCI7fVxyXG4gICAgZ2V0IGNhdGVnb3JpZXMoKSB7cmV0dXJuIE9iamVjdC5rZXlzKGJkRW1vdGVTZXR0aW5nSURzKS5maWx0ZXIoayA9PiB0aGlzLmlzQ2F0ZWdvcnlFbmFibGVkKGJkRW1vdGVTZXR0aW5nSURzW2tdKSk7fVxyXG4gICAgZ2V0IHNob3VsZERvd25sb2FkKCkge3JldHVybiBTZXR0aW5ncy5nZXQoXCJlbW90ZXNcIiwgdGhpcy5jYXRlZ29yeSwgXCJkb3dubG9hZFwiKTt9XHJcblxyXG4gICAgaXNDYXRlZ29yeUVuYWJsZWQoaWQpIHtyZXR1cm4gc3VwZXIuZ2V0KFwiZW1vdGVzXCIsIFwiY2F0ZWdvcmllc1wiLCBpZCk7fVxyXG5cclxuICAgIGdldChpZCkge3JldHVybiBzdXBlci5nZXQoXCJlbW90ZXNcIiwgXCJnZW5lcmFsXCIsIGlkKTt9XHJcblxyXG4gICAgZ2V0IE1lc3NhZ2VDb250ZW50Q29tcG9uZW50KCkge3JldHVybiBXZWJwYWNrTW9kdWxlcy5nZXRNb2R1bGUobSA9PiBtLmRlZmF1bHRQcm9wcyAmJiBtLmRlZmF1bHRQcm9wcy5oYXNPd25Qcm9wZXJ0eShcImRpc2FibGVCdXR0b25zXCIpKTt9XHJcblxyXG4gICAgZ2V0IEVtb3RlcygpIHtyZXR1cm4gRW1vdGVzO31cclxuICAgIGdldCBUd2l0Y2hHbG9iYWwoKSB7cmV0dXJuIEVtb3Rlcy5Ud2l0Y2hHbG9iYWw7fVxyXG4gICAgZ2V0IFR3aXRjaFN1YnNjcmliZXIoKSB7cmV0dXJuIEVtb3Rlcy5Ud2l0Y2hTdWJzY3JpYmVyO31cclxuICAgIGdldCBCVFRWKCkge3JldHVybiBFbW90ZXMuQlRUVjt9XHJcbiAgICBnZXQgRnJhbmtlckZhY2VaKCkge3JldHVybiBFbW90ZXMuRnJhbmtlckZhY2VaO31cclxuICAgIGdldCBCVFRWMigpIHtyZXR1cm4gRW1vdGVzLkJUVFYyO31cclxuICAgIGdldCBibGFja2xpc3QoKSB7cmV0dXJuIGJsYWNrbGlzdDt9XHJcbiAgICBnZXQgZmF2b3JpdGVzKCkge3JldHVybiB0aGlzLmZhdm9yaXRlRW1vdGVzO31cclxuXHJcbiAgICBnZXRDYXRlZ29yeShjYXRlZ29yeSkge3JldHVybiBFbW90ZXNbY2F0ZWdvcnldO31cclxuICAgIGdldFJlbW90ZUZpbGUoY2F0ZWdvcnkpIHtyZXR1cm4gbmV3IEZvcm1hdHRhYmxlU3RyaW5nKFV0aWxpdGllcy5yZXBvVXJsKGBkYXRhL2Vtb3Rlcy8ke2NhdGVnb3J5LnRvTG93ZXJDYXNlKCl9Lmpzb25gKSk7fVxyXG5cclxuICAgIGluaXRpYWxpemUoKSB7XHJcbiAgICAgICAgc3VwZXIuaW5pdGlhbGl6ZSgpO1xyXG4gICAgICAgIHRoaXMuZmF2b3JpdGVFbW90ZXMgPSB7fTtcclxuICAgICAgICBjb25zdCBmZSA9IERhdGFTdG9yZS5nZXRCRERhdGEoXCJiZGZhdmVtb3Rlc1wiKTtcclxuICAgICAgICBpZiAoZmUgIT09IFwiXCIgJiYgZmUgIT09IG51bGwpIHRoaXMuZmF2b3JpdGVFbW90ZXMgPSBKU09OLnBhcnNlKHdpbmRvdy5hdG9iKGZlKSk7XHJcbiAgICAgICAgdGhpcy5zYXZlRmF2b3JpdGVzKCk7XHJcbiAgICAgICAgdGhpcy5hZGRGYXZvcml0ZSA9IHRoaXMuYWRkRmF2b3JpdGUuYmluZCh0aGlzKTtcclxuICAgICAgICB0aGlzLnJlbW92ZUZhdm9yaXRlID0gdGhpcy5yZW1vdmVGYXZvcml0ZS5iaW5kKHRoaXMpO1xyXG4gICAgICAgIC8vIEVtb3RlQ29uZmlnO1xyXG4gICAgICAgIC8vIGVtb3RlQ29sbGVjdGlvbi5idXR0b24gPSB7dGl0bGU6IFwiQ2xlYXIgRW1vdGUgQ2FjaGVcIiwgb25DbGljazogKCkgPT4geyB0aGlzLmNsZWFyRW1vdGVEYXRhKCk7IHRoaXMubG9hZEVtb3RlRGF0YShFbW90ZUluZm8pOyB9fTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBlbmFibGVkKCkge1xyXG4gICAgICAgIFNldHRpbmdzLnJlZ2lzdGVyQ29sbGVjdGlvbihcImVtb3Rlc1wiLCBcIkVtb3Rlc1wiLCBFbW90ZUNvbmZpZywge3RpdGxlOiBTdHJpbmdzLkVtb3Rlcy5jbGVhckVtb3Rlcywgb25DbGljazogKCkgPT4ge3RoaXMuY2xlYXJFbW90ZURhdGEoKTsgdGhpcy5sb2FkRW1vdGVEYXRhKCk7fX0pO1xyXG4gICAgICAgIC8vIERpc2FibGUgZW1vdGUgbW9kdWxlIGZvciBub3cgYmVjYXVzZSBpdCdzIGFubm95aW5nIGFuZCBzbG93XHJcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCbGFja2xpc3QoKTtcclxuICAgICAgICBhd2FpdCB0aGlzLmxvYWRFbW90ZURhdGEoKTtcclxuXHJcbiAgICAgICAgd2hpbGUgKCF0aGlzLk1lc3NhZ2VDb250ZW50Q29tcG9uZW50KSBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMTAwKSk7XHJcbiAgICAgICAgdGhpcy5wYXRjaE1lc3NhZ2VDb250ZW50KCk7XHJcbiAgICAgICAgRXZlbnRzLm9uKFwiZW1vdGVzLWZhdm9yaXRlLWFkZGVkXCIsIHRoaXMuYWRkRmF2b3JpdGUpO1xyXG4gICAgICAgIEV2ZW50cy5vbihcImVtb3Rlcy1mYXZvcml0ZS1yZW1vdmVkXCIsIHRoaXMucmVtb3ZlRmF2b3JpdGUpO1xyXG4gICAgfVxyXG5cclxuICAgIGRpc2FibGVkKCkge1xyXG4gICAgICAgIEV2ZW50cy5vZmYoXCJlbW90ZXMtZmF2b3JpdGUtYWRkZWRcIiwgdGhpcy5hZGRGYXZvcml0ZSk7XHJcbiAgICAgICAgRXZlbnRzLm9mZihcImVtb3Rlcy1mYXZvcml0ZS1yZW1vdmVkXCIsIHRoaXMucmVtb3ZlRmF2b3JpdGUpO1xyXG4gICAgICAgIFNldHRpbmdzLnJlbW92ZUNvbGxlY3Rpb24oXCJlbW90ZXNcIik7XHJcbiAgICAgICAgdGhpcy5lbXB0eUVtb3RlcygpO1xyXG4gICAgICAgIGlmICghdGhpcy5jYW5jZWxFbW90ZVJlbmRlcikgcmV0dXJuO1xyXG4gICAgICAgIHRoaXMuY2FuY2VsRW1vdGVSZW5kZXIoKTtcclxuICAgICAgICBkZWxldGUgdGhpcy5jYW5jZWxFbW90ZVJlbmRlcjtcclxuICAgIH1cclxuXHJcbiAgICBhZGRGYXZvcml0ZShuYW1lLCB1cmwpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZmF2b3JpdGVFbW90ZXMuaGFzT3duUHJvcGVydHkobmFtZSkpIHRoaXMuZmF2b3JpdGVFbW90ZXNbbmFtZV0gPSB1cmw7XHJcbiAgICAgICAgdGhpcy5zYXZlRmF2b3JpdGVzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlRmF2b3JpdGUobmFtZSkge1xyXG4gICAgICAgIGlmICghdGhpcy5mYXZvcml0ZUVtb3Rlcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkgcmV0dXJuO1xyXG4gICAgICAgIGRlbGV0ZSB0aGlzLmZhdm9yaXRlRW1vdGVzW25hbWVdO1xyXG4gICAgICAgIHRoaXMuc2F2ZUZhdm9yaXRlcygpO1xyXG4gICAgfVxyXG5cclxuICAgIGlzRmF2b3JpdGUobmFtZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmZhdm9yaXRlRW1vdGVzLmhhc093blByb3BlcnR5KG5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIHNhdmVGYXZvcml0ZXMoKSB7XHJcbiAgICAgICAgRGF0YVN0b3JlLnNldEJERGF0YShcImJkZmF2ZW1vdGVzXCIsIHdpbmRvdy5idG9hKEpTT04uc3RyaW5naWZ5KHRoaXMuZmF2b3JpdGVFbW90ZXMpKSk7XHJcbiAgICB9XHJcblxyXG4gICAgZW1wdHlFbW90ZXMoKSB7XHJcbiAgICAgICAgZm9yIChjb25zdCBjYXQgaW4gRW1vdGVzKSBPYmplY3QuYXNzaWduKEVtb3Rlcywge1tjYXRdOiB7fX0pO1xyXG4gICAgfVxyXG5cclxuICAgIHBhdGNoTWVzc2FnZUNvbnRlbnQoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY2FuY2VsRW1vdGVSZW5kZXIpIHJldHVybjtcclxuICAgICAgICB0aGlzLmNhbmNlbEVtb3RlUmVuZGVyID0gdGhpcy5hZnRlcih0aGlzLk1lc3NhZ2VDb250ZW50Q29tcG9uZW50LnByb3RvdHlwZSwgXCJyZW5kZXJcIiwgKHRoaXNPYmosIGFyZ3MsIHJldFZhbCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmFmdGVyKHJldFZhbC5wcm9wcywgXCJjaGlsZHJlblwiLCAodCwgYSwgcmV0dXJuVmFsdWUpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNhdGVnb3JpZXMubGVuZ3RoID09IDApIHJldHVybjtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG1hcmt1cCA9IHJldHVyblZhbHVlLnByb3BzLmNoaWxkcmVuWzFdO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFtYXJrdXAucHJvcHMuY2hpbGRyZW4pIHJldHVybjtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5vZGVzID0gbWFya3VwLnByb3BzLmNoaWxkcmVuWzFdO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFub2RlcyB8fCAhbm9kZXMubGVuZ3RoKSByZXR1cm47XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBuID0gMDsgbiA8IG5vZGVzLmxlbmd0aDsgbisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IG5vZGVzW25dO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Yobm9kZSkgIT09IFwic3RyaW5nXCIpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdvcmRzID0gbm9kZS5zcGxpdCgvKFteXFxzXSspKFtcXHNdfCQpL2cpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGMgPSAwLCBjbGVuID0gdGhpcy5jYXRlZ29yaWVzLmxlbmd0aDsgYyA8IGNsZW47IGMrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB3ID0gMCwgd2xlbiA9IHdvcmRzLmxlbmd0aDsgdyA8IHdsZW47IHcrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZW1vdGUgPSB3b3Jkc1t3XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVtb3RlU3BsaXQgPSBlbW90ZS5zcGxpdChcIjpcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbW90ZU5hbWUgPSBlbW90ZVNwbGl0WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGVtb3RlTW9kaWZpZXIgPSBlbW90ZVNwbGl0WzFdID8gZW1vdGVTcGxpdFsxXSA6IFwiXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZW1vdGVPdmVycmlkZSA9IGVtb3RlTW9kaWZpZXIuc2xpY2UoMCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVtb3RlTmFtZS5sZW5ndGggPCA0IHx8IGJsYWNrbGlzdC5pbmNsdWRlcyhlbW90ZU5hbWUpKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbW9kaWZpZXJzLmluY2x1ZGVzKGVtb3RlTW9kaWZpZXIpIHx8ICFTZXR0aW5ncy5nZXQodGhpcy5jYXRlZ29yeSwgXCJnZW5lcmFsXCIsIFwibW9kaWZpZXJzXCIpKSBlbW90ZU1vZGlmaWVyID0gXCJcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghb3ZlcnJpZGVzLmluY2x1ZGVzKGVtb3RlT3ZlcnJpZGUpKSBlbW90ZU92ZXJyaWRlID0gXCJcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZW1vdGVNb2RpZmllciA9IGVtb3RlT3ZlcnJpZGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGN1cnJlbnQgPSB0aGlzLmNhdGVnb3JpZXNbY107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW1vdGVPdmVycmlkZSA9PT0gXCJ0d2l0Y2hcIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChFbW90ZXMuVHdpdGNoR2xvYmFsW2Vtb3RlTmFtZV0pIGN1cnJlbnQgPSBcIlR3aXRjaEdsb2JhbFwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKEVtb3Rlcy5Ud2l0Y2hTdWJzY3JpYmVyW2Vtb3RlTmFtZV0pIGN1cnJlbnQgPSBcIlR3aXRjaFN1YnNjcmliZXJcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVtb3RlT3ZlcnJpZGUgPT09IFwiYnR0dlwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEVtb3Rlcy5CVFRWW2Vtb3RlTmFtZV0pIGN1cnJlbnQgPSBcIkJUVFZcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChFbW90ZXMuQlRUVjJbZW1vdGVOYW1lXSkgY3VycmVudCA9IFwiQlRUVjJcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVtb3RlT3ZlcnJpZGUgPT09IFwiZmZ6XCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoRW1vdGVzLkZyYW5rZXJGYWNlWltlbW90ZU5hbWVdKSBjdXJyZW50ID0gXCJGcmFua2VyRmFjZVpcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUVtb3Rlc1tjdXJyZW50XVtlbW90ZU5hbWVdIHx8ICFTZXR0aW5ncy5nZXQodGhpcy5jYXRlZ29yeSwgXCJjYXRlZ29yaWVzXCIsIGJkRW1vdGVTZXR0aW5nSURzW2N1cnJlbnRdKSkgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHRzID0gbm9kZXNbbl0ubWF0Y2gobmV3IFJlZ0V4cChgKFtcXFxcc118Xikke1V0aWxpdGllcy5lc2NhcGUoZW1vdGVNb2RpZmllciA/IGVtb3RlTmFtZSArIFwiOlwiICsgZW1vdGVNb2RpZmllciA6IGVtb3RlTmFtZSl9KFtcXFxcc118JClgKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdHMpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJlID0gbm9kZXNbbl0uc3Vic3RyaW5nKDAsIHJlc3VsdHMuaW5kZXggKyByZXN1bHRzWzFdLmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3N0ID0gbm9kZXNbbl0uc3Vic3RyaW5nKHJlc3VsdHMuaW5kZXggKyByZXN1bHRzWzBdLmxlbmd0aCAtIHJlc3VsdHNbMl0ubGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzW25dID0gcHJlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZW1vdGVDb21wb25lbnQgPSBEaXNjb3JkTW9kdWxlcy5SZWFjdC5jcmVhdGVFbGVtZW50KEJERW1vdGUsIHtuYW1lOiBlbW90ZU5hbWUsIHVybDogRW1vdGVzW2N1cnJlbnRdW2Vtb3RlTmFtZV0sIG1vZGlmaWVyOiBlbW90ZU1vZGlmaWVyLCBpc0Zhdm9yaXRlOiB0aGlzLmlzRmF2b3JpdGUoZW1vdGVOYW1lKX0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXMuc3BsaWNlKG4gKyAxLCAwLCBwb3N0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzLnNwbGljZShuICsgMSwgMCwgZW1vdGVDb21wb25lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY29uc3Qgb25seUVtb3RlcyA9IG5vZGVzLmV2ZXJ5KHIgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YocikgPT0gXCJzdHJpbmdcIiAmJiByLnJlcGxhY2UoL1xccyovLCBcIlwiKSA9PSBcIlwiKSByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChyLnR5cGUgJiYgci50eXBlLm5hbWUgPT0gXCJCREVtb3RlXCIpIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHIucHJvcHMgJiYgci5wcm9wcy5jaGlsZHJlbiAmJiByLnByb3BzLmNoaWxkcmVuLnByb3BzICYmIHIucHJvcHMuY2hpbGRyZW4ucHJvcHMuZW1vamlOYW1lKSByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGlmICghb25seUVtb3RlcykgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBub2Rlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Yobm9kZSkgIT0gXCJvYmplY3RcIikgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUudHlwZS5uYW1lID09IFwiQkRFbW90ZVwiKSBub2RlLnByb3BzLmp1bWJvYWJsZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobm9kZS5wcm9wcyAmJiBub2RlLnByb3BzLmNoaWxkcmVuICYmIG5vZGUucHJvcHMuY2hpbGRyZW4ucHJvcHMgJiYgbm9kZS5wcm9wcy5jaGlsZHJlbi5wcm9wcy5lbW9qaU5hbWUpIG5vZGUucHJvcHMuY2hpbGRyZW4ucHJvcHMuanVtYm9hYmxlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0QmxhY2tsaXN0KCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcclxuICAgICAgICAgICAgcmVxdWVzdC5nZXQoe3VybDogVXRpbGl0aWVzLnJlcG9VcmwoYGRhdGEvZW1vdGVzL2JsYWNrbGlzdC5qc29uYCksIGpzb246IHRydWV9LCAoZXJyLCByZXNwLCBkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyIHx8IHJlc3Auc3RhdHVzQ29kZSAhPSAyMDApIHJldHVybiByZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKGJsYWNrbGlzdC5wdXNoKC4uLmRhdGEpKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaXNDYWNoZVZhbGlkKGNhdGVnb3J5KSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBldGFnID0gRGF0YVN0b3JlLmdldENhY2hlSGFzaChcImVtb3Rlc1wiLCBjYXRlZ29yeSk7XHJcbiAgICAgICAgICAgIGlmICghZXRhZykgcmV0dXJuIHJlc29sdmUoZmFsc2UpO1xyXG4gICAgICAgICAgICByZXF1ZXN0LmhlYWQoe3VybDogdGhpcy5nZXRSZW1vdGVGaWxlKGNhdGVnb3J5KSwgaGVhZGVyczoge1wiSWYtTm9uZS1NYXRjaFwiOiBldGFnfX0sIChlcnIsIHJlc3ApID0+IHtcclxuICAgICAgICAgICAgICAgIHJlc29sdmUocmVzcC5zdGF0dXNDb2RlID09IDMwNCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGxvYWRFbW90ZURhdGEoKSB7XHJcbiAgICAgICAgdGhpcy5lbW90ZXNMb2FkZWQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBjYXRlZ29yeSBpbiBFbW90ZXMpIHtcclxuICAgICAgICAgICAgY29uc3QgZXhpc3RzID0gRGF0YVN0b3JlLmVtb3Rlc0V4aXN0KGNhdGVnb3J5KTtcclxuICAgICAgICAgICAgY29uc3QgdmFsaWQgPSBhd2FpdCB0aGlzLmlzQ2FjaGVWYWxpZChjYXRlZ29yeSk7XHJcbiAgICAgICAgICAgIGNvbnN0IHVzZUNhY2hlID0gKHZhbGlkKSB8fCAoIXZhbGlkICYmIGV4aXN0cyAmJiAhdGhpcy5zaG91bGREb3dubG9hZCk7XHJcbiAgICAgICAgICAgIGxldCBkYXRhID0gbnVsbDtcclxuICAgICAgICAgICAgaWYgKHVzZUNhY2hlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvZyhgTG9hZGluZyAke2NhdGVnb3J5fSBlbW90ZXMgZnJvbSBsb2NhbCBjYWNoZS5gKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNhY2hlZERhdGEgPSBEYXRhU3RvcmUuZ2V0RW1vdGVEYXRhKGNhdGVnb3J5KTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGhhc0RhdGEgPSBPYmplY3Qua2V5cyhkYXRhKS5sZW5ndGggPiAwO1xyXG4gICAgICAgICAgICAgICAgaWYgKGhhc0RhdGEpIGRhdGEgPSBjYWNoZWREYXRhO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghZGF0YSkgZGF0YSA9IGF3YWl0IHRoaXMuZG93bmxvYWRFbW90ZXMoY2F0ZWdvcnkpO1xyXG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKEVtb3Rlc1tjYXRlZ29yeV0sIGRhdGEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gVG9hc3RzLnNob3coU3RyaW5ncy5FbW90ZXMuZG93bmxvYWRpbmcsIHt0eXBlOiBcImluZm9cIn0pO1xyXG4gICAgICAgIC8vIFRvYXN0cy5zaG93KFN0cmluZ3MuRW1vdGVzLmRvd25sb2FkZWQsIHt0eXBlOiBcInN1Y2Nlc3NcIn0pO1xyXG5cclxuICAgICAgICB0aGlzLmVtb3Rlc0xvYWRlZCA9IHRydWU7XHJcbiAgICAgICAgRXZlbnRzLmRpc3BhdGNoKFwiZW1vdGVzLWxvYWRlZFwiKTtcclxuICAgIH1cclxuXHJcbiAgICBkb3dubG9hZEVtb3RlcyhjYXRlZ29yeSkge1xyXG4gICAgICAgIGNvbnN0IHVybCA9IHRoaXMuZ2V0UmVtb3RlRmlsZShjYXRlZ29yeSk7XHJcbiAgICAgICAgdGhpcy5sb2coYERvd25sb2FkaW5nICR7Y2F0ZWdvcnl9IGZyb20gJHt1cmx9YCk7XHJcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHt1cmw6IHVybCwgdGltZW91dDogNTAwMCwganNvbjogdHJ1ZX07XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xyXG4gICAgICAgICAgICByZXF1ZXN0LmdldChvcHRpb25zLCAoZXJyb3IsIHJlc3BvbnNlLCBwYXJzZWREYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IgfHwgcmVzcG9uc2Uuc3RhdHVzQ29kZSAhPSAyMDApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YWNrdHJhY2UoYENvdWxkIG5vdCBkb3dubG9hZCAke2NhdGVnb3J5fSBlbW90ZXMuYCwgZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHt9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGVtb3RlIGluIHBhcnNlZERhdGEpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZW1vdGUubGVuZ3RoIDwgNCB8fCBibGFja2xpc3QuaW5jbHVkZXMoZW1vdGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBwYXJzZWREYXRhW2Vtb3RlXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlZERhdGFbZW1vdGVdID0gRW1vdGVVUkxzW2NhdGVnb3J5XS5mb3JtYXQoe2lkOiBwYXJzZWREYXRhW2Vtb3RlXX0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgRGF0YVN0b3JlLnNhdmVFbW90ZURhdGEoY2F0ZWdvcnksIHBhcnNlZERhdGEpO1xyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShwYXJzZWREYXRhKTtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9nKGBEb3dubG9hZGVkICR7Y2F0ZWdvcnl9YCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGNsZWFyRW1vdGVEYXRhKCkge1xyXG4gICAgICAgIGNvbnN0IF9mcyA9IHJlcXVpcmUoXCJmc1wiKTtcclxuICAgICAgICBjb25zdCBlbW90ZUZpbGUgPSBcImVtb3RlX2RhdGEuanNvblwiO1xyXG4gICAgICAgIGNvbnN0IGZpbGUgPSBDb25maWcuZGF0YVBhdGggKyBlbW90ZUZpbGU7XHJcbiAgICAgICAgY29uc3QgZXhpc3RzID0gX2ZzLmV4aXN0c1N5bmMoZmlsZSk7XHJcbiAgICAgICAgaWYgKGV4aXN0cykgX2ZzLnVubGlua1N5bmMoZmlsZSk7XHJcbiAgICAgICAgRGF0YVN0b3JlLnNldEJERGF0YShcImVtb3RlQ2FjaGVEYXRlXCIsIChuZXcgRGF0ZSgpKS50b0pTT04oKSk7XHJcbiAgICAgICAgZm9yIChjb25zdCBjYXRlZ29yeSBpbiBFbW90ZXMpIE9iamVjdC5hc3NpZ24oRW1vdGVzLCB7W2NhdGVnb3J5XToge319KTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLyAoYXN5bmMgKCkgPT4ge1xyXG4vLyAgICAgY29uc3QgZW1vdGVEYXRhID0gYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XHJcbi8vICAgICAgICAgY29uc3QgcmVxID0gcmVxdWlyZShcInJlcXVlc3RcIik7XHJcbi8vICAgICAgICAgcmVxLmdldCh7dXJsOiBcImh0dHBzOi8vdHdpdGNoZW1vdGVzLmNvbS9hcGlfY2FjaGUvdjMvZ2xvYmFsLmpzb25cIiwganNvbjogdHJ1ZX0sIChlcnIsIHJlc3AsIHBhcnNlZERhdGEpID0+IHtcclxuLy8gICAgICAgICAgICAgZm9yIChjb25zdCBlbW90ZSBpbiBwYXJzZWREYXRhKSB7XHJcbi8vICAgICAgICAgICAgICAgICBpZiAoZW1vdGUubGVuZ3RoIDwgNCB8fCB3aW5kb3cuYmVtb3Rlcy5pbmNsdWRlcyhlbW90ZSkpIHtcclxuLy8gICAgICAgICAgICAgICAgICAgICBkZWxldGUgcGFyc2VkRGF0YVtlbW90ZV07XHJcbi8vICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbi8vICAgICAgICAgICAgICAgICB9XHJcbi8vICAgICAgICAgICAgICAgICBwYXJzZWREYXRhW2Vtb3RlXSA9IHBhcnNlZERhdGFbZW1vdGVdLmlkO1xyXG4vLyAgICAgICAgICAgICB9XHJcbi8vICAgICAgICAgICAgIHJlc29sdmUocGFyc2VkRGF0YSk7XHJcbi8vICAgICAgICAgfSk7XHJcbi8vICAgICB9KTtcclxuLy8gICAgIGNvbnN0IGZzID0gcmVxdWlyZShcImZzXCIpO1xyXG4vLyAgICAgZnMud3JpdGVGaWxlU3luYyhcIlo6XFxcXFByb2dyYW1taW5nXFxcXEJldHRlckRpc2NvcmRTdHVmZlxcXFxCZXR0ZXJEaXNjb3JkQXBwXFxcXGRhdGFcXFxcZW1vdGVzXFxcXGdsb2JhbC5qc29uXCIsIEpTT04uc3RyaW5naWZ5KGVtb3RlRGF0YSkpO1xyXG4vLyAgICAgcmV0dXJuIGVtb3RlRGF0YTtcclxuLy8gfSkoKTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/builtins/emotes.js\n"); /***/ }), @@ -283,35 +283,11 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ /*!**************************!*\ !*** ./src/data/data.js ***! \**************************/ -/*! exports provided: Config, EmoteInfo, EmoteConfig, SettingsConfig */ +/*! exports provided: Config, EmoteConfig, SettingsConfig, Strings */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./config */ \"./src/data/config.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"Config\", function() { return _config__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; });\n\n/* harmony import */ var _emotes_info__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./emotes/info */ \"./src/data/emotes/info.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"EmoteInfo\", function() { return _emotes_info__WEBPACK_IMPORTED_MODULE_1__[\"default\"]; });\n\n/* harmony import */ var _emotes_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./emotes/config */ \"./src/data/emotes/config.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"EmoteConfig\", function() { return _emotes_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"]; });\n\n/* harmony import */ var _settings_config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./settings/config */ \"./src/data/settings/config.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"SettingsConfig\", function() { return _settings_config__WEBPACK_IMPORTED_MODULE_3__[\"default\"]; });\n\n\n\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Db3JlLy4vc3JjL2RhdGEvZGF0YS5qcz9kNWM3Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiLi9zcmMvZGF0YS9kYXRhLmpzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENvbmZpZyBmcm9tIFwiLi9jb25maWdcIjtcclxuaW1wb3J0IEVtb3RlSW5mbyBmcm9tIFwiLi9lbW90ZXMvaW5mb1wiO1xyXG5pbXBvcnQgRW1vdGVDb25maWcgZnJvbSBcIi4vZW1vdGVzL2NvbmZpZ1wiO1xyXG5pbXBvcnQgU2V0dGluZ3NDb25maWcgZnJvbSBcIi4vc2V0dGluZ3MvY29uZmlnXCI7XHJcblxyXG5leHBvcnQge0NvbmZpZywgRW1vdGVJbmZvLCBFbW90ZUNvbmZpZywgU2V0dGluZ3NDb25maWd9OyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/data/data.js\n"); - -/***/ }), - -/***/ "./src/data/emotes/config.js": -/*!***********************************!*\ - !*** ./src/data/emotes/config.js ***! - \***********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = ([{\n type: \"category\",\n id: \"general\",\n name: \"General\",\n collapsible: true,\n settings: [{\n type: \"switch\",\n id: \"download\",\n value: true\n }, {\n type: \"switch\",\n id: \"emoteMenu\",\n value: true\n }, {\n type: \"switch\",\n id: \"hideEmojiMenu\",\n value: false,\n enableWith: \"emoteMenu\"\n }, {\n type: \"switch\",\n id: \"autoCaps\",\n value: false\n }, {\n type: \"switch\",\n id: \"showNames\",\n value: true\n }, {\n type: \"switch\",\n id: \"modifiers\",\n value: true\n }, {\n type: \"switch\",\n id: \"animateOnHover\",\n value: false\n }]\n}, {\n type: \"category\",\n id: \"categories\",\n name: \"Categories\",\n collapsible: true,\n settings: [{\n type: \"switch\",\n id: \"twitch\",\n value: true\n }, {\n type: \"switch\",\n id: \"ffz\",\n value: true\n }, {\n type: \"switch\",\n id: \"bttv\",\n value: true\n }]\n}]);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Db3JlLy4vc3JjL2RhdGEvZW1vdGVzL2NvbmZpZy5qcz8yZDVkIl0sIm5hbWVzIjpbInR5cGUiLCJpZCIsIm5hbWUiLCJjb2xsYXBzaWJsZSIsInNldHRpbmdzIiwidmFsdWUiLCJlbmFibGVXaXRoIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUFlLGdFQUNYO0FBQ0lBLE1BQUksRUFBRSxVQURWO0FBRUlDLElBQUUsRUFBRSxTQUZSO0FBR0lDLE1BQUksRUFBRSxTQUhWO0FBSUlDLGFBQVcsRUFBRSxJQUpqQjtBQUtJQyxVQUFRLEVBQUUsQ0FDTjtBQUFDSixRQUFJLEVBQUUsUUFBUDtBQUFpQkMsTUFBRSxFQUFFLFVBQXJCO0FBQWlDSSxTQUFLLEVBQUU7QUFBeEMsR0FETSxFQUVOO0FBQUNMLFFBQUksRUFBRSxRQUFQO0FBQWlCQyxNQUFFLEVBQUUsV0FBckI7QUFBa0NJLFNBQUssRUFBRTtBQUF6QyxHQUZNLEVBR047QUFBQ0wsUUFBSSxFQUFFLFFBQVA7QUFBaUJDLE1BQUUsRUFBRSxlQUFyQjtBQUFzQ0ksU0FBSyxFQUFFLEtBQTdDO0FBQW9EQyxjQUFVLEVBQUU7QUFBaEUsR0FITSxFQUlOO0FBQUNOLFFBQUksRUFBRSxRQUFQO0FBQWlCQyxNQUFFLEVBQUUsVUFBckI7QUFBaUNJLFNBQUssRUFBRTtBQUF4QyxHQUpNLEVBS047QUFBQ0wsUUFBSSxFQUFFLFFBQVA7QUFBaUJDLE1BQUUsRUFBRSxXQUFyQjtBQUFrQ0ksU0FBSyxFQUFFO0FBQXpDLEdBTE0sRUFNTjtBQUFDTCxRQUFJLEVBQUUsUUFBUDtBQUFpQkMsTUFBRSxFQUFFLFdBQXJCO0FBQWtDSSxTQUFLLEVBQUU7QUFBekMsR0FOTSxFQU9OO0FBQUNMLFFBQUksRUFBRSxRQUFQO0FBQWlCQyxNQUFFLEVBQUUsZ0JBQXJCO0FBQXVDSSxTQUFLLEVBQUU7QUFBOUMsR0FQTTtBQUxkLENBRFcsRUFnQlg7QUFDSUwsTUFBSSxFQUFFLFVBRFY7QUFFSUMsSUFBRSxFQUFFLFlBRlI7QUFHSUMsTUFBSSxFQUFFLFlBSFY7QUFJSUMsYUFBVyxFQUFFLElBSmpCO0FBS0lDLFVBQVEsRUFBRSxDQUNOO0FBQUNKLFFBQUksRUFBRSxRQUFQO0FBQWlCQyxNQUFFLEVBQUUsUUFBckI7QUFBK0JJLFNBQUssRUFBRTtBQUF0QyxHQURNLEVBRU47QUFBQ0wsUUFBSSxFQUFFLFFBQVA7QUFBaUJDLE1BQUUsRUFBRSxLQUFyQjtBQUE0QkksU0FBSyxFQUFFO0FBQW5DLEdBRk0sRUFHTjtBQUFDTCxRQUFJLEVBQUUsUUFBUDtBQUFpQkMsTUFBRSxFQUFFLE1BQXJCO0FBQTZCSSxTQUFLLEVBQUU7QUFBcEMsR0FITTtBQUxkLENBaEJXLENBQWYiLCJmaWxlIjoiLi9zcmMvZGF0YS9lbW90ZXMvY29uZmlnLmpzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgW1xyXG4gICAge1xyXG4gICAgICAgIHR5cGU6IFwiY2F0ZWdvcnlcIixcclxuICAgICAgICBpZDogXCJnZW5lcmFsXCIsXHJcbiAgICAgICAgbmFtZTogXCJHZW5lcmFsXCIsXHJcbiAgICAgICAgY29sbGFwc2libGU6IHRydWUsXHJcbiAgICAgICAgc2V0dGluZ3M6IFtcclxuICAgICAgICAgICAge3R5cGU6IFwic3dpdGNoXCIsIGlkOiBcImRvd25sb2FkXCIsIHZhbHVlOiB0cnVlfSxcclxuICAgICAgICAgICAge3R5cGU6IFwic3dpdGNoXCIsIGlkOiBcImVtb3RlTWVudVwiLCB2YWx1ZTogdHJ1ZX0sXHJcbiAgICAgICAgICAgIHt0eXBlOiBcInN3aXRjaFwiLCBpZDogXCJoaWRlRW1vamlNZW51XCIsIHZhbHVlOiBmYWxzZSwgZW5hYmxlV2l0aDogXCJlbW90ZU1lbnVcIn0sXHJcbiAgICAgICAgICAgIHt0eXBlOiBcInN3aXRjaFwiLCBpZDogXCJhdXRvQ2Fwc1wiLCB2YWx1ZTogZmFsc2V9LFxyXG4gICAgICAgICAgICB7dHlwZTogXCJzd2l0Y2hcIiwgaWQ6IFwic2hvd05hbWVzXCIsIHZhbHVlOiB0cnVlfSxcclxuICAgICAgICAgICAge3R5cGU6IFwic3dpdGNoXCIsIGlkOiBcIm1vZGlmaWVyc1wiLCB2YWx1ZTogdHJ1ZX0sXHJcbiAgICAgICAgICAgIHt0eXBlOiBcInN3aXRjaFwiLCBpZDogXCJhbmltYXRlT25Ib3ZlclwiLCB2YWx1ZTogZmFsc2V9XHJcbiAgICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgICB0eXBlOiBcImNhdGVnb3J5XCIsXHJcbiAgICAgICAgaWQ6IFwiY2F0ZWdvcmllc1wiLFxyXG4gICAgICAgIG5hbWU6IFwiQ2F0ZWdvcmllc1wiLFxyXG4gICAgICAgIGNvbGxhcHNpYmxlOiB0cnVlLFxyXG4gICAgICAgIHNldHRpbmdzOiBbXHJcbiAgICAgICAgICAgIHt0eXBlOiBcInN3aXRjaFwiLCBpZDogXCJ0d2l0Y2hcIiwgdmFsdWU6IHRydWV9LFxyXG4gICAgICAgICAgICB7dHlwZTogXCJzd2l0Y2hcIiwgaWQ6IFwiZmZ6XCIsIHZhbHVlOiB0cnVlfSxcclxuICAgICAgICAgICAge3R5cGU6IFwic3dpdGNoXCIsIGlkOiBcImJ0dHZcIiwgdmFsdWU6IHRydWV9XHJcbiAgICAgICAgXVxyXG4gICAgfVxyXG5dOyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/data/emotes/config.js\n"); - -/***/ }), - -/***/ "./src/data/emotes/info.js": -/*!*********************************!*\ - !*** ./src/data/emotes/info.js ***! - \*********************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n TwitchGlobal: {\n url: \"https://twitchemotes.com/api_cache/v3/global.json\",\n variable: \"TwitchGlobal\",\n getEmoteURL: e => `https://static-cdn.jtvnw.net/emoticons/v1/${e.id}/1.0`,\n getOldData: (url, name) => {\n return {\n id: url.match(/\\/([0-9]+)\\//)[1],\n code: name,\n emoticon_set: 0,\n description: null\n };\n }\n },\n TwitchSubscriber: {\n variable: \"TwitchSubscriber\",\n getEmoteURL: e => `https://static-cdn.jtvnw.net/emoticons/v1/${e}/1.0`,\n getOldData: url => url.match(/\\/([0-9]+)\\//)[1]\n },\n FrankerFaceZ: {\n variable: \"FrankerFaceZ\",\n getEmoteURL: e => `https://cdn.frankerfacez.com/emoticon/${e}/1`,\n getOldData: url => url.match(/\\/([0-9]+)\\//)[1]\n },\n BTTV: {\n url: \"https://api.betterttv.net/emotes\",\n variable: \"BTTV\",\n parser: data => {\n const emotes = {};\n\n for (let e = 0, len = data.emotes.length; e < len; e++) {\n const emote = data.emotes[e];\n emotes[emote.regex] = emote.url;\n }\n\n return emotes;\n },\n getEmoteURL: e => `${e}`,\n getOldData: url => url\n },\n BTTV2: {\n variable: \"BTTV2\",\n oldVariable: \"emotesBTTV2\",\n getEmoteURL: e => `https://cdn.betterttv.net/emote/${e}/1x`,\n getOldData: url => url.match(/emote\\/(.+)\\//)[1]\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Db3JlLy4vc3JjL2RhdGEvZW1vdGVzL2luZm8uanM/OWY4ZSJdLCJuYW1lcyI6WyJUd2l0Y2hHbG9iYWwiLCJ1cmwiLCJ2YXJpYWJsZSIsImdldEVtb3RlVVJMIiwiZSIsImlkIiwiZ2V0T2xkRGF0YSIsIm5hbWUiLCJtYXRjaCIsImNvZGUiLCJlbW90aWNvbl9zZXQiLCJkZXNjcmlwdGlvbiIsIlR3aXRjaFN1YnNjcmliZXIiLCJGcmFua2VyRmFjZVoiLCJCVFRWIiwicGFyc2VyIiwiZGF0YSIsImVtb3RlcyIsImxlbiIsImxlbmd0aCIsImVtb3RlIiwicmVnZXgiLCJCVFRWMiIsIm9sZFZhcmlhYmxlIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUFlO0FBQ1hBLGNBQVksRUFBRTtBQUNWQyxPQUFHLEVBQUUsbURBREs7QUFFVkMsWUFBUSxFQUFFLGNBRkE7QUFHVkMsZUFBVyxFQUFHQyxDQUFELElBQVEsNkNBQTRDQSxDQUFDLENBQUNDLEVBQUcsTUFINUQ7QUFJVkMsY0FBVSxFQUFFLENBQUNMLEdBQUQsRUFBTU0sSUFBTixLQUFlO0FBQUMsYUFBTztBQUFDRixVQUFFLEVBQUVKLEdBQUcsQ0FBQ08sS0FBSixDQUFVLGNBQVYsRUFBMEIsQ0FBMUIsQ0FBTDtBQUFtQ0MsWUFBSSxFQUFFRixJQUF6QztBQUErQ0csb0JBQVksRUFBRSxDQUE3RDtBQUFnRUMsbUJBQVcsRUFBRTtBQUE3RSxPQUFQO0FBQTJGO0FBSjdHLEdBREg7QUFPWEMsa0JBQWdCLEVBQUU7QUFDZFYsWUFBUSxFQUFFLGtCQURJO0FBRWRDLGVBQVcsRUFBR0MsQ0FBRCxJQUFRLDZDQUE0Q0EsQ0FBRSxNQUZyRDtBQUdkRSxjQUFVLEVBQUdMLEdBQUQsSUFBU0EsR0FBRyxDQUFDTyxLQUFKLENBQVUsY0FBVixFQUEwQixDQUExQjtBQUhQLEdBUFA7QUFZWEssY0FBWSxFQUFFO0FBQ1ZYLFlBQVEsRUFBRSxjQURBO0FBRVZDLGVBQVcsRUFBR0MsQ0FBRCxJQUFRLHlDQUF3Q0EsQ0FBRSxJQUZyRDtBQUdWRSxjQUFVLEVBQUdMLEdBQUQsSUFBU0EsR0FBRyxDQUFDTyxLQUFKLENBQVUsY0FBVixFQUEwQixDQUExQjtBQUhYLEdBWkg7QUFpQlhNLE1BQUksRUFBRTtBQUNGYixPQUFHLEVBQUUsa0NBREg7QUFFRkMsWUFBUSxFQUFFLE1BRlI7QUFHRmEsVUFBTSxFQUFHQyxJQUFELElBQVU7QUFDZCxZQUFNQyxNQUFNLEdBQUcsRUFBZjs7QUFDQSxXQUFLLElBQUliLENBQUMsR0FBRyxDQUFSLEVBQVdjLEdBQUcsR0FBR0YsSUFBSSxDQUFDQyxNQUFMLENBQVlFLE1BQWxDLEVBQTBDZixDQUFDLEdBQUdjLEdBQTlDLEVBQW1EZCxDQUFDLEVBQXBELEVBQXdEO0FBQ3BELGNBQU1nQixLQUFLLEdBQUdKLElBQUksQ0FBQ0MsTUFBTCxDQUFZYixDQUFaLENBQWQ7QUFDQWEsY0FBTSxDQUFDRyxLQUFLLENBQUNDLEtBQVAsQ0FBTixHQUFzQkQsS0FBSyxDQUFDbkIsR0FBNUI7QUFDSDs7QUFDRCxhQUFPZ0IsTUFBUDtBQUNILEtBVkM7QUFXRmQsZUFBVyxFQUFHQyxDQUFELElBQVEsR0FBRUEsQ0FBRSxFQVh2QjtBQVlGRSxjQUFVLEVBQUdMLEdBQUQsSUFBU0E7QUFabkIsR0FqQks7QUErQlhxQixPQUFLLEVBQUU7QUFDSHBCLFlBQVEsRUFBRSxPQURQO0FBRUhxQixlQUFXLEVBQUUsYUFGVjtBQUdIcEIsZUFBVyxFQUFHQyxDQUFELElBQVEsbUNBQWtDQSxDQUFFLEtBSHREO0FBSUhFLGNBQVUsRUFBR0wsR0FBRCxJQUFTQSxHQUFHLENBQUNPLEtBQUosQ0FBVSxlQUFWLEVBQTJCLENBQTNCO0FBSmxCO0FBL0JJLENBQWYiLCJmaWxlIjoiLi9zcmMvZGF0YS9lbW90ZXMvaW5mby5qcy5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IHtcclxuICAgIFR3aXRjaEdsb2JhbDoge1xyXG4gICAgICAgIHVybDogXCJodHRwczovL3R3aXRjaGVtb3Rlcy5jb20vYXBpX2NhY2hlL3YzL2dsb2JhbC5qc29uXCIsXHJcbiAgICAgICAgdmFyaWFibGU6IFwiVHdpdGNoR2xvYmFsXCIsXHJcbiAgICAgICAgZ2V0RW1vdGVVUkw6IChlKSA9PiBgaHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9lbW90aWNvbnMvdjEvJHtlLmlkfS8xLjBgLFxyXG4gICAgICAgIGdldE9sZERhdGE6ICh1cmwsIG5hbWUpID0+IHtyZXR1cm4ge2lkOiB1cmwubWF0Y2goL1xcLyhbMC05XSspXFwvLylbMV0sIGNvZGU6IG5hbWUsIGVtb3RpY29uX3NldDogMCwgZGVzY3JpcHRpb246IG51bGx9O31cclxuICAgIH0sXHJcbiAgICBUd2l0Y2hTdWJzY3JpYmVyOiB7XHJcbiAgICAgICAgdmFyaWFibGU6IFwiVHdpdGNoU3Vic2NyaWJlclwiLFxyXG4gICAgICAgIGdldEVtb3RlVVJMOiAoZSkgPT4gYGh0dHBzOi8vc3RhdGljLWNkbi5qdHZudy5uZXQvZW1vdGljb25zL3YxLyR7ZX0vMS4wYCxcclxuICAgICAgICBnZXRPbGREYXRhOiAodXJsKSA9PiB1cmwubWF0Y2goL1xcLyhbMC05XSspXFwvLylbMV1cclxuICAgIH0sXHJcbiAgICBGcmFua2VyRmFjZVo6IHtcclxuICAgICAgICB2YXJpYWJsZTogXCJGcmFua2VyRmFjZVpcIixcclxuICAgICAgICBnZXRFbW90ZVVSTDogKGUpID0+IGBodHRwczovL2Nkbi5mcmFua2VyZmFjZXouY29tL2Vtb3RpY29uLyR7ZX0vMWAsXHJcbiAgICAgICAgZ2V0T2xkRGF0YTogKHVybCkgPT4gdXJsLm1hdGNoKC9cXC8oWzAtOV0rKVxcLy8pWzFdXHJcbiAgICB9LFxyXG4gICAgQlRUVjoge1xyXG4gICAgICAgIHVybDogXCJodHRwczovL2FwaS5iZXR0ZXJ0dHYubmV0L2Vtb3Rlc1wiLFxyXG4gICAgICAgIHZhcmlhYmxlOiBcIkJUVFZcIixcclxuICAgICAgICBwYXJzZXI6IChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGVtb3RlcyA9IHt9O1xyXG4gICAgICAgICAgICBmb3IgKGxldCBlID0gMCwgbGVuID0gZGF0YS5lbW90ZXMubGVuZ3RoOyBlIDwgbGVuOyBlKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVtb3RlID0gZGF0YS5lbW90ZXNbZV07XHJcbiAgICAgICAgICAgICAgICBlbW90ZXNbZW1vdGUucmVnZXhdID0gZW1vdGUudXJsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBlbW90ZXM7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBnZXRFbW90ZVVSTDogKGUpID0+IGAke2V9YCxcclxuICAgICAgICBnZXRPbGREYXRhOiAodXJsKSA9PiB1cmxcclxuICAgIH0sXHJcbiAgICBCVFRWMjoge1xyXG4gICAgICAgIHZhcmlhYmxlOiBcIkJUVFYyXCIsXHJcbiAgICAgICAgb2xkVmFyaWFibGU6IFwiZW1vdGVzQlRUVjJcIixcclxuICAgICAgICBnZXRFbW90ZVVSTDogKGUpID0+IGBodHRwczovL2Nkbi5iZXR0ZXJ0dHYubmV0L2Vtb3RlLyR7ZX0vMXhgLFxyXG4gICAgICAgIGdldE9sZERhdGE6ICh1cmwpID0+IHVybC5tYXRjaCgvZW1vdGVcXC8oLispXFwvLylbMV1cclxuICAgIH1cclxufTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/data/emotes/info.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./config */ \"./src/data/config.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"Config\", function() { return _config__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; });\n\n/* harmony import */ var _settings_emoteconfig__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./settings/emoteconfig */ \"./src/data/settings/emoteconfig.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"EmoteConfig\", function() { return _settings_emoteconfig__WEBPACK_IMPORTED_MODULE_1__[\"default\"]; });\n\n/* harmony import */ var _settings_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./settings/config */ \"./src/data/settings/config.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"SettingsConfig\", function() { return _settings_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"]; });\n\n/* harmony import */ var _strings__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./strings */ \"./src/data/strings.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"Strings\", function() { return _strings__WEBPACK_IMPORTED_MODULE_3__[\"default\"]; });\n\n\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Db3JlLy4vc3JjL2RhdGEvZGF0YS5qcz9kNWM3Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBIiwiZmlsZSI6Ii4vc3JjL2RhdGEvZGF0YS5qcy5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7ZGVmYXVsdCBhcyBDb25maWd9IGZyb20gXCIuL2NvbmZpZ1wiO1xyXG5leHBvcnQge2RlZmF1bHQgYXMgRW1vdGVDb25maWd9IGZyb20gXCIuL3NldHRpbmdzL2Vtb3RlY29uZmlnXCI7XHJcbmV4cG9ydCB7ZGVmYXVsdCBhcyBTZXR0aW5nc0NvbmZpZ30gZnJvbSBcIi4vc2V0dGluZ3MvY29uZmlnXCI7XHJcbmV4cG9ydCB7ZGVmYXVsdCBhcyBTdHJpbmdzfSBmcm9tIFwiLi9zdHJpbmdzXCI7Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/data/data.js\n"); /***/ }), @@ -327,6 +303,18 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ /***/ }), +/***/ "./src/data/settings/emoteconfig.js": +/*!******************************************!*\ + !*** ./src/data/settings/emoteconfig.js ***! + \******************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = ([{\n type: \"category\",\n id: \"general\",\n name: \"General\",\n collapsible: true,\n settings: [{\n type: \"switch\",\n id: \"download\",\n value: true\n }, {\n type: \"switch\",\n id: \"emoteMenu\",\n value: true\n }, {\n type: \"switch\",\n id: \"hideEmojiMenu\",\n value: false,\n enableWith: \"emoteMenu\"\n }, {\n type: \"switch\",\n id: \"autoCaps\",\n value: false\n }, {\n type: \"switch\",\n id: \"showNames\",\n value: true\n }, {\n type: \"switch\",\n id: \"modifiers\",\n value: true\n }, {\n type: \"switch\",\n id: \"animateOnHover\",\n value: false\n }]\n}, {\n type: \"category\",\n id: \"categories\",\n name: \"Categories\",\n collapsible: true,\n settings: [{\n type: \"switch\",\n id: \"twitch\",\n value: true\n }, {\n type: \"switch\",\n id: \"ffz\",\n value: true\n }, {\n type: \"switch\",\n id: \"bttv\",\n value: true\n }]\n}]);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Db3JlLy4vc3JjL2RhdGEvc2V0dGluZ3MvZW1vdGVjb25maWcuanM/ODU5NyJdLCJuYW1lcyI6WyJ0eXBlIiwiaWQiLCJuYW1lIiwiY29sbGFwc2libGUiLCJzZXR0aW5ncyIsInZhbHVlIiwiZW5hYmxlV2l0aCJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBZSxnRUFDWDtBQUNJQSxNQUFJLEVBQUUsVUFEVjtBQUVJQyxJQUFFLEVBQUUsU0FGUjtBQUdJQyxNQUFJLEVBQUUsU0FIVjtBQUlJQyxhQUFXLEVBQUUsSUFKakI7QUFLSUMsVUFBUSxFQUFFLENBQ047QUFBQ0osUUFBSSxFQUFFLFFBQVA7QUFBaUJDLE1BQUUsRUFBRSxVQUFyQjtBQUFpQ0ksU0FBSyxFQUFFO0FBQXhDLEdBRE0sRUFFTjtBQUFDTCxRQUFJLEVBQUUsUUFBUDtBQUFpQkMsTUFBRSxFQUFFLFdBQXJCO0FBQWtDSSxTQUFLLEVBQUU7QUFBekMsR0FGTSxFQUdOO0FBQUNMLFFBQUksRUFBRSxRQUFQO0FBQWlCQyxNQUFFLEVBQUUsZUFBckI7QUFBc0NJLFNBQUssRUFBRSxLQUE3QztBQUFvREMsY0FBVSxFQUFFO0FBQWhFLEdBSE0sRUFJTjtBQUFDTixRQUFJLEVBQUUsUUFBUDtBQUFpQkMsTUFBRSxFQUFFLFVBQXJCO0FBQWlDSSxTQUFLLEVBQUU7QUFBeEMsR0FKTSxFQUtOO0FBQUNMLFFBQUksRUFBRSxRQUFQO0FBQWlCQyxNQUFFLEVBQUUsV0FBckI7QUFBa0NJLFNBQUssRUFBRTtBQUF6QyxHQUxNLEVBTU47QUFBQ0wsUUFBSSxFQUFFLFFBQVA7QUFBaUJDLE1BQUUsRUFBRSxXQUFyQjtBQUFrQ0ksU0FBSyxFQUFFO0FBQXpDLEdBTk0sRUFPTjtBQUFDTCxRQUFJLEVBQUUsUUFBUDtBQUFpQkMsTUFBRSxFQUFFLGdCQUFyQjtBQUF1Q0ksU0FBSyxFQUFFO0FBQTlDLEdBUE07QUFMZCxDQURXLEVBZ0JYO0FBQ0lMLE1BQUksRUFBRSxVQURWO0FBRUlDLElBQUUsRUFBRSxZQUZSO0FBR0lDLE1BQUksRUFBRSxZQUhWO0FBSUlDLGFBQVcsRUFBRSxJQUpqQjtBQUtJQyxVQUFRLEVBQUUsQ0FDTjtBQUFDSixRQUFJLEVBQUUsUUFBUDtBQUFpQkMsTUFBRSxFQUFFLFFBQXJCO0FBQStCSSxTQUFLLEVBQUU7QUFBdEMsR0FETSxFQUVOO0FBQUNMLFFBQUksRUFBRSxRQUFQO0FBQWlCQyxNQUFFLEVBQUUsS0FBckI7QUFBNEJJLFNBQUssRUFBRTtBQUFuQyxHQUZNLEVBR047QUFBQ0wsUUFBSSxFQUFFLFFBQVA7QUFBaUJDLE1BQUUsRUFBRSxNQUFyQjtBQUE2QkksU0FBSyxFQUFFO0FBQXBDLEdBSE07QUFMZCxDQWhCVyxDQUFmIiwiZmlsZSI6Ii4vc3JjL2RhdGEvc2V0dGluZ3MvZW1vdGVjb25maWcuanMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBbXHJcbiAgICB7XHJcbiAgICAgICAgdHlwZTogXCJjYXRlZ29yeVwiLFxyXG4gICAgICAgIGlkOiBcImdlbmVyYWxcIixcclxuICAgICAgICBuYW1lOiBcIkdlbmVyYWxcIixcclxuICAgICAgICBjb2xsYXBzaWJsZTogdHJ1ZSxcclxuICAgICAgICBzZXR0aW5nczogW1xyXG4gICAgICAgICAgICB7dHlwZTogXCJzd2l0Y2hcIiwgaWQ6IFwiZG93bmxvYWRcIiwgdmFsdWU6IHRydWV9LFxyXG4gICAgICAgICAgICB7dHlwZTogXCJzd2l0Y2hcIiwgaWQ6IFwiZW1vdGVNZW51XCIsIHZhbHVlOiB0cnVlfSxcclxuICAgICAgICAgICAge3R5cGU6IFwic3dpdGNoXCIsIGlkOiBcImhpZGVFbW9qaU1lbnVcIiwgdmFsdWU6IGZhbHNlLCBlbmFibGVXaXRoOiBcImVtb3RlTWVudVwifSxcclxuICAgICAgICAgICAge3R5cGU6IFwic3dpdGNoXCIsIGlkOiBcImF1dG9DYXBzXCIsIHZhbHVlOiBmYWxzZX0sXHJcbiAgICAgICAgICAgIHt0eXBlOiBcInN3aXRjaFwiLCBpZDogXCJzaG93TmFtZXNcIiwgdmFsdWU6IHRydWV9LFxyXG4gICAgICAgICAgICB7dHlwZTogXCJzd2l0Y2hcIiwgaWQ6IFwibW9kaWZpZXJzXCIsIHZhbHVlOiB0cnVlfSxcclxuICAgICAgICAgICAge3R5cGU6IFwic3dpdGNoXCIsIGlkOiBcImFuaW1hdGVPbkhvdmVyXCIsIHZhbHVlOiBmYWxzZX1cclxuICAgICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICAgIHR5cGU6IFwiY2F0ZWdvcnlcIixcclxuICAgICAgICBpZDogXCJjYXRlZ29yaWVzXCIsXHJcbiAgICAgICAgbmFtZTogXCJDYXRlZ29yaWVzXCIsXHJcbiAgICAgICAgY29sbGFwc2libGU6IHRydWUsXHJcbiAgICAgICAgc2V0dGluZ3M6IFtcclxuICAgICAgICAgICAge3R5cGU6IFwic3dpdGNoXCIsIGlkOiBcInR3aXRjaFwiLCB2YWx1ZTogdHJ1ZX0sXHJcbiAgICAgICAgICAgIHt0eXBlOiBcInN3aXRjaFwiLCBpZDogXCJmZnpcIiwgdmFsdWU6IHRydWV9LFxyXG4gICAgICAgICAgICB7dHlwZTogXCJzd2l0Y2hcIiwgaWQ6IFwiYnR0dlwiLCB2YWx1ZTogdHJ1ZX1cclxuICAgICAgICBdXHJcbiAgICB9XHJcbl07Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/data/settings/emoteconfig.js\n"); + +/***/ }), + /***/ "./src/data/strings.js": /*!*****************************!*\ !*** ./src/data/strings.js ***! @@ -395,7 +383,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _loc /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var data__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! data */ \"./src/data/data.js\");\n/* harmony import */ var _utilities__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utilities */ \"./src/modules/utilities.js\");\n\n\n\nconst fs = __webpack_require__(/*! fs */ \"fs\");\n\nconst path = __webpack_require__(/*! path */ \"path\");\n\nconst releaseChannel = DiscordNative.globals.releaseChannel; // Schema\n// =======================\n// %appdata%\\BetterDiscord\n// -> data\n// -> [releaseChannel]\\ (stable/canary/ptb)\n// -> settings.json\n// -> plugins.json\n// -> themes.json\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (new class DataStore {\n constructor() {\n this.data = {\n misc: {}\n };\n this.pluginData = {};\n this.localeHashes = {};\n }\n\n initialize() {\n if (!fs.existsSync(this.baseFolder)) fs.mkdirSync(this.baseFolder);\n if (!fs.existsSync(this.dataFolder)) fs.mkdirSync(this.dataFolder);\n if (!fs.existsSync(this.localeFolder)) fs.mkdirSync(this.localeFolder);\n if (!fs.existsSync(this.localeCache)) fs.writeFileSync(this.localeCache, JSON.stringify({}));\n if (!fs.existsSync(this.BDFile)) fs.writeFileSync(this.BDFile, JSON.stringify(this.data.misc, null, 4));\n if (!fs.existsSync(this.customCSS)) fs.writeFileSync(this.customCSS, \"\");\n const dataFiles = fs.readdirSync(this.dataFolder).filter(f => !fs.statSync(path.resolve(this.dataFolder, f)).isDirectory() && f.endsWith(\".json\"));\n\n for (const file of dataFiles) {\n this.data[file.split(\".\")[0]] = require(path.resolve(this.dataFolder, file));\n }\n\n this.localeHashes = JSON.parse(fs.readFileSync(this.localeCache).toString());\n }\n\n get customCSS() {\n return this._customCSS || (this._customCSS = path.resolve(this.dataFolder, \"custom.css\"));\n }\n\n get baseFolder() {\n return this._baseFolder || (this._baseFolder = path.resolve(data__WEBPACK_IMPORTED_MODULE_0__[\"Config\"].dataPath, \"data\"));\n }\n\n get dataFolder() {\n return this._dataFolder || (this._dataFolder = path.resolve(this.baseFolder, `${releaseChannel}`));\n }\n\n get localeFolder() {\n return this._localeFolder || (this._localeFolder = path.resolve(this.baseFolder, `locales`));\n }\n\n get localeCache() {\n return this._localeCache || (this._localeCache = path.resolve(this.localeFolder, `.cache`));\n }\n\n get BDFile() {\n return this._BDFile || (this._BDFile = path.resolve(data__WEBPACK_IMPORTED_MODULE_0__[\"Config\"].dataPath, \"data\", `${releaseChannel}.json`));\n }\n\n getPluginFile(pluginName) {\n return path.resolve(data__WEBPACK_IMPORTED_MODULE_0__[\"Config\"].dataPath, \"plugins\", pluginName + \".config.json\");\n }\n\n _getFile(key) {\n if (key == \"settings\" || key == \"plugins\" || key == \"themes\") return path.resolve(this.dataFolder, `${key}.json`);\n return path.resolve(this.dataFolder, `misc.json`);\n }\n\n getBDData(key) {\n return this.data.misc[key] || \"\";\n }\n\n setBDData(key, value) {\n this.data.misc[key] = value;\n fs.writeFileSync(path.resolve(this.dataFolder, `misc.json`), JSON.stringify(this.data.misc, null, 4));\n }\n\n getLocale(locale) {\n const file = path.resolve(this.localeFolder, `${locale}.json`);\n if (!fs.existsSync(file)) return null;\n return _utilities__WEBPACK_IMPORTED_MODULE_1__[\"default\"].testJSON(fs.readFileSync(file).toString());\n }\n\n saveLocale(locale, strings) {\n fs.writeFileSync(path.resolve(this.localeFolder, `${locale}.json`), JSON.stringify(strings, null, 4));\n }\n\n getLocaleHash(locale) {\n return this.localeHashes[locale] || \"\";\n }\n\n saveLocaleHash(locale, hash) {\n this.localeHashes[locale] = hash;\n fs.writeFileSync(this.localeCache, JSON.stringify(this.localeHashes, null, 4));\n }\n\n getData(key) {\n return this.data[key] || \"\";\n }\n\n setData(key, value) {\n this.data[key] = value;\n fs.writeFileSync(path.resolve(this.dataFolder, `${key}.json`), JSON.stringify(value, null, 4));\n }\n\n loadCustomCSS() {\n return fs.readFileSync(this.customCSS).toString();\n }\n\n saveCustomCSS(css) {\n return fs.writeFileSync(this.customCSS, css);\n }\n\n getPluginData(pluginName, key) {\n if (this.pluginData[pluginName] !== undefined) return this.pluginData[pluginName][key] || undefined;\n if (!fs.existsSync(this.getPluginFile(pluginName))) return undefined;\n this.pluginData[pluginName] = JSON.parse(fs.readFileSync(this.getPluginFile(pluginName)));\n return this.pluginData[pluginName][key] || undefined;\n }\n\n setPluginData(pluginName, key, value) {\n if (value === undefined) return;\n if (this.pluginData[pluginName] === undefined) this.pluginData[pluginName] = {};\n this.pluginData[pluginName][key] = value;\n fs.writeFileSync(this.getPluginFile(pluginName), JSON.stringify(this.pluginData[pluginName], null, 4));\n }\n\n deletePluginData(pluginName, key) {\n if (this.pluginData[pluginName] === undefined) this.pluginData[pluginName] = {};\n delete this.pluginData[pluginName][key];\n fs.writeFileSync(this.getPluginFile(pluginName), JSON.stringify(this.pluginData[pluginName], null, 4));\n }\n\n}());//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Db3JlLy4vc3JjL21vZHVsZXMvZGF0YXN0b3JlLmpzPzEwNTIiXSwibmFtZXMiOlsiZnMiLCJyZXF1aXJlIiwicGF0aCIsInJlbGVhc2VDaGFubmVsIiwiRGlzY29yZE5hdGl2ZSIsImdsb2JhbHMiLCJEYXRhU3RvcmUiLCJjb25zdHJ1Y3RvciIsImRhdGEiLCJtaXNjIiwicGx1Z2luRGF0YSIsImxvY2FsZUhhc2hlcyIsImluaXRpYWxpemUiLCJleGlzdHNTeW5jIiwiYmFzZUZvbGRlciIsIm1rZGlyU3luYyIsImRhdGFGb2xkZXIiLCJsb2NhbGVGb2xkZXIiLCJsb2NhbGVDYWNoZSIsIndyaXRlRmlsZVN5bmMiLCJKU09OIiwic3RyaW5naWZ5IiwiQkRGaWxlIiwiY3VzdG9tQ1NTIiwiZGF0YUZpbGVzIiwicmVhZGRpclN5bmMiLCJmaWx0ZXIiLCJmIiwic3RhdFN5bmMiLCJyZXNvbHZlIiwiaXNEaXJlY3RvcnkiLCJlbmRzV2l0aCIsImZpbGUiLCJzcGxpdCIsIl9fbm9uX3dlYnBhY2tfcmVxdWlyZV9fIiwicGFyc2UiLCJyZWFkRmlsZVN5bmMiLCJ0b1N0cmluZyIsIl9jdXN0b21DU1MiLCJfYmFzZUZvbGRlciIsIkNvbmZpZyIsImRhdGFQYXRoIiwiX2RhdGFGb2xkZXIiLCJfbG9jYWxlRm9sZGVyIiwiX2xvY2FsZUNhY2hlIiwiX0JERmlsZSIsImdldFBsdWdpbkZpbGUiLCJwbHVnaW5OYW1lIiwiX2dldEZpbGUiLCJrZXkiLCJnZXRCRERhdGEiLCJzZXRCRERhdGEiLCJ2YWx1ZSIsImdldExvY2FsZSIsImxvY2FsZSIsIlV0aWxpdGllcyIsInRlc3RKU09OIiwic2F2ZUxvY2FsZSIsInN0cmluZ3MiLCJnZXRMb2NhbGVIYXNoIiwic2F2ZUxvY2FsZUhhc2giLCJoYXNoIiwiZ2V0RGF0YSIsInNldERhdGEiLCJsb2FkQ3VzdG9tQ1NTIiwic2F2ZUN1c3RvbUNTUyIsImNzcyIsImdldFBsdWdpbkRhdGEiLCJ1bmRlZmluZWQiLCJz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QUFnQixDQUFDdkIsVUFBRCxFQUFhRSxHQUFiLEVBQWtCO0FBQzlCLFFBQUksS0FBS3ZDLFVBQUwsQ0FBZ0JxQyxVQUFoQixNQUFnQ3FCLFNBQXBDLEVBQStDLEtBQUsxRCxVQUFMLENBQWdCcUMsVUFBaEIsSUFBOEIsRUFBOUI7QUFDL0MsV0FBTyxLQUFLckMsVUFBTCxDQUFnQnFDLFVBQWhCLEVBQTRCRSxHQUE1QixDQUFQO0FBQ0FqRCxNQUFFLENBQUNtQixhQUFILENBQWlCLEtBQUsyQixhQUFMLENBQW1CQyxVQUFuQixDQUFqQixFQUFpRDNCLElBQUksQ0FBQ0MsU0FBTCxDQUFlLEtBQUtYLFVBQUwsQ0FBZ0JxQyxVQUFoQixDQUFmLEVBQTRDLElBQTVDLEVBQWtELENBQWxELENBQWpEO0FBQ0g7O0FBbEc4QixDQUFwQixFQUFmIiwiZmlsZSI6Ii4vc3JjL21vZHVsZXMvZGF0YXN0b3JlLmpzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDb25maWd9IGZyb20gXCJkYXRhXCI7XHJcbmltcG9ydCBVdGlsaXRpZXMgZnJvbSBcIi4vdXRpbGl0aWVzXCI7XHJcbmNvbnN0IGZzID0gcmVxdWlyZShcImZzXCIpO1xyXG5jb25zdCBwYXRoID0gcmVxdWlyZShcInBhdGhcIik7XHJcbmNvbnN0IHJlbGVhc2VDaGFubmVsID0gRGlzY29yZE5hdGl2ZS5nbG9iYWxzLnJlbGVhc2VDaGFubmVsO1xyXG5cclxuLy8gU2NoZW1hXHJcbi8vID09PT09PT09PT09PT09PT09PT09PT09XHJcbi8vICVhcHBkYXRhJVxcQmV0dGVyRGlzY29yZFxyXG4vLyAgICAgLT4gZGF0YVxyXG4vLyAgICAgICAgIC0+IFtyZWxlYXNlQ2hhbm5lbF1cXCAoc3RhYmxlL2NhbmFyeS9wdGIpXHJcbi8vICAgICAgICAgICAgIC0+IHNldHRpbmdzLmpzb25cclxuLy8gICAgICAgICAgICAgLT4gcGx1Z2lucy5qc29uXHJcbi8vICAgICAgICAgICAgIC0+IHRoZW1lcy5qc29uXHJcblxyXG5leHBvcnQgZGVmYXVsdCBuZXcgY2xhc3MgRGF0YVN0b3JlIHtcclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHRoaXMuZGF0YSA9IHttaXNjOiB7fX07XHJcbiAgICAgICAgdGhpcy5wbHVnaW5EYXRhID0ge307XHJcbiAgICAgICAgdGhpcy5sb2NhbGVIYXNoZXMgPSB7fTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0aWFsaXplKCkge1xyXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyh0aGlzLmJhc2VGb2xkZXIpKSBmcy5ta2RpclN5bmModGhpcy5iYXNlRm9sZGVyKTtcclxuICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmModGhpcy5kYXRhRm9sZGVyKSkgZnMubWtkaXJTeW5jKHRoaXMuZGF0YUZvbGRlcik7XHJcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHRoaXMubG9jYWxlRm9sZGVyKSkgZnMubWtkaXJTeW5jKHRoaXMubG9jYWxlRm9sZGVyKTtcclxuICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmModGhpcy5sb2NhbGVDYWNoZSkpIGZzLndyaXRlRmlsZVN5bmModGhpcy5sb2NhbGVDYWNoZSwgSlNPTi5zdHJpbmdpZnkoe30pKTtcclxuICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmModGhpcy5CREZpbGUpKSBmcy53cml0ZUZpbGVTeW5jKHRoaXMuQkRGaWxlLCBKU09OLnN0cmluZ2lmeSh0aGlzLmRhdGEubWlzYywgbnVsbCwgNCkpO1xyXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyh0aGlzLmN1c3RvbUNTUykpIGZzLndyaXRlRmlsZVN5bmModGhpcy5jdXN0b21DU1MsIFwiXCIpO1xyXG4gICAgICAgIGNvbnN0IGRhdGFGaWxlcyA9IGZzLnJlYWRkaXJTeW5jKHRoaXMuZGF0YUZvbGRlcikuZmlsdGVyKGYgPT4gIWZzLnN0YXRTeW5jKHBhdGgucmVzb2x2ZSh0aGlzLmRhdGFGb2xkZXIsIGYpKS5pc0RpcmVjdG9yeSgpICYmIGYuZW5kc1dpdGgoXCIuanNvblwiKSk7XHJcbiAgICAgICAgZm9yIChjb25zdCBmaWxlIG9mIGRhdGFGaWxlcykge1xyXG4gICAgICAgICAgICB0aGlzLmRhdGFbZmlsZS5zcGxpdChcIi5cIilbMF1dID0gX19ub25fd2VicGFja19yZXF1aXJlX18ocGF0aC5yZXNvbHZlKHRoaXMuZGF0YUZvbGRlciwgZmlsZSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmxvY2FsZUhhc2hlcyA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKHRoaXMubG9jYWxlQ2FjaGUpLnRvU3RyaW5nKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBjdXN0b21DU1MoKSB7cmV0dXJuIHRoaXMuX2N1c3RvbUNTUyB8fCAodGhpcy5fY3VzdG9tQ1NTID0gcGF0aC5yZXNvbHZlKHRoaXMuZGF0YUZvbGRlciwgXCJjdXN0b20uY3NzXCIpKTt9XHJcbiAgICBnZXQgYmFzZUZvbGRlcigpIHtyZXR1cm4gdGhpcy5fYmFzZUZvbGRlciB8fCAodGhpcy5fYmFzZUZvbGRlciA9IHBhdGgucmVzb2x2ZShDb25maWcuZGF0YVBhdGgsIFwiZGF0YVwiKSk7fVxyXG4gICAgZ2V0IGRhdGFGb2xkZXIoKSB7cmV0dXJuIHRoaXMuX2RhdGFGb2xkZXIgfHwgKHRoaXMuX2RhdGFGb2xkZXIgPSBwYXRoLnJlc29sdmUodGhpcy5iYXNlRm9sZGVyLCBgJHtyZWxlYXNlQ2hhbm5lbH1gKSk7fVxyXG4gICAgZ2V0IGxvY2FsZUZvbGRlcigpIHtyZXR1cm4gdGhpcy5fbG9jYWxlRm9sZGVyIHx8ICh0aGlzLl9sb2NhbGVGb2xkZXIgPSBwYXRoLnJlc29sdmUodGhpcy5iYXNlRm9sZGVyLCBgbG9jYWxlc2ApKTt9XHJcbiAgICBnZXQgbG9jYWxlQ2FjaGUoKSB7cmV0dXJuIHRoaXMuX2xvY2FsZUNhY2hlIHx8ICh0aGlzLl9sb2NhbGVDYWNoZSA9IHBhdGgucmVzb2x2ZSh0aGlzLmxvY2FsZUZvbGRlciwgYC5jYWNoZWApKTt9XHJcbiAgICBnZXQgQkRGaWxlKCkge3JldHVybiB0aGlzLl9CREZpbGUgfHwgKHRoaXMuX0JERmlsZSA9IHBhdGgucmVzb2x2ZShDb25maWcuZGF0YVBhdGgsIFwiZGF0YVwiLCBgJHtyZWxlYXNlQ2hhbm5lbH0uanNvbmApKTt9XHJcbiAgICBnZXRQbHVnaW5GaWxlKHBsdWdpbk5hbWUpIHtyZXR1cm4gcGF0aC5yZXNvbHZlKENvbmZpZy5kYXRhUGF0aCwgXCJwbHVnaW5zXCIsIHBsdWdpbk5hbWUgKyBcIi5jb25maWcuanNvblwiKTt9XHJcblxyXG5cclxuICAgIF9nZXRGaWxlKGtleSkge1xyXG4gICAgICAgIGlmIChrZXkgPT0gXCJzZXR0aW5nc1wiIHx8IGtleSA9PSBcInBsdWdpbnNcIiB8fCBrZXkgPT0gXCJ0aGVtZXNcIikgcmV0dXJuIHBhdGgucmVzb2x2ZSh0aGlzLmRhdGFGb2xkZXIsIGAke2tleX0uanNvbmApO1xyXG4gICAgICAgIHJldHVybiBwYXRoLnJlc29sdmUodGhpcy5kYXRhRm9sZGVyLCBgbWlzYy5qc29uYCk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0QkREYXRhKGtleSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEubWlzY1trZXldIHx8IFwiXCI7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0QkREYXRhKGtleSwgdmFsdWUpIHtcclxuICAgICAgICB0aGlzLmRhdGEubWlzY1trZXldID0gdmFsdWU7XHJcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhwYXRoLnJlc29sdmUodGhpcy5kYXRhRm9sZGVyLCBgbWlzYy5qc29uYCksIEpTT04uc3RyaW5naWZ5KHRoaXMuZGF0YS5taXNjLCBudWxsLCA0KSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0TG9jYWxlKGxvY2FsZSkge1xyXG4gICAgICAgIGNvbnN0IGZpbGUgPSBwYXRoLnJlc29sdmUodGhpcy5sb2NhbGVGb2xkZXIsIGAke2xvY2FsZX0uanNvbmApO1xyXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyhmaWxlKSkgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgcmV0dXJuIFV0aWxpdGllcy50ZXN0SlNPTihmcy5yZWFkRmlsZVN5bmMoZmlsZSkudG9TdHJpbmcoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2F2ZUxvY2FsZShsb2NhbGUsIHN0cmluZ3MpIHtcclxuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHBhdGgucmVzb2x2ZSh0aGlzLmxvY2FsZUZvbGRlciwgYCR7bG9jYWxlfS5qc29uYCksIEpTT04uc3RyaW5naWZ5KHN0cmluZ3MsIG51bGwsIDQpKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRMb2NhbGVIYXNoKGxvY2FsZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxvY2FsZUhhc2hlc1tsb2NhbGVdIHx8IFwiXCI7XHJcbiAgICB9XHJcblxyXG4gICAgc2F2ZUxvY2FsZUhhc2gobG9jYWxlLCBoYXNoKSB7XHJcbiAgICAgICAgdGhpcy5sb2NhbGVIYXNoZXNbbG9jYWxlXSA9IGhhc2g7XHJcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLmxvY2FsZUNhY2hlLCBKU09OLnN0cmluZ2lmeSh0aGlzLmxvY2FsZUhhc2hlcywgbnVsbCwgNCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldERhdGEoa2V5KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YVtrZXldIHx8IFwiXCI7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0RGF0YShrZXksIHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy5kYXRhW2tleV0gPSB2YWx1ZTtcclxuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHBhdGgucmVzb2x2ZSh0aGlzLmRhdGFGb2xkZXIsIGAke2tleX0uanNvbmApLCBKU09OLnN0cmluZ2lmeSh2YWx1ZSwgbnVsbCwgNCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGxvYWRDdXN0b21DU1MoKSB7XHJcbiAgICAgICAgcmV0dXJuIGZzLnJlYWRGaWxlU3luYyh0aGlzLmN1c3RvbUNTUykudG9TdHJpbmcoKTtcclxuICAgIH1cclxuXHJcbiAgICBzYXZlQ3VzdG9tQ1NTKGNzcykge1xyXG4gICAgICAgIHJldHVybiBmcy53cml0ZUZpbGVTeW5jKHRoaXMuY3VzdG9tQ1NTLCBjc3MpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFBsdWdpbkRhdGEocGx1Z2luTmFtZSwga2V5KSB7XHJcbiAgICAgICAgaWYgKHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXSAhPT0gdW5kZWZpbmVkKSByZXR1cm4gdGhpcy5wbHVnaW5EYXRhW3BsdWdpbk5hbWVdW2tleV0gfHwgdW5kZWZpbmVkO1xyXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyh0aGlzLmdldFBsdWdpbkZpbGUocGx1Z2luTmFtZSkpKSByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgICAgIHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXSA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKHRoaXMuZ2V0UGx1Z2luRmlsZShwbHVnaW5OYW1lKSkpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLnBsdWdpbkRhdGFbcGx1Z2luTmFtZV1ba2V5XSB8fCB1bmRlZmluZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0UGx1Z2luRGF0YShwbHVnaW5OYW1lLCBrZXksIHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybjtcclxuICAgICAgICBpZiAodGhpcy5wbHVnaW5EYXRhW3BsdWdpbk5hbWVdID09PSB1bmRlZmluZWQpIHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXSA9IHt9O1xyXG4gICAgICAgIHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXVtrZXldID0gdmFsdWU7XHJcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLmdldFBsdWdpbkZpbGUocGx1Z2luTmFtZSksIEpTT04uc3RyaW5naWZ5KHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXSwgbnVsbCwgNCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGRlbGV0ZVBsdWdpbkRhdGEocGx1Z2luTmFtZSwga2V5KSB7XHJcbiAgICAgICAgaWYgKHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXSA9PT0gdW5kZWZpbmVkKSB0aGlzLnBsdWdpbkRhdGFbcGx1Z2luTmFtZV0gPSB7fTtcclxuICAgICAgICBkZWxldGUgdGhpcy5wbHVnaW5EYXRhW3BsdWdpbk5hbWVdW2tleV07XHJcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLmdldFBsdWdpbkZpbGUocGx1Z2luTmFtZSksIEpTT04uc3RyaW5naWZ5KHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXSwgbnVsbCwgNCkpO1xyXG4gICAgfVxyXG59OyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/modules/datastore.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var data__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! data */ \"./src/data/data.js\");\n/* harmony import */ var _utilities__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utilities */ \"./src/modules/utilities.js\");\n\n\n\nconst fs = __webpack_require__(/*! fs */ \"fs\");\n\nconst path = __webpack_require__(/*! path */ \"path\");\n\nconst releaseChannel = DiscordNative.globals.releaseChannel; // Schema\n// =======================\n// %appdata%\\BetterDiscord\n// -> data\n// -> [releaseChannel]\\ (stable/canary/ptb)\n// -> settings.json\n// -> plugins.json\n// -> themes.json\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (new class DataStore {\n constructor() {\n this.data = {\n misc: {}\n };\n this.pluginData = {};\n this.cacheData = {};\n }\n\n initialize() {\n if (!fs.existsSync(this.baseFolder)) fs.mkdirSync(this.baseFolder);\n if (!fs.existsSync(this.dataFolder)) fs.mkdirSync(this.dataFolder);\n if (!fs.existsSync(this.localeFolder)) fs.mkdirSync(this.localeFolder);\n if (!fs.existsSync(this.emoteFolder)) fs.mkdirSync(this.emoteFolder);\n if (!fs.existsSync(this.cacheFile)) fs.writeFileSync(this.cacheFile, JSON.stringify({}));\n if (!fs.existsSync(this.BDFile)) fs.writeFileSync(this.BDFile, JSON.stringify(this.data.misc, null, 4));\n if (!fs.existsSync(this.customCSS)) fs.writeFileSync(this.customCSS, \"\");\n const dataFiles = fs.readdirSync(this.dataFolder).filter(f => !fs.statSync(path.resolve(this.dataFolder, f)).isDirectory() && f.endsWith(\".json\"));\n\n for (const file of dataFiles) {\n this.data[file.split(\".\")[0]] = require(path.resolve(this.dataFolder, file));\n }\n\n this.cacheData = _utilities__WEBPACK_IMPORTED_MODULE_1__[\"default\"].testJSON(fs.readFileSync(this.cacheFile).toString()) || {};\n }\n\n get customCSS() {\n return this._customCSS || (this._customCSS = path.resolve(this.dataFolder, \"custom.css\"));\n }\n\n get baseFolder() {\n return this._baseFolder || (this._baseFolder = path.resolve(data__WEBPACK_IMPORTED_MODULE_0__[\"Config\"].dataPath, \"data\"));\n }\n\n get dataFolder() {\n return this._dataFolder || (this._dataFolder = path.resolve(this.baseFolder, `${releaseChannel}`));\n }\n\n get localeFolder() {\n return this._localeFolder || (this._localeFolder = path.resolve(this.baseFolder, `locales`));\n }\n\n get emoteFolder() {\n return this._emoteFolder || (this._emoteFolder = path.resolve(this.baseFolder, `emotes`));\n }\n\n get cacheFile() {\n return this._cacheFile || (this._cacheFile = path.resolve(this.baseFolder, `.cache`));\n }\n\n get BDFile() {\n return this._BDFile || (this._BDFile = path.resolve(data__WEBPACK_IMPORTED_MODULE_0__[\"Config\"].dataPath, \"data\", `${releaseChannel}.json`));\n }\n\n getPluginFile(pluginName) {\n return path.resolve(data__WEBPACK_IMPORTED_MODULE_0__[\"Config\"].dataPath, \"plugins\", pluginName + \".config.json\");\n }\n\n _getFile(key) {\n if (key == \"settings\" || key == \"plugins\" || key == \"themes\") return path.resolve(this.dataFolder, `${key}.json`);\n return path.resolve(this.dataFolder, `misc.json`);\n }\n\n getBDData(key) {\n return this.data.misc[key] || \"\";\n }\n\n setBDData(key, value) {\n this.data.misc[key] = value;\n fs.writeFileSync(path.resolve(this.dataFolder, `misc.json`), JSON.stringify(this.data.misc, null, 4));\n }\n\n getLocale(locale) {\n const file = path.resolve(this.localeFolder, `${locale}.json`);\n if (!fs.existsSync(file)) return null;\n return _utilities__WEBPACK_IMPORTED_MODULE_1__[\"default\"].testJSON(fs.readFileSync(file).toString());\n }\n\n saveLocale(locale, strings) {\n fs.writeFileSync(path.resolve(this.localeFolder, `${locale}.json`), JSON.stringify(strings, null, 4));\n }\n\n getCacheHash(category, key) {\n if (!this.cacheData[category]) return \"\";\n if (!fs.existsSync(path.resolve(this.baseFolder, category, `${key}.json`))) return \"\";\n return this.cacheData[category][key] || \"\";\n }\n\n setCacheHash(category, key, hash) {\n if (!this.cacheData[category]) this.cacheData[category] = {};\n this.cacheData[category][key] = hash;\n fs.writeFileSync(this.cacheFile, JSON.stringify(this.cacheData, null, 4));\n }\n\n emotesExist(category) {\n return fs.existsSync(path.resolve(this.emoteFolder, `${category}.json`));\n }\n\n getEmoteData(category) {\n const file = path.resolve(this.emoteFolder, `${category}.json`);\n if (!fs.existsSync(file)) return null;\n return _utilities__WEBPACK_IMPORTED_MODULE_1__[\"default\"].testJSON(fs.readFileSync(file).toString());\n }\n\n saveEmoteData(category, data) {\n fs.writeFileSync(path.resolve(this.emoteFolder, `${category}.json`), JSON.stringify(data));\n }\n\n getData(key) {\n return this.data[key] || \"\";\n }\n\n setData(key, value) {\n this.data[key] = value;\n fs.writeFileSync(path.resolve(this.dataFolder, `${key}.json`), JSON.stringify(value, null, 4));\n }\n\n loadCustomCSS() {\n return fs.readFileSync(this.customCSS).toString();\n }\n\n saveCustomCSS(css) {\n return fs.writeFileSync(this.customCSS, css);\n }\n\n getPluginData(pluginName, key) {\n if (this.pluginData[pluginName] !== undefined) return this.pluginData[pluginName][key] || undefined;\n if (!fs.existsSync(this.getPluginFile(pluginName))) return undefined;\n this.pluginData[pluginName] = JSON.parse(fs.readFileSync(this.getPluginFile(pluginName)));\n return this.pluginData[pluginName][key] || undefined;\n }\n\n setPluginData(pluginName, key, value) {\n if (value === undefined) return;\n if (this.pluginData[pluginName] === undefined) this.pluginData[pluginName] = {};\n this.pluginData[pluginName][key] = value;\n fs.writeFileSync(this.getPluginFile(pluginName), JSON.stringify(this.pluginData[pluginName], null, 4));\n }\n\n deletePluginData(pluginName, key) {\n if (this.pluginData[pluginName] === undefined) this.pluginData[pluginName] = {};\n delete this.pluginData[pluginName][key];\n fs.writeFileSync(this.getPluginFile(pluginName), JSON.stringify(this.pluginData[pluginName], null, 4));\n }\n\n}());//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Db3JlLy4vc3JjL21vZHVsZXMvZGF0YXN0b3JlLmpzPzEwNTIiXSwibmFtZXMiOlsiZnMiLCJyZXF1aXJlIiwicGF0aCIsInJlbGVhc2VDaGFubmVsIiwiRGlzY29yZE5hdGl2ZSIsImdsb2JhbHMiLCJEYXRhU3RvcmUiLCJjb25zdHJ1Y3RvciIsImRhdGEiLCJtaXNjIiwicGx1Z2luRGF0YSIsImNhY2hlRGF0YSIsImluaXRpYWxpemUiLCJleGlzdHNTeW5jIiwiYmFzZUZvbGRlciIsIm1rZGlyU3luYyIsImRhdGFGb2xkZXIiLCJsb2NhbGVGb2xkZXIiLCJlbW90ZUZvbGRlciIsImNhY2hlRmlsZSIsIndyaXRlRmlsZVN5bmMiLCJKU09OIiwic3RyaW5naWZ5IiwiQkRGaWxlIiwiY3VzdG9tQ1NTIiwiZGF0YUZpbGVzIiwicmVhZGRpclN5bmMiLCJmaWx0ZXIiLCJmIiwic3RhdFN5bmMiLCJyZXNvbHZlIiwiaXNEaXJlY3RvcnkiLCJlbmRzV2l0aCIsImZpbGUiLCJzcGxpdCIsIl9fbm9uX3dlYnBhY2tfcmVxdWlyZV9fIiwiVXRpbGl0aWVzIiwidGVzdEpTT04iLCJyZWFkRmlsZVN5bmMiLCJ0b1N0cmluZyIsIl9jdXN0b21DU1MiLCJfYmFzZUZvbGRlciIsIkNvbmZpZyIsImRhdGFQYXRoIiwiX2RhdGFGb2xkZXIiLCJfbG9jYWxlRm9sZGVyIiwiX2Vtb3RlRm9sZGVyIiwiX2NhY2hlRmlsZSIsIl9CREZpbGUiLCJnZXRQbHVnaW5GaWxlIiwicGx1Z2luTmFtZSIsIl9nZXRGaWxlIiwia2V5IiwiZ2V0QkREYXRhIiwic2V0QkREYXRhIiwidmFsdWUiLCJnZXRMb2NhbGUiLCJsb2NhbGUiLCJzYXZlTG9jYWxlIiwic3RyaW5ncyIsImdldENhY2hlSGFzaCIsImNhdGVnb3J5Iiwic2V0Q2FjaGVIYXNoIiwiaGFzaCIsImVtb3Rlc0V4aXN0IiwiZ2V0RW1vdGVEYXRhIiwic2F2ZUVtb3RlRGF0YSIsImdldERhdGEiLCJzZXREYXRhIiwibG9hZEN1c3RvbUNTUyIsInNhdmVDdXN0b21DU1MiLCJjc3MiLCJnZXRQbHVnaW5EYXRhIiwidW5kZWZpbmVkIiwicGFyc2UiLCJzZXRQbHVnaW5EYXRhIiwiZGVsZXRlUGx1Z2luRGF0YSJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTs7QUFDQSxNQUFNQSxFQUFFLEdBQUdDLG1CQUFPLENBQUMsY0FBRCxDQUFsQjs7QUFDQSxNQUFNQyxJQUFJLEdBQUdELG1CQUFPLENBQUMsa0JBQUQsQ0FBcEI7O0FBQ0EsTUFBTUUsY0FBYyxHQUFHQyxhQUFhLENBQUNDLE9BQWQsQ0FBc0JGLGNBQTdDLEMsQ0FFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVlLG1FQUFJLE1BQU1HLFNBQU4sQ0FBZ0I7QUFDL0JDLGFBQVcsR0FBRztBQUNWLFNBQUtDLElBQUwsR0FBWTtBQUFDQyxVQUFJLEVBQUU7QUFBUCxLQUFaO0FBQ0EsU0FBS0MsVUFBTCxHQUFrQixFQUFsQjtBQUNBLFNBQUtDLFNBQUwsR0FBaUIsRUFBakI7QUFDSDs7QUFFREMsWUFBVSxHQUFHO0FBQ1QsUUFBSSxDQUFDWixFQUFFLENBQUNhLFVBQUgsQ0FBYyxLQUFLQyxVQUFuQixDQUFMLEVBQXFDZCxFQUFFLENBQUNlLFNBQUgsQ0FBYSxLQUFLRCxVQUFsQjtBQUNyQyxRQUFJLENBQUNkLEVBQUUsQ0FBQ2EsVUFBSCxDQUFjLEtBQUtHLFVBQW5CLENBQUwsRUFBcUNoQixFQUFFLENBQUNlLFNBQUgsQ0FBYSxLQUFLQyxVQUFsQjtBQUNyQyxRQUFJLENBQUNoQixFQUFFLENBQUNhLFVBQUgsQ0FBYyxLQUFLSSxZQUFuQixDQUFMLEVBQXVDakIsRUFBRSxDQUFDZSxTQUFILENBQWEsS0FBS0UsWUFBbEI7QUFDdkMsUUFBSSxDQUFDakIsRUFBRSxDQUFDYSxVQUFILENBQWMsS0FBS0ssV0FBbkIsQ0FBTCxFQUFzQ2xCLEVBQUUsQ0FBQ2UsU0FBSCxDQUFhLEtBQUtHLFdBQWxCO0FBQ3RDLFFBQUksQ0FB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QjtBQUNsQyxRQUFJQSxLQUFLLEtBQUtrQixTQUFkLEVBQXlCO0FBQ3pCLFFBQUksS0FBSy9ELFVBQUwsQ0FBZ0J3QyxVQUFoQixNQUFnQ3VCLFNBQXBDLEVBQStDLEtBQUsvRCxVQUFMLENBQWdCd0MsVUFBaEIsSUFBOEIsRUFBOUI7QUFDL0MsU0FBS3hDLFVBQUwsQ0FBZ0J3QyxVQUFoQixFQUE0QkUsR0FBNUIsSUFBbUNHLEtBQW5DO0FBQ0F2RCxNQUFFLENBQUNvQixhQUFILENBQWlCLEtBQUs2QixhQUFMLENBQW1CQyxVQUFuQixDQUFqQixFQUFpRDdCLElBQUksQ0FBQ0MsU0FBTCxDQUFlLEtBQUtaLFVBQUwsQ0FBZ0J3QyxVQUFoQixDQUFmLEVBQTRDLElBQTVDLEVBQWtELENBQWxELENBQWpEO0FBQ0g7O0FBRUQwQixrQkFBZ0IsQ0FBQzFCLFVBQUQsRUFBYUUsR0FBYixFQUFrQjtBQUM5QixRQUFJLEtBQUsxQyxVQUFMLENBQWdCd0MsVUFBaEIsTUFBZ0N1QixTQUFwQyxFQUErQyxLQUFLL0QsVUFBTCxDQUFnQndDLFVBQWhCLElBQThCLEVBQTlCO0FBQy9DLFdBQU8sS0FBS3hDLFVBQUwsQ0FBZ0J3QyxVQUFoQixFQUE0QkUsR0FBNUIsQ0FBUDtBQUNBcEQsTUFBRSxDQUFDb0IsYUFBSCxDQUFpQixLQUFLNkIsYUFBTCxDQUFtQkMsVUFBbkIsQ0FBakIsRUFBaUQ3QixJQUFJLENBQUNDLFNBQUwsQ0FBZSxLQUFLWixVQUFMLENBQWdCd0MsVUFBaEIsQ0FBZixFQUE0QyxJQUE1QyxFQUFrRCxDQUFsRCxDQUFqRDtBQUNIOztBQXJIOEIsQ0FBcEIsRUFBZiIsImZpbGUiOiIuL3NyYy9tb2R1bGVzL2RhdGFzdG9yZS5qcy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29uZmlnfSBmcm9tIFwiZGF0YVwiO1xyXG5pbXBvcnQgVXRpbGl0aWVzIGZyb20gXCIuL3V0aWxpdGllc1wiO1xyXG5jb25zdCBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcclxuY29uc3QgcGF0aCA9IHJlcXVpcmUoXCJwYXRoXCIpO1xyXG5jb25zdCByZWxlYXNlQ2hhbm5lbCA9IERpc2NvcmROYXRpdmUuZ2xvYmFscy5yZWxlYXNlQ2hhbm5lbDtcclxuXHJcbi8vIFNjaGVtYVxyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PVxyXG4vLyAlYXBwZGF0YSVcXEJldHRlckRpc2NvcmRcclxuLy8gICAgIC0+IGRhdGFcclxuLy8gICAgICAgICAtPiBbcmVsZWFzZUNoYW5uZWxdXFwgKHN0YWJsZS9jYW5hcnkvcHRiKVxyXG4vLyAgICAgICAgICAgICAtPiBzZXR0aW5ncy5qc29uXHJcbi8vICAgICAgICAgICAgIC0+IHBsdWdpbnMuanNvblxyXG4vLyAgICAgICAgICAgICAtPiB0aGVtZXMuanNvblxyXG5cclxuZXhwb3J0IGRlZmF1bHQgbmV3IGNsYXNzIERhdGFTdG9yZSB7XHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICB0aGlzLmRhdGEgPSB7bWlzYzoge319O1xyXG4gICAgICAgIHRoaXMucGx1Z2luRGF0YSA9IHt9O1xyXG4gICAgICAgIHRoaXMuY2FjaGVEYXRhID0ge307XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdGlhbGl6ZSgpIHtcclxuICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmModGhpcy5iYXNlRm9sZGVyKSkgZnMubWtkaXJTeW5jKHRoaXMuYmFzZUZvbGRlcik7XHJcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHRoaXMuZGF0YUZvbGRlcikpIGZzLm1rZGlyU3luYyh0aGlzLmRhdGFGb2xkZXIpO1xyXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyh0aGlzLmxvY2FsZUZvbGRlcikpIGZzLm1rZGlyU3luYyh0aGlzLmxvY2FsZUZvbGRlcik7XHJcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHRoaXMuZW1vdGVGb2xkZXIpKSBmcy5ta2RpclN5bmModGhpcy5lbW90ZUZvbGRlcik7XHJcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHRoaXMuY2FjaGVGaWxlKSkgZnMud3JpdGVGaWxlU3luYyh0aGlzLmNhY2hlRmlsZSwgSlNPTi5zdHJpbmdpZnkoe30pKTtcclxuICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmModGhpcy5CREZpbGUpKSBmcy53cml0ZUZpbGVTeW5jKHRoaXMuQkRGaWxlLCBKU09OLnN0cmluZ2lmeSh0aGlzLmRhdGEubWlzYywgbnVsbCwgNCkpO1xyXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyh0aGlzLmN1c3RvbUNTUykpIGZzLndyaXRlRmlsZVN5bmModGhpcy5jdXN0b21DU1MsIFwiXCIpO1xyXG4gICAgICAgIGNvbnN0IGRhdGFGaWxlcyA9IGZzLnJlYWRkaXJTeW5jKHRoaXMuZGF0YUZvbGRlcikuZmlsdGVyKGYgPT4gIWZzLnN0YXRTeW5jKHBhdGgucmVzb2x2ZSh0aGlzLmRhdGFGb2xkZXIsIGYpKS5pc0RpcmVjdG9yeSgpICYmIGYuZW5kc1dpdGgoXCIuanNvblwiKSk7XHJcbiAgICAgICAgZm9yIChjb25zdCBmaWxlIG9mIGRhdGFGaWxlcykge1xyXG4gICAgICAgICAgICB0aGlzLmRhdGFbZmlsZS5zcGxpdChcIi5cIilbMF1dID0gX19ub25fd2VicGFja19yZXF1aXJlX18ocGF0aC5yZXNvbHZlKHRoaXMuZGF0YUZvbGRlciwgZmlsZSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmNhY2hlRGF0YSA9IFV0aWxpdGllcy50ZXN0SlNPTihmcy5yZWFkRmlsZVN5bmModGhpcy5jYWNoZUZpbGUpLnRvU3RyaW5nKCkpIHx8IHt9O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBjdXN0b21DU1MoKSB7cmV0dXJuIHRoaXMuX2N1c3RvbUNTUyB8fCAodGhpcy5fY3VzdG9tQ1NTID0gcGF0aC5yZXNvbHZlKHRoaXMuZGF0YUZvbGRlciwgXCJjdXN0b20uY3NzXCIpKTt9XHJcbiAgICBnZXQgYmFzZUZvbGRlcigpIHtyZXR1cm4gdGhpcy5fYmFzZUZvbGRlciB8fCAodGhpcy5fYmFzZUZvbGRlciA9IHBhdGgucmVzb2x2ZShDb25maWcuZGF0YVBhdGgsIFwiZGF0YVwiKSk7fVxyXG4gICAgZ2V0IGRhdGFGb2xkZXIoKSB7cmV0dXJuIHRoaXMuX2RhdGFGb2xkZXIgfHwgKHRoaXMuX2RhdGFGb2xkZXIgPSBwYXRoLnJlc29sdmUodGhpcy5iYXNlRm9sZGVyLCBgJHtyZWxlYXNlQ2hhbm5lbH1gKSk7fVxyXG4gICAgZ2V0IGxvY2FsZUZvbGRlcigpIHtyZXR1cm4gdGhpcy5fbG9jYWxlRm9sZGVyIHx8ICh0aGlzLl9sb2NhbGVGb2xkZXIgPSBwYXRoLnJlc29sdmUodGhpcy5iYXNlRm9sZGVyLCBgbG9jYWxlc2ApKTt9XHJcbiAgICBnZXQgZW1vdGVGb2xkZXIoKSB7cmV0dXJuIHRoaXMuX2Vtb3RlRm9sZGVyIHx8ICh0aGlzLl9lbW90ZUZvbGRlciA9IHBhdGgucmVzb2x2ZSh0aGlzLmJhc2VGb2xkZXIsIGBlbW90ZXNgKSk7fVxyXG4gICAgZ2V0IGNhY2hlRmlsZSgpIHtyZXR1cm4gdGhpcy5fY2FjaGVGaWxlIHx8ICh0aGlzLl9jYWNoZUZpbGUgPSBwYXRoLnJlc29sdmUodGhpcy5iYXNlRm9sZGVyLCBgLmNhY2hlYCkpO31cclxuICAgIGdldCBCREZpbGUoKSB7cmV0dXJuIHRoaXMuX0JERmlsZSB8fCAodGhpcy5fQkRGaWxlID0gcGF0aC5yZXNvbHZlKENvbmZpZy5kYXRhUGF0aCwgXCJkYXRhXCIsIGAke3JlbGVhc2VDaGFubmVsfS5qc29uYCkpO31cclxuICAgIGdldFBsdWdpbkZpbGUocGx1Z2luTmFtZSkge3JldHVybiBwYXRoLnJlc29sdmUoQ29uZmlnLmRhdGFQYXRoLCBcInBsdWdpbnNcIiwgcGx1Z2luTmFtZSArIFwiLmNvbmZpZy5qc29uXCIpO31cclxuXHJcblxyXG4gICAgX2dldEZpbGUoa2V5KSB7XHJcbiAgICAgICAgaWYgKGtleSA9PSBcInNldHRpbmdzXCIgfHwga2V5ID09IFwicGx1Z2luc1wiIHx8IGtleSA9PSBcInRoZW1lc1wiKSByZXR1cm4gcGF0aC5yZXNvbHZlKHRoaXMuZGF0YUZvbGRlciwgYCR7a2V5fS5qc29uYCk7XHJcbiAgICAgICAgcmV0dXJuIHBhdGgucmVzb2x2ZSh0aGlzLmRhdGFGb2xkZXIsIGBtaXNjLmpzb25gKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRCRERhdGEoa2V5KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS5taXNjW2tleV0gfHwgXCJcIjtcclxuICAgIH1cclxuXHJcbiAgICBzZXRCRERhdGEoa2V5LCB2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuZGF0YS5taXNjW2tleV0gPSB2YWx1ZTtcclxuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHBhdGgucmVzb2x2ZSh0aGlzLmRhdGFGb2xkZXIsIGBtaXNjLmpzb25gKSwgSlNPTi5zdHJpbmdpZnkodGhpcy5kYXRhLm1pc2MsIG51bGwsIDQpKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRMb2NhbGUobG9jYWxlKSB7XHJcbiAgICAgICAgY29uc3QgZmlsZSA9IHBhdGgucmVzb2x2ZSh0aGlzLmxvY2FsZUZvbGRlciwgYCR7bG9jYWxlfS5qc29uYCk7XHJcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGZpbGUpKSByZXR1cm4gbnVsbDtcclxuICAgICAgICByZXR1cm4gVXRpbGl0aWVzLnRlc3RKU09OKGZzLnJlYWRGaWxlU3luYyhmaWxlKS50b1N0cmluZygpKTtcclxuICAgIH1cclxuXHJcbiAgICBzYXZlTG9jYWxlKGxvY2FsZSwgc3RyaW5ncykge1xyXG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMocGF0aC5yZXNvbHZlKHRoaXMubG9jYWxlRm9sZGVyLCBgJHtsb2NhbGV9Lmpzb25gKSwgSlNPTi5zdHJpbmdpZnkoc3RyaW5ncywgbnVsbCwgNCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldENhY2hlSGFzaChjYXRlZ29yeSwga2V5KSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmNhY2hlRGF0YVtjYXRlZ29yeV0pIHJldHVybiBcIlwiO1xyXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyhwYXRoLnJlc29sdmUodGhpcy5iYXNlRm9sZGVyLCBjYXRlZ29yeSwgYCR7a2V5fS5qc29uYCkpKSByZXR1cm4gXCJcIjtcclxuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZURhdGFbY2F0ZWdvcnldW2tleV0gfHwgXCJcIjtcclxuICAgIH1cclxuXHJcbiAgICBzZXRDYWNoZUhhc2goY2F0ZWdvcnksIGtleSwgaGFzaCkge1xyXG4gICAgICAgIGlmICghdGhpcy5jYWNoZURhdGFbY2F0ZWdvcnldKSB0aGlzLmNhY2hlRGF0YVtjYXRlZ29yeV0gPSB7fTtcclxuICAgICAgICB0aGlzLmNhY2hlRGF0YVtjYXRlZ29yeV1ba2V5XSA9IGhhc2g7XHJcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLmNhY2hlRmlsZSwgSlNPTi5zdHJpbmdpZnkodGhpcy5jYWNoZURhdGEsIG51bGwsIDQpKTtcclxuICAgIH1cclxuXHJcbiAgICBlbW90ZXNFeGlzdChjYXRlZ29yeSkge1xyXG4gICAgICAgIHJldHVybiBmcy5leGlzdHNTeW5jKHBhdGgucmVzb2x2ZSh0aGlzLmVtb3RlRm9sZGVyLCBgJHtjYXRlZ29yeX0uanNvbmApKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRFbW90ZURhdGEoY2F0ZWdvcnkpIHtcclxuICAgICAgICBjb25zdCBmaWxlID0gcGF0aC5yZXNvbHZlKHRoaXMuZW1vdGVGb2xkZXIsIGAke2NhdGVnb3J5fS5qc29uYCk7XHJcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGZpbGUpKSByZXR1cm4gbnVsbDtcclxuICAgICAgICByZXR1cm4gVXRpbGl0aWVzLnRlc3RKU09OKGZzLnJlYWRGaWxlU3luYyhmaWxlKS50b1N0cmluZygpKTtcclxuICAgIH1cclxuXHJcbiAgICBzYXZlRW1vdGVEYXRhKGNhdGVnb3J5LCBkYXRhKSB7XHJcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhwYXRoLnJlc29sdmUodGhpcy5lbW90ZUZvbGRlciwgYCR7Y2F0ZWdvcnl9Lmpzb25gKSwgSlNPTi5zdHJpbmdpZnkoZGF0YSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldERhdGEoa2V5KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YVtrZXldIHx8IFwiXCI7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0RGF0YShrZXksIHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy5kYXRhW2tleV0gPSB2YWx1ZTtcclxuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHBhdGgucmVzb2x2ZSh0aGlzLmRhdGFGb2xkZXIsIGAke2tleX0uanNvbmApLCBKU09OLnN0cmluZ2lmeSh2YWx1ZSwgbnVsbCwgNCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGxvYWRDdXN0b21DU1MoKSB7XHJcbiAgICAgICAgcmV0dXJuIGZzLnJlYWRGaWxlU3luYyh0aGlzLmN1c3RvbUNTUykudG9TdHJpbmcoKTtcclxuICAgIH1cclxuXHJcbiAgICBzYXZlQ3VzdG9tQ1NTKGNzcykge1xyXG4gICAgICAgIHJldHVybiBmcy53cml0ZUZpbGVTeW5jKHRoaXMuY3VzdG9tQ1NTLCBjc3MpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFBsdWdpbkRhdGEocGx1Z2luTmFtZSwga2V5KSB7XHJcbiAgICAgICAgaWYgKHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXSAhPT0gdW5kZWZpbmVkKSByZXR1cm4gdGhpcy5wbHVnaW5EYXRhW3BsdWdpbk5hbWVdW2tleV0gfHwgdW5kZWZpbmVkO1xyXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyh0aGlzLmdldFBsdWdpbkZpbGUocGx1Z2luTmFtZSkpKSByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgICAgIHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXSA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKHRoaXMuZ2V0UGx1Z2luRmlsZShwbHVnaW5OYW1lKSkpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLnBsdWdpbkRhdGFbcGx1Z2luTmFtZV1ba2V5XSB8fCB1bmRlZmluZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0UGx1Z2luRGF0YShwbHVnaW5OYW1lLCBrZXksIHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybjtcclxuICAgICAgICBpZiAodGhpcy5wbHVnaW5EYXRhW3BsdWdpbk5hbWVdID09PSB1bmRlZmluZWQpIHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXSA9IHt9O1xyXG4gICAgICAgIHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXVtrZXldID0gdmFsdWU7XHJcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLmdldFBsdWdpbkZpbGUocGx1Z2luTmFtZSksIEpTT04uc3RyaW5naWZ5KHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXSwgbnVsbCwgNCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGRlbGV0ZVBsdWdpbkRhdGEocGx1Z2luTmFtZSwga2V5KSB7XHJcbiAgICAgICAgaWYgKHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXSA9PT0gdW5kZWZpbmVkKSB0aGlzLnBsdWdpbkRhdGFbcGx1Z2luTmFtZV0gPSB7fTtcclxuICAgICAgICBkZWxldGUgdGhpcy5wbHVnaW5EYXRhW3BsdWdpbk5hbWVdW2tleV07XHJcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLmdldFBsdWdpbkZpbGUocGx1Z2luTmFtZSksIEpTT04uc3RyaW5naWZ5KHRoaXMucGx1Z2luRGF0YVtwbHVnaW5OYW1lXSwgbnVsbCwgNCkpO1xyXG4gICAgfVxyXG59OyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/modules/datastore.js\n"); /***/ }), @@ -443,7 +431,7 @@ eval("__webpack_require__.r(__webpack_exports__);\nconst EventEmitter = __webpac /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _data_strings__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../data/strings */ \"./src/data/strings.js\");\n/* harmony import */ var _discordmodules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./discordmodules */ \"./src/modules/discordmodules.js\");\n/* harmony import */ var _utilities__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utilities */ \"./src/modules/utilities.js\");\n/* harmony import */ var _emitter__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./emitter */ \"./src/modules/emitter.js\");\n/* harmony import */ var _datastore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./datastore */ \"./src/modules/datastore.js\");\n\n\n\n\n\n\nconst request = __webpack_require__(/*! request */ \"request\");\n\nconst {\n Dispatcher,\n DiscordConstants,\n UserSettingsStore\n} = _discordmodules__WEBPACK_IMPORTED_MODULE_1__[\"default\"];\n/* harmony default export */ __webpack_exports__[\"default\"] = (new class LocaleManager {\n get discordLocale() {\n return UserSettingsStore.locale.split(\"-\")[0];\n }\n\n get defaultLocale() {\n return \"en\";\n }\n\n constructor() {\n this.locale = \"\";\n this.strings = {};\n }\n\n async initialize() {\n await this.setLocale(this.discordLocale);\n Dispatcher.subscribe(DiscordConstants.ActionTypes.USER_SETTINGS_UPDATE, ({\n settings\n }) => {\n const newLocale = settings.locale;\n if (newLocale && newLocale != this.locale) this.setLocale(newLocale.split(\"-\")[0]);\n });\n }\n\n async setLocale(newLocale) {\n let newStrings;\n\n if (newLocale != this.defaultLocale) {\n newStrings = await this.getLocaleStrings(newLocale);\n if (!newStrings) return this.setLocale(this.defaultLocale);\n } else {\n newStrings = _data_strings__WEBPACK_IMPORTED_MODULE_0__[\"default\"];\n }\n\n this.locale = newLocale;\n _utilities__WEBPACK_IMPORTED_MODULE_2__[\"default\"].extend(this.strings, newStrings);\n _emitter__WEBPACK_IMPORTED_MODULE_3__[\"default\"].emit(\"strings-updated\");\n }\n\n async getLocaleStrings(locale) {\n const hash = _datastore__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getLocaleHash(locale);\n if (!hash) return await this.downloadLocale(locale);\n const invalid = await this.downloadLocale(locale, hash);\n if (!invalid) return _datastore__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getLocale(locale);\n return invalid;\n }\n\n downloadLocale(locale, hash = \"\") {\n return new Promise(resolve => {\n const options = {\n url: _utilities__WEBPACK_IMPORTED_MODULE_2__[\"default\"].repoUrl(`data/locales/${locale}.json`),\n timeout: 2000,\n json: true\n };\n if (hash) options.headers = {\n \"If-None-Match\": hash\n };\n console.log(options.headers);\n request.get(options, (err, resp, newStrings) => {\n if (err || resp.statusCode !== 200) return resolve(null);\n console.log(resp);\n _datastore__WEBPACK_IMPORTED_MODULE_4__[\"default\"].saveLocale(locale, newStrings);\n _datastore__WEBPACK_IMPORTED_MODULE_4__[\"default\"].saveLocaleHash(locale, resp.headers.etag);\n resolve(newStrings);\n });\n });\n }\n\n}());//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Db3JlLy4vc3JjL21vZHVsZXMvbG9jYWxlbWFuYWdlci5qcz8yMzlkIl0sIm5hbWVzIjpbInJlcXVlc3QiLCJyZXF1aXJlIiwiRGlzcGF0Y2hlciIsIkRpc2NvcmRDb25zdGFudHMiLCJVc2VyU2V0dGluZ3NTdG9yZSIsIkRpc2NvcmRNb2R1bGVzIiwiTG9jYWxlTWFuYWdlciIsImRpc2NvcmRMb2NhbGUiLCJsb2NhbGUiLCJzcGxpdCIsImRlZmF1bHRMb2NhbGUiLCJjb25zdHJ1Y3RvciIsInN0cmluZ3MiLCJpbml0aWFsaXplIiwic2V0TG9jYWxlIiwic3Vic2NyaWJlIiwiQWN0aW9uVHlwZXMiLCJVU0VSX1NFVFRJTkdTX1VQREFURSIsInNldHRpbmdzIiwibmV3TG9jYWxlIiwibmV3U3RyaW5ncyIsImdldExvY2FsZVN0cmluZ3MiLCJEZWZhdWx0U3RyaW5ncyIsIlV0aWxpdGllcyIsImV4dGVuZCIsIkV2ZW50cyIsImVtaXQiLCJoYXNoIiwiRGF0YVN0b3JlIiwiZ2V0TG9jYWxlSGFzaCIsImRvd25sb2FkTG9jYWxlIiwiaW52YWxpZCIsImdldExvY2FsZSIsIlByb21pc2UiLCJyZXNvbHZlIiwib3B0aW9ucyIsInVybCIsInJlcG9VcmwiLCJ0aW1lb3V0IiwianNvbiIsImhlYWRlcnMiLCJjb25zb2xlIiwibG9nIiwiZ2V0IiwiZXJyIiwicmVzcCIsInN0YXR1c0NvZGUiLCJzYXZlTG9jYWxlIiwic2F2ZUxvY2FsZUhhc2giLCJldGFnIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUNBLE1BQU1BLE9BQU8sR0FBR0MsbUJBQU8sQ0FBQyx3QkFBRCxDQUF2Qjs7QUFFQSxNQUFNO0FBQUNDLFlBQUQ7QUFBYUMsa0JBQWI7QUFBK0JDO0FBQS9CLElBQW9EQyx1REFBMUQ7QUFFZSxtRUFBSSxNQUFNQyxhQUFOLENBQW9CO0FBQ3RDLE1BQUlDLGFBQUos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LENBQXFCdkMsTUFBckIsRUFBNkJZLFVBQTdCO0FBQ0FRLDBEQUFTLENBQUNvQixjQUFWLENBQXlCeEMsTUFBekIsRUFBaUNxQyxJQUFJLENBQUNMLE9BQUwsQ0FBYVMsSUFBOUM7QUFDQWYsZUFBTyxDQUFDZCxVQUFELENBQVA7QUFDQSxPQU5EO0FBT0EsS0FmTSxDQUFQO0FBZ0JBOztBQXhEcUMsQ0FBeEIsRUFBZiIsImZpbGUiOiIuL3NyYy9tb2R1bGVzL2xvY2FsZW1hbmFnZXIuanMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgRGVmYXVsdFN0cmluZ3MgZnJvbSBcIi4uL2RhdGEvc3RyaW5nc1wiO1xyXG5pbXBvcnQgRGlzY29yZE1vZHVsZXMgZnJvbSBcIi4vZGlzY29yZG1vZHVsZXNcIjtcclxuaW1wb3J0IFV0aWxpdGllcyBmcm9tIFwiLi91dGlsaXRpZXNcIjtcclxuaW1wb3J0IEV2ZW50cyBmcm9tIFwiLi9lbWl0dGVyXCI7XHJcbmltcG9ydCBEYXRhU3RvcmUgZnJvbSBcIi4vZGF0YXN0b3JlXCI7XHJcbmNvbnN0IHJlcXVlc3QgPSByZXF1aXJlKFwicmVxdWVzdFwiKTtcclxuXHJcbmNvbnN0IHtEaXNwYXRjaGVyLCBEaXNjb3JkQ29uc3RhbnRzLCBVc2VyU2V0dGluZ3NTdG9yZX0gPSBEaXNjb3JkTW9kdWxlcztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IG5ldyBjbGFzcyBMb2NhbGVNYW5hZ2VyIHtcclxuXHRnZXQgZGlzY29yZExvY2FsZSgpIHtyZXR1cm4gVXNlclNldHRpbmdzU3RvcmUubG9jYWxlLnNwbGl0KFwiLVwiKVswXTt9XHJcblx0Z2V0IGRlZmF1bHRMb2NhbGUoKSB7cmV0dXJuIFwiZW5cIjt9XHJcblxyXG5cdGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHRoaXMubG9jYWxlID0gXCJcIjtcclxuICAgICAgICB0aGlzLnN0cmluZ3MgPSB7fTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIGluaXRpYWxpemUoKSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5zZXRMb2NhbGUodGhpcy5kaXNjb3JkTG9jYWxlKTtcclxuICAgICAgICBEaXNwYXRjaGVyLnN1YnNjcmliZShEaXNjb3JkQ29uc3RhbnRzLkFjdGlvblR5cGVzLlVTRVJfU0VUVElOR1NfVVBEQVRFLCAoe3NldHRpbmdzfSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBuZXdMb2NhbGUgPSBzZXR0aW5ncy5sb2NhbGU7XHJcbiAgICAgICAgICAgIGlmIChuZXdMb2NhbGUgJiYgbmV3TG9jYWxlICE9IHRoaXMubG9jYWxlKSB0aGlzLnNldExvY2FsZShuZXdMb2NhbGUuc3BsaXQoXCItXCIpWzBdKTtcclxuICAgICAgICB9KTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIHNldExvY2FsZShuZXdMb2NhbGUpIHtcclxuICAgICAgICBsZXQgbmV3U3RyaW5ncztcclxuICAgICAgICBpZiAobmV3TG9jYWxlICE9IHRoaXMuZGVmYXVsdExvY2FsZSkge1xyXG5cdFx0XHRuZXdTdHJpbmdzID0gYXdhaXQgdGhpcy5nZXRMb2NhbGVTdHJpbmdzKG5ld0xvY2FsZSk7XHJcbiAgICAgICAgICAgIGlmICghbmV3U3RyaW5ncykgcmV0dXJuIHRoaXMuc2V0TG9jYWxlKHRoaXMuZGVmYXVsdExvY2FsZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBuZXdTdHJpbmdzID0gRGVmYXVsdFN0cmluZ3M7XHJcbiAgICAgICAgfVxyXG5cdFx0dGhpcy5sb2NhbGUgPSBuZXdMb2NhbGU7XHJcblx0XHRVdGlsaXRpZXMuZXh0ZW5kKHRoaXMuc3RyaW5ncywgbmV3U3RyaW5ncyk7XHJcblx0XHRFdmVudHMuZW1pdChcInN0cmluZ3MtdXBkYXRlZFwiKTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIGdldExvY2FsZVN0cmluZ3MobG9jYWxlKSB7XHJcblx0XHRjb25zdCBoYXNoID0gRGF0YVN0b3JlLmdldExvY2FsZUhhc2gobG9jYWxlKTtcclxuXHRcdGlmICghaGFzaCkgcmV0dXJuIGF3YWl0IHRoaXMuZG93bmxvYWRMb2NhbGUobG9jYWxlKTtcclxuXHRcdGNvbnN0IGludmFsaWQgPSBhd2FpdCB0aGlzLmRvd25sb2FkTG9jYWxlKGxvY2FsZSwgaGFzaCk7XHJcblx0XHRpZiAoIWludmFsaWQpIHJldHVybiBEYXRhU3RvcmUuZ2V0TG9jYWxlKGxvY2FsZSk7XHJcblx0XHRyZXR1cm4gaW52YWxpZDtcclxuXHR9XHJcblxyXG5cdGRvd25sb2FkTG9jYWxlKGxvY2FsZSwgaGFzaCA9IFwiXCIpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcclxuXHRcdFx0Y29uc3Qgb3B0aW9ucyA9IHtcclxuXHRcdFx0XHR1cmw6IFV0aWxpdGllcy5yZXBvVXJsKGBkYXRhL2xvY2FsZXMvJHtsb2NhbGV9Lmpzb25gKSxcclxuXHRcdFx0XHR0aW1lb3V0OiAyMDAwLFxyXG5cdFx0XHRcdGpzb246IHRydWVcclxuXHRcdFx0fTtcclxuXHRcdFx0aWYgKGhhc2gpIG9wdGlvbnMuaGVhZGVycyA9IHtcIklmLU5vbmUtTWF0Y2hcIjogaGFzaH07XHJcblx0XHRcdGNvbnNvbGUubG9nKG9wdGlvbnMuaGVhZGVycyk7XHJcblx0XHRcdHJlcXVlc3QuZ2V0KG9wdGlvbnMsIChlcnIsIHJlc3AsIG5ld1N0cmluZ3MpID0+IHtcclxuXHRcdFx0XHRpZiAoZXJyIHx8IHJlc3Auc3RhdHVzQ29kZSAhPT0gMjAwKSByZXR1cm4gcmVzb2x2ZShudWxsKTtcclxuXHRcdFx0XHRjb25zb2xlLmxvZyhyZXNwKTtcclxuXHRcdFx0XHREYXRhU3RvcmUuc2F2ZUxvY2FsZShsb2NhbGUsIG5ld1N0cmluZ3MpO1xyXG5cdFx0XHRcdERhdGFTdG9yZS5zYXZlTG9jYWxlSGFzaChsb2NhbGUsIHJlc3AuaGVhZGVycy5ldGFnKTtcclxuXHRcdFx0XHRyZXNvbHZlKG5ld1N0cmluZ3MpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxufTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/modules/localemanager.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _data_strings__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../data/strings */ \"./src/data/strings.js\");\n/* harmony import */ var _discordmodules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./discordmodules */ \"./src/modules/discordmodules.js\");\n/* harmony import */ var _utilities__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utilities */ \"./src/modules/utilities.js\");\n/* harmony import */ var _emitter__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./emitter */ \"./src/modules/emitter.js\");\n/* harmony import */ var _datastore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./datastore */ \"./src/modules/datastore.js\");\n\n\n\n\n\n\nconst request = __webpack_require__(/*! request */ \"request\");\n\nconst {\n Dispatcher,\n DiscordConstants,\n UserSettingsStore\n} = _discordmodules__WEBPACK_IMPORTED_MODULE_1__[\"default\"];\n/* harmony default export */ __webpack_exports__[\"default\"] = (new class LocaleManager {\n get discordLocale() {\n return UserSettingsStore.locale.split(\"-\")[0];\n }\n\n get defaultLocale() {\n return \"en\";\n }\n\n constructor() {\n this.locale = \"\";\n this.strings = {};\n }\n\n async initialize() {\n await this.setLocale(this.discordLocale);\n Dispatcher.subscribe(DiscordConstants.ActionTypes.USER_SETTINGS_UPDATE, ({\n settings\n }) => {\n const newLocale = settings.locale;\n if (newLocale && newLocale != this.locale) this.setLocale(newLocale.split(\"-\")[0]);\n });\n }\n\n async setLocale(newLocale) {\n let newStrings;\n\n if (newLocale != this.defaultLocale) {\n newStrings = await this.getLocaleStrings(newLocale);\n if (!newStrings) return this.setLocale(this.defaultLocale);\n } else {\n newStrings = _data_strings__WEBPACK_IMPORTED_MODULE_0__[\"default\"];\n }\n\n this.locale = newLocale;\n _utilities__WEBPACK_IMPORTED_MODULE_2__[\"default\"].extend(this.strings, newStrings);\n _emitter__WEBPACK_IMPORTED_MODULE_3__[\"default\"].emit(\"strings-updated\");\n }\n\n async getLocaleStrings(locale) {\n const hash = _datastore__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getCacheHash(\"locales\", locale);\n if (!hash) return await this.downloadLocale(locale);\n const invalid = await this.downloadLocale(locale, hash);\n if (!invalid) return _datastore__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getLocale(locale);\n return invalid;\n }\n\n downloadLocale(locale, hash = \"\") {\n return new Promise(resolve => {\n const options = {\n url: _utilities__WEBPACK_IMPORTED_MODULE_2__[\"default\"].repoUrl(`data/locales/${locale}.json`),\n timeout: 2000,\n json: true\n };\n if (hash) options.headers = {\n \"If-None-Match\": hash\n };\n request.get(options, (err, resp, newStrings) => {\n if (err || resp.statusCode !== 200) return resolve(null);\n _datastore__WEBPACK_IMPORTED_MODULE_4__[\"default\"].saveLocale(locale, newStrings);\n _datastore__WEBPACK_IMPORTED_MODULE_4__[\"default\"].setCacheHash(\"locales\", locale, resp.headers.etag);\n resolve(newStrings);\n });\n });\n }\n\n}());//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Db3JlLy4vc3JjL21vZHVsZXMvbG9jYWxlbWFuYWdlci5qcz8yMzlkIl0sIm5hbWVzIjpbInJlcXVlc3QiLCJyZXF1aXJlIiwiRGlzcGF0Y2hlciIsIkRpc2NvcmRDb25zdGFudHMiLCJVc2VyU2V0dGluZ3NTdG9yZSIsIkRpc2NvcmRNb2R1bGVzIiwiTG9jYWxlTWFuYWdlciIsImRpc2NvcmRMb2NhbGUiLCJsb2NhbGUiLCJzcGxpdCIsImRlZmF1bHRMb2NhbGUiLCJjb25zdHJ1Y3RvciIsInN0cmluZ3MiLCJpbml0aWFsaXplIiwic2V0TG9jYWxlIiwic3Vic2NyaWJlIiwiQWN0aW9uVHlwZXMiLCJVU0VSX1NFVFRJTkdTX1VQREFURSIsInNldHRpbmdzIiwibmV3TG9jYWxlIiwibmV3U3RyaW5ncyIsImdldExvY2FsZVN0cmluZ3MiLCJEZWZhdWx0U3RyaW5ncyIsIlV0aWxpdGllcyIsImV4dGVuZCIsIkV2ZW50cyIsImVtaXQiLCJoYXNoIiwiRGF0YVN0b3JlIiwiZ2V0Q2FjaGVIYXNoIiwiZG93bmxvYWRMb2NhbGUiLCJpbnZhbGlkIiwiZ2V0TG9jYWxlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJvcHRpb25zIiwidXJsIiwicmVwb1VybCIsInRpbWVvdXQiLCJqc29uIiwiaGVhZGVycyIsImdldCIsImVyciIsInJlc3AiLCJzdGF0dXNDb2RlIiwic2F2ZUxvY2FsZSIsInNldENhY2hlSGFzaCIsImV0YWciXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBQ0EsTUFBTUEsT0FBTyxHQUFHQyxtQkFBTyxDQUFDLHdCQUFELENBQXZCOztBQUVBLE1BQU07QUFBQ0MsWUFBRDtBQUFhQyxrQkFBYjtBQUErQkM7QUFBL0IsSUFBb0RDLHVEQUExRDtBQUVlLG1FQUFJLE1BQU1DLGFBQU4sQ0FBb0I7QUFDdEMsTUFBSUMsYUFBSixHQUFvQjtBQUFDLFdBQU9ILGlC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SUFBSSxDQUFDSCxPQUFMLENBQWFPLElBQXZEO0FBQ0FiLGVBQU8sQ0FBQ2QsVUFBRCxDQUFQO0FBQ0EsT0FMRDtBQU1BLEtBYk0sQ0FBUDtBQWNBOztBQXREcUMsQ0FBeEIsRUFBZiIsImZpbGUiOiIuL3NyYy9tb2R1bGVzL2xvY2FsZW1hbmFnZXIuanMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgRGVmYXVsdFN0cmluZ3MgZnJvbSBcIi4uL2RhdGEvc3RyaW5nc1wiO1xyXG5pbXBvcnQgRGlzY29yZE1vZHVsZXMgZnJvbSBcIi4vZGlzY29yZG1vZHVsZXNcIjtcclxuaW1wb3J0IFV0aWxpdGllcyBmcm9tIFwiLi91dGlsaXRpZXNcIjtcclxuaW1wb3J0IEV2ZW50cyBmcm9tIFwiLi9lbWl0dGVyXCI7XHJcbmltcG9ydCBEYXRhU3RvcmUgZnJvbSBcIi4vZGF0YXN0b3JlXCI7XHJcbmNvbnN0IHJlcXVlc3QgPSByZXF1aXJlKFwicmVxdWVzdFwiKTtcclxuXHJcbmNvbnN0IHtEaXNwYXRjaGVyLCBEaXNjb3JkQ29uc3RhbnRzLCBVc2VyU2V0dGluZ3NTdG9yZX0gPSBEaXNjb3JkTW9kdWxlcztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IG5ldyBjbGFzcyBMb2NhbGVNYW5hZ2VyIHtcclxuXHRnZXQgZGlzY29yZExvY2FsZSgpIHtyZXR1cm4gVXNlclNldHRpbmdzU3RvcmUubG9jYWxlLnNwbGl0KFwiLVwiKVswXTt9XHJcblx0Z2V0IGRlZmF1bHRMb2NhbGUoKSB7cmV0dXJuIFwiZW5cIjt9XHJcblxyXG5cdGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHRoaXMubG9jYWxlID0gXCJcIjtcclxuICAgICAgICB0aGlzLnN0cmluZ3MgPSB7fTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIGluaXRpYWxpemUoKSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5zZXRMb2NhbGUodGhpcy5kaXNjb3JkTG9jYWxlKTtcclxuICAgICAgICBEaXNwYXRjaGVyLnN1YnNjcmliZShEaXNjb3JkQ29uc3RhbnRzLkFjdGlvblR5cGVzLlVTRVJfU0VUVElOR1NfVVBEQVRFLCAoe3NldHRpbmdzfSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBuZXdMb2NhbGUgPSBzZXR0aW5ncy5sb2NhbGU7XHJcbiAgICAgICAgICAgIGlmIChuZXdMb2NhbGUgJiYgbmV3TG9jYWxlICE9IHRoaXMubG9jYWxlKSB0aGlzLnNldExvY2FsZShuZXdMb2NhbGUuc3BsaXQoXCItXCIpWzBdKTtcclxuICAgICAgICB9KTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIHNldExvY2FsZShuZXdMb2NhbGUpIHtcclxuICAgICAgICBsZXQgbmV3U3RyaW5ncztcclxuICAgICAgICBpZiAobmV3TG9jYWxlICE9IHRoaXMuZGVmYXVsdExvY2FsZSkge1xyXG5cdFx0XHRuZXdTdHJpbmdzID0gYXdhaXQgdGhpcy5nZXRMb2NhbGVTdHJpbmdzKG5ld0xvY2FsZSk7XHJcbiAgICAgICAgICAgIGlmICghbmV3U3RyaW5ncykgcmV0dXJuIHRoaXMuc2V0TG9jYWxlKHRoaXMuZGVmYXVsdExvY2FsZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBuZXdTdHJpbmdzID0gRGVmYXVsdFN0cmluZ3M7XHJcbiAgICAgICAgfVxyXG5cdFx0dGhpcy5sb2NhbGUgPSBuZXdMb2NhbGU7XHJcblx0XHRVdGlsaXRpZXMuZXh0ZW5kKHRoaXMuc3RyaW5ncywgbmV3U3RyaW5ncyk7XHJcblx0XHRFdmVudHMuZW1pdChcInN0cmluZ3MtdXBkYXRlZFwiKTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIGdldExvY2FsZVN0cmluZ3MobG9jYWxlKSB7XHJcblx0XHRjb25zdCBoYXNoID0gRGF0YVN0b3JlLmdldENhY2hlSGFzaChcImxvY2FsZXNcIiwgbG9jYWxlKTtcclxuXHRcdGlmICghaGFzaCkgcmV0dXJuIGF3YWl0IHRoaXMuZG93bmxvYWRMb2NhbGUobG9jYWxlKTtcclxuXHRcdGNvbnN0IGludmFsaWQgPSBhd2FpdCB0aGlzLmRvd25sb2FkTG9jYWxlKGxvY2FsZSwgaGFzaCk7XHJcblx0XHRpZiAoIWludmFsaWQpIHJldHVybiBEYXRhU3RvcmUuZ2V0TG9jYWxlKGxvY2FsZSk7XHJcblx0XHRyZXR1cm4gaW52YWxpZDtcclxuXHR9XHJcblxyXG5cdGRvd25sb2FkTG9jYWxlKGxvY2FsZSwgaGFzaCA9IFwiXCIpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcclxuXHRcdFx0Y29uc3Qgb3B0aW9ucyA9IHtcclxuXHRcdFx0XHR1cmw6IFV0aWxpdGllcy5yZXBvVXJsKGBkYXRhL2xvY2FsZXMvJHtsb2NhbGV9Lmpzb25gKSxcclxuXHRcdFx0XHR0aW1lb3V0OiAyMDAwLFxyXG5cdFx0XHRcdGpzb246IHRydWVcclxuXHRcdFx0fTtcclxuXHRcdFx0aWYgKGhhc2gpIG9wdGlvbnMuaGVhZGVycyA9IHtcIklmLU5vbmUtTWF0Y2hcIjogaGFzaH07XHJcblx0XHRcdHJlcXVlc3QuZ2V0KG9wdGlvbnMsIChlcnIsIHJlc3AsIG5ld1N0cmluZ3MpID0+IHtcclxuXHRcdFx0XHRpZiAoZXJyIHx8IHJlc3Auc3RhdHVzQ29kZSAhPT0gMjAwKSByZXR1cm4gcmVzb2x2ZShudWxsKTtcclxuXHRcdFx0XHREYXRhU3RvcmUuc2F2ZUxvY2FsZShsb2NhbGUsIG5ld1N0cmluZ3MpO1xyXG5cdFx0XHRcdERhdGFTdG9yZS5zZXRDYWNoZUhhc2goXCJsb2NhbGVzXCIsIGxvY2FsZSwgcmVzcC5oZWFkZXJzLmV0YWcpO1xyXG5cdFx0XHRcdHJlc29sdmUobmV3U3RyaW5ncyk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblx0fVxyXG59OyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/modules/localemanager.js\n"); /***/ }), diff --git a/src/builtins/emotes.js b/src/builtins/emotes.js index d4e2aee7..5cd666fa 100644 --- a/src/builtins/emotes.js +++ b/src/builtins/emotes.js @@ -1,11 +1,28 @@ import Builtin from "../structs/builtin"; -import {Config, EmoteInfo, EmoteConfig} from "data"; +import {Config, EmoteConfig} from "data"; import {Utilities, WebpackModules, DataStore, DiscordModules, Events, Settings, Strings} from "modules"; import BDEmote from "../ui/emote"; import Toasts from "../ui/toasts"; -// import EmoteMenu from "./emotemenu"; +import FormattableString from "../structs/string"; const request = require("request"); +// const fs = require("fs"); + +const EmoteURLs = { + TwitchGlobal: new FormattableString(`https://static-cdn.jtvnw.net/emoticons/v1/{{id}}/1.0`), + TwitchSubscriber: new FormattableString(`https://static-cdn.jtvnw.net/emoticons/v1/{{id}}/1.0`), + FrankerFaceZ: new FormattableString(`https://cdn.frankerfacez.com/emoticon/{{id}}/1`), + BTTV: new FormattableString(`https://cdn.betterttv.net/emote/{{id}}/1x`), + BTTV2: new FormattableString(`https://cdn.betterttv.net/emote/{{id}}/1x`) +}; + +const EmoteMetaInfo = { + TwitchGlobal: {}, + TwitchSubscriber: {}, + BTTV: {}, + FrankerFaceZ: {}, + BTTV2: {} +}; const Emotes = { TwitchGlobal: {}, @@ -32,7 +49,8 @@ export default new class EmoteModule extends Builtin { get collection() {return "settings";} get category() {return "general";} get id() {return "emotes";} - get categories() { return Object.keys(bdEmoteSettingIDs).filter(k => this.isCategoryEnabled(bdEmoteSettingIDs[k])); } + get categories() {return Object.keys(bdEmoteSettingIDs).filter(k => this.isCategoryEnabled(bdEmoteSettingIDs[k]));} + get shouldDownload() {return Settings.get("emotes", this.category, "download");} isCategoryEnabled(id) {return super.get("emotes", "categories", id);} @@ -49,9 +67,8 @@ export default new class EmoteModule extends Builtin { get blacklist() {return blacklist;} get favorites() {return this.favoriteEmotes;} - getCategory(category) { - return Emotes[category]; - } + getCategory(category) {return Emotes[category];} + getRemoteFile(category) {return new FormattableString(Utilities.repoUrl(`data/emotes/${category.toLowerCase()}.json`));} initialize() { super.initialize(); @@ -66,10 +83,10 @@ export default new class EmoteModule extends Builtin { } async enabled() { - Settings.registerCollection("emotes", "Emotes", EmoteConfig, {title: Strings.Emotes.clearEmotes, onClick: () => { this.clearEmoteData(); this.loadEmoteData(EmoteInfo); }}); + Settings.registerCollection("emotes", "Emotes", EmoteConfig, {title: Strings.Emotes.clearEmotes, onClick: () => {this.clearEmoteData(); this.loadEmoteData();}}); // Disable emote module for now because it's annoying and slow await this.getBlacklist(); - await this.loadEmoteData(EmoteInfo); + await this.loadEmoteData(); while (!this.MessageContentComponent) await new Promise(resolve => setTimeout(resolve, 100)); this.patchMessageContent(); @@ -178,103 +195,6 @@ export default new class EmoteModule extends Builtin { }); } - async loadEmoteData(emoteInfo) { - this.emotesLoaded = false; - const _fs = require("fs"); - const emoteFile = "emote_data.json"; - const file = Config.dataPath + emoteFile; - const exists = _fs.existsSync(file); - - if (exists && this.isCacheValid()) { - Toasts.show("Loading emotes from cache.", {type: "info"}); - this.log("Loading emotes from local cache."); - - const data = await new Promise(resolve => { - _fs.readFile(file, "utf8", (err, content) => { - this.log("Emotes loaded from cache."); - if (err) content = {}; - resolve(content); - }); - }); - - const parsed = Utilities.testJSON(data); - let isValid = !!parsed; - if (isValid) Object.assign(Emotes, parsed); - - for (const e in emoteInfo) { - isValid = Object.keys(Emotes[emoteInfo[e].variable]).length > 0; - } - - if (isValid) { - Toasts.show("Emotes successfully loaded.", {type: "success"}); - this.emotesLoaded = true; - Events.dispatch("emotes-loaded"); - return; - } - - this.log("Cache was corrupt, downloading..."); - _fs.unlinkSync(file); - } - - if (!Settings.get(this.category, "general", "download")) return; - Toasts.show(Strings.Emotes.downloading, {type: "info"}); - - for (const e in emoteInfo) { - await new Promise(r => setTimeout(r, 1000)); - const data = await this.downloadEmotes(emoteInfo[e]); - Emotes[emoteInfo[e].variable] = data; - } - - Toasts.show(Strings.Emotes.downloaded, {type: "success"}); - - try { _fs.writeFileSync(file, JSON.stringify(Emotes), "utf8"); } - catch (err) { this.stacktrace("Could not save emote data.", err); } - - this.emotesLoaded = true; - Events.dispatch("emotes-loaded"); - } - - downloadEmotes(emoteMeta) { - const repoFile = Utilities.repoUrl(`data/emotes/${emoteMeta.variable.toLowerCase()}.json`); - if (emoteMeta.url && !emoteMeta.backup) emoteMeta.backup = repoFile; - if (!emoteMeta.url) emoteMeta.url = repoFile; - - const options = { - url: emoteMeta.url, - timeout: emoteMeta.timeout ? emoteMeta.timeout : 5000, - json: true - }; - - this.log(`Downloading: ${emoteMeta.variable} (${emoteMeta.url})`); - - return new Promise((resolve, reject) => { - request.get(options, (error, response, parsedData) => { - if (error) { - this.stacktrace("Could not download " + emoteMeta.variable, error); - if (emoteMeta.backup || emoteMeta.url) { - emoteMeta.url = emoteMeta.backup; - emoteMeta.backup = null; - if (emoteMeta.backupParser) emoteMeta.parser = emoteMeta.backupParser; - return resolve(this.downloadEmotes(emoteMeta)); - } - return reject({}); - } - - if (typeof(emoteMeta.parser) === "function") parsedData = emoteMeta.parser(parsedData); - - for (const emote in parsedData) { - if (emote.length < 4 || blacklist.includes(emote)) { - delete parsedData[emote]; - continue; - } - parsedData[emote] = emoteMeta.getEmoteURL(parsedData[emote]); - } - resolve(parsedData); - this.log("Downloaded: " + emoteMeta.variable); - }); - }); - } - getBlacklist() { return new Promise(resolve => { request.get({url: Utilities.repoUrl(`data/emotes/blacklist.json`), json: true}, (err, resp, data) => { @@ -284,16 +204,64 @@ export default new class EmoteModule extends Builtin { }); } - isCacheValid() { - const cacheLength = DataStore.getBDData("emoteCacheDays") || DataStore.setBDData("emoteCacheDays", 7) || 7; - const cacheDate = new Date(DataStore.getBDData("emoteCacheDate") || null); - const currentDate = new Date(); - const daysBetween = Math.round(Math.abs((currentDate.getTime() - cacheDate.getTime()) / (24 * 60 * 60 * 1000))); - if (daysBetween > cacheLength) { - DataStore.setBDData("emoteCacheDate", currentDate.toJSON()); - return false; + isCacheValid(category) { + return new Promise(resolve => { + const etag = DataStore.getCacheHash("emotes", category); + if (!etag) return resolve(false); + request.head({url: this.getRemoteFile(category), headers: {"If-None-Match": etag}}, (err, resp) => { + resolve(resp.statusCode == 304); + }); + }); + } + + async loadEmoteData() { + this.emotesLoaded = false; + + for (const category in Emotes) { + const exists = DataStore.emotesExist(category); + const valid = await this.isCacheValid(category); + const useCache = (valid) || (!valid && exists && !this.shouldDownload); + let data = null; + if (useCache) { + this.log(`Loading ${category} emotes from local cache.`); + const cachedData = DataStore.getEmoteData(category); + const hasData = Object.keys(data).length > 0; + if (hasData) data = cachedData; + } + if (!data) data = await this.downloadEmotes(category); + Object.assign(Emotes[category], data); } - return true; + + // Toasts.show(Strings.Emotes.downloading, {type: "info"}); + // Toasts.show(Strings.Emotes.downloaded, {type: "success"}); + + this.emotesLoaded = true; + Events.dispatch("emotes-loaded"); + } + + downloadEmotes(category) { + const url = this.getRemoteFile(category); + this.log(`Downloading ${category} from ${url}`); + const options = {url: url, timeout: 5000, json: true}; + return new Promise(resolve => { + request.get(options, (error, response, parsedData) => { + if (error || response.statusCode != 200) { + this.stacktrace(`Could not download ${category} emotes.`, error); + return resolve({}); + } + + for (const emote in parsedData) { + if (emote.length < 4 || blacklist.includes(emote) || !parsedData[emote]) { + delete parsedData[emote]; + continue; + } + parsedData[emote] = EmoteURLs[category].format({id: parsedData[emote]}); + } + DataStore.saveEmoteData(category, parsedData); + resolve(parsedData); + this.log(`Downloaded ${category}`); + }); + }); } clearEmoteData() { @@ -305,4 +273,24 @@ export default new class EmoteModule extends Builtin { DataStore.setBDData("emoteCacheDate", (new Date()).toJSON()); for (const category in Emotes) Object.assign(Emotes, {[category]: {}}); } -}; \ No newline at end of file +}; + + +// (async () => { +// const emoteData = await new Promise(resolve => { +// const req = require("request"); +// req.get({url: "https://twitchemotes.com/api_cache/v3/global.json", json: true}, (err, resp, parsedData) => { +// for (const emote in parsedData) { +// if (emote.length < 4 || window.bemotes.includes(emote)) { +// delete parsedData[emote]; +// continue; +// } +// parsedData[emote] = parsedData[emote].id; +// } +// resolve(parsedData); +// }); +// }); +// const fs = require("fs"); +// fs.writeFileSync("Z:\\Programming\\BetterDiscordStuff\\BetterDiscordApp\\data\\emotes\\global.json", JSON.stringify(emoteData)); +// return emoteData; +// })(); \ No newline at end of file diff --git a/src/data/data.js b/src/data/data.js index e1c52774..1a9a9a7c 100644 --- a/src/data/data.js +++ b/src/data/data.js @@ -1,6 +1,4 @@ -import Config from "./config"; -import EmoteInfo from "./emotes/info"; -import EmoteConfig from "./emotes/config"; -import SettingsConfig from "./settings/config"; - -export {Config, EmoteInfo, EmoteConfig, SettingsConfig}; \ No newline at end of file +export {default as Config} from "./config"; +export {default as EmoteConfig} from "./settings/emoteconfig"; +export {default as SettingsConfig} from "./settings/config"; +export {default as Strings} from "./strings"; \ No newline at end of file diff --git a/src/data/emotes/info.js b/src/data/emotes/info.js deleted file mode 100644 index 240adf23..00000000 --- a/src/data/emotes/info.js +++ /dev/null @@ -1,38 +0,0 @@ -export default { - TwitchGlobal: { - url: "https://twitchemotes.com/api_cache/v3/global.json", - variable: "TwitchGlobal", - getEmoteURL: (e) => `https://static-cdn.jtvnw.net/emoticons/v1/${e.id}/1.0`, - getOldData: (url, name) => {return {id: url.match(/\/([0-9]+)\//)[1], code: name, emoticon_set: 0, description: null};} - }, - TwitchSubscriber: { - variable: "TwitchSubscriber", - getEmoteURL: (e) => `https://static-cdn.jtvnw.net/emoticons/v1/${e}/1.0`, - getOldData: (url) => url.match(/\/([0-9]+)\//)[1] - }, - FrankerFaceZ: { - variable: "FrankerFaceZ", - getEmoteURL: (e) => `https://cdn.frankerfacez.com/emoticon/${e}/1`, - getOldData: (url) => url.match(/\/([0-9]+)\//)[1] - }, - BTTV: { - url: "https://api.betterttv.net/emotes", - variable: "BTTV", - parser: (data) => { - const emotes = {}; - for (let e = 0, len = data.emotes.length; e < len; e++) { - const emote = data.emotes[e]; - emotes[emote.regex] = emote.url; - } - return emotes; - }, - getEmoteURL: (e) => `${e}`, - getOldData: (url) => url - }, - BTTV2: { - variable: "BTTV2", - oldVariable: "emotesBTTV2", - getEmoteURL: (e) => `https://cdn.betterttv.net/emote/${e}/1x`, - getOldData: (url) => url.match(/emote\/(.+)\//)[1] - } -}; \ No newline at end of file diff --git a/src/data/emotes/config.js b/src/data/settings/emoteconfig.js similarity index 100% rename from src/data/emotes/config.js rename to src/data/settings/emoteconfig.js diff --git a/src/modules/datastore.js b/src/modules/datastore.js index 6ad5d558..238dd1e3 100644 --- a/src/modules/datastore.js +++ b/src/modules/datastore.js @@ -17,28 +17,30 @@ export default new class DataStore { constructor() { this.data = {misc: {}}; this.pluginData = {}; - this.localeHashes = {}; + this.cacheData = {}; } initialize() { if (!fs.existsSync(this.baseFolder)) fs.mkdirSync(this.baseFolder); if (!fs.existsSync(this.dataFolder)) fs.mkdirSync(this.dataFolder); if (!fs.existsSync(this.localeFolder)) fs.mkdirSync(this.localeFolder); - if (!fs.existsSync(this.localeCache)) fs.writeFileSync(this.localeCache, JSON.stringify({})); + if (!fs.existsSync(this.emoteFolder)) fs.mkdirSync(this.emoteFolder); + if (!fs.existsSync(this.cacheFile)) fs.writeFileSync(this.cacheFile, JSON.stringify({})); if (!fs.existsSync(this.BDFile)) fs.writeFileSync(this.BDFile, JSON.stringify(this.data.misc, null, 4)); if (!fs.existsSync(this.customCSS)) fs.writeFileSync(this.customCSS, ""); const dataFiles = fs.readdirSync(this.dataFolder).filter(f => !fs.statSync(path.resolve(this.dataFolder, f)).isDirectory() && f.endsWith(".json")); for (const file of dataFiles) { this.data[file.split(".")[0]] = __non_webpack_require__(path.resolve(this.dataFolder, file)); } - this.localeHashes = JSON.parse(fs.readFileSync(this.localeCache).toString()); + this.cacheData = Utilities.testJSON(fs.readFileSync(this.cacheFile).toString()) || {}; } get customCSS() {return this._customCSS || (this._customCSS = path.resolve(this.dataFolder, "custom.css"));} get baseFolder() {return this._baseFolder || (this._baseFolder = path.resolve(Config.dataPath, "data"));} get dataFolder() {return this._dataFolder || (this._dataFolder = path.resolve(this.baseFolder, `${releaseChannel}`));} get localeFolder() {return this._localeFolder || (this._localeFolder = path.resolve(this.baseFolder, `locales`));} - get localeCache() {return this._localeCache || (this._localeCache = path.resolve(this.localeFolder, `.cache`));} + get emoteFolder() {return this._emoteFolder || (this._emoteFolder = path.resolve(this.baseFolder, `emotes`));} + get cacheFile() {return this._cacheFile || (this._cacheFile = path.resolve(this.baseFolder, `.cache`));} get BDFile() {return this._BDFile || (this._BDFile = path.resolve(Config.dataPath, "data", `${releaseChannel}.json`));} getPluginFile(pluginName) {return path.resolve(Config.dataPath, "plugins", pluginName + ".config.json");} @@ -67,13 +69,30 @@ export default new class DataStore { fs.writeFileSync(path.resolve(this.localeFolder, `${locale}.json`), JSON.stringify(strings, null, 4)); } - getLocaleHash(locale) { - return this.localeHashes[locale] || ""; + getCacheHash(category, key) { + if (!this.cacheData[category]) return ""; + if (!fs.existsSync(path.resolve(this.baseFolder, category, `${key}.json`))) return ""; + return this.cacheData[category][key] || ""; } - saveLocaleHash(locale, hash) { - this.localeHashes[locale] = hash; - fs.writeFileSync(this.localeCache, JSON.stringify(this.localeHashes, null, 4)); + setCacheHash(category, key, hash) { + if (!this.cacheData[category]) this.cacheData[category] = {}; + this.cacheData[category][key] = hash; + fs.writeFileSync(this.cacheFile, JSON.stringify(this.cacheData, null, 4)); + } + + emotesExist(category) { + return fs.existsSync(path.resolve(this.emoteFolder, `${category}.json`)); + } + + getEmoteData(category) { + const file = path.resolve(this.emoteFolder, `${category}.json`); + if (!fs.existsSync(file)) return null; + return Utilities.testJSON(fs.readFileSync(file).toString()); + } + + saveEmoteData(category, data) { + fs.writeFileSync(path.resolve(this.emoteFolder, `${category}.json`), JSON.stringify(data)); } getData(key) { diff --git a/src/modules/localemanager.js b/src/modules/localemanager.js index 03cd863a..83d66179 100644 --- a/src/modules/localemanager.js +++ b/src/modules/localemanager.js @@ -39,7 +39,7 @@ export default new class LocaleManager { } async getLocaleStrings(locale) { - const hash = DataStore.getLocaleHash(locale); + const hash = DataStore.getCacheHash("locales", locale); if (!hash) return await this.downloadLocale(locale); const invalid = await this.downloadLocale(locale, hash); if (!invalid) return DataStore.getLocale(locale); @@ -54,12 +54,10 @@ export default new class LocaleManager { json: true }; if (hash) options.headers = {"If-None-Match": hash}; - console.log(options.headers); request.get(options, (err, resp, newStrings) => { if (err || resp.statusCode !== 200) return resolve(null); - console.log(resp); DataStore.saveLocale(locale, newStrings); - DataStore.saveLocaleHash(locale, resp.headers.etag); + DataStore.setCacheHash("locales", locale, resp.headers.etag); resolve(newStrings); }); });