diff --git a/js/main.js b/js/main.js index 39db626..bc53a43 100644 --- a/js/main.js +++ b/js/main.js @@ -304,18 +304,22 @@ Core.prototype.init = async function() { this.injectExternals(); + settingsPanel = new V2_SettingsPanel(); + pluginModule = new PluginModule(); + themeModule = new ThemeModule(); + + this.setupAPI(); + await this.checkForGuilds(); BDV2.initialize(); + Utils.log("Startup", "Updating Settings"); - settingsPanel = new V2_SettingsPanel(); settingsPanel.initializeSettings(); Utils.log("Startup", "Loading Plugins"); - pluginModule = new PluginModule(); pluginModule.loadPlugins(); Utils.log("Startup", "Loading Themes"); - themeModule = new ThemeModule(); themeModule.loadThemes(); $("#customcss").detach().appendTo(document.head); @@ -393,6 +397,48 @@ Core.prototype.loadSettings = function () { settingsCookie = DataStore.getSettingGroup("settings"); }; +Core.prototype.setupAPI = function() { + const createAddonAPI = function(cookie, list, manager) { + return new class AddonAPI { + + isEnabled(name) { + return !!cookie[name]; + } + + enable(name) { + return manager.enable(name); + } + + disable(name) { + return manager.disable(name); + } + + toggle(name) { + if (cookie[name]) this.disable(name); + else this.enable(name); + } + + reload(name) { + return manager.reload(name); + } + + get(name) { + if (list.hasOwnProperty(name)) { + if (list[name].plugin) return list[name].plugin; + return list[name]; + } + return null; + } + + getAll() { + return Object.keys(list).map(k => this.get(k)).filter(a => a); + } + }; + }; + BdApi.Themes = createAddonAPI(themeCookie, bdthemes, themeModule); + BdApi.Plugins = createAddonAPI(pluginCookie, bdplugins, pluginModule); +}; + Core.prototype.initObserver = function () { const mainObserver = new MutationObserver((mutations) => { @@ -1821,7 +1867,7 @@ PluginModule.prototype.updatePluginList = function() { PluginModule.prototype.loadPluginData = function () { let saved = DataStore.getSettingGroup("plugins"); if (saved) { - pluginCookie = saved; + Object.assign(pluginCookie, saved); } }; @@ -1984,7 +2030,7 @@ ThemeModule.prototype.updateThemeList = function() { ThemeModule.prototype.loadThemeData = function() { let saved = DataStore.getSettingGroup("themes"); if (saved) { - themeCookie = saved; + Object.assign(themeCookie, saved); } }; @@ -2255,50 +2301,6 @@ BdApi.setBDData = function(key, data) { return DataStore.setBDData(key, data); }; -((API) => { - const createAddonAPI = function(cookie, list, manager) { - return new class AddonAPI { - - isEnabled(name) { - return !!cookie[name]; - } - - enable(name) { - return manager.enable(name); - } - - disable(name) { - return manager.disable(name); - } - - toggle(name) { - if (cookie[name]) this.disable(name); - else this.enable(name); - } - - reload(name) { - return manager.reload(name); - } - - get(name) { - if (list.hasOwnProperty(name)) { - if (list[name].plugin) return list[name].plugin; - return list[name]; - } - return null; - } - - getAll() { - return Object.keys(list).map(k => this.get(k)).filter(a => a); - } - }; - }; - API.Themes = createAddonAPI(themeCookie, bdthemes, themeModule); - API.Plugins = createAddonAPI(pluginCookie, bdplugins, pluginModule); -})(BdApi); - -Object.freeze(BdApi); - diff --git a/js/main.min.js b/js/main.min.js index f881b47..5622c9a 100644 --- a/js/main.min.js +++ b/js/main.min.js @@ -1,7 +1,7 @@ (function(){const e=Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype,"contentWindow").get;Object.defineProperty(HTMLIFrameElement.prototype,"contentWindow",{get:function(){const t=Reflect.apply(e,this,arguments);return new Proxy(t,{get:function(e,t){if("localStorage"===t)return null;const a=e[t];return"function"==typeof a?a.bind(e):a}})}}),Object.defineProperty(Reflect,"apply",{value:Reflect.apply,writable:!1,configurable:!1}),Object.defineProperty(Function.prototype,"bind",{value:Function.prototype.bind,writable:!1,configurable:!1});const t=XMLHttpRequest.prototype.open;XMLHttpRequest.prototype.open=function(){const e=arguments[1];return e.toLowerCase().includes("api/webhooks")?null:Reflect.apply(t,this,arguments)}})(),(()=>{const e=document.createElement("div");e.className="bd-loaderv2",e.title="BandagedBD is loading...",document.body.appendChild(e)})();var DataStore=(()=>{const e=require("fs"),t=require("path"),a=DiscordNative.globals.releaseChannel;return new class{constructor(){this.data={settings:{stable:{},canary:{},ptb:{}}},this.pluginData={}}initialize(){try{e.existsSync(this.BDFile)||e.writeFileSync(this.BDFile,JSON.stringify(this.data,null,4));const t=require(this.BDFile);if(t.hasOwnProperty("settings")&&(this.data=t),!e.existsSync(this.settingsFile))return;let n=require(this.settingsFile);e.unlinkSync(this.settingsFile),n=n.hasOwnProperty("settings")?Object.assign({stable:{},canary:{},ptb:{}},{[a]:n}):Object.assign({stable:{},canary:{},ptb:{}},n),this.setBDData("settings",n)}catch(e){BdApi.alert("Corrupt Storage","The bd storage has somehow become corrupt. You may either try to salvage the file or delete it then reload.")}}get BDFile(){return this._BDFile||(this._BDFile=t.resolve(bdConfig.dataPath,"bdstorage.json"))}get settingsFile(){return this._settingsFile||(this._settingsFile=t.resolve(bdConfig.dataPath,"bdsettings.json"))}getPluginFile(e){return t.resolve(ContentManager.pluginsFolder,e+".config.json")}getSettingGroup(e){return this.data.settings[a][e]||null}setSettingGroup(t,n){this.data.settings[a][t]=n,e.writeFileSync(this.BDFile,JSON.stringify(this.data,null,4))}getBDData(e){return this.data[e]||""}setBDData(t,a){this.data[t]=a,e.writeFileSync(this.BDFile,JSON.stringify(this.data,null,4))}getPluginData(t,a){return void 0===this.pluginData[t]?e.existsSync(this.getPluginFile(t))?(this.pluginData[t]=JSON.parse(e.readFileSync(this.getPluginFile(t))),this.pluginData[t][a]||void 0):void 0:this.pluginData[t][a]||void 0}setPluginData(t,a,n){void 0===n||(this.pluginData[t]===void 0&&(this.pluginData[t]={}),this.pluginData[t][a]=n,e.writeFileSync(this.getPluginFile(t),JSON.stringify(this.pluginData[t],null,4)))}deletePluginData(t,a){this.pluginData[t]===void 0&&(this.pluginData[t]={}),delete this.pluginData[t][a],e.writeFileSync(this.getPluginFile(t),JSON.stringify(this.pluginData[t],null,4))}}})(),BDEvents=(()=>{const e=require("events");return new class extends e{dispatch(e,...t){this.emit(e,...t)}off(e,t){this.removeListener(e,t)}}})();window.bdStorage=class{static get(e){return Utils.warn("Deprecation Notice","Please use BdApi.getBDData(). bdStorage may be removed in future versions."),DataStore.getBDData(e)}static set(e,t){Utils.warn("Deprecation Notice","Please use BdApi.setBDData(). bdStorage may be removed in future versions."),DataStore.setBDData(e,t)}},window.bdPluginStorage=class{static get(e,t){return Utils.warn("Deprecation Notice",`${e}, please use BdApi.loadData() or BdApi.getData(). bdPluginStorage may be removed in future versions.`),DataStore.getPluginData(e,t)||null}static set(e,t,a){return Utils.warn("Deprecation Notice",`${e}, please use BdApi.saveData() or BdApi.setData(). bdPluginStorage may be removed in future versions.`),"undefined"==typeof a?Utils.warn("Deprecation Notice","Trying to set undefined value in plugin "+e):void DataStore.setPluginData(e,t,a)}static delete(e,t){Utils.warn("Deprecation Notice",`${e}, please use BdApi.deleteData(). bdPluginStorage may be removed in future versions.`),DataStore.deletePluginData(e,t)}};var settingsPanel,emoteModule,quickEmoteMenu,voiceMode,pluginModule,themeModule,dMode,publicServersModule,mainCore,minSupportedVersion="0.3.0",bbdVersion="0.2.25",bbdChangelog={description:"Mostly behind the scenes changes again.",changes:[{title:"What's New?",items:["**Changes for plugin developers!** There are some new items in the `BdApi` that you may want to check out."]},{title:"Fixes",type:"fixed",items:["**Modal Footers** are no longer blank hopefully!"]},{title:"Minor Stuff",type:"improved",items:["**Injector Version** is now included in the version list to try and quell the confusion."]}]},settings={"Custom css live update":{id:"bda-css-0",info:"",implemented:!0,hidden:!0,cat:"core"},"Custom css auto udpate":{id:"bda-css-1",info:"",implemented:!0,hidden:!0,cat:"core"},"BetterDiscord Blue":{id:"bda-gs-b",info:"Replace Discord blue with BD Blue",implemented:!1,hidden:!1,cat:"core"},"Public Servers":{id:"bda-gs-1",info:"Display public servers button",implemented:!0,hidden:!1,cat:"core",category:"modules"},"Minimal Mode":{id:"bda-gs-2",info:"Hide elements and reduce the size of elements.",implemented:!0,hidden:!1,cat:"core",category:"modules"},"Voice Mode":{id:"bda-gs-4",info:"Only show voice chat",implemented:!0,hidden:!1,cat:"core",category:"modules"},"Hide Channels":{id:"bda-gs-3",info:"Hide channels in minimal mode",implemented:!0,hidden:!1,cat:"core",category:"modules"},"Dark Mode":{id:"bda-gs-5",info:"Make certain elements dark by default(wip)",implemented:!0,hidden:!1,cat:"core",category:"modules"},"Voice Disconnect":{id:"bda-dc-0",info:"Disconnect from voice server when closing Discord",implemented:!0,hidden:!1,cat:"core",category:"modules"},"24 Hour Timestamps":{id:"bda-gs-6",info:"Replace 12hr timestamps with proper ones",implemented:!0,hidden:!1,cat:"core",category:"modules"},"Colored Text":{id:"bda-gs-7",info:"Make text color the same as role color",implemented:!0,hidden:!1,cat:"core",category:"modules"},"Normalize Classes":{id:"fork-ps-4",info:"Adds stable classes to elements to help themes. (e.g. adds .da-channels to .channels-Ie2l6A)",implemented:!0,hidden:!1,cat:"core",category:"modules"},"Content Error Modal":{id:"fork-ps-1",info:"Shows a modal with plugin/theme errors",implemented:!0,hidden:!1,cat:"core",category:"content manager"},"Show Toasts":{id:"fork-ps-2",info:"Shows a small notification for important information",implemented:!0,hidden:!1,cat:"core",category:"content manager"},"Scroll To Settings":{id:"fork-ps-3",info:"Auto-scrolls to a plugin's settings when the button is clicked (only if out of view)",implemented:!0,hidden:!1,cat:"core",category:"content manager"},"Automatic Loading":{id:"fork-ps-5",info:"Automatically loads, reloads, and unloads plugins and themes",implemented:!0,hidden:!1,cat:"core",category:"content manager"},"Developer Mode":{id:"bda-gs-8",info:"Developer Mode",implemented:!0,hidden:!1,cat:"core",category:"developer settings"},"Copy Selector":{id:"fork-dm-1",info:"Adds a \"Copy Selector\" option to context menus when developer mode is active",implemented:!0,hidden:!1,cat:"core",category:"developer settings"},"Enable Transparency":{id:"fork-wp-1",info:"Enables the main window to be see-through (requires restart)",implemented:!0,hidden:!1,cat:"core",category:"window preferences"},"Window Frame":{id:"fork-wp-2",info:"Adds the native os window frame to the main window",implemented:!1,hidden:!0,cat:"core",category:"window preferences"},"Download Emotes":{id:"fork-es-3",info:"Download emotes when the cache is expired",implemented:!0,hidden:!1,cat:"emote"},"Twitch Emotes":{id:"bda-es-7",info:"Show Twitch emotes",implemented:!0,hidden:!1,cat:"emote"},"FrankerFaceZ Emotes":{id:"bda-es-1",info:"Show FrankerFaceZ Emotes",implemented:!0,hidden:!1,cat:"emote"},"BetterTTV Emotes":{id:"bda-es-2",info:"Show BetterTTV Emotes",implemented:!0,hidden:!1,cat:"emote"},"Emote Menu":{id:"bda-es-0",info:"Show Twitch/Favourite emotes in emote menu",implemented:!0,hidden:!1,cat:"emote"},"Emoji Menu":{id:"bda-es-9",info:"Show Discord emoji menu",implemented:!0,hidden:!1,cat:"emote"},"Emote Auto Capitalization":{id:"bda-es-4",info:"Autocapitalize emote commands",implemented:!0,hidden:!1,cat:"emote"},"Show Names":{id:"bda-es-6",info:"Show emote names on hover",implemented:!0,hidden:!1,cat:"emote"},"Show emote modifiers":{id:"bda-es-8",info:"Enable emote mods (flip, spin, pulse, spin2, spin3, 1spin, 2spin, 3spin, tr, bl, br, shake, shake2, shake3, flap)",implemented:!0,hidden:!1,cat:"emote"},"Animate On Hover":{id:"fork-es-2",info:"Only animate the emote modifiers on hover",implemented:!0,hidden:!1,cat:"emote"}},defaultCookie={"bda-gs-1":!0,"bda-gs-2":!1,"bda-gs-3":!1,"bda-gs-4":!1,"bda-gs-5":!0,"bda-gs-6":!1,"bda-gs-7":!1,"bda-gs-8":!1,"bda-es-0":!0,"bda-es-1":!0,"bda-es-2":!0,"bda-es-4":!1,"bda-es-6":!0,"bda-es-7":!0,"bda-gs-b":!1,"bda-es-8":!0,"bda-dc-0":!1,"bda-css-0":!1,"bda-css-1":!1,"bda-es-9":!0,"fork-dm-1":!1,"fork-ps-1":!0,"fork-ps-2":!0,"fork-ps-3":!0,"fork-ps-4":!0,"fork-ps-5":!0,"fork-es-2":!1,"fork-es-3":!0,"fork-wp-1":!1,"fork-wp-2":!1,"fork-beta":!1},settingsCookie={},bdpluginErrors=[],bdthemeErrors=[],bdConfig=null;function Core(e){window.bdConfig=e}Core.prototype.init=async function(){if(bdConfig.version
Please download the latest version from GitHub");if(window.ED)return void this.alert("Not Supported","BandagedBD does not work with EnhancedDiscord. Please uninstall one of them.");if(window.WebSocket&&window.WebSocket.name&&window.WebSocket.name.includes("Patched"))return void this.alert("Not Supported","BandagedBD does not work with Powercord. Please uninstall one of them.");const e=bdConfig.updater?bdConfig.updater.LatestVersion:bdConfig.latestVersion;e>bdConfig.version&&this.alert("Update Available",` An update for BandagedBD is available (${e})! Please Reinstall!

Download Installer - `),Utils.log("Startup","Initializing Settings"),this.initSettings(),emoteModule=new EmoteModule,quickEmoteMenu=new QuickEmoteMenu,Utils.log("Startup","Initializing EmoteModule"),window.emotePromise=emoteModule.init().then(()=>{emoteModule.initialized=!0,Utils.log("Startup","Initializing QuickEmoteMenu"),quickEmoteMenu.init()}),publicServersModule=new V2_PublicServers,voiceMode=new VoiceMode,dMode=new devMode,this.injectExternals(),await this.checkForGuilds(),BDV2.initialize(),Utils.log("Startup","Updating Settings"),settingsPanel=new V2_SettingsPanel,settingsPanel.initializeSettings(),Utils.log("Startup","Loading Plugins"),pluginModule=new PluginModule,pluginModule.loadPlugins(),Utils.log("Startup","Loading Themes"),themeModule=new ThemeModule,themeModule.loadThemes(),$("#customcss").detach().appendTo(document.head),window.addEventListener("beforeunload",function(){settingsCookie["bda-dc-0"]&&document.querySelector(".btn.btn-disconnect").click()}),emoteModule.autoCapitalize(),Utils.log("Startup","Removing Loading Icon"),document.getElementsByClassName("bd-loaderv2")[0].remove(),Utils.log("Startup","Initializing Main Observer"),this.initObserver(),settingsCookie["fork-ps-1"]&&(Utils.log("Startup","Collecting Startup Errors"),this.showContentErrors({plugins:bdpluginErrors,themes:bdthemeErrors}));const t=DataStore.getBDData("version");bbdVersion>t&&(bbdChangelog&&this.showChangelogModal(bbdChangelog),DataStore.setBDData("version",bbdVersion))},Core.prototype.checkForGuilds=function(){let e=0;return new Promise(t=>{const a=function(){const n=BDV2.guildClasses.wrapper.split(" ")[0];0").text(atob(DataStore.getBDData("bdcustomcss"))).appendTo(document.head),defaultCookie)null==settingsCookie[e]&&(settingsCookie[e]=defaultCookie[e],this.saveSettings())},Core.prototype.saveSettings=function(){DataStore.setSettingGroup("settings",settingsCookie)},Core.prototype.loadSettings=function(){settingsCookie=DataStore.getSettingGroup("settings")},Core.prototype.initObserver=function(){const e=new MutationObserver(e=>{for(let t,a=0,n=e.length;a{if(settingsCookie["bda-gs-6"]){const a=t.returnValue.match(e);return a&&4===a.length?"AM"===a[3]?t.returnValue=t.returnValue.replace(a[0],`${"12"===a[1]?"00":a[1].padStart(2,"0")}:${a[2]}`):t.returnValue=t.returnValue.replace(a[0],`${"12"===a[1]?"12":parseInt(a[1])+12}:${a[2]}`):void 0}},a=Utils.monkeyPatch(BDV2.TimeFormatter,"calendarFormat",{after:t}),n=Utils.monkeyPatch(BDV2.TimeFormatter,"dateFormat",{after:t});this.cancel24Hour=()=>{a(),n()}},Core.prototype.injectColoredText=function(){this.cancelColoredText||!BDV2.MessageComponent||(this.cancelColoredText=Utils.monkeyPatch(BDV2.MessageComponent,"default",{before:e=>{const t=e.methodArguments[0];if(!t||!t.childrenMessageContent)return;const a=t.childrenMessageContent;if(!a.type||!a.type.type||"MessageContent"!=a.type.type.displayName)return;const n=a.type.type;n.__originalMethod||(a.type.type=function(e){const t=n(e),a=settingsCookie["bda-gs-7"]?e.message.colorString||"":"";return t.props.style={color:a},t},a.type.type.__originalMethod=n,Object.assign(a.type.type,n))}}))},Core.prototype.removeColoredText=function(){document.querySelectorAll(".markup-2BOw-j").forEach(e=>{e.style.setProperty("color","")})},Core.prototype.alert=function(e,t){let a=$(`
+ `),Utils.log("Startup","Initializing Settings"),this.initSettings(),emoteModule=new EmoteModule,quickEmoteMenu=new QuickEmoteMenu,Utils.log("Startup","Initializing EmoteModule"),window.emotePromise=emoteModule.init().then(()=>{emoteModule.initialized=!0,Utils.log("Startup","Initializing QuickEmoteMenu"),quickEmoteMenu.init()}),publicServersModule=new V2_PublicServers,voiceMode=new VoiceMode,dMode=new devMode,this.injectExternals(),settingsPanel=new V2_SettingsPanel,pluginModule=new PluginModule,themeModule=new ThemeModule,this.setupAPI(),await this.checkForGuilds(),BDV2.initialize(),Utils.log("Startup","Updating Settings"),settingsPanel.initializeSettings(),Utils.log("Startup","Loading Plugins"),pluginModule.loadPlugins(),Utils.log("Startup","Loading Themes"),themeModule.loadThemes(),$("#customcss").detach().appendTo(document.head),window.addEventListener("beforeunload",function(){settingsCookie["bda-dc-0"]&&document.querySelector(".btn.btn-disconnect").click()}),emoteModule.autoCapitalize(),Utils.log("Startup","Removing Loading Icon"),document.getElementsByClassName("bd-loaderv2")[0].remove(),Utils.log("Startup","Initializing Main Observer"),this.initObserver(),settingsCookie["fork-ps-1"]&&(Utils.log("Startup","Collecting Startup Errors"),this.showContentErrors({plugins:bdpluginErrors,themes:bdthemeErrors}));const t=DataStore.getBDData("version");bbdVersion>t&&(bbdChangelog&&this.showChangelogModal(bbdChangelog),DataStore.setBDData("version",bbdVersion))},Core.prototype.checkForGuilds=function(){let e=0;return new Promise(t=>{const a=function(){const n=BDV2.guildClasses.wrapper.split(" ")[0];0").text(atob(DataStore.getBDData("bdcustomcss"))).appendTo(document.head),defaultCookie)null==settingsCookie[e]&&(settingsCookie[e]=defaultCookie[e],this.saveSettings())},Core.prototype.saveSettings=function(){DataStore.setSettingGroup("settings",settingsCookie)},Core.prototype.loadSettings=function(){settingsCookie=DataStore.getSettingGroup("settings")},Core.prototype.setupAPI=function(){const e=function(e,t,a){return new class{isEnabled(t){return!!e[t]}enable(e){return a.enable(e)}disable(e){return a.disable(e)}toggle(t){e[t]?this.disable(t):this.enable(t)}reload(e){return a.reload(e)}get(e){return t.hasOwnProperty(e)?t[e].plugin?t[e].plugin:t[e]:null}getAll(){return Object.keys(t).map(e=>this.get(e)).filter(e=>e)}}};BdApi.Themes=e(themeCookie,bdthemes,themeModule),BdApi.Plugins=e(pluginCookie,bdplugins,pluginModule)},Core.prototype.initObserver=function(){const e=new MutationObserver(e=>{for(let t,a=0,n=e.length;a{if(settingsCookie["bda-gs-6"]){const a=t.returnValue.match(e);return a&&4===a.length?"AM"===a[3]?t.returnValue=t.returnValue.replace(a[0],`${"12"===a[1]?"00":a[1].padStart(2,"0")}:${a[2]}`):t.returnValue=t.returnValue.replace(a[0],`${"12"===a[1]?"12":parseInt(a[1])+12}:${a[2]}`):void 0}},a=Utils.monkeyPatch(BDV2.TimeFormatter,"calendarFormat",{after:t}),n=Utils.monkeyPatch(BDV2.TimeFormatter,"dateFormat",{after:t});this.cancel24Hour=()=>{a(),n()}},Core.prototype.injectColoredText=function(){this.cancelColoredText||!BDV2.MessageComponent||(this.cancelColoredText=Utils.monkeyPatch(BDV2.MessageComponent,"default",{before:e=>{const t=e.methodArguments[0];if(!t||!t.childrenMessageContent)return;const a=t.childrenMessageContent;if(!a.type||!a.type.type||"MessageContent"!=a.type.type.displayName)return;const n=a.type.type;n.__originalMethod||(a.type.type=function(e){const t=n(e),a=settingsCookie["bda-gs-7"]?e.message.colorString||"":"";return t.props.style={color:a},t},a.type.type.__originalMethod=n,Object.assign(a.type.type,n))}}))},Core.prototype.removeColoredText=function(){document.querySelectorAll(".markup-2BOw-j").forEach(e=>{e.style.setProperty("color","")})},Core.prototype.alert=function(e,t){let a=$(`
-
`),o=[a(e),a(t)];n.find(".tab-bar-item").on("click",t=>{t.preventDefault(),n.find(".tab-bar-item").removeClass("selected"),$(t.target).addClass("selected"),n.find(".scroller").empty().append(o[$(t.target).index()])}),n.find(".footer button").on("click",()=>{n.addClass("closing"),setTimeout(()=>{n.remove()},300)}),n.find(".bd-backdrop").on("click",()=>{n.addClass("closing"),setTimeout(()=>{n.remove()},300)}),n.appendTo("#app-mount"),e.length?n.find(".tab-bar-item")[0].click():n.find(".tab-bar-item")[1].click()},Core.prototype.showToast=function(e,t={}){if(!bdConfig.deferLoaded)return;if(!document.querySelector(".bd-toasts")){let e=document.createElement("div");e.classList.add("bd-toasts");let t=document.querySelector(".chat-3bRxxu form, #friends, .noChannel-Z1DQK7, .activityFeed-28jde9");e.style.setProperty("left",t?t.getBoundingClientRect().left+"px":"0px"),e.style.setProperty("width",t?t.offsetWidth+"px":"100%"),e.style.setProperty("bottom",(document.querySelector(".chat-3bRxxu form")?document.querySelector(".chat-3bRxxu form").offsetHeight:80)+"px"),document.querySelector(".app, .app-2rEoOp").appendChild(e)}const{type:a="",icon:n=!0,timeout:o=3e3}=t;let s=document.createElement("div");s.classList.add("bd-toast"),a&&s.classList.add("toast-"+a),a&&n&&s.classList.add("icon"),s.innerText=e,document.querySelector(".bd-toasts").appendChild(s),setTimeout(()=>{s.classList.add("closing"),setTimeout(()=>{s.remove(),document.querySelectorAll(".bd-toasts .bd-toast").length||document.querySelector(".bd-toasts").remove()},300)},o)},Core.prototype.showChangelogModal=function(e={}){const t=BdApi.findModuleByProps("push","update","pop","popWithKey"),a=BdApi.findModuleByProps("fixed","improved"),n=BdApi.findModuleByProps("Sizes","Weights"),o=BdApi.findModuleByProps("Child"),s=BdApi.findModuleByProps("Tags","default"),r=BdApi.findModule(e=>e.defaultProps&&!1==e.defaultProps.selectable),l=BdApi.findModuleByProps("defaultRules","parse");if(!r||!t||!a||!n||!o||!s||!l)return;const{image:c="https://repository-images.githubusercontent.com/105473537/957b5480-7c26-11e9-8401-50fa820cbae5",description:p="",changes:m=[],title:u="BandagedBD",subtitle:h=`v${bbdVersion}`,footer:d}=e,g=BdApi.React.createElement,i=[g("img",{src:c})];p&&i.push(g("p",null,l.parse(p)));for(let t=0;tg("li",null,l.parse(e))));i.push(s)}const f=function(){return g(o.Child,{grow:1,shrink:1},g(s.default,{tag:s.Tags.H4},u),g(n,{size:n.Sizes.SMALL,color:n.Colors.PRIMARY,className:a.date},h))},b=()=>{const e=BdApi.findModule(e=>"Anchor"==e.displayName),a=BdApi.findModuleByProps("anchorUnderlineOnHover")||{anchor:"anchor-3Z-8Bb",anchorUnderlineOnHover:"anchorUnderlineOnHover-2ESHQB"},s=e=>{e.preventDefault(),e.stopPropagation(),t.pop(),BDV2.joinBD2()},r=e?g(e,{onClick:s},"Join our Discord Server."):g("a",{className:`${a.anchor} ${a.anchorUnderlineOnHover}`,onClick:s},"Join our Discord Server."),i=g(n,{size:n.Sizes.SMALL,color:n.Colors.PRIMARY},"Need support? ",r);return g(o.Child,{grow:1,shrink:1},d?d:i)};t.push(function(e){return g(r,Object.assign({className:a.container,selectable:!0,onScroll:e=>e,onClose:e=>e,renderHeader:f,renderFooter:b,children:i},e))})},window.emotesFfz={},window.emotesBTTV={},window.emotesBTTV2={},window.emotesTwitch={},window.subEmotesTwitch={},window.bdEmotes={TwitchGlobal:{},TwitchSubscriber:{},BTTV:{},FrankerFaceZ:{},BTTV2:{}},window.bdEmoteSettingIDs={TwitchGlobal:"bda-es-7",TwitchSubscriber:"bda-es-7",BTTV:"bda-es-2",FrankerFaceZ:"bda-es-1",BTTV2:"bda-es-2"};function EmoteModule(){Object.defineProperty(this,"categories",{get:function(){const e=[];for(const t in window.bdEmoteSettingIDs)settingsCookie[window.bdEmoteSettingIDs[t]]&&e.push(t);return e}})}EmoteModule.prototype.init=async function(){this.modifiers=["flip","spin","pulse","spin2","spin3","1spin","2spin","3spin","tr","bl","br","shake","shake2","shake3","flap"],this.overrides=["twitch","bttv","ffz"];let e={TwitchGlobal:{url:`https://rauenzi.github.io/BetterDiscordApp/data/emotedata_twitch_global.json`,variable:"TwitchGlobal",oldVariable:"emotesTwitch",getEmoteURL:t=>`https://static-cdn.jtvnw.net/emoticons/v1/${t}/1.0`},TwitchSubscriber:{url:`https://rauenzi.github.io/BetterDiscordApp/data/emotedata_twitch_subscriber.json`,variable:"TwitchSubscriber",oldVariable:"subEmotesTwitch",getEmoteURL:t=>`https://static-cdn.jtvnw.net/emoticons/v1/${t}/1.0`},FrankerFaceZ:{url:`https://rauenzi.github.io/BetterDiscordApp/data/emotedata_ffz.json`,variable:"FrankerFaceZ",oldVariable:"emotesFfz",getEmoteURL:t=>`https://cdn.frankerfacez.com/emoticon/${t}/1`},BTTV:{url:`https://rauenzi.github.io/BetterDiscordApp/data/emotedata_bttv.json`,variable:"BTTV",oldVariable:"emotesBTTV",getEmoteURL:t=>`https://cdn.betterttv.net/emote/${t}/1x`},BTTV2:{url:`https://rauenzi.github.io/BetterDiscordApp/data/emotedata_bttv2.json`,variable:"BTTV2",oldVariable:"emotesBTTV2",getEmoteURL:t=>`https://cdn.betterttv.net/emote/${t}/1x`}};for(await this.getBlacklist(),await this.loadEmoteData(e);!BDV2.MessageComponent;)await new Promise(e=>setTimeout(e,100));this.cancelEmoteRender||(this.cancelEmoteRender=Utils.monkeyPatch(BDV2.MessageComponent,"default",{before:({methodArguments:e})=>{const t=e[0].childrenMessageContent.props.content;if(t&&t.length){for(let e=0;ei.length||bemotes.includes(i))continue;this.modifiers.includes(l)&&settingsCookie["bda-es-8"]||(l=""),this.overrides.includes(d)?l=d:d="";let c=this.categories[a];if("twitch"===d?window.bdEmotes.TwitchGlobal[i]?c="TwitchGlobal":window.bdEmotes.TwitchSubscriber[i]&&(c="TwitchSubscriber"):"bttv"===d?window.bdEmotes.BTTV[i]?c="BTTV":window.bdEmotes.BTTV2[i]&&(c="BTTV2"):"ffz"===d&&window.bdEmotes.FrankerFaceZ[i]&&(c="FrankerFaceZ"),!window.bdEmotes[c][i]||!settingsCookie[window.bdEmoteSettingIDs[c]])continue;const p=t[e].match(new RegExp(`([\\s]|^)${Utils.escape(l?i+":"+l:i)}([\\s]|$)`));if(!p)continue;const m=t[e].substring(0,p.index+p[1].length),u=t[e].substring(p.index+p[0].length-p[2].length);t[e]=m;const h=BDV2.react.createElement(BDEmote,{name:i,url:window.bdEmotes[c][i],modifier:l});t.splice(e+1,0,u),t.splice(e+1,0,h)}}const e=t.every(e=>"string"==typeof e&&""==e.replace(/\s*/,"")||!!(e.type&&"BDEmote"==e.type.name)||!!(e.props&&e.props.children&&e.props.children.props&&e.props.children.props.emojiName));if(e)for(let e of t)"object"==typeof e&&("BDEmote"==e.type.name?e.props.jumboable=!0:e.props&&e.props.children&&e.props.children.props&&e.props.children.props.emojiName&&(e.props.children.props.jumboable=!0))}}}))},EmoteModule.prototype.disable=function(){this.disableAutoCapitalize();this.cancelEmoteRender||(this.cancelEmoteRender(),this.cancelEmoteRender=null)},EmoteModule.prototype.clearEmoteData=async function(){let e=require("fs"),t=bdConfig.dataPath+"emote_data.json",a=e.existsSync(t);a&&e.unlinkSync(t),DataStore.setBDData("emoteCacheDate",new Date().toJSON()),window.bdEmotes={TwitchGlobal:{},TwitchSubscriber:{},BTTV:{},FrankerFaceZ:{},BTTV2:{}}},EmoteModule.prototype.isCacheValid=function(){const e=DataStore.getBDData("emoteCacheDays")||DataStore.setBDData("emoteCacheDays",7)||7,t=new Date(DataStore.getBDData("emoteCacheDate")||null),a=new Date,n=Math.round(Math.abs((a.getTime()-t.getTime())/86400000));return!(n>e)||(DataStore.setBDData("emoteCacheDate",a.toJSON()),!1)},EmoteModule.prototype.loadEmoteData=async function(t){const a=require("fs"),e=bdConfig.dataPath+"emote_data.json",n=await new Promise(t=>a.exists(e,t));if(n&&this.isCacheValid()){settingsCookie["fork-ps-2"]&&mainCore.showToast("Loading emotes from cache.",{type:"info"}),Utils.log("Emotes","Loading emotes from local cache.");const n=await new Promise(t=>{a.readFile(e,"utf8",(e,a)=>{Utils.log("Emotes","Emote file read."),e&&(a={}),t(a)})}),o=Utils.testJSON(n);let s=!!o;for(const a in s&&(window.bdEmotes=o),t)s=0a.unlink(e,t))}if(settingsCookie["fork-es-3"]){for(let a in settingsCookie["fork-ps-2"]&&mainCore.showToast("Downloading emotes in the background do not reload.",{type:"info"}),t){await new Promise(e=>setTimeout(e,1e3));let e=await this.downloadEmotes(t[a]);window.bdEmotes[t[a].variable]=e}settingsCookie["fork-ps-2"]&&mainCore.showToast("All emotes successfully downloaded.",{type:"success"});try{await new Promise(t=>a.writeFile(e,JSON.stringify(window.bdEmotes),"utf8",t))}catch(e){Utils.err("Emotes","Could not save emote data.",e)}}},EmoteModule.prototype.downloadEmotes=function(e){let t=require("request"),a={url:e.url,timeout:e.timeout?e.timeout:5e3,json:!0};return Utils.log("Emotes",`Downloading: ${e.variable} (${e.url})`),new Promise((n,o)=>{t(a,(t,a,s)=>{if(t)return Utils.err("Emotes","Could not download "+e.variable,t),e.backup?(e.url=e.backup,e.backup=null,e.backupParser&&(e.parser=e.backupParser),n(this.downloadEmotes(e))):o({});for(let n in"function"==typeof e.parser&&(s=e.parser(s)),s){if(4>n.length||bemotes.includes(n)){delete s[n];continue}s[n]=e.getEmoteURL(s[n])}n(s),Utils.log("Emotes","Downloaded: "+e.variable)})})},EmoteModule.prototype.getBlacklist=function(){return new Promise(e=>{$.getJSON(`https://rauenzi.github.io/BetterDiscordApp/data/emotefilter.json`,function(t){e(bemotes=t.blacklist)})})};var bemotes=[];EmoteModule.prototype.autoCapitalize=function(){!settingsCookie["bda-es-4"]||this.autoCapitalizeActive||($("body").on("keyup.bdac change.bdac paste.bdac",$(".channelTextArea-rNsIhG textarea:first"),()=>{var e=$(".channelTextArea-rNsIhG textarea:first").val();if(null!=e){var t=e.split(" ").pop();if(3",t+=" ",t+=" ",t+="