var Core=function(e){var t={};function n(s){if(t[s])return t[s].exports;var o=t[s]={i:s,l:!1,exports:{}};return e[s].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,s){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(n.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(s,o,function(t){return e[t]}.bind(null,o));return s},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=6)}([function(e,t){e.exports=require("fs")},function(e,t){e.exports=require("path")},function(e,t){e.exports=require("electron")},function(e,t){e.exports=require("module")},function(e,t){e.exports=require("events")},function(e,t){e.exports=require("request")},function(e,t,n){"use strict";n.r(t);var s={};n.r(s),n.d(s,"Menu",function(){return ye}),n.d(s,"Card",function(){return be}),n.d(s,"Layer",function(){return ve});var o={};n.r(o),n.d(o,"VoiceMode",function(){return $e}),n.d(o,"ClassNormalizer",function(){return Ne}),n.d(o,"DeveloperMode",function(){return je}),n.d(o,"PublicServers",function(){return Fe}),n.d(o,"DarkMode",function(){return Oe}),n.d(o,"MinimalMode",function(){return Ae}),n.d(o,"TwentyFourHour",function(){return Ie}),n.d(o,"ColoredText",function(){return Re}),n.d(o,"VoiceDisconnect",function(){return Ge}),n.d(o,"EmoteMenu",function(){return He}),n.d(o,"EmoteAutocaps",function(){return We}),n.d(o,"EmoteModule",function(){return Ue});var r={emotesLoaded:!1},i={"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"},"Coloured Text":{id:"bda-gs-7",info:"Make text colour the same as role colour",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"}},a={"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},l={local:!1,localServer:"//localhost:8080",minified:!0,version:"0.3.0",branch:"master",repo:"rauenzi",minSupportedVersion:"0.3.0",bbdVersion:"0.2.17"},c={},d={},u={},h={},p={TwitchGlobal:{},TwitchSubscriber:{},BTTV:{},FrankerFaceZ:{},BTTV2:{}},m=[],g=["flip","spin","pulse","spin2","spin3","1spin","2spin","3spin","tr","bl","br","shake","shake2","shake3","flap"],f=["twitch","bttv","ffz"],b=[{type:"collection",id:"settings",name:"Settings",settings:[{type:"category",id:"general",name:"General",collapsible:!0,settings:[{type:"switch",id:"emotes",name:"Emote System",note:"Enables BD's emote system",value:!0},{type:"switch",id:"publicServers",name:"Public Servers",note:"Display public servers button",value:!0},{type:"switch",id:"voiceDisconnect",name:"Voice Disconnect",note:"Disconnect from voice server when closing Discord",value:!1},{type:"switch",id:"twentyFourHour",name:"24 Hour Timestamps",note:"Hides channels when in minimal mode",value:!1},{type:"switch",id:"classNormalizer",name:"Normalize Classes",note:"Adds stable classes to elements to help themes. (e.g. adds .da-channels to .channels-Ie2l6A)",value:!0},{type:"switch",id:"showToasts",name:"Show Toasts",note:"Shows a small notification for important information",value:!0}]},{type:"category",id:"appearance",name:"Appearance",collapsible:!0,settings:[{type:"switch",id:"voiceMode",name:"Voice Mode",note:"Hides everything that isn't voice chat",value:!1},{type:"switch",id:"minimalMode",name:"Minimal Mode",note:"Hide elements and reduce the size of elements",value:!1},{type:"switch",id:"hideChannels",name:"Hide Channels",note:"Hides channels when in minimal mode",value:!1,enableWith:"minimalMode"},{type:"switch",id:"darkMode",name:"Dark Mode",note:"Make certain elements dark by default",value:!0},{type:"switch",id:"coloredText",name:"Colored Text",note:"Make text colour the same as role color",value:!1}]},{type:"category",id:"content",name:"Content Manager",collapsible:!0,settings:[{type:"switch",id:"contentErrors",name:"Show Content Errors",note:"Shows a modal with plugin/theme errors",value:!0},{type:"switch",id:"autoScroll",name:"Scroll To Settings",note:"Auto-scrolls to a plugin's settings when the button is clicked (only if out of view)",value:!0},{type:"switch",id:"autoReload",name:"Automatic Loading",note:"Automatically loads, reloads, and unloads plugins and themes",value:!0}]},{type:"category",id:"developer",name:"Developer Settings",collapsible:!0,shown:!1,settings:[{type:"switch",id:"developerMode",name:"Developer Mode",note:"Allows activating debugger when pressing F8",value:!1},{type:"switch",id:"copySelector",name:"Copy Selector",note:'Adds a "Copy Selector" option to context menus when developer mode is active',value:!1,enableWith:"developerMode"}]},{type:"category",id:"window",name:"Window Preferences",collapsible:!0,shown:!1,settings:[{type:"switch",id:"transparency",name:"Enable Transparency",note:"Enables the main window to be see-through (requires restart)",value:!1},{type:"switch",id:"frame",name:"Window Frame",note:"Adds the native os window frame to the main window",value:!1,hidden:!0}]}]},{type:"collection",id:"emotes",name:"Emotes",enableWith:"settings.general.emotes",settings:[{type:"category",id:"general",name:"General",collapsible:!0,settings:[{type:"switch",id:"download",name:"Download Emotes",note:"Download emotes once a week to stay up to date",value:!0},{type:"switch",id:"emoteMenu",name:"Emote Menu",note:"Show Twitch/Favourite emotes in emote menu",value:!0},{type:"switch",id:"hideEmojiMenu",name:"Hide Emoji Menu",note:"Hides Discord's emoji menu when using emote menu",value:!1,enableWith:"emoteMenu"},{type:"switch",id:"autoCaps",name:"Emote Autocapitalization",note:"Autocapitalize emote commands",value:!1},{type:"switch",id:"showNames",name:"Show Names",note:"Show emote names on hover",value:!0},{type:"switch",id:"modifiers",name:"Show Emote Modifiers",note:"Enable emote mods (flip, spin, pulse, spin2, spin3, 1spin, 2spin, 3spin, tr, bl, br, shake, shake2, shake3, flap)",value:!0},{type:"switch",id:"animateOnHover",name:"Animate On Hover",note:"Only animate the emote modifiers on hover",value:!1}]},{type:"category",id:"categories",name:"Categories",collapsible:!0,settings:[{type:"switch",id:"twitch",name:"Twitch",note:"Show Twitch global & subscriber emotes",value:!0},{type:"switch",id:"ffz",name:"FrankerFaceZ",note:"Show emotes from FFZ",value:!0},{type:"switch",id:"bttv",name:"BetterTTV",note:"Show emotes from BTTV",value:!0}]}]}],y={};class v{static get screenWidth(){return Math.max(document.documentElement.clientWidth,window.innerWidth||0)}static get screenHeight(){return Math.max(document.documentElement.clientHeight,window.innerHeight||0)}static stripBOM(e){return 65279===e.charCodeAt(0)&&(e=e.slice(1)),e}static getTextArea(){return $(".channelTextArea-1LDbYG textarea")}static getInternalInstance(e){return e[Object.keys(e).find(e=>e.startsWith("__reactInternalInstance"))]||null}static insertText(e,t){e.focus(),e.selectionStart=0,e.selectionEnd=e.value.length,document.execCommand("insertText",!1,t)}static injectCss(e){$("",{type:"text/css",rel:"stylesheet",href:e}).appendTo($("head"))}static injectJs(e){return new Promise(t=>{$("",{type:"text/javascript",src:e,onload:t}).appendTo($("body"))})}static escapeID(e){return e.replace(/^[^a-z]+|[^\w-]+/gi,"")}static log(e,t){console.log(`%c[BandagedBD]%c [${e}]%c ${t}`,"color: #3a71c1; font-weight: 700;","color: #3a71c1;","")}static warn(e,t){console.warn(`%c[BandagedBD]%c [${e}]%c ${t}`,"color: #E8A400; font-weight: 700;","color: #E8A400;","")}static err(e,t,n){console.log(`%c[BandagedBD]%c [${e}]%c ${t}`,"color: red; font-weight: 700;","color: red;",""),n&&(console.groupCollapsed("%cError: "+n.message,"color: red;"),console.error(n.stack),console.groupEnd())}static escape(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}static testJSON(e){try{return JSON.parse(e),!0}catch(e){return!1}}static suppressErrors(e,t){return(...n)=>{try{return e(...n)}catch(e){this.err("SuppressedError","Error occurred in "+t,e)}}}static monkeyPatch(e,t,n){const{before:s,after:o,instead:r,once:i=!1,silent:a=!1,force:l=!1}=n,c=n.displayName||e.displayName||e.name||e.constructor.displayName||e.constructor.name;if(a||console.log("patch",t,"of",c),!e[t]){if(!l)return console.error(t,"does not exist for",c);e[t]=function(){}}const d=e[t],u=()=>{a||console.log("unpatch",t,"of",c),e[t]=d};return e[t]=function(){const n={thisObject:this,methodArguments:arguments,cancelPatch:u,originalMethod:d,callOriginalMethod:()=>n.returnValue=n.originalMethod.apply(n.thisObject,n.methodArguments)};if(r){const s=v.suppressErrors(r,"`instead` callback of "+e[t].displayName)(n);void 0!==s&&(n.returnValue=s)}else s&&v.suppressErrors(s,"`before` callback of "+e[t].displayName)(n),n.callOriginalMethod(),o&&v.suppressErrors(o,"`after` callback of "+e[t].displayName)(n);return i&&u(),n.returnValue},e[t].__monkeyPatched=!0,e[t].__originalMethod||(e[t].__originalMethod=d),e[t].displayName="patched "+(e[t].displayName||t),u}static onRemoved(e,t){const n=new MutationObserver(s=>{for(let o=0;o-1,l=i.some(t=>t.contains(e));(a||l)&&(n.disconnect(),t())}});n.observe(document.body,{subtree:!0,childList:!0})}static memoizeObject(e){const t=new Proxy(e,{get:function(e,t){if(e.hasOwnProperty(t)){if(Object.getOwnPropertyDescriptor(e,t).get){const n=e[t];delete e[t],e[t]=n}return e[t]}},set:function(e,t,n){return e.hasOwnProperty(t)?this.err("MemoizedObject","Trying to overwrite existing property"):(e[t]=n,e[t])}});return Object.defineProperty(t,"hasOwnProperty",{value:function(e){return void 0!==this[e]}}),t}static className(){const e=[],t={}.hasOwnProperty;for(let n=0;ne)){return n=>{const s=t(n);return!!s&&e.every(e=>void 0!==s[e])}}static byPrototypeFields(e,t=(e=>e)){return n=>{const s=t(n);return!!s&&(!!s.prototype&&e.every(e=>void 0!==s.prototype[e]))}}static byCode(e,t=(e=>e)){return n=>{const s=t(n);return!!s&&-1!==s.toString([]).search(e)}}static byString(...e){return t=>{const n=t.toString([]);for(const t of e)if(!n.includes(t))return!1;return!0}}static byDisplayName(e){return t=>t&&t.displayName===e}static combine(...e){return t=>e.every(e=>e(t))}}class S{static find(e,t=!0){return this.getModule(e,t)}static findAll(e){return this.getModule(e,!1)}static findByUniqueProperties(e,t=!0){return t?this.getByProps(...e):this.getAllByProps(...e)}static findByDisplayName(e){return this.getByDisplayName(e)}static getModule(e,t=!0){const n=this.getAllModules(),s=[];for(const o in n){if(!n.hasOwnProperty(o))continue;const r=n[o],{exports:i}=r;let a=null;if(i&&(i.__esModule&&i.default&&e(i.default)&&(a=i.default),e(i)&&(a=i),a)){if(t)return a;s.push(a)}}return t||0==s.length?void 0:s}static getModules(e){return this.getModule(e,!1)}static getModuleByName(e,t){if(w.hasOwnProperty(e))return w[e];if(!t)return;const n=this.getModule(t,!0);return n?w[e]=n:void 0}static getByDisplayName(e){return this.getModule(C.byDisplayName(e),!0)}static getByRegex(e,t=!0){return this.getModule(C.byCode(e),t)}static getByPrototypes(...e){return this.getModule(C.byPrototypeFields(e),!0)}static getAllByPrototypes(...e){return this.getModule(C.byPrototypeFields(e),!1)}static getByProps(...e){return this.getModule(C.byProperties(e),!0)}static getAllByProps(...e){return this.getModule(C.byProperties(e),!1)}static getByString(...e){return this.getModule(C.byString(...e),!0)}static getAllByString(...e){return this.getModule(C.byString(...e),!1)}static get require(){if(this._require)return this._require;const e="bbd-webpackmodules",t="function"==typeof window.webpackJsonp?window.webpackJsonp([],{[e]:(e,t,n)=>t.default=n},[e]).default:window.webpackJsonp.push([[],{[e]:(e,t,n)=>e.exports=n},[[e]]]);return delete t.m[e],delete t.c[e],this._require=t}static getAllModules(){return this.require.c}}const E=n(0),P=n(1),x=DiscordNative.globals.releaseChannel;var k=new class{constructor(){this.data={misc:{}},this.pluginData={}}initialize(){E.existsSync(this.baseFolder)||E.mkdirSync(this.baseFolder),E.existsSync(this.dataFolder)||E.mkdirSync(this.dataFolder),E.existsSync(this.BDFile)||E.writeFileSync(this.BDFile,JSON.stringify(this.data.misc,null,4));const e=E.readdirSync(this.dataFolder).filter(e=>!E.statSync(P.resolve(this.dataFolder,e)).isDirectory()&&e.endsWith(".json"));for(const t of e)this.data[t.split(".")[0]]=require(P.resolve(this.dataFolder,t))}get baseFolder(){return this._baseFolder||(this._baseFolder=P.resolve(l.dataPath,"data"))}get dataFolder(){return this._dataFolder||(this._dataFolder=P.resolve(this.baseFolder,`${x}`))}get BDFile(){return this._BDFile||(this._BDFile=P.resolve(l.dataPath,"data",`${x}.json`))}getPluginFile(e){return P.resolve(l.dataPath,"plugins",e+".config.json")}_getFile(e){return"settings"==e||"plugins"==e||"themes"==e?P.resolve(this.dataFolder,`${e}.json`):P.resolve(this.dataFolder,"misc.json")}getBDData(e){return this.data.misc[e]||""}setBDData(e,t){this.data.misc[e]=t,E.writeFileSync(P.resolve(this.dataFolder,"misc.json"),JSON.stringify(this.data.misc,null,4))}getData(e){return this.data[e]||""}setData(e,t){this.data[e]=t,E.writeFileSync(P.resolve(this.dataFolder,`${e}.json`),JSON.stringify(t,null,4))}getPluginData(e,t){return void 0!==this.pluginData[e]?this.pluginData[e][t]||void 0:E.existsSync(this.getPluginFile(e))?(this.pluginData[e]=JSON.parse(E.readFileSync(this.getPluginFile(e))),this.pluginData[e][t]||void 0):void 0}setPluginData(e,t,n){void 0!==n&&(void 0===this.pluginData[e]&&(this.pluginData[e]={}),this.pluginData[e][t]=n,E.writeFileSync(this.getPluginFile(e),JSON.stringify(this.pluginData[e],null,4)))}deletePluginData(e,t){void 0===this.pluginData[e]&&(this.pluginData[e]={}),delete this.pluginData[e][t],E.writeFileSync(this.getPluginFile(e),JSON.stringify(this.pluginData[e],null,4))}};const D=n(4);var M=new class extends D{constructor(){super(),this.setMaxListeners(20)}dispatch(e,...t){this.emit(e,...t)}};function B(){}B.prototype.loadPlugins=function(){this.loadPluginData();const e=G.loadPlugins(),t=Object.keys(h);for(let n=0;nt.filename==e).plugin;try{n.load&&"function"==typeof n.load&&n.load()}catch(e){Ee.showContentErrors({plugins:[e]})}v.log("ContentManager",`${n.getName()} v${n.getVersion()} was loaded.`),Se.show(`${n.getName()} v${n.getVersion()} was loaded.`,{type:"success"}),M.dispatch("plugin-loaded",n.getName())},B.prototype.unloadPlugin=function(e){const t=Object.values(h).find(t=>t.filename==e)||h[e];if(!t)return;const n=t.plugin.getName();c[n]&&this.disablePlugin(n,!0);const s=G.unloadContent(h[n].filename,"plugin");if(delete h[n],s)return Ee.showContentErrors({plugins:[s]}),Se.show(`${n} could not be unloaded. It may have not been loaded yet.`,{type:"error"}),v.err("ContentManager",`${n} could not be unloaded. It may have not been loaded yet.`,s);v.log("ContentManager",`${n} was unloaded.`),Se.show(`${n} was unloaded.`,{type:"success"}),M.dispatch("plugin-unloaded",n)},B.prototype.reloadPlugin=function(e){const t=Object.values(h).find(t=>t.filename==e)||h[e];if(!t)return this.loadPlugin(e);const n=t.plugin.getName(),s=c[n];s&&this.stopPlugin(n,!0);const o=G.reloadContent(h[n].filename,"plugin");if(o)return Ee.showContentErrors({plugins:[o]}),Se.show(`${n} could not be reloaded.`,{type:"error"}),v.err("ContentManager",`${n} could not be reloaded.`,o);h[n].plugin.load&&"function"==typeof h[n].plugin.load&&h[n].plugin.load(),s&&this.startPlugin(n,!0),v.log("ContentManager",`${n} v${h[n].plugin.getVersion()} was reloaded.`),Se.show(`${n} v${h[n].plugin.getVersion()} was reloaded.`,{type:"success"}),M.dispatch("plugin-reloaded",n)},B.prototype.updatePluginList=function(){const e=G.loadNewContent("plugin");for(const t of e.added)this.loadPlugin(t);for(const t of e.removed)this.unloadPlugin(t)},B.prototype.loadPluginData=function(){const e=k.getData("plugins");e&&Object.assign(c,e)},B.prototype.savePluginData=function(){k.setData("plugins",c)},B.prototype.newMessage=function(){const e=Object.keys(h);for(let t=0;t",{id:v.escapeID(n),text:unescape(u[n].css)}))}for(const e in d)u[e]||delete d[e];return this.saveThemeData(),e},N.prototype.enableTheme=function(e,t=!1){d[e]=!0,this.saveThemeData(),$("head").append($("