(_ => {
if (window.BDFDB && window.BDFDB.ListenerUtils && typeof window.BDFDB.ListenerUtils.remove == "function") window.BDFDB.ListenerUtils.remove(window.BDFDB);
if (window.BDFDB && window.BDFDB.ObserverUtils && typeof window.BDFDB.ObserverUtils.disconnect == "function") window.BDFDB.ObserverUtils.disconnect(window.BDFDB);
if (window.BDFDB && window.BDFDB.ModuleUtils && typeof window.BDFDB.ModuleUtils.unpatch == "function") window.BDFDB.ModuleUtils.unpatch(window.BDFDB);
if (window.BDFDB && window.BDFDB.WindowUtils && typeof window.BDFDB.WindowUtils.closeAll == "function") window.BDFDB.WindowUtils.closeAll(window.BDFDB);
if (window.BDFDB && window.BDFDB.WindowUtils && typeof window.BDFDB.WindowUtils.removeListener == "function") window.BDFDB.WindowUtils.removeListener(window.BDFDB);
var BDFDB = {
myPlugins: Object.assign({}, window.BDFDB && window.BDFDB.myPlugins),
InternalData: Object.assign({
pressedKeys: [],
mousePosition: {
pageX: 0,
pageY: 0
},
patchMenuQueries: {}
}, window.BDFDB && window.BDFDB.InternalData, {
creationTime: performance.now()
}),
BDv2Api: window.BDFDB && window.BDFDB.BDv2Api || undefined,
name: "$BDFDB"
};
var loadid = Math.round(Math.random() * 10000000000000000), InternalBDFDB = {};
BDFDB.InternalData.loadid = loadid;
BDFDB.LogUtils = {};
BDFDB.LogUtils.log = function (string, name) {
if (typeof string != "string") string = "";
if (typeof name != "string" || name == "$BDFDB") name = "BDFDB";
console.log(`%c[${name}]`, "color: #3a71c1; font-weight: 700;", string.trim());
};
BDFDB.LogUtils.warn = function (string, name) {
if (typeof string != "string") string = "";
if (typeof name != "string" || name == "$BDFDB") name = "BDFDB";
console.warn(`%c[${name}]`, "color: #3a71c1; font-weight: 700;", string.trim());
};
BDFDB.LogUtils.error = function (string, name) {
if (typeof string != "string") string = "";
if (typeof name != "string" || name == "$BDFDB") name = "BDFDB";
console.error(`%c[${name}]`, "color: #3a71c1; font-weight: 700;", "Fatal Error: " + string.trim());
};
BDFDB.LogUtils.log("Loading library.");
BDFDB.PluginUtils = {};
BDFDB.PluginUtils.init = function (plugin) {
plugin.name = plugin.name || (typeof plugin.getName == "function" ? plugin.getName() : null);
plugin.version = plugin.version || (typeof plugin.getVersion == "function" ? plugin.getVersion() : null);
plugin.author = plugin.author || (typeof plugin.getAuthor == "function" ? plugin.getAuthor() : null);
plugin.description = plugin.description || (typeof plugin.getDescription == "function" ? plugin.getDescription() : null);
if (plugin.patchModules) {
plugin.patchedModules = {after: plugin.patchModules};
delete plugin.patchModules;
}
plugin.patchedModules = BDFDB.ObjectUtils.filter(plugin.patchedModules, type => WebModulesData.Patchtypes.includes(type), true);
InternalBDFDB.clearStartTimeout(plugin);
var loadmessage = BDFDB.LanguageUtils.LibraryStringsFormat("toast_plugin_started", "v" + plugin.version);
BDFDB.LogUtils.log(loadmessage, plugin.name);
if (!BDFDB.BDUtils.getSettings("fork-ps-2")) BDFDB.NotificationUtils.toast(plugin.name + " " + loadmessage, {nopointer: true, selector: "plugin-started-toast"});
var url = typeof plugin.getRawUrl == "function" && typeof plugin.getRawUrl() == "string" ? plugin.getRawUrl() : `https://mwittrien.github.io/BetterDiscordAddons/Plugins/${plugin.name}/${plugin.name}.plugin.js`;
BDFDB.PluginUtils.checkUpdate(plugin.name, url);
if (BDFDB.ObjectUtils.is(plugin.classes)) InternalBDFDB.addPluginClasses(plugin);
if (typeof plugin.initConstructor === "function") BDFDB.TimeUtils.suppress(plugin.initConstructor.bind(plugin), "Could not initiate constructor!", plugin.name)();
if (typeof plugin.css === "string") BDFDB.DOMUtils.appendLocalStyle(plugin.name, plugin.css);
InternalBDFDB.patchPlugin(plugin);
InternalBDFDB.addOnSettingsClosedListener(plugin);
InternalBDFDB.addOnSwitchListener(plugin);
InternalBDFDB.addContextListeners(plugin);
BDFDB.PluginUtils.translate(plugin);
BDFDB.PluginUtils.checkChangeLog(plugin);
if (!window.PluginUpdates || typeof window.PluginUpdates !== "object") window.PluginUpdates = {plugins: {} };
window.PluginUpdates.plugins[url] = {name: plugin.name, raw: url, version: plugin.version};
if (typeof window.PluginUpdates.interval === "undefined") window.PluginUpdates.interval = BDFDB.TimeUtils.interval(_ => {BDFDB.PluginUtils.checkAllUpdates();}, 1000*60*60*2);
plugin.started = true;
delete plugin.stopping;
for (let name in BDFDB.myPlugins) if (!BDFDB.myPlugins[name].started && typeof BDFDB.myPlugins[name].initialize == "function") setImmediate(_ => {BDFDB.TimeUtils.suppress(BDFDB.myPlugins[name].initialize.bind(BDFDB.myPlugins[name]), "Could not initiate plugin!", name)();});
};
BDFDB.PluginUtils.clear = function (plugin) {
InternalBDFDB.clearStartTimeout(plugin);
delete BDFDB.myPlugins[plugin.name];
var unloadmessage = BDFDB.LanguageUtils.LibraryStringsFormat("toast_plugin_stopped", "v" + plugin.version);
BDFDB.LogUtils.log(unloadmessage, plugin.name);
if (!BDFDB.BDUtils.getSettings("fork-ps-2")) BDFDB.NotificationUtils.toast(plugin.name + " " + unloadmessage, {nopointer: true, selector: "plugin-stopped-toast"});
var url = typeof plugin.getRawUrl == "function" && typeof plugin.getRawUrl() == "string" ? plugin.getRawUrl() : `https://mwittrien.github.io/BetterDiscordAddons/Plugins/${plugin.name}/${plugin.name}.plugin.js`;
if (BDFDB.ObjectUtils.is(plugin.classes)) InternalBDFDB.removePluginClasses(plugin);
if (typeof plugin.css === "string") BDFDB.DOMUtils.removeLocalStyle(plugin.name);
BDFDB.ModuleUtils.unpatch(plugin);
BDFDB.ListenerUtils.remove(plugin);
BDFDB.ObserverUtils.disconnect(plugin);
BDFDB.WindowUtils.closeAll(plugin);
BDFDB.WindowUtils.removeListener(plugin);
InternalBDFDB.removeOnSwitchListener(plugin);
for (let modal of document.querySelectorAll(`.${plugin.name}-modal, .${plugin.name.toLowerCase()}-modal, .${plugin.name}-settingsmodal, .${plugin.name.toLowerCase()}-settingsmodal`)) {
let closebutton = modal.querySelector(BDFDB.dotCN.modalclose);
if (closebutton) closebutton.click();
}
delete window.PluginUpdates.plugins[url];
delete plugin.started;
BDFDB.TimeUtils.timeout(_ => {delete plugin.stopping;});
};
BDFDB.PluginUtils.translate = function (plugin) {
plugin.labels = {};
if (typeof plugin.setLabelsByLanguage === "function" || typeof plugin.changeLanguageStrings === "function") {
if (document.querySelector("html").lang) translate();
else {
var translateinterval = BDFDB.TimeUtils.interval(_ => {
if (document.querySelector("html").lang) {
BDFDB.TimeUtils.clear(translateinterval);
translate();
}
}, 100);
}
function translate() {
var language = BDFDB.LanguageUtils.getLanguage();
if (typeof plugin.setLabelsByLanguage === "function") plugin.labels = plugin.setLabelsByLanguage(language.id);
if (typeof plugin.changeLanguageStrings === "function") plugin.changeLanguageStrings();
BDFDB.LogUtils.log(BDFDB.LanguageUtils.LibraryStringsFormat("toast_plugin_translated", language.ownlang), plugin.name);
}
}
};
BDFDB.PluginUtils.checkUpdate = function (pluginname, url) {
if (BDFDB.BDUtils.isBDv2() || !pluginname || !url) return;
LibraryRequires.request(url, (error, response, result) => {
if (error) return;
var newversion = result.match(/['"][0-9]+\.[0-9]+\.[0-9]+['"]/i);
if (!newversion) return;
if (BDFDB.NumberUtils.getVersionDifference(newversion[0], window.PluginUpdates.plugins[url].version) > 0.2) {
BDFDB.NotificationUtils.toast(`${pluginname} will be force updated, because your version is heavily outdated.`, {type:"warn", nopointer:true, selector:"plugin-forceupdate-toast"});
BDFDB.PluginUtils.downloadUpdate(pluginname, url);
}
else if (BDFDB.NumberUtils.compareVersions(newversion[0], window.PluginUpdates.plugins[url].version)) BDFDB.PluginUtils.showUpdateNotice(pluginname, url);
else BDFDB.PluginUtils.removeUpdateNotice(pluginname);
});
};
BDFDB.PluginUtils.checkAllUpdates = function () {
for (let url in window.PluginUpdates.plugins) {
var plugin = window.PluginUpdates.plugins[url];
BDFDB.PluginUtils.checkUpdate(plugin.name, plugin.raw);
}
};
BDFDB.PluginUtils.showUpdateNotice = function (pluginname, url) {
if (!pluginname || !url) return;
var updatenotice = document.querySelector("#pluginNotice");
if (!updatenotice) {
updatenotice = BDFDB.NotificationUtils.notice(`The following plugins need to be updated: `, {html:true, id:"pluginNotice", type:"info", btn:!BDFDB.BDUtils.isAutoLoadEnabled() ? "Reload" : "", customicon:``});
updatenotice.style.setProperty("display", "block", "important");
updatenotice.style.setProperty("visibility", "visible", "important");
updatenotice.style.setProperty("opacity", "1", "important");
updatenotice.querySelector(BDFDB.dotCN.noticedismiss).addEventListener("click", _ => {
BDFDB.DOMUtils.remove(".update-clickme-tooltip");
});
var reloadbutton = updatenotice.querySelector(BDFDB.dotCN.noticebutton);
if (reloadbutton) {
BDFDB.DOMUtils.toggle(reloadbutton, true);
reloadbutton.addEventListener("click", _ => {
window.location.reload(false);
});
reloadbutton.addEventListener("mouseenter", _ => {
if (window.PluginUpdates.downloaded) BDFDB.TooltipUtils.create(reloadbutton, window.PluginUpdates.downloaded.join(", "), {type:"bottom", selector:"update-notice-tooltip", style: "max-width: 420px"});
});
}
}
if (updatenotice) {
var updatenoticelist = updatenotice.querySelector("#outdatedPlugins");
if (updatenoticelist && !updatenoticelist.querySelector(`#${pluginname}-notice`)) {
if (updatenoticelist.querySelector("span")) updatenoticelist.appendChild(BDFDB.DOMUtils.create(`, `));
var updateentry = BDFDB.DOMUtils.create(`${pluginname}`);
updateentry.addEventListener("click", _ => {BDFDB.PluginUtils.downloadUpdate(pluginname, url);});
updatenoticelist.appendChild(updateentry);
if (!document.querySelector(".update-clickme-tooltip")) BDFDB.TooltipUtils.create(updatenoticelist, "Click us!", {type:"bottom", selector:"update-clickme-tooltip", delay:500});
}
}
};
BDFDB.PluginUtils.removeUpdateNotice = function (pluginname, updatenotice = document.querySelector("#pluginNotice")) {
if (!pluginname || !updatenotice) return;
var updatenoticelist = updatenotice.querySelector("#outdatedPlugins");
if (updatenoticelist) {
var noticeentry = updatenoticelist.querySelector(`#${pluginname}-notice`);
if (noticeentry) {
var nextsibling = noticeentry.nextSibling;
var prevsibling = noticeentry.prevSibling;
if (nextsibling && BDFDB.DOMUtils.containsClass(nextsibling, "separator")) nextsibling.remove();
else if (prevsibling && BDFDB.DOMUtils.containsClass(prevsibling, "separator")) prevsibling.remove();
noticeentry.remove();
}
if (!updatenoticelist.querySelector("span")) {
var reloadbutton = updatenotice.querySelector(BDFDB.dotCN.noticebutton);
if (reloadbutton) {
updatenotice.querySelector(".notice-message").innerText = "To finish updating you need to reload.";
BDFDB.DOMUtils.toggle(reloadbutton, false);
}
else updatenotice.querySelector(BDFDB.dotCN.noticedismiss).click();
}
}
};
BDFDB.PluginUtils.downloadUpdate = function (pluginname, url) {
if (!pluginname || !url) return;
LibraryRequires.request(url, (error, response, result) => {
if (error) return BDFDB.LogUtils.warn("Unable to get update for " + pluginname);
BDFDB.InternalData.creationTime = 0;
var newversion = result.match(/['"][0-9]+\.[0-9]+\.[0-9]+['"]/i);
newversion = newversion.toString().replace(/['"]/g, "");
LibraryRequires.fs.writeFileSync(LibraryRequires.path.join(BDFDB.BDUtils.getPluginsFolder(), url.split("/").slice(-1)[0]), result);
BDFDB.NotificationUtils.toast(`${pluginname} v${window.PluginUpdates.plugins[url].version} has been replaced by ${pluginname} v${newversion}.`, {nopointer:true, selector:"plugin-updated-toast"});
var updatenotice = document.querySelector("#pluginNotice");
if (updatenotice) {
if (updatenotice.querySelector(BDFDB.dotCN.noticebutton)) {
window.PluginUpdates.plugins[url].version = newversion;
if (!window.PluginUpdates.downloaded) window.PluginUpdates.downloaded = [];
if (!window.PluginUpdates.downloaded.includes(pluginname)) window.PluginUpdates.downloaded.push(pluginname);
}
BDFDB.PluginUtils.removeUpdateNotice(pluginname, updatenotice);
}
});
};
BDFDB.PluginUtils.checkChangeLog = function (plugin) {
if (!BDFDB.ObjectUtils.is(plugin) || !plugin.changelog) return;
var changelog = BDFDB.DataUtils.load(plugin, "changelog");
if (!changelog.currentversion || BDFDB.NumberUtils.compareVersions(plugin.version, changelog.currentversion)) {
changelog.currentversion = plugin.version;
BDFDB.DataUtils.save(changelog, plugin, "changelog");
BDFDB.PluginUtils.openChangeLog(plugin);
}
};
BDFDB.PluginUtils.openChangeLog = function (plugin) {
if (!BDFDB.ObjectUtils.is(plugin) || !plugin.changelog) return;
var changeLogHTML = "", headers = {
added: "New Features",
fixed: "Bug Fixes",
improved: "Improvements",
progress: "Progress"
};
for (let type in plugin.changelog) {
type = type.toLowerCase();
var classname = BDFDB.disCN["changelog" + type];
if (classname) {
changeLogHTML += `
${headers[type]}
`;
for (let log of plugin.changelog[type]) changeLogHTML += `
${log[0]}${log[1] ? (": " + log[1] + ".") : ""}
`;
changeLogHTML += `
`
}
}
if (changeLogHTML) BDFDB.ModalUtils.open(plugin, {header:`${plugin.name} ${BDFDB.LanguageUtils.LanguageStrings.CHANGE_LOG}`, subheader:`Version ${plugin.version}`, children:BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(changeLogHTML)), className:BDFDB.disCN.modalchangelogmodal, contentClassName:BDFDB.disCNS.changelogcontainer + BDFDB.disCN.modalminicontent});
};
BDFDB.PluginUtils.createSettingsPanel = function (plugin, children) {
if (!BDFDB.ObjectUtils.is(plugin) || !children || (!BDFDB.ReactUtils.isValidElement(children) && !BDFDB.ArrayUtils.is(children)) || (BDFDB.ArrayUtils.is(children) && !children.length)) return;
var settingspanel = BDFDB.DOMUtils.create(``);
BDFDB.ReactUtils.render(BDFDB.ReactUtils.createElement(LibraryComponents.SettingsPanel, {
key: `${plugin.name}-settingspanel`,
title: plugin.name,
children
}), settingspanel);
return settingspanel;
};
InternalBDFDB.addPluginClasses = function (plugin) {
DiscordClassModules[`PLUGIN_${plugin.name}`] = plugin.classes;
for (let classname in plugin.classes) DiscordClasses[`$${(plugin.name + classname).toLowerCase()}`] = [`PLUGIN_${plugin.name}`, classname];
};
InternalBDFDB.removePluginClasses = function (plugin) {
delete DiscordClassModules[`PLUGIN_${plugin.name}`];
DiscordClasses = BDFDB.ObjectUtils.filter(DiscordClasses, classArray => classArray[0] != `PLUGIN_${plugin.name}`);
};
InternalBDFDB.clearStartTimeout = function (plugin) {
if (!BDFDB.ObjectUtils.is(plugin)) return;
BDFDB.TimeUtils.clear(plugin.startTimeout, plugin.libLoadTimeout);
delete plugin.startTimeout;
delete plugin.libLoadTimeout;
};
InternalBDFDB.addOnSettingsClosedListener = function (plugin) {
if (BDFDB.ObjectUtils.is(plugin) && typeof plugin.onSettingsClosed === "function") {
let SettingsLayer = BDFDB.ModuleUtils.findByName("StandardSidebarView");
if (SettingsLayer) BDFDB.ModuleUtils.patch(plugin, SettingsLayer.prototype, "componentWillUnmount", {after: e => {
plugin.onSettingsClosed();
}});
}
};
InternalBDFDB.addOnSwitchListener = function (plugin) {
if (BDFDB.ObjectUtils.is(plugin) && typeof plugin.onSwitch === "function") {
InternalBDFDB.removeOnSwitchListener(plugin);
var spacer = document.querySelector(`${BDFDB.dotCN.guildswrapper} ~ * > ${BDFDB.dotCN.chatspacer}`);
if (spacer) {
var nochannelobserver = new MutationObserver(changes => {changes.forEach(change => {
if (change.target && BDFDB.DOMUtils.containsClass(change.target, BDFDB.disCN.nochannel)) plugin.onSwitch();
});});
var nochannel = spacer.querySelector(BDFDB.dotCNC.chat + BDFDB.dotCN.nochannel);
if (nochannel) nochannelobserver.observe(nochannel, {attributes:true});
plugin.onSwitchFix = new MutationObserver(changes => {changes.forEach(change => {if (change.addedNodes) {change.addedNodes.forEach(node => {
if (BDFDB.DOMUtils.containsClass(node, BDFDB.disCN.chat, BDFDB.disCN.nochannel, false)) nochannelobserver.observe(node, {attributes:true});
});}});});
plugin.onSwitchFix.observe(spacer, {childList:true});
}
}
};
InternalBDFDB.removeOnSwitchListener = function (plugin) {
if (BDFDB.ObjectUtils.is(plugin) && typeof plugin.onSwitch === "function" && BDFDB.ObjectUtils.is(plugin.onSwitchFix)) {
plugin.onSwitchFix.disconnect();
delete plugin.onSwitchFix;
}
};
BDFDB.ObserverUtils = {};
BDFDB.ObserverUtils.connect = function (plugin, eleOrSelec, observer, config = {childList: true}) {
if (!BDFDB.ObjectUtils.is(plugin) || !eleOrSelec || !observer) return;
if (BDFDB.ObjectUtils.isEmpty(plugin.observers)) plugin.observers = {};
if (!BDFDB.ArrayUtils.is(plugin.observers[observer.name])) plugin.observers[observer.name] = [];
if (!observer.multi) for (let subinstance of plugin.observers[observer.name]) subinstance.disconnect();
if (observer.instance) plugin.observers[observer.name].push(observer.instance);
var instance = plugin.observers[observer.name][plugin.observers[observer.name].length - 1];
if (instance) {
var node = Node.prototype.isPrototypeOf(eleOrSelec) ? eleOrSelec : typeof eleOrSelec === "string" ? document.querySelector(eleOrSelec) : null;
if (node) instance.observe(node, config);
}
};
BDFDB.ObserverUtils.disconnect = function (plugin, observer) {
if (BDFDB.ObjectUtils.is(plugin) && !BDFDB.ObjectUtils.isEmpty(plugin.observers)) {
let observername = typeof observer == "string" ? observer : (BDFDB.ObjectUtils.is(observer) ? observer.name : null);
if (!observername) {
for (let observer in plugin.observers) for (let instance of plugin.observers[observer]) instance.disconnect();
delete plugin.observers;
}
else if (!BDFDB.ArrayUtils.is(plugin.observers[observername])) {
for (let instance of plugin.observers[observername]) instance.disconnect();
delete plugin.observers[observername];
}
}
};
BDFDB.ListenerUtils = {};
BDFDB.ListenerUtils.add = function (plugin, ele, actions, selectorOrCallback, callbackOrNothing) {
if (!BDFDB.ObjectUtils.is(plugin) || (!Node.prototype.isPrototypeOf(ele) && ele !== window) || !actions) return;
var callbackIs4th = typeof selectorOrCallback == "function";
var selector = callbackIs4th ? undefined : selectorOrCallback;
var callback = callbackIs4th ? selectorOrCallback : callbackOrNothing;
if (typeof callback != "function") return;
BDFDB.ListenerUtils.remove(plugin, ele, actions, selector);
for (var action of actions.split(" ")) {
action = action.split(".");
var eventname = action.shift().toLowerCase();
if (!eventname) return;
var origeventname = eventname;
eventname = eventname == "mouseenter" || eventname == "mouseleave" ? "mouseover" : eventname;
var namespace = (action.join(".") || "") + plugin.name;
if (!BDFDB.ArrayUtils.is(plugin.listeners)) plugin.listeners = [];
var eventcallback = null;
if (selector) {
if (origeventname == "mouseenter" || origeventname == "mouseleave") {
eventcallback = e => {
for (let child of e.path) if (typeof child.matches == "function" && child.matches(selector) && !child[namespace + "BDFDB" + origeventname]) {
child[namespace + "BDFDB" + origeventname] = true;
if (origeventname == "mouseenter") callback(BDFDB.ListenerUtils.copyEvent(e, child));
let mouseout = e2 => {
if (e2.target.contains(child) || e2.target == child || !child.contains(e2.target)) {
if (origeventname == "mouseleave") callback(BDFDB.ListenerUtils.copyEvent(e, child));
delete child[namespace + "BDFDB" + origeventname];
document.removeEventListener("mouseout", mouseout);
}
};
document.addEventListener("mouseout", mouseout);
break;
}
};
}
else {
eventcallback = e => {
for (let child of e.path) if (typeof child.matches == "function" && child.matches(selector)) {
callback(BDFDB.ListenerUtils.copyEvent(e, child));
break;
}
};
}
}
else eventcallback = e => {callback(BDFDB.ListenerUtils.copyEvent(e, ele));};
plugin.listeners.push({ele, eventname, origeventname, namespace, selector, eventcallback});
ele.addEventListener(eventname, eventcallback, true);
}
};
BDFDB.ListenerUtils.remove = function (plugin, ele, actions = "", selector) {
if (!BDFDB.ObjectUtils.is(plugin) || !BDFDB.ArrayUtils.is(plugin.listeners)) return;
if (Node.prototype.isPrototypeOf(ele) || ele === window) {
for (var action of actions.split(" ")) {
action = action.split(".");
var eventname = action.shift().toLowerCase();
var namespace = (action.join(".") || "") + plugin.name;
for (let listener of plugin.listeners) {
let removedlisteners = [];
if (listener.ele == ele && (!eventname || listener.origeventname == eventname) && listener.namespace == namespace && (selector === undefined || listener.selector == selector)) {
ele.removeEventListener(listener.eventname, listener.eventcallback, true);
removedlisteners.push(listener);
}
if (removedlisteners.length) plugin.listeners = plugin.listeners.filter(listener => {return removedlisteners.indexOf(listener) < 0;});
}
}
}
else if (!ele) {
for (let listener of plugin.listeners) listener.ele.removeEventListener(listener.eventname, listener.eventcallback, true);
plugin.listeners = [];
}
};
BDFDB.ListenerUtils.multiAdd = function (node, actions, callback) {
if (!Node.prototype.isPrototypeOf(node) || !actions || typeof callback != "function") return;
for (var action of actions.trim().split(" ").filter(n => n)) node.addEventListener(action, callback, true);
};
BDFDB.ListenerUtils.multiRemove = function (node, actions, callback) {
if (!Node.prototype.isPrototypeOf(node) || !actions || typeof callback != "function") return;
for (var action of actions.trim().split(" ").filter(n => n)) node.removeEventListener(action, callback, true);
};
BDFDB.ListenerUtils.addToChildren = function (node, actions, selector, callback) {
if (!Node.prototype.isPrototypeOf(node) || !actions || !selector || !selector.trim() || typeof callback != "function") return;
for (var action of actions.trim().split(" ").filter(n => n)) {
var eventcallback = callback;
if (action == "mouseenter" || action == "mouseleave") eventcallback = e => {if (e.target.matches(selector)) callback(e);};
node.querySelectorAll(selector.trim()).forEach(child => {child.addEventListener(action, eventcallback, true);});
}
};
BDFDB.ListenerUtils.copyEvent = function (e, ele) {
if (!e || !e.constructor || !e.type) return e;
var ecopy = new e.constructor(e.type, e);
Object.defineProperty(ecopy, "originalEvent", {value: e});
Object.defineProperty(ecopy, "which", {value: e.which});
Object.defineProperty(ecopy, "keyCode", {value: e.keyCode});
Object.defineProperty(ecopy, "path", {value: e.path});
Object.defineProperty(ecopy, "relatedTarget", {value: e.relatedTarget});
Object.defineProperty(ecopy, "srcElement", {value: e.srcElement});
Object.defineProperty(ecopy, "target", {value: e.target});
Object.defineProperty(ecopy, "toElement", {value: e.toElement});
if (ele) Object.defineProperty(ecopy, "currentTarget", {value: ele});
return ecopy;
};
BDFDB.ListenerUtils.stopEvent = function (e) {
if (BDFDB.ObjectUtils.is(e)) {
if (typeof e.preventDefault == "function") e.preventDefault();
if (typeof e.stopPropagation == "function") e.stopPropagation();
if (typeof e.stopImmediatePropagation == "function") e.stopImmediatePropagation();
if (BDFDB.ObjectUtils.is(e.originalEvent)) {
if (typeof e.originalEvent.preventDefault == "function") e.originalEvent.preventDefault();
if (typeof e.originalEvent.stopPropagation == "function") e.originalEvent.stopPropagation();
if (typeof e.originalEvent.stopImmediatePropagation == "function") e.originalEvent.stopImmediatePropagation();
}
}
};
var NotificationBars = [], DesktopNotificationQueue = {queue:[], running:false};
BDFDB.NotificationUtils = {};
BDFDB.NotificationUtils.toast = function (text, options = {}) {
var toasts = document.querySelector(".toasts, .bd-toasts");
if (!toasts) {
var channels = document.querySelector(BDFDB.dotCN.channels + " + div");
var channelrects = channels ? BDFDB.DOMUtils.getRects(channels) : null;
var members = channels ? channels.querySelector(BDFDB.dotCN.memberswrap) : null;
var left = channelrects ? channelrects.left : 310;
var width = channelrects ? (members ? channelrects.width - BDFDB.DOMUtils.getRects(members).width : channelrects.width) : window.outerWidth - 0;
var form = channels ? channels.querySelector("form") : null;
var bottom = form ? BDFDB.DOMUtils.getRects(form).height : 80;
toasts = BDFDB.DOMUtils.create(``);
(document.querySelector(BDFDB.dotCN.app) || document.body).appendChild(toasts);
}
const {type = "", icon = true, timeout = 3000, html = false, selector = "", nopointer = false, color = ""} = options;
var toast = BDFDB.DOMUtils.create(`
${html === true ? text : BDFDB.StringUtils.htmlEscape(text)}
`);
if (type) {
BDFDB.DOMUtils.addClass(toast, "toast-" + type);
if (icon) BDFDB.DOMUtils.addClass(toast, "icon");
}
else if (color) {
var rgbcolor = BDFDB.ColorUtils.convert(color, "RGB");
if (rgbcolor) toast.style.setProperty("background-color", rgbcolor);
}
BDFDB.DOMUtils.addClass(toast, selector);
toasts.appendChild(toast);
toast.close = _ => {
if (document.contains(toast)) {
BDFDB.DOMUtils.addClass(toast, "closing");
toast.style.setProperty("pointer-events", "none", "important");
BDFDB.TimeUtils.timeout(_ => {
toast.remove();
if (!toasts.querySelectorAll(".toast, .bd-toast").length) toasts.remove();
}, 3000);
}
};
if (nopointer) toast.style.setProperty("pointer-events", "none", "important");
else toast.addEventListener("click", toast.close);
BDFDB.TimeUtils.timeout(_ => {toast.close();}, timeout > 0 ? timeout : 600000);
return toast;
};
BDFDB.NotificationUtils.desktop = function (parsedcontent, parsedoptions = {}) {
var queue = _ => {
DesktopNotificationQueue.queue.push({parsedcontent, parsedoptions});
runqueue();
};
var runqueue = _ => {
if (!DesktopNotificationQueue.running) {
var notification = DesktopNotificationQueue.queue.shift();
if (notification) notify(notification.parsedcontent, notification.parsedoptions);
}
};
var notify = (content, options) => {
DesktopNotificationQueue.running = true;
var muted = options.silent;
options.silent = options.silent || options.sound ? true : false;
var notification = new Notification(content, options);
var audio = new Audio();
var timeout = BDFDB.TimeUtils.timeout(_ => {close();}, options.timeout ? options.timeout : 3000);
if (typeof options.click == "function") notification.onclick = _ => {
BDFDB.TimeUtils.clear(timeout);
close();
options.click();
};
if (!muted && options.sound) {
audio.src = options.sound;
audio.play();
}
var close = _ => {
audio.pause();
notification.close();
DesktopNotificationQueue.running = false;
BDFDB.TimeUtils.timeout(_ => {runqueue();}, 1000);
};
};
if (!("Notification" in window)) {}
else if (Notification.permission === "granted") queue();
else if (Notification.permission !== "denied") Notification.requestPermission(function (response) {if (response === "granted") queue();});
};
BDFDB.NotificationUtils.notice = function (text, options = {}) {
if (!text) return;
var layers = document.querySelector(BDFDB.dotCN.layers);
if (!layers) return;
var id = BDFDB.NumberUtils.generateId(NotificationBars);
var notice = BDFDB.DOMUtils.create(`
`);
layers.parentElement.insertBefore(notice, layers);
var noticemessage = notice.querySelector(".notice-message");
if (options.platform) for (let platform of options.platform.split(" ")) if (DiscordClasses["noticeicon" + platform]) {
let icon = BDFDB.DOMUtils.create(``);
BDFDB.DOMUtils.addClass(icon, BDFDB.disCN.noticeplatformicon);
BDFDB.DOMUtils.removeClass(icon, BDFDB.disCN.noticeicon);
notice.insertBefore(icon, noticemessage);
}
if (options.customicon) {
let iconinner = BDFDB.DOMUtils.create(options.customicon)
let icon = BDFDB.DOMUtils.create(``);
if (iconinner.tagName == "span" && !iconinner.firstElementChild) icon.style.setProperty("background", `url(${options.customicon}) center/cover no-repeat`);
else icon.appendChild(iconinner);
BDFDB.DOMUtils.addClass(icon, BDFDB.disCN.noticeplatformicon);
BDFDB.DOMUtils.removeClass(icon, BDFDB.disCN.noticeicon);
notice.insertBefore(icon, noticemessage);
}
if (options.btn || options.button) notice.appendChild(BDFDB.DOMUtils.create(``));
if (options.id) notice.id = options.id.split(" ").join("");
if (options.selector) BDFDB.DOMUtils.addClass(notice, options.selector);
if (options.css) BDFDB.DOMUtils.appendLocalStyle("BDFDBcustomnotificationbar" + id, options.css);
if (options.style) notice.style = options.style;
if (options.html === true) noticemessage.innerHTML = text;
else {
var link = document.createElement("a");
var newtext = [];
for (let word of text.split(" ")) {
var encodedword = BDFDB.StringUtils.htmlEscape(word);
link.href = word;
newtext.push(link.host && link.host !== window.location.host ? `` : encodedword);
}
noticemessage.innerHTML = newtext.join(" ");
}
var type = null;
if (options.type && !document.querySelector(BDFDB.dotCNS.chatbase + BDFDB.dotCN.noticestreamer)) {
if (type = BDFDB.disCN["notice" + options.type]) BDFDB.DOMUtils.addClass(notice, type);
if (options.type == "premium") {
var noticebutton = notice.querySelector(BDFDB.dotCN.noticebutton);
if (noticebutton) BDFDB.DOMUtils.addClass(noticebutton, BDFDB.disCN.noticepremiumaction);
BDFDB.DOMUtils.addClass(noticemessage, BDFDB.disCN.noticepremiumtext);
notice.insertBefore(BDFDB.DOMUtils.create(``), noticemessage);
}
}
if (!type) {
var comp = BDFDB.ColorUtils.convert(options.color, "RGBCOMP");
if (comp) {
var fontcolor = comp[0] > 180 && comp[1] > 180 && comp[2] > 180 ? "#000" : "#FFF";
var backgroundcolor = BDFDB.ColorUtils.convert(comp, "HEX");
var filter = comp[0] > 180 && comp[1] > 180 && comp[2] > 180 ? "brightness(0%)" : "brightness(100%)";
BDFDB.DOMUtils.appendLocalStyle("BDFDBcustomnotificationbarColorCorrection" + id, `${BDFDB.dotCN.noticewrapper}[notice-id="${id}"]{background-color:${backgroundcolor} !important;}${BDFDB.dotCN.noticewrapper}[notice-id="${id}"] .notice-message {color:${fontcolor} !important;}${BDFDB.dotCN.noticewrapper}[notice-id="${id}"] ${BDFDB.dotCN.noticebutton} {color:${fontcolor} !important;border-color:${BDFDB.ColorUtils.setAlpha(fontcolor,0.25,"RGBA")} !important;}${BDFDB.dotCN.noticewrapper}[notice-id="${id}"] ${BDFDB.dotCN.noticebutton}:hover {color:${backgroundcolor} !important;background-color:${fontcolor} !important;}${BDFDB.dotCN.noticewrapper}[notice-id="${id}"] ${BDFDB.dotCN.noticedismiss} {filter:${filter} !important;}`);
}
else BDFDB.DOMUtils.addClass(notice, BDFDB.disCN.noticedefault);
}
notice.style.setProperty("height", "36px", "important");
notice.style.setProperty("min-width", "70vw", "important");
notice.style.setProperty("left", "unset", "important");
notice.style.setProperty("right", "unset", "important");
let sidemargin = ((BDFDB.DOMUtils.getWidth(document.body.firstElementChild) - BDFDB.DOMUtils.getWidth(notice))/2);
notice.style.setProperty("left", sidemargin + "px", "important");
notice.style.setProperty("right", sidemargin + "px", "important");
notice.style.setProperty("min-width", "unset", "important");
notice.style.setProperty("width", "unset", "important");
notice.style.setProperty("max-width", "calc(100vw - " + (sidemargin*2) + "px)", "important");
notice.querySelector(BDFDB.dotCN.noticedismiss).addEventListener("click", _ => {
notice.style.setProperty("overflow", "hidden", "important");
notice.style.setProperty("height", "0px", "important");
BDFDB.TimeUtils.timeout(_ => {
BDFDB.ArrayUtils.remove(NotificationBars, id);
BDFDB.DOMUtils.removeLocalStyle("BDFDBcustomnotificationbar" + id);
BDFDB.DOMUtils.removeLocalStyle("BDFDBcustomnotificationbarColorCorrection" + id);
notice.remove();
}, 500);
});
return notice;
};
BDFDB.NotificationUtils.alert = function (header, body) {
if (typeof header == "string" && typeof header == "string" && window.BdApi && typeof BdApi.alert == "function") BdApi.alert(header, body);
};
var Tooltips = [];
BDFDB.TooltipUtils = {};
BDFDB.TooltipUtils.create = function (anker, text, options = {}) {
var itemlayercontainer = document.querySelector(BDFDB.dotCN.appmount + " > * > " + BDFDB.dotCN.itemlayercontainer);
if (!itemlayercontainer || (typeof text != "string" && !BDFDB.ObjectUtils.is(options.guild)) || !Node.prototype.isPrototypeOf(anker) || !document.contains(anker)) return null;
var id = BDFDB.NumberUtils.generateId(Tooltips);
var itemlayer = BDFDB.DOMUtils.create(`
`);
itemlayercontainer.appendChild(itemlayer);
var tooltip = itemlayer.firstElementChild;
if (options.id) tooltip.id = options.id.split(" ").join("");
if (!options.type || !BDFDB.disCN["tooltip" + options.type.toLowerCase()]) options.type = "top";
BDFDB.DOMUtils.addClass(tooltip, BDFDB.disCN["tooltip" + options.type.toLowerCase()]);
tooltip.type = options.type.toLowerCase();
let fontColorIsGradient = false, customBackgroundColor = false, style = "";
if (options.style) style += options.style;
if (options.fontColor) {
fontColorIsGradient = BDFDB.ObjectUtils.is(options.fontColor);
if (!fontColorIsGradient) style = (style ? (style + " ") : "") + `color: ${BDFDB.ColorUtils.convert(options.fontColor, "RGBA")} !important;`
}
if (options.backgroundColor) {
customBackgroundColor = true;
let backgroundColorIsGradient = BDFDB.ObjectUtils.is(options.backgroundColor);
let backgroundColor = !backgroundColorIsGradient ? BDFDB.ColorUtils.convert(options.backgroundColor, "RGBA") : BDFDB.ColorUtils.createGradient(options.backgroundColor);
style = (style ? (style + " ") : "") + `background: ${backgroundColor} !important; border-color: ${backgroundColorIsGradient ? BDFDB.ColorUtils.convert(options.backgroundColor[options.type == "left" ? 100 : 0], "RGBA") : backgroundColor} !important;`;
}
if (style) tooltip.style = style;
if (customBackgroundColor) BDFDB.DOMUtils.addClass(tooltip, BDFDB.disCN.tooltipcustom);
else if (options.color && BDFDB.disCN["tooltip" + options.color.toLowerCase()]) BDFDB.DOMUtils.addClass(tooltip, BDFDB.disCN["tooltip" + options.color.toLowerCase()]);
else BDFDB.DOMUtils.addClass(tooltip, BDFDB.disCN.tooltipblack);
if (options.list || BDFDB.ObjectUtils.is(options.guild)) BDFDB.DOMUtils.addClass(tooltip, BDFDB.disCN.tooltiplistitem);
if (options.selector) BDFDB.DOMUtils.addClass(tooltip, options.selector);
if (BDFDB.ObjectUtils.is(options.guild)) {
let streamOwnerIds = LibraryModules.StreamUtils.getAllApplicationStreams().filter(app => app.guildId === options.guild.id).map(app => app.ownerId);
let streamOwners = streamOwnerIds.map(ownerId => LibraryModules.UserStore.getUser(ownerId));
let connectedUsers = Object.keys(LibraryModules.VoiceUtils.getVoiceStates(options.guild.id)).map(userId => !streamOwnerIds.includes(userId) && BDFDB.LibraryModules.UserStore.getUser(userId));
let tooltiptext = text || options.guild.toString();
if (fontColorIsGradient) tooltiptext = `${BDFDB.StringUtils.htmlEscape(tooltiptext)}`;
BDFDB.ReactUtils.render(BDFDB.ReactUtils.createElement(BDFDB.ReactUtils.Fragment, {
children: [
BDFDB.ReactUtils.createElement("div", {
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN.tooltiprow, BDFDB.disCN.tooltiprowguildname),
children: [
BDFDB.ReactUtils.createElement(LibraryComponents.GuildComponents.Badge, {
guild: options.guild,
size: LibraryModules.StringUtils.cssValueToNumber(DiscordClassModules.TooltipGuild.iconSize),
className: BDFDB.disCN.tooltiprowicon
}),
BDFDB.ReactUtils.createElement("span", {
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN.tooltipguildnametext, (connectedUsers.length || streamOwners.length) && BDFDB.disCN.tooltipguildnametextlimitedsize),
children: fontColorIsGradient || options.html ? BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(tooltiptext)) : tooltiptext
})
]
}),
connectedUsers.length ? BDFDB.ReactUtils.createElement("div", {
className: BDFDB.disCN.tooltiprow,
children: [
BDFDB.ReactUtils.createElement(LibraryComponents.SvgIcon, {
name: LibraryComponents.SvgIcon.Names.SPEAKER,
className: BDFDB.disCN.tooltipactivityicon
}),
BDFDB.ReactUtils.createElement(LibraryComponents.UserSummaryItem, {
users: connectedUsers,
max: 6
})
]
}) : null,
streamOwners.length ? BDFDB.ReactUtils.createElement("div", {
className: BDFDB.disCN.tooltiprow,
children: [
BDFDB.ReactUtils.createElement(LibraryComponents.SvgIcon, {
name: LibraryComponents.SvgIcon.Names.STREAM,
className: BDFDB.disCN.tooltipactivityicon
}),
BDFDB.ReactUtils.createElement(LibraryComponents.UserSummaryItem, {
users: streamOwners,
max: 6
})
]
}) : null
].filter(n => n)
}), tooltip);
}
else {
if (fontColorIsGradient) tooltip.innerHTML = `${BDFDB.StringUtils.htmlEscape(text)}`;
else if (options.html === true) tooltip.innerHTML = text;
else tooltip.innerText = text;
}
tooltip.appendChild(BDFDB.DOMUtils.create(``));
tooltip.anker = anker;
if (options.hide) BDFDB.DOMUtils.appendLocalStyle("BDFDBhideOtherTooltips" + id, `#app-mount ${BDFDB.dotCN.tooltip}:not([tooltip-id="${id}"]) {display: none !important;}`, itemlayercontainer);
var mouseleave = _ => {
BDFDB.DOMUtils.remove(itemlayer);
};
anker.addEventListener("mouseleave", mouseleave);
var observer = new MutationObserver(changes => {
changes.forEach(change => {
var nodes = Array.from(change.removedNodes);
var ownmatch = nodes.indexOf(itemlayer) > -1;
var ankermatch = nodes.indexOf(anker) > -1;
var parentmatch = nodes.some(n => n.contains(anker));
if (ownmatch || ankermatch || parentmatch) {
BDFDB.ArrayUtils.remove(Tooltips, id);
observer.disconnect();
BDFDB.DOMUtils.remove(itemlayer);
BDFDB.DOMUtils.removeLocalStyle("BDFDBhideOtherTooltips" + id, itemlayercontainer);
anker.removeEventListener("mouseleave", mouseleave);
}
});
});
observer.observe(document.body, {subtree:true, childList:true});
BDFDB.TooltipUtils.update(tooltip);
if (options.delay) {
BDFDB.DOMUtils.toggle(itemlayer);
BDFDB.TimeUtils.timeout(_ => {BDFDB.DOMUtils.toggle(itemlayer);}, options.delay);
}
return itemlayer;
};
BDFDB.TooltipUtils.update = function (tooltip) {
if (!Node.prototype.isPrototypeOf(tooltip)) return;
let itemlayer = BDFDB.DOMUtils.getParent(BDFDB.dotCN.itemlayer, tooltip);
if (!Node.prototype.isPrototypeOf(itemlayer)) return;
tooltip = itemlayer.querySelector(BDFDB.dotCN.tooltip);
if (!Node.prototype.isPrototypeOf(tooltip) || !Node.prototype.isPrototypeOf(tooltip.anker) || !tooltip.type) return;
var pointer = tooltip.querySelector(BDFDB.dotCN.tooltippointer);
var left, top, trects = BDFDB.DOMUtils.getRects(tooltip.anker), irects = BDFDB.DOMUtils.getRects(itemlayer), arects = BDFDB.DOMUtils.getRects(document.querySelector(BDFDB.dotCN.appmount)), positionoffsets = {height: 10, width: 10};
switch (tooltip.type) {
case "top":
top = trects.top - irects.height - positionoffsets.height + 2;
left = trects.left + (trects.width - irects.width) / 2;
break;
case "bottom":
top = trects.top + trects.height + positionoffsets.height - 2;
left = trects.left + (trects.width - irects.width) / 2;
break;
case "left":
top = trects.top + (trects.height - irects.height) / 2;
left = trects.left - irects.width - positionoffsets.width + 2;
break;
case "right":
top = trects.top + (trects.height - irects.height) / 2;
left = trects.left + trects.width + positionoffsets.width - 2;
break;
}
itemlayer.style.setProperty("top", top + "px");
itemlayer.style.setProperty("left", left + "px");
pointer.style.removeProperty("margin-left");
pointer.style.removeProperty("margin-top");
if (tooltip.type == "top" || tooltip.type == "bottom") {
if (left < 0) {
itemlayer.style.setProperty("left", "5px");
pointer.style.setProperty("margin-left", `${left - 10}px`);
}
else {
var rightmargin = arects.width - (left + irects.width);
if (rightmargin < 0) {
itemlayer.style.setProperty("left", arects.width - irects.width - 5 + "px");
pointer.style.setProperty("margin-left", `${-1*rightmargin}px`);
}
}
}
else if (tooltip.type == "left" || tooltip.type == "right") {
if (top < 0) {
itemlayer.style.setProperty("top", "5px");
pointer.style.setProperty("margin-top", `${top - 10}px`);
}
else {
var bottommargin = arects.height - (top + irects.height);
if (bottommargin < 0) {
itemlayer.style.setProperty("top", arects.height - irects.height - 5 + "px");
pointer.style.setProperty("margin-top", `${-1*bottommargin}px`);
}
}
}
};
BDFDB.ObjectUtils = {};
BDFDB.ObjectUtils.is = function (obj) {
return obj && Object.prototype.isPrototypeOf(obj) && !Array.prototype.isPrototypeOf(obj);
};
BDFDB.ObjectUtils.extract = function (obj, ...keys) {
let newobj = {};
if (BDFDB.ObjectUtils.is(obj)) for (let key of keys.flat(10).filter(n => n)) if (obj[key]) newobj[key] = obj[key];
return newobj;
};
BDFDB.ObjectUtils.exclude = function (obj, ...keys) {
let newobj = Object.assign({}, obj);
BDFDB.ObjectUtils.delete(newobj, ...keys)
return newobj;
};
BDFDB.ObjectUtils.delete = function (obj, ...keys) {
if (BDFDB.ObjectUtils.is(obj)) for (let key of keys.flat(10).filter(n => n)) delete obj[key];
};
BDFDB.ObjectUtils.sort = function (obj, sort, except) {
if (!BDFDB.ObjectUtils.is(obj)) return {};
var newobj = {};
if (sort === undefined || !sort) for (let key of Object.keys(obj).sort()) newobj[key] = obj[key];
else {
let values = [];
for (let key in obj) values.push(obj[key]);
values = BDFDB.ArrayUtils.keySort(values, sort, except);
for (let value of values) for (let key in obj) if (BDFDB.equals(value, obj[key])) {
newobj[key] = value;
break;
}
}
return newobj;
};
BDFDB.ObjectUtils.reverse = function (obj, sort) {
if (!BDFDB.ObjectUtils.is(obj)) return {};
var newobj = {};
for (let key of (sort === undefined || !sort) ? Object.keys(obj).reverse() : Object.keys(obj).sort().reverse()) newobj[key] = obj[key];
return newobj;
};
BDFDB.ObjectUtils.filter = function (obj, filter, bykey = false) {
if (!BDFDB.ObjectUtils.is(obj)) return {};
if (typeof filter != "function") return obj;
return Object.keys(obj).filter(key => filter(bykey ? key : obj[key])).reduce((newobj, key) => (newobj[key] = obj[key], newobj), {});
};
BDFDB.ObjectUtils.push = function (obj, value) {
if (BDFDB.ObjectUtils.is(obj)) obj[Object.keys(obj).length] = value;
};
BDFDB.ObjectUtils.pop = function (obj, value) {
if (BDFDB.ObjectUtils.is(obj)) {
let keys = Object.keys(obj);
if (!keys.length) return;
let value = obj[keys[keys.length-1]];
delete obj[keys[keys.length-1]];
return value;
}
};
BDFDB.ObjectUtils.map = function (obj, mapfunc) {
if (!BDFDB.ObjectUtils.is(obj)) return {};
if (typeof mapfunc != "string" && typeof mapfunc != "function") return obj;
var newobj = {};
for (let key in obj) if (BDFDB.ObjectUtils.is(obj[key])) newobj[key] = typeof mapfunc == "string" ? obj[key][mapfunc] : mapfunc(obj[key], key);
return newobj;
};
BDFDB.ObjectUtils.toArray = function (obj) {
if (!BDFDB.ObjectUtils.is(obj)) return [];
return Object.entries(obj).map(n => n[1]);
};
BDFDB.ObjectUtils.deepAssign = function (obj, ...objs) {
if (!objs.length) return obj;
var nextobj = objs.shift();
if (BDFDB.ObjectUtils.is(obj) && BDFDB.ObjectUtils.is(nextobj)) {
for (var key in nextobj) {
if (BDFDB.ObjectUtils.is(nextobj[key])) {
if (!obj[key]) Object.assign(obj, {[key]:{}});
BDFDB.ObjectUtils.deepAssign(obj[key], nextobj[key]);
}
else Object.assign(obj, {[key]:nextobj[key]});
}
}
return BDFDB.ObjectUtils.deepAssign(obj, ...objs);
};
BDFDB.ObjectUtils.isEmpty = function (obj) {
return !BDFDB.ObjectUtils.is(obj) || Object.getOwnPropertyNames(obj).length == 0;
};
BDFDB.ArrayUtils = {};
BDFDB.ArrayUtils.is = function (array) {
return array && Array.isArray(array);
};
BDFDB.ArrayUtils.keySort = function (array, key, except) {
if (!BDFDB.ArrayUtils.is(array)) return [];
if (key == null) return array;
if (except === undefined) except = null;
return array.sort(function (x, y) {
var xvalue = x[key], yvalue = y[key];
if (xvalue !== except) return xvalue < yvalue ? -1 : xvalue > yvalue ? 1 : 0;
});
};
BDFDB.ArrayUtils.numSort = function (array) {
return array.sort(function (x, y) {return x < y ? -1 : x > y ? 1 : 0;});
};
BDFDB.ArrayUtils.remove = function (array, value, all = false) {
if (!BDFDB.ArrayUtils.is(array)) return [];
if (!array.includes(value)) return array;
if (!all) array.splice(array.indexOf(value), 1);
else while (array.indexOf(value) > -1) array.splice(array.indexOf(value), 1);
return array;
};
BDFDB.ArrayUtils.getAllIndexes = function (array, value) {
if (!BDFDB.ArrayUtils.is(array) && typeof array != "string") return [];
var indexes = [], index = -1;
while ((index = array.indexOf(value, index + 1)) !== -1) indexes.push(index);
return indexes;
};
BDFDB.ArrayUtils.removeCopies = function (array) {
if (!BDFDB.ArrayUtils.is(array)) return [];
return [...new Set(array)];
};
BDFDB.ModuleUtils = {};
BDFDB.ModuleUtils.cached = {};
BDFDB.ModuleUtils.find = function (filter, getExport) {
getExport = typeof getExport != "boolean" ? true : getExport;
var req = InternalBDFDB.getWebModuleReq();
for (let i in req.c) if (req.c.hasOwnProperty(i)) {
var m = req.c[i].exports;
if (m && (typeof m == "object" || typeof m == "function") && filter(m)) return getExport ? m : req.c[i];
if (m && m.__esModule) for (let j in m) if (m[j] && (typeof m[j] == "object" || typeof m[j] == "function") && filter(m[j])) return getExport ? m[j] : req.c[i];
}
};
BDFDB.ModuleUtils.findByProperties = function (...properties) {
properties = properties.flat(10);
let getExport = properties.pop();
if (typeof getExport != "boolean") {
properties.push(getExport);
getExport = true;
}
return InternalBDFDB.findModule("prop", JSON.stringify(properties), m => properties.every(prop => m[prop] !== undefined), getExport);
};
BDFDB.ModuleUtils.findByName = function (name, getExport) {
return InternalBDFDB.findModule("name", JSON.stringify(name), m => m.displayName === name, typeof getExport != "boolean" ? true : getExport);
};
BDFDB.ModuleUtils.findByString = function (...strings) {
strings = strings.flat(10);
let getExport = strings.pop();
if (typeof getExport != "boolean") {
strings.push(getExport);
getExport = true;
}
return InternalBDFDB.findModule("string", JSON.stringify(strings), m => strings.every(string => typeof m == "function" && (m.toString().indexOf(string) > -1 || m.originalsource && m.originalsource.toString().indexOf(string) > -1)), getExport);
};
BDFDB.ModuleUtils.findByPrototypes = function (...protoprops) {
protoprops = protoprops.flat(10);
let getExport = protoprops.pop();
if (typeof getExport != "boolean") {
protoprops.push(getExport);
getExport = true;
}
return InternalBDFDB.findModule("proto", JSON.stringify(protoprops), m => m.prototype && protoprops.every(prop => m.prototype[prop] !== undefined), getExport);
};
InternalBDFDB.findModule = function (type, cachestring, filter, getExport) {
if (!BDFDB.ObjectUtils.is(BDFDB.ModuleUtils.cached[type])) BDFDB.ModuleUtils.cached[type] = {module:{}, export:{}};
if (getExport && BDFDB.ModuleUtils.cached[type].export[cachestring]) return BDFDB.ModuleUtils.cached[type].export[cachestring];
else if (!getExport && BDFDB.ModuleUtils.cached[type].module[cachestring]) return BDFDB.ModuleUtils.cached[type].module[cachestring];
else {
var m = BDFDB.ModuleUtils.find(filter, getExport);
if (m) {
if (getExport) BDFDB.ModuleUtils.cached[type].export[cachestring] = m;
else BDFDB.ModuleUtils.cached[type].module[cachestring] = m;
return m;
}
else BDFDB.LogUtils.warn(`${cachestring} [${type}] not found in WebModules`);
}
};
InternalBDFDB.getWebModuleReq = function () {
if (!InternalBDFDB.getWebModuleReq.req) {
const id = "BDFDB-WebModules";
const req = window.webpackJsonp.push([[], {[id]: (module, exports, req) => module.exports = req}, [[id]]]);
delete req.m[id];
delete req.c[id];
InternalBDFDB.getWebModuleReq.req = req;
}
return InternalBDFDB.getWebModuleReq.req;
};
var WebModulesData = {};
WebModulesData.Patchtypes = ["before", "instead", "after"];
WebModulesData.Patchmap = {
BannedCard: "BannedUser",
InvitationCard: "InviteRow",
InviteCard: "InviteRow",
MemberCard: "Member",
PopoutContainer: "Popout",
QuickSwitchChannelResult: "Channel",
QuickSwitchGuildResult: "Guild",
QuickSwitchResult: "Result",
WebhookCard: "Webhook"
};
WebModulesData.Forceobserve = [
"GuildIcon",
"QuickSwitchChannelResult",
"QuickSwitchGuildResult"
];
WebModulesData.Patchfinder = {
Account: "accountinfo",
App: "app",
AppSkeleton: "app",
AppView: "appcontainer",
AuthWrapper: "loginscreen",
BannedCard: "guildsettingsbannedcard",
ChannelMember: "member",
EmojiPicker: "emojipicker",
FriendRow: "friendsrow",
Guild: "guildouter",
GuildIcon: "avataricon",
GuildSidebar: "guildchannels",
I18nLoaderWrapper: "app",
InstantInviteModal: "invitemodalwrapper",
InvitationCard: "invitemodalinviterow",
InviteCard: "guildsettingsinvitecard",
PopoutContainer: "popout",
PrivateChannelCall: "callcurrentcontainer",
PrivateChannelsList: "dmchannelsscroller",
QuickSwitchChannelResult: "quickswitchresult",
QuickSwitchGuildResult: "quickswitchresult",
QuickSwitchResult: "quickswitchresult",
MemberCard: "guildsettingsmembercard",
MutualGuilds: "userprofilebody",
MutualFriends: "userprofilebody",
NameTag: "nametag",
Note: "usernote",
SearchResults: "searchresultswrap",
TypingUsers: "typing",
UnreadDMs: "guildsscroller",
UserPopout: "userpopout",
V2C_ContentColumn: "contentcolumn",
V2C_List: "_repolist",
V2C_PluginCard: "_repoheader",
V2C_ThemeCard: "_repoheader"
};
WebModulesData.GlobalModules = {};
try {WebModulesData.GlobalModules["V2C_ContentColumn"] = V2C_ContentColumn;} catch(err) {BDFDB.LogUtils.warn(`Could not find global Module "V2C_ContentColumn"`);}
try {WebModulesData.GlobalModules["V2C_List"] = V2C_List;} catch(err) {BDFDB.LogUtils.warn(`Could not find global Module "V2C_List"`);}
try {WebModulesData.GlobalModules["V2C_PluginCard"] = V2C_PluginCard;} catch(err) {BDFDB.LogUtils.warn(`Could not find global Module "V2C_PluginCard"`);}
try {WebModulesData.GlobalModules["V2C_ThemeCard"] = V2C_ThemeCard;} catch(err) {BDFDB.LogUtils.warn(`Could not find global Module "V2C_ThemeCard"`);}
BDFDB.ModuleUtils.isPatched = function (plugin, module, modulefunction) {
if (!plugin || !BDFDB.ObjectUtils.is(module) || !module.BDFDBpatch || !modulefunction) return false;
const pluginid = (typeof plugin === "string" ? plugin : plugin.name).toLowerCase();
return pluginid && module[modulefunction] && module[modulefunction].isBDFDBpatched && module.BDFDBpatch[modulefunction] && Object.keys(module.BDFDBpatch[modulefunction]).some(patchfunc => Object.keys(module.BDFDBpatch[modulefunction][patchfunc]).includes(pluginid));
};
BDFDB.ModuleUtils.patch = function (plugin, module, modulefunctions, patchfunctions, forceRepatch = false) {
if (!plugin || !BDFDB.ObjectUtils.is(module) || !modulefunctions || !BDFDB.ObjectUtils.is(patchfunctions)) return null;
patchfunctions = BDFDB.ObjectUtils.filter(patchfunctions, type => WebModulesData.Patchtypes.includes(type), true);
if (BDFDB.ObjectUtils.isEmpty(patchfunctions)) return null;
const pluginname = typeof plugin === "string" ? plugin : plugin.name;
const pluginid = pluginname.toLowerCase();
if (!module.BDFDBpatch) module.BDFDBpatch = {};
modulefunctions = [modulefunctions].flat(10).filter(n => n);
for (let modulefunction of modulefunctions) {
if (!module.BDFDBpatch[modulefunction] || forceRepatch && !module[modulefunction].isBDFDBpatched) {
if (!module.BDFDBpatch[modulefunction]) {
module.BDFDBpatch[modulefunction] = {};
for (let type of WebModulesData.Patchtypes) module.BDFDBpatch[modulefunction][type] = {};
}
if (!module[modulefunction]) module[modulefunction] = _ => {};
const originalfunction = module[modulefunction];
module.BDFDBpatch[modulefunction].originalMethod = originalfunction;
module[modulefunction] = function () {
let callInstead = false, stopCall = false;
const data = {
thisObject: this,
methodArguments: arguments,
originalMethod: originalfunction,
originalMethodName: modulefunction,
callOriginalMethod: _ => {if (!stopCall) data.returnValue = data.originalMethod.apply(data.thisObject, data.methodArguments)},
callOriginalMethodAfterwards: _ => {callInstead = true;},
stopOriginalMethodCall: _ => {stopCall = true;}
};
if (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded && module.BDFDBpatch[modulefunction]) {
if (!BDFDB.ObjectUtils.isEmpty(module.BDFDBpatch[modulefunction].before)) for (let id in BDFDB.ObjectUtils.sort(module.BDFDBpatch[modulefunction].before)) {
BDFDB.TimeUtils.suppress(module.BDFDBpatch[modulefunction].before[id], `"before" callback of ${modulefunction} in ${module.constructor ? module.constructor.displayName || module.constructor.name : "module"}`, module.BDFDBpatch[modulefunction].before[id].pluginname)(data);
}
let hasInsteadPatches = !BDFDB.ObjectUtils.isEmpty(module.BDFDBpatch[modulefunction].instead);
if (hasInsteadPatches) for (let id in BDFDB.ObjectUtils.sort(module.BDFDBpatch[modulefunction].instead)) {
let tempreturn = BDFDB.TimeUtils.suppress(module.BDFDBpatch[modulefunction].instead[id], `"instead" callback of ${modulefunction} in ${module.constructor ? module.constructor.displayName || module.constructor.name : "module"}`, module.BDFDBpatch[modulefunction].instead[id].pluginname)(data);
if (tempreturn !== undefined) data.returnValue = tempreturn;
}
if ((!hasInsteadPatches || callInstead) && !stopCall) BDFDB.TimeUtils.suppress(data.callOriginalMethod, `originalMethod of ${modulefunction} in ${module.constructor ? module.constructor.displayName || module.constructor.name : "module"}`)();
if (!BDFDB.ObjectUtils.isEmpty(module.BDFDBpatch[modulefunction].after)) for (let id in BDFDB.ObjectUtils.sort(module.BDFDBpatch[modulefunction].after)) {
let tempreturn = BDFDB.TimeUtils.suppress(module.BDFDBpatch[modulefunction].after[id], `"after" callback of ${modulefunction} in ${module.constructor ? module.constructor.displayName || module.constructor.name : "module"}`, module.BDFDBpatch[modulefunction].after[id].pluginname)(data);
if (tempreturn !== undefined) data.returnValue = tempreturn;
}
}
else BDFDB.TimeUtils.suppress(data.callOriginalMethod, `originalMethod of ${modulefunction} in ${module.constructor ? module.constructor.displayName || module.constructor.name : "module"}`)();
callInstead = false, stopCall = false;
return modulefunction == "render" && data.returnValue === undefined ? null : data.returnValue;
};
module[modulefunction].originalsource = originalfunction;
module[modulefunction].isBDFDBpatched = true;
}
for (let type in patchfunctions) if (typeof patchfunctions[type] == "function") {
module.BDFDBpatch[modulefunction][type][pluginid] = patchfunctions[type];
module.BDFDBpatch[modulefunction][type][pluginid].pluginname = pluginname;
}
}
let cancel = _ => {BDFDB.ModuleUtils.unpatch(plugin, module, modulefunctions);};
if (BDFDB.ObjectUtils.is(plugin)) {
if (!BDFDB.ArrayUtils.is(plugin.patchCancels)) plugin.patchCancels = [];
plugin.patchCancels.push(cancel);
}
return cancel;
};
BDFDB.ModuleUtils.unpatch = function (plugin, module, modulefunctions) {
if (!module && !modulefunctions) {
if (BDFDB.ObjectUtils.is(plugin) && BDFDB.ArrayUtils.is(plugin.patchCancels)) {
for (let cancel of plugin.patchCancels) cancel();
plugin.patchCancels = [];
}
}
else {
if (!BDFDB.ObjectUtils.is(module) || !module.BDFDBpatch) return;
const pluginname = !plugin ? null : (typeof plugin === "string" ? plugin : plugin.name).toLowerCase();
if (modulefunctions) {
for (let modulefunction of [modulefunctions].flat(10).filter(n => n)) if (module[modulefunction] && module.BDFDBpatch[modulefunction]) unpatch(modulefunction, pluginname);
}
else for (let patchedfunction of module.BDFDBpatch) unpatch(patchedfunction, pluginname);
}
function unpatch (func, pluginname) {
for (let type of WebModulesData.Patchtypes) {
if (pluginname) delete module.BDFDBpatch[func][type][pluginname];
else delete module.BDFDBpatch[func][type];
}
var empty = true;
for (let type of WebModulesData.Patchtypes) if (!BDFDB.ObjectUtils.isEmpty(module.BDFDBpatch[func][type])) empty = false;
if (empty) {
module[func] = module.BDFDBpatch[func].originalMethod;
delete module.BDFDBpatch[func];
if (BDFDB.ObjectUtils.isEmpty(module.BDFDBpatch)) delete module.BDFDBpatch;
}
}
};
BDFDB.ModuleUtils.forceAllUpdates = function (plugin, selectedtypes) {
if (BDFDB.ObjectUtils.is(plugin) && BDFDB.ObjectUtils.is(plugin.patchedModules)) {
const app = document.querySelector(BDFDB.dotCN.app);
const bdsettings = document.querySelector("#bd-settingspane-container " + BDFDB.dotCN.scrollerwrap);
if (app) {
let filteredmodules = [], patchtypes = {};
for (let patchtype in plugin.patchedModules) for (let type in plugin.patchedModules[patchtype]) {
let methodnames = [plugin.patchedModules[patchtype][type]].flat(10).filter(n => n);
if (methodnames.includes("componentDidMount") || methodnames.includes("componentDidUpdate") || methodnames.includes("render")) {
filteredmodules.push(type);
let unmappedtype = type.split(" _ _ ")[0];
if (!patchtypes[unmappedtype]) patchtypes[unmappedtype] = [];
patchtypes[unmappedtype].push(patchtype);
}
}
selectedtypes = [selectedtypes].flat(10).filter(n => n);
if (selectedtypes.length) {
selectedtypes = selectedtypes.map(type => type && WebModulesData.Patchmap[type] ? WebModulesData.Patchmap[type] + " _ _ " + type : type);
filteredmodules = filteredmodules.filter(type => selectedtypes.indexOf(type) > -1);
}
filteredmodules = BDFDB.ArrayUtils.removeCopies(filteredmodules);
if (filteredmodules.length) {
try {
const appinsdown = BDFDB.ReactUtils.findOwner(app, {name:filteredmodules, all:true, group:true, unlimited:true});
const appinsup = BDFDB.ReactUtils.findOwner(app, {name:filteredmodules, all:true, group:true, unlimited:true, up:true});
for (let type in appinsdown) for (let ins of appinsdown[type]) InternalBDFDB.forceInitiateProcess(plugin, ins, type, patchtypes[type]);
for (let type in appinsup) for (let ins of appinsup[type]) InternalBDFDB.forceInitiateProcess(plugin, ins, type, patchtypes[type]);
if (bdsettings) {
const bdsettingsins = BDFDB.ReactUtils.findOwner(bdsettings, {name:filteredmodules, all:true, group:true, unlimited:true});
for (let type in bdsettingsins) for (let ins of bdsettingsins[type]) InternalBDFDB.forceInitiateProcess(plugin, ins, type, patchtypes[type]);
}
}
catch (err) {BDFDB.LogUtils.error("Could not force update components! " + err, plugin.name);}
}
}
}
};
InternalBDFDB.forceInitiateProcess = function (plugin, instance, type, patchtypes) {
if (!plugin || !instance || !type) return;
let methodnames = [];
for (let patchtype in plugin.patchedModules) if (plugin.patchedModules[patchtype][type]) methodnames.push(plugin.patchedModules[patchtype][type]);
methodnames = BDFDB.ArrayUtils.removeCopies(methodnames).flat(10).filter(n => n);
if (methodnames.includes("componentDidMount")) InternalBDFDB.initiateProcess(plugin, type, {instance, methodname:"componentDidMount", patchtypes});
if (methodnames.includes("render")) BDFDB.ReactUtils.forceUpdate(instance);
else if (methodnames.includes("componentDidUpdate")) InternalBDFDB.initiateProcess(plugin, type, {instance, methodname:"componentDidUpdate", patchtypes});
};
InternalBDFDB.initiateProcess = function (plugin, type, e) {
if (BDFDB.ObjectUtils.is(plugin) && !plugin.stopping && e.instance) {
// REMOVE
let isLib = plugin.name == "$BDFDB";
if (plugin.name == "$BDFDB") plugin = BDFDBprocessFunctions;
type = (type.split(" _ _ ")[1] || type).replace(/[^A-z0-9]|_/g, "");
type = type.charAt(0).toUpperCase() + type.slice(1);
if (typeof plugin["process" + type] == "function") {
// REMOVE
let isOldType = !isLib && plugin["process" + type].toString().split("\n")[0].replace(/ /g, "").split(",").length > 1;
if (isOldType) {
if (e.methodname == "render") {
if (e.returnvalue) plugin["process" + type](e.instance, null, e.returnvalue, [e.methodname]);
}
else {
let wrapper = BDFDB.ReactUtils.findDOMNode(e.instance);
if (wrapper) plugin["process" + type](e.instance, wrapper, e.returnvalue, [e.methodname]);
else BDFDB.TimeUtils.timeout(_ => {
wrapper = BDFDB.ReactUtils.findDOMNode(e.instance);
if (wrapper) plugin["process" + type](e.instance, wrapper, e.returnvalue, [e.methodname]);
});
}
}
else {
if (e.methodname == "render") {
if (e.returnvalue || e.patchtypes.includes("before")) plugin["process" + type](e);
}
else {
e.node = BDFDB.ReactUtils.findDOMNode(e.instance);
if (e.node) plugin["process" + type](e);
else BDFDB.TimeUtils.timeout(_ => {
e.node = BDFDB.ReactUtils.findDOMNode(e.instance);
if (e.node) plugin["process" + type](e);
});
}
}
}
}
};
InternalBDFDB.patchPlugin = function (plugin) {
if (!BDFDB.ObjectUtils.is(plugin) || !BDFDB.ObjectUtils.is(plugin.patchedModules)) return;
BDFDB.ModuleUtils.unpatch(plugin);
for (let patchtype in plugin.patchedModules) for (let type in plugin.patchedModules[patchtype]) {
if (WebModulesData.GlobalModules[type] && typeof WebModulesData.GlobalModules[type] == "function") patchInstance(WebModulesData.GlobalModules[type], type, patchtype);
else {
let mapped = WebModulesData.Patchmap[type];
let classname = WebModulesData.Patchfinder[type.split(" _ _ ")[1] || type];
let mappedtype = mapped ? mapped + " _ _ " + type : type;
if (mapped) {
plugin.patchedModules[patchtype][mappedtype] = plugin.patchedModules[patchtype][type];
delete plugin.patchedModules[patchtype][type];
}
if (!classname) patchInstance(BDFDB.ModuleUtils.findByName(mappedtype.split(" _ _ ")[0]), mappedtype, patchtype);
else if (DiscordClasses[classname]) checkForInstance(classname, mappedtype, patchtype, WebModulesData.Forceobserve.includes(type.split(" _ _ ")[1] || type));
}
}
function patchInstance(instance, type, patchtype) {
if (instance) {
var name = type.split(" _ _ ")[0];
instance = instance._reactInternalFiber && instance._reactInternalFiber.type ? instance._reactInternalFiber.type : instance;
instance = instance.displayName == name || instance.name == name ? instance : (BDFDB.ReactUtils.findConstructor(instance, name) || BDFDB.ReactUtils.findConstructor(instance, name, {up:true}));
if (instance) {
instance = instance._reactInternalFiber && instance._reactInternalFiber.type ? instance._reactInternalFiber.type : instance;
let patchfunctions = {};
patchfunctions[patchtype] = e => {
if (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) InternalBDFDB.initiateProcess(plugin, type, {instance:e.thisObject, returnvalue:e.returnValue, methodname:e.originalMethodName, patchtypes:[patchtype]});
}
BDFDB.ModuleUtils.patch(plugin, instance.prototype, plugin.patchedModules[patchtype][type], patchfunctions);
}
}
}
function checkForInstance(classname, type, patchtype, forceobserve) {
const app = document.querySelector(BDFDB.dotCN.app), bdsettings = document.querySelector("#bd-settingspane-container " + BDFDB.dotCN.scrollerwrap);
let instancefound = false;
if (!forceobserve) {
if (app) {
let appins = BDFDB.ReactUtils.findConstructor(app, type, {unlimited:true}) || BDFDB.ReactUtils.findConstructor(app, type, {unlimited:true, up:true});
if (appins && (instancefound = true)) patchInstance(appins, type, patchtype);
}
if (!instancefound && bdsettings) {
let bdsettingsins = BDFDB.ReactUtils.findConstructor(bdsettings, type, {unlimited:true});
if (bdsettingsins && (instancefound = true)) patchInstance(bdsettingsins, type, patchtype);
}
}
if (!instancefound) {
let found = false, disclass = BDFDB.disCN[classname], dotclass = BDFDB.dotCN[classname];
for (let ele of document.querySelectorAll(dotclass)) {
let ins = BDFDB.ReactUtils.getInstance(ele);
if (isCorrectInstance(ins, type)) {
found = true;
patchInstance(ins, type, patchtype);
BDFDB.ModuleUtils.forceAllUpdates(plugin, type);
break;
}
}
if (!found) {
let instanceobserver = new MutationObserver(cs => {cs.forEach(c => {c.addedNodes.forEach(n => {
if (found || !n || !n.tagName) return;
let ele = null;
if ((ele = BDFDB.DOMUtils.containsClass(n, disclass) ? n : n.querySelector(dotclass)) != null) {
let ins = BDFDB.ReactUtils.getInstance(ele);
if (isCorrectInstance(ins, type)) {
found = true;
instanceobserver.disconnect();
patchInstance(ins, type, patchtype);
BDFDB.ModuleUtils.forceAllUpdates(plugin, type);
}
}
});});});
BDFDB.ObserverUtils.connect(plugin, BDFDB.dotCN.appmount, {name:"checkForInstanceObserver", instance:instanceobserver, multi:true
}, {childList:true, subtree:true});
}
}
}
function isCorrectInstance(instance, name) {
if (!instance) return false;
instance = instance._reactInternalFiber && instance._reactInternalFiber.type ? instance._reactInternalFiber.type : instance;
instance = instance.displayName == name || instance.name == name ? instance : (BDFDB.ReactUtils.findConstructor(instance, name) || BDFDB.ReactUtils.findConstructor(instance, name, {up:true}));
return !!instance;
}
};
var NoFluxPopouts = ["MessageOptionPopout"];
InternalBDFDB.addContextListeners = (plugin) => {
if (!BDFDB.ObjectUtils.is(plugin)) return;
for (let type of LibraryComponents.ContextMenus._NormalMenus) if (typeof plugin[`on${type}`] === "function") InternalBDFDB.patchContextMenuPlugin(plugin, type, LibraryComponents.ContextMenus[type]);
for (let type of NoFluxPopouts) if (typeof plugin[`on${type}`] === "function") InternalBDFDB.patchPopoutPlugin(plugin, type, BDFDB.ModuleUtils.findByName(type));
for (let type of LibraryComponents.ContextMenus._FluxMenus) if (typeof plugin[`on${type}`] === "function") {
if (BDFDB.InternalData.patchMenuQueries[type].module) InternalBDFDB.patchContextMenuPlugin(plugin, type, BDFDB.InternalData.patchMenuQueries[type].module);
else BDFDB.InternalData.patchMenuQueries[type].query.push(plugin);
}
for (let type of LibraryComponents.ContextMenus._NonRenderMenus) if (typeof plugin[`on${type}`] === "function") InternalBDFDB.patchNonRenderContextMenuPlugin(plugin, type, LibraryComponents.ContextMenus._Modules[type]);
};
InternalBDFDB.patchContextMenuPlugin = (plugin, type, module) => {
if (module && module.prototype) {
// REMOVE
let isOldType = plugin["on" + type].toString().split("\n")[0].replace(/ /g, "").split(",").length > 1;
if (isOldType) {
BDFDB.ModuleUtils.patch(plugin, module.prototype, "render", {after: e => {
let instance = e.thisObject, menu = BDFDB.ReactUtils.findDOMNode(e.thisObject), returnvalue = e.returnValue;
if (instance && menu && returnvalue && typeof plugin[`on${type}`] === "function") plugin[`on${type}`](instance, menu, returnvalue);
}});
}
else {
BDFDB.ModuleUtils.patch(plugin, module.prototype, "render", {after: e => {
if (e.thisObject && e.returnValue && typeof plugin[`on${type}`] === "function") plugin[`on${type}`]({instance:e.thisObject, returnvalue:e.returnValue, methodname:"render"});
}});
}
}
};
InternalBDFDB.patchNonRenderContextMenuPlugin = (plugin, type, module) => {
if (module && module.exports) {
let isOldType = plugin["on" + type].toString().split("\n")[0].replace(/ /g, "").split(",").length > 1;
if (isOldType) BDFDB.ModuleUtils.patch(plugin, module.exports, "default", {after: e => {
if (e.returnValue && typeof plugin[`on${type}`] === "function") plugin[`on${type}`]({props:e.methodArguments[0]}, document, e.returnValue);
}});
else BDFDB.ModuleUtils.patch(plugin, module.exports, "default", {after: e => {
if (e.returnValue && typeof plugin[`on${type}`] === "function") plugin[`on${type}`]({instance:{props:e.methodArguments[0]}, returnvalue:e.returnValue, methodname:"default"});
}});
}
};
InternalBDFDB.patchPopoutPlugin = (plugin, type, module) => {
if (module && module.prototype) {
// REMOVE
let isOldType = plugin["on" + type].toString().split("\n")[0].replace(/ /g, "").split(",").length > 1;
if (isOldType) BDFDB.ModuleUtils.patch(plugin, module.prototype, "render", {after: e => {
let instance = e.thisObject, menu = BDFDB.ReactUtils.findDOMNode(e.thisObject), returnvalue = e.returnValue;
if (instance && menu && returnvalue && typeof plugin[`on${type}`] === "function") {
plugin[`on${type}`](instance, menu, returnvalue);
if (!instance.BDFDBforceUpdateTimeout) BDFDB.ReactUtils.forceUpdate(instance);
}
}});
else BDFDB.ModuleUtils.patch(plugin, module.prototype, "render", {after: e => {
if (e.thisObject && e.returnValue && typeof plugin[`on${type}`] === "function") plugin[`on${type}`]({instance:e.thisObject, returnvalue:e.returnValue, methodname:"render"});
}});
}
};
InternalBDFDB.patchContextMenuLib = (module, repatch) => {
if (module && module.prototype) {
// REMOVE
BDFDB.ModuleUtils.patch(BDFDB, module.prototype, "componentDidMount", {after: e => {
if (!e.thisObject.BDFDBforceRenderTimeout && typeof e.thisObject.render == "function") e.thisObject.render();
}});
BDFDB.ModuleUtils.patch(BDFDB, module.prototype, "componentDidUpdate", {after: e => {
var menu = BDFDB.ReactUtils.findDOMNode(e.thisObject);
if (menu) {
const updater = BDFDB.ReactUtils.getValue(e, "thisObject._reactInternalFiber.stateNode.props.onHeightUpdate");
const mrects = BDFDB.DOMUtils.getRects(menu), arects = BDFDB.DOMUtils.getRects(document.querySelector(BDFDB.dotCN.appmount));
if (updater && (mrects.top + mrects.height > arects.height)) updater();
}
}});
BDFDB.ModuleUtils.patch(BDFDB, module.prototype, "render", {after: e => {
if (e.thisObject.props.BDFDBcontextMenu && e.thisObject.props.children && e.returnValue && e.returnValue.props) {
e.returnValue.props.children = e.thisObject.props.children;
delete e.thisObject.props.value;
delete e.thisObject.props.children;
delete e.thisObject.props.BDFDBcontextMenu;
}
if (BDFDB.ReactUtils.findDOMNode(e.thisObject)) {
e.thisObject.BDFDBforceRenderTimeout = true;
BDFDB.TimeUtils.timeout(_ => {delete e.thisObject.BDFDBforceRenderTimeout;}, 1000);
}
if (repatch) {
let newmodule = BDFDB.ReactUtils.getValue(e, "thisObject._reactInternalFiber.child.type");
if (newmodule && newmodule.displayName && BDFDB.InternalData.patchMenuQueries[newmodule.displayName] && !BDFDB.InternalData.patchMenuQueries[newmodule.displayName].module) {
BDFDB.InternalData.patchMenuQueries[newmodule.displayName].module = newmodule;
InternalBDFDB.patchContextMenuLib(newmodule, false);
while (BDFDB.InternalData.patchMenuQueries[newmodule.displayName].query.length) {
InternalBDFDB.patchContextMenuPlugin(BDFDB.InternalData.patchMenuQueries[newmodule.displayName].query.pop(), newmodule.displayName, newmodule);
}
}
}
}});
}
};
InternalBDFDB.patchPopoutLib = (module, repatch) => {
if (module && module.prototype) {
// REMOVE
BDFDB.ModuleUtils.patch(BDFDB, module.prototype, "componentDidMount", {after: e => {
if (!e.thisObject.BDFDBforceRenderTimeout && !e.thisObject.BDFDBforceUpdateTimeout && typeof e.thisObject.render == "function") e.thisObject.render();
}});
BDFDB.ModuleUtils.patch(BDFDB, module.prototype, "componentDidUpdate", {after: e => {
const updater = BDFDB.ReactUtils.getValue(e, "thisObject._reactInternalFiber.return.return.return.stateNode.updateOffsets");
if (updater) updater();
e.thisObject.BDFDBforceUpdateTimeout = true;
BDFDB.TimeUtils.timeout(_ => {delete e.thisObject.BDFDBforceUpdateTimeout;}, 1000);
}});
BDFDB.ModuleUtils.patch(BDFDB, module.prototype, "render", {after: e => {
if (BDFDB.ReactUtils.findDOMNode(e.thisObject)) {
e.thisObject.BDFDBforceRenderTimeout = true;
BDFDB.TimeUtils.timeout(_ => {delete e.thisObject.BDFDBforceRenderTimeout;}, 1000);
}
if (e.thisObject.props.message && !e.thisObject.props.target) {
const messageswrap = document.querySelector(BDFDB.dotCN.messages);
if (messageswrap) for (let message of BDFDB.ReactUtils.findOwner(messageswrap, {name:"Message", all:true, unlimited:true})) {
if (e.thisObject.props.message.id == message.props.message.id) {
target = BDFDB.ReactUtils.findDOMNode(message);
if (target) e.thisObject.props.target = target
break;
}
}
}
}});
}
};
BDFDB.DiscordConstants = BDFDB.ModuleUtils.findByProperties("Permissions", "ActivityTypes");
var DiscordObjects = {};
DiscordObjects.Channel = BDFDB.ModuleUtils.findByPrototypes("getRecipientId", "getTitleIcon", "getGuildId");
DiscordObjects.Guild = BDFDB.ModuleUtils.findByPrototypes("getIconURL", "getMaxEmojiSlots", "getRole");
DiscordObjects.Message = BDFDB.ModuleUtils.findByPrototypes("getReaction", "getAuthorName", "getChannelId");
DiscordObjects.Timestamp = BDFDB.ModuleUtils.findByPrototypes("add", "dayOfYear", "hasAlignedHourOffset");
DiscordObjects.User = BDFDB.ModuleUtils.findByPrototypes("hasFlag", "isLocalBot", "isClaimed");
BDFDB.DiscordObjects = Object.assign({}, DiscordObjects);
var LibraryRequires = {};
for (let name of ["child_process", "electron", "fs", "path", "process", "request"]) {
try {LibraryRequires[name] = require(name);} catch (err) {}
}
BDFDB.LibraryRequires = Object.assign({}, LibraryRequires);
var LibraryModules = {};
LibraryModules.AckUtils = BDFDB.ModuleUtils.findByProperties("localAck", "bulkAck");
LibraryModules.APIUtils = BDFDB.ModuleUtils.findByProperties("getAPIBaseURL");
LibraryModules.AnimationUtils = BDFDB.ModuleUtils.findByProperties("spring", "decay");
LibraryModules.BadgeUtils = BDFDB.ModuleUtils.findByProperties("getBadgeCountString", "getBadgeWidthForValue");
LibraryModules.CategoryCollapseStore = BDFDB.ModuleUtils.findByProperties("getCollapsedCategories", "isCollapsed");
LibraryModules.CategoryCollapseUtils = BDFDB.ModuleUtils.findByProperties("categoryCollapse", "categoryCollapseAll");
LibraryModules.ChannelStore = BDFDB.ModuleUtils.findByProperties("getChannel", "getChannels");
LibraryModules.ColorUtils = BDFDB.ModuleUtils.findByProperties("hex2int", "hex2rgb");
LibraryModules.ContextMenuUtils = BDFDB.ModuleUtils.findByProperties("closeContextMenu", "openContextMenu");
LibraryModules.CopyLinkUtils = BDFDB.ModuleUtils.findByProperties("SUPPORTS_COPY", "copy");
LibraryModules.CurrentUserStore = BDFDB.ModuleUtils.findByProperties("getCurrentUser");
LibraryModules.CurrentVoiceUtils = BDFDB.ModuleUtils.findByProperties("getAveragePing", "isConnected");
LibraryModules.DirectMessageUnreadStore = BDFDB.ModuleUtils.findByProperties("getUnreadPrivateChannelIds");
LibraryModules.DirectMessageUtils = BDFDB.ModuleUtils.findByProperties("addRecipient", "openPrivateChannel");
LibraryModules.FriendUtils = BDFDB.ModuleUtils.findByProperties("getFriendIDs", "getRelationships");
LibraryModules.FolderStore = BDFDB.ModuleUtils.findByProperties("getGuildFolderById", "getFlattenedGuilds");
LibraryModules.FolderUtils = BDFDB.ModuleUtils.findByProperties("isFolderExpanded", "getExpandedFolders");
LibraryModules.GuildBoostUtils = BDFDB.ModuleUtils.findByProperties("getTierName", "getUserLevel");
LibraryModules.GuildChannelStore = BDFDB.ModuleUtils.findByProperties("getChannels", "getDefaultChannel");
LibraryModules.GuildEmojiStore = BDFDB.ModuleUtils.findByProperties("getGuildEmoji", "getDisambiguatedEmojiContext");
LibraryModules.GuildSettingsUtils = BDFDB.ModuleUtils.findByProperties("updateChannelOverrideSettings", "updateNotificationSettings");
LibraryModules.GuildStore = BDFDB.ModuleUtils.findByProperties("getGuild", "getGuilds");
LibraryModules.GuildUtils = BDFDB.ModuleUtils.findByProperties("transitionToGuildSync");
LibraryModules.HistoryUtils = BDFDB.ModuleUtils.findByProperties("transitionTo", "replaceWith", "getHistory");;
LibraryModules.IconUtils = BDFDB.ModuleUtils.findByProperties("getGuildIconURL", "getGuildBannerURL");
LibraryModules.InviteUtils = BDFDB.ModuleUtils.findByProperties("acceptInvite", "createInvite");
LibraryModules.KeyCodeUtils = Object.assign({}, BDFDB.ModuleUtils.findByProperties("toCombo", "keyToCode"));
LibraryModules.KeyCodeUtils.getString = keyarray => {
return LibraryModules.KeyCodeUtils.toString([keyarray].flat(10).filter(n => n).map(keycode => [BDFDB.DiscordConstants.KeyboardDeviceTypes.KEYBOARD_KEY, keycode, BDFDB.DiscordConstants.KeyboardEnvs.BROWSER]), true);
};
LibraryModules.KeyEvents = BDFDB.ModuleUtils.findByProperties("aliases", "code", "codes");
LibraryModules.LanguageStore = BDFDB.ModuleUtils.findByProperties("getLanguages", "Messages");
LibraryModules.LastChannelStore = BDFDB.ModuleUtils.findByProperties("getLastSelectedChannelId");
LibraryModules.LastGuildStore = BDFDB.ModuleUtils.findByProperties("getLastSelectedGuildId");
LibraryModules.LoginUtils = BDFDB.ModuleUtils.findByProperties("login", "logout");
LibraryModules.MemberStore = BDFDB.ModuleUtils.findByProperties("getMember", "getMembers");
LibraryModules.MessageCreationUtils = BDFDB.ModuleUtils.findByProperties("parse", "isMentioned");
LibraryModules.MessagePinUtils = BDFDB.ModuleUtils.findByProperties("pinMessage", "unpinMessage");
LibraryModules.MessageStore = BDFDB.ModuleUtils.findByProperties("getMessage", "getMessages");
LibraryModules.MessageUtils = BDFDB.ModuleUtils.findByProperties("receiveMessage", "editMessage");
LibraryModules.ModalUtils = BDFDB.ModuleUtils.findByProperties("openModal", "registerModalDispatch");
LibraryModules.MutedUtils = BDFDB.ModuleUtils.findByProperties("isGuildOrCategoryOrChannelMuted");
LibraryModules.NoteStore = BDFDB.ModuleUtils.findByProperties("getNotes", "getNote");
LibraryModules.NotificationSettingsUtils = BDFDB.ModuleUtils.findByProperties("setDesktopType", "setTTSType");
LibraryModules.NotificationSettingsStore = BDFDB.ModuleUtils.findByProperties("getDesktopType", "getTTSType");
LibraryModules.PlatformUtils = BDFDB.ModuleUtils.findByProperties("isWindows", "isLinux");
LibraryModules.PermissionUtils = BDFDB.ModuleUtils.findByProperties("getChannelPermissions", "canUser");
LibraryModules.PermissionRoleUtils = BDFDB.ModuleUtils.findByProperties("getHighestRole", "can");
LibraryModules.ReactionUtils = BDFDB.ModuleUtils.findByProperties("addReaction", "removeReaction");
LibraryModules.SearchPageUtils = BDFDB.ModuleUtils.findByProperties("searchNextPage", "searchPreviousPage");
LibraryModules.SelectChannelUtils = BDFDB.ModuleUtils.findByProperties("selectChannel", "selectPrivateChannel");
LibraryModules.SettingsUtils = BDFDB.ModuleUtils.findByProperties("updateRemoteSettings", "updateLocalSettings");
LibraryModules.SoundUtils = BDFDB.ModuleUtils.findByProperties("playSound", "createSound");
LibraryModules.SpellCheckUtils = BDFDB.ModuleUtils.findByProperties("learnWord", "toggleSpellcheck");
LibraryModules.SlateUtils = BDFDB.ModuleUtils.findByProperties("serialize", "deserialize");
LibraryModules.StateStoreUtils = BDFDB.ModuleUtils.findByProperties("useStateFromStores", "useStateFromStoresArray");
LibraryModules.StatusMetaUtils = BDFDB.ModuleUtils.findByProperties("getApplicationActivity", "getStatus");
LibraryModules.StreamUtils = BDFDB.ModuleUtils.findByProperties("getStreamForUser", "getActiveStream");
LibraryModules.StringUtils = BDFDB.ModuleUtils.findByProperties("cssValueToNumber", "upperCaseFirstChar");
LibraryModules.UnreadGuildUtils = BDFDB.ModuleUtils.findByProperties("hasUnread", "getUnreadGuilds");
LibraryModules.UnreadChannelUtils = BDFDB.ModuleUtils.findByProperties("getUnreadCount", "getOldestUnreadMessageId");
LibraryModules.UploadUtils = BDFDB.ModuleUtils.findByProperties("upload", "instantBatchUpload");
LibraryModules.UserStore = BDFDB.ModuleUtils.findByProperties("getUser", "getUsers");
LibraryModules.Utilities = BDFDB.ModuleUtils.findByProperties("flatMap", "cloneDeep");
LibraryModules.VoiceUtils = BDFDB.ModuleUtils.findByProperties("getAllVoiceStates", "getVoiceStatesForChannel");
LibraryModules.ZoomUtils = BDFDB.ModuleUtils.findByProperties("setZoom", "setFontSize");
BDFDB.LibraryModules = Object.assign({}, LibraryModules);
LibraryModules.React = BDFDB.ModuleUtils.findByProperties("createElement", "cloneElement");
LibraryModules.ReactDOM = BDFDB.ModuleUtils.findByProperties("render", "findDOMNode");
BDFDB.ReactUtils = Object.assign({}, LibraryModules.React, LibraryModules.ReactDOM);
BDFDB.ReactUtils.createElement = function (component, props) {
if (component && component.defaultProps) for (let key in component.defaultProps) if (props[key] == null) props[key] = component.defaultProps[key];
try {return LibraryModules.React.createElement(component || "div", props || {}) || null;}
catch (err) {BDFDB.LogUtils.error("Fatal Error: Could not create react element! " + err);}
return null;
};
BDFDB.ReactUtils.elementToReact = function (node) {
if (BDFDB.ReactUtils.isValidElement(node)) return node;
else if (!Node.prototype.isPrototypeOf(node)) return null;
else if (node.nodeType == Node.TEXT_NODE) return node.nodeValue;
let attributes = {}, importantstyleprops = {};
for (let attr of node.attributes) attributes[attr.name] = attr.value;
if (node.attributes.style) attributes.style = BDFDB.ObjectUtils.filter(node.style, n => node.style[n] && isNaN(parseInt(n)), true);
attributes.children = [];
if (node.style && node.style.cssText) for (let propstr of node.style.cssText.split(";")) if (propstr.endsWith("!important")) {
let importantprop = propstr.split(":")[0];
let camelprop = importantprop.replace(/-([a-z]?)/g, (m, g) => g.toUpperCase());
if (attributes.style[camelprop] != null) importantstyleprops[importantprop] = attributes.style[camelprop];
}
if (Object.keys(importantstyleprops).length) attributes.ref = instance => {
let ele = BDFDB.ReactUtils.findDOMNode(instance);
if (ele) for (let importantprop in importantstyleprops) ele.style.setProperty(importantprop, importantstyleprops[importantprop], "important");
}
for (let child of node.childNodes) attributes.children.push(BDFDB.ReactUtils.elementToReact(child));
return BDFDB.ReactUtils.createElement(node.tagName, attributes);
};
BDFDB.ReactUtils.findDOMNode = function (instance) {
if (Node.prototype.isPrototypeOf(instance)) return instance;
if (!instance || !instance.updater || typeof instance.updater.isMounted !== "function" || !instance.updater.isMounted(instance)) return null;
var node = LibraryModules.ReactDOM.findDOMNode(instance) || BDFDB.ReactUtils.getValue(instance, "child.stateNode");
return Node.prototype.isPrototypeOf(node) ? node : null;
};
BDFDB.ReactUtils.childrenToArray = function (parent) {
if (parent && parent.props && parent.props.children && !BDFDB.ArrayUtils.is(parent.props.children)) {
var child = parent.props.children;
parent.props.children = [];
parent.props.children.push(child);
}
return parent.props.children;
}
BDFDB.ReactUtils.findChildren = function (nodeOrInstance, config) {
if (!nodeOrInstance || !BDFDB.ObjectUtils.is(config) || !config.name && !config.key && !config.props && !config.filter) return [null, -1];
var instance = Node.prototype.isPrototypeOf(nodeOrInstance) ? BDFDB.ReactUtils.getInstance(nodeOrInstance) : nodeOrInstance;
if (!BDFDB.ObjectUtils.is(instance) && !BDFDB.ArrayUtils.is(instance)) return [null, -1];
config.name = config.name && [config.name].flat().filter(n => n);
config.key = config.key && [config.key].flat().filter(n => n);
config.props = config.props && [config.props].flat().filter(n => n);
config.filter = typeof config.filter == "function" && config.filter;
var parent = firstarray = instance;
while (!BDFDB.ArrayUtils.is(firstarray) && firstarray.props && firstarray.props.children) firstarray = firstarray.props.children;
if (!BDFDB.ArrayUtils.is(firstarray)) {
if (parent && parent.props) {
parent.props.children = [parent.props.children];
firstarray = parent.props.children;
}
else firstarray = [];
}
return getChildren(instance);
function getChildren (children) {
var result = [firstarray, -1];
if (!children) return result;
if (!BDFDB.ArrayUtils.is(children)) {
if (check(children)) result = found(children);
else if (children.props && children.props.children) {
parent = children;
result = getChildren(children.props.children);
}
}
else {
for (let i = 0; result[1] == -1 && i < children.length; i++) if (children[i]) {
if (BDFDB.ArrayUtils.is(children[i])) {
parent = children;
result = getChildren(children[i]);
}
else if (check(children[i])) {
parent = children;
result = found(children[i]);
}
else if (children[i].props && children[i].props.children) {
parent = children[i];
result = getChildren(children[i].props.children);
}
}
}
return result;
}
function found (child) {
if (BDFDB.ArrayUtils.is(parent)) return [parent, parent.indexOf(child)];
else {
parent.props.children = [];
parent.props.children.push(child);
return [parent.props.children, 0];
}
}
function check (instance) {
if (!instance) return false;
let props = instance.stateNode ? instance.stateNode.props : instance.props;
return instance.type && config.name && config.name.some(name => ((instance.type.displayName || instance.type.name || instance.type) === name)) || config.key && config.key.some(key => instance.key == key) || props && config.props && config.props.every(prop => BDFDB.ArrayUtils.is(prop) ? (BDFDB.ArrayUtils.is(prop[1]) ? prop[1].some(checkvalue => propCheck(props, prop[0], checkvalue)) : propCheck(props, prop[0], prop[1])) : props[prop] !== undefined) || config.filter && config.filter(instance);
}
function propCheck (props, key, value) {
return key != null && props[key] != null && value != null && (key == "className" ? (" " + props[key] + " ").indexOf(" " + value + " ") > -1 : BDFDB.equals(props[key], value));
}
};
BDFDB.ReactUtils.findConstructor = function (nodeOrInstance, types, config) {
if (!BDFDB.ObjectUtils.is(config)) return null;
if (!nodeOrInstance || !types) return config.all ? (config.group ? {} : []) : null;
var instance = Node.prototype.isPrototypeOf(nodeOrInstance) ? BDFDB.ReactUtils.getInstance(nodeOrInstance) : nodeOrInstance;
if (!BDFDB.ObjectUtils.is(instance)) return config.all ? (config.group ? {} : []) : null;
types = types && [types].flat().filter(n => n);
if (!types.length) return config.all ? (config.group ? {} : []) : null;;
var depth = -1;
var start = performance.now();
var maxdepth = config.unlimited ? 999999999 : (config.depth === undefined ? 30 : config.depth);
var maxtime = config.unlimited ? 999999999 : (config.time === undefined ? 150 : config.time);
var whitelist = config.up ? {return:true, sibling:true, _reactInternalFiber:true} : {child:true, sibling:true, _reactInternalFiber:true};
var foundconstructors = config.group ? {} : [];
var singleconstructor = getConstructor(instance);
if (config.all) {
for (let i in foundconstructors) {
if (config.group) for (let j in foundconstructors[i]) delete foundconstructors[i][j].BDFDBreactSearch;
else delete foundconstructors[i].BDFDBreactSearch;
}
return foundconstructors;
}
else return singleconstructor;
function getConstructor (instance) {
depth++;
var result = undefined;
if (instance && !Node.prototype.isPrototypeOf(instance) && !BDFDB.ReactUtils.getInstance(instance) && depth < maxdepth && performance.now() - start < maxtime) {
if (instance.type && types.some(name => (instance.type.displayName || instance.type.name) === name.split(" _ _ ")[0])) {
if (config.all === undefined || !config.all) result = instance.type;
else if (config.all) {
if (!instance.type.BDFDBreactSearch) {
instance.type.BDFDBreactSearch = true;
if (config.group) {
if (instance.type && (instance.type.displayName || instance.type.name)) {
var group = "Default";
for (let name of types) if ((instance.type.displayName || instance.type.name).split(" _ _ ")[0]) {
group = name;
break;
}
if (typeof foundinstances[group] == "undefined") foundinstances[group] = [];
foundinstances[group].push(instance.type);
}
}
else foundinstances.push(instance.type);
}
}
}
if (result === undefined) {
let keys = Object.getOwnPropertyNames(instance);
for (let i = 0; result === undefined && i < keys.length; i++) {
let key = keys[i];
if (key && whitelist[key] && (typeof instance[key] === "object" || typeof instance[key] === "function")) result = getConstructor(instance[key]);
}
}
}
depth--;
return result;
}
};
BDFDB.ReactUtils.findOwner = function (nodeOrInstance, config) {
if (!BDFDB.ObjectUtils.is(config)) return null;
if (!nodeOrInstance || !config.name && !config.key && !config.props) return config.all ? (config.group ? {} : []) : null;
var instance = Node.prototype.isPrototypeOf(nodeOrInstance) ? BDFDB.ReactUtils.getInstance(nodeOrInstance) : nodeOrInstance;
if (!BDFDB.ObjectUtils.is(instance)) return config.all ? (config.group ? {} : []) : null;
config.name = config.name && [config.name].flat().filter(n => n);
config.key = config.key && [config.key].flat().filter(n => n);
config.props = config.props && [config.props].flat().filter(n => n);
var depth = -1;
var start = performance.now();
var maxdepth = config.unlimited ? 999999999 : (config.depth === undefined ? 30 : config.depth);
var maxtime = config.unlimited ? 999999999 : (config.time === undefined ? 150 : config.time);
var whitelist = config.up ? {return:true, sibling:true, _reactInternalFiber:true} : {child:true, sibling:true, _reactInternalFiber:true};
var foundinstances = config.group ? {} : [];
var singleinstance = getOwner(instance);
if (config.all) {
for (let i in foundinstances) {
if (config.group) for (let j in foundinstances[i]) delete foundinstances[i][j].BDFDBreactSearch;
else delete foundinstances[i].BDFDBreactSearch;
}
return foundinstances;
}
else return singleinstance;
function getOwner (instance) {
depth++;
var result = undefined;
if (instance && !Node.prototype.isPrototypeOf(instance) && !BDFDB.ReactUtils.getInstance(instance) && depth < maxdepth && performance.now() - start < maxtime) {
let props = instance.stateNode ? instance.stateNode.props : instance.props;
if (instance.stateNode && !Node.prototype.isPrototypeOf(instance.stateNode) && (instance.type && config.name && config.name.some(name => (instance.type.displayName || instance.type.name || instance.type) === name.split(" _ _ ")[0]) || config.key && config.key.some(key => instance.key == key) || props && config.props && config.props.every(prop => BDFDB.ArrayUtils.is(prop) ? (BDFDB.ArrayUtils.is(prop[1]) ? prop[1].some(checkvalue => BDFDB.equals(props[prop[0]], checkvalue)) : BDFDB.equals(props[prop[0]], prop[1])) : props[prop] !== undefined))) {
if (config.all === undefined || !config.all) result = instance.stateNode;
else if (config.all) {
if (!instance.stateNode.BDFDBreactSearch) {
instance.stateNode.BDFDBreactSearch = true;
if (config.group) {
if (config.name && instance.type && (instance.type.displayName || instance.type.name || instance.type)) {
var group = "Default";
for (let name of config.name) if ((instance.type.displayName || instance.type.name || instance.type).split(" _ _ ")[0]) {
group = name;
break;
}
if (typeof foundinstances[group] == "undefined") foundinstances[group] = [];
foundinstances[group].push(instance.stateNode);
}
}
else foundinstances.push(instance.stateNode);
}
}
}
if (result === undefined) {
let keys = Object.getOwnPropertyNames(instance);
for (let i = 0; result === undefined && i < keys.length; i++) {
let key = keys[i];
if (key && whitelist[key] && (typeof instance[key] === "object" || typeof instance[key] === "function")) result = getOwner(instance[key]);
}
}
}
depth--;
return result;
}
};
BDFDB.ReactUtils.findProps = function (nodeOrInstance, config) {
if (!BDFDB.ObjectUtils.is(config)) return null;
if (!nodeOrInstance || !config.name && !config.key) return null;
var instance = Node.prototype.isPrototypeOf(nodeOrInstance) ? BDFDB.ReactUtils.getInstance(nodeOrInstance) : nodeOrInstance;
if (!BDFDB.ObjectUtils.is(instance)) return null;
config.name = config.name && [config.name].flat().filter(n => n);
config.key = config.key && [config.key].flat().filter(n => n);
var depth = -1;
var start = performance.now();
var maxdepth = config.unlimited ? 999999999 : (config.depth === undefined ? 30 : config.depth);
var maxtime = config.unlimited ? 999999999 : (config.time === undefined ? 150 : config.time);
var whitelist = config.up ? {return:true, sibling:true, _reactInternalFiber:true} : {child:true, sibling:true, _reactInternalFiber:true};
return findProps(instance);
function findProps (instance) {
depth++;
var result = undefined;
if (instance && !Node.prototype.isPrototypeOf(instance) && !BDFDB.ReactUtils.getInstance(instance) && depth < maxdepth && performance.now() - start < maxtime) {
if (instance.memoizedProps && (instance.type && config.name && config.name.some(name => (instance.type.displayName || instance.type.name || instance.type) === name.split(" _ _ ")[0]) || config.key && config.key.some(key => instance.key == key))) result = instance.memoizedProps;
if (result === undefined) {
let keys = Object.getOwnPropertyNames(instance);
for (let i = 0; result === undefined && i < keys.length; i++) {
let key = keys[i];
if (key && whitelist[key] && (typeof instance[key] === "object" || typeof instance[key] === "function")) result = findProps(instance[key]);
}
}
}
depth--;
return result;
}
};
BDFDB.ReactUtils.findValue = function (nodeOrInstance, searchkey, config = {}) {
if (!BDFDB.ObjectUtils.is(config)) return null;
if (!nodeOrInstance || typeof searchkey != "string") return config.all ? [] : null;
var instance = Node.prototype.isPrototypeOf(nodeOrInstance) ? BDFDB.ReactUtils.getInstance(nodeOrInstance) : nodeOrInstance;
if (!BDFDB.ObjectUtils.is(instance)) return config.all ? [] : null;
instance = instance._reactInternalFiber || instance;
var depth = -1;
var start = performance.now();
var maxdepth = config.unlimited ? 999999999 : (config.depth === undefined ? 30 : config.depth);
var maxtime = config.unlimited ? 999999999 : (config.time === undefined ? 150 : config.time);
var whitelist = {
props: true,
state: true,
stateNode: true,
updater: true,
prototype: true,
type: true,
children: config.up ? false : true,
memoizedProps: true,
memoizedState: true,
child: config.up ? false : true,
return: config.up ? true : false,
sibling: config.up ? false : true
};
var blacklist = {
contextSection: true
};
if (BDFDB.ObjectUtils.is(config.whitelist)) Object.assign(whitelist, config.whiteList);
if (BDFDB.ObjectUtils.is(config.blacklist)) Object.assign(blacklist, config.blacklist);
var foundkeys = [];
var singlekey = getKey(instance);
if (config.all) return foundkeys;
else return singlekey;
function getKey(instance) {
depth++;
var result = undefined;
if (instance && !Node.prototype.isPrototypeOf(instance) && !BDFDB.ReactUtils.getInstance(instance) && depth < maxdepth && performance.now() - start < maxtime) {
let keys = Object.getOwnPropertyNames(instance);
for (let i = 0; result === undefined && i < keys.length; i++) {
let key = keys[i];
if (key && !blacklist[key]) {
var value = instance[key];
if (searchkey === key && (config.value === undefined || BDFDB.equals(config.value, value))) {
if (config.all === undefined || !config.all) result = value;
else if (config.all) {
if (config.noCopies === undefined || !config.noCopies) foundkeys.push(value);
else if (config.noCopies) {
var copy = false;
for (let foundkey of foundkeys) if (BDFDB.equals(value, foundkey)) {
copy = true;
break;
}
if (!copy) foundkeys.push(value);
}
}
}
else if ((typeof value === "object" || typeof value === "function") && (whitelist[key] || key[0] == "." || !isNaN(key[0]))) result = getKey(value);
}
}
}
depth--;
return result;
}
};
BDFDB.ReactUtils.forceUpdate = function (...instances) {
// REMOVE AppSkeleton CHECK
for (let ins of instances.flat(10).filter(n => n)) if (ins.updater && typeof ins.updater.isMounted == "function" && ins.updater.isMounted(ins) && BDFDB.ReactUtils.getValue(ins, "_reactInternalFiber.type.displayName") != "AppSkeleton") ins.forceUpdate();
};
BDFDB.ReactUtils.getInstance = function (node) {
if (!BDFDB.ObjectUtils.is(node)) return null;
return node[Object.keys(node).find(key => key.startsWith("__reactInternalInstance"))];
};
BDFDB.ReactUtils.getValue = function (nodeOrInstance, valuepath) {
if (!nodeOrInstance || !valuepath) return null;
var instance = Node.prototype.isPrototypeOf(nodeOrInstance) ? BDFDB.ReactUtils.getInstance(nodeOrInstance) : nodeOrInstance;
if (!BDFDB.ObjectUtils.is(instance)) return null;
var found = instance, values = valuepath.split(".").filter(n => n);
for (value of values) {
if (!found) return null;
found = found[value];
}
return found;
};
InternalBDFDB.setDefaultProps = function (component, defaultProps) {
if (BDFDB.ObjectUtils.is(component)) component.defaultProps = Object.assign({}, component.defaultProps, defaultProps);
};
BDFDB.equals = function (mainA, mainB, sorted) {
var i = -1;
if (sorted === undefined || typeof sorted !== "boolean") sorted = false;
return equal(mainA, mainB);
function equal(a, b) {
i++;
var result = true;
if (i > 1000) result = null;
else {
if (typeof a !== typeof b) result = false;
else if (typeof a === "undefined") result = true;
else if (typeof a === "symbol") result = true;
else if (typeof a === "boolean") result = a == b;
else if (typeof a === "string") result = a == b;
else if (typeof a === "number") {
if (isNaN(a) || isNaN(b)) result = isNaN(a) == isNaN(b);
else result = a == b;
}
else if (!a && !b) result = true;
else if (!a || !b) result = false;
else if (typeof a === "function" || typeof a === "object") {
var keysA = Object.getOwnPropertyNames(a);
var keysB = Object.getOwnPropertyNames(b);
if (keysA.length !== keysB.length) result = false;
else for (let j = 0; result === true && j < keysA.length; j++) {
if (sorted) result = equal(a[keysA[j]], b[keysB[j]]);
else result = equal(a[keysA[j]], b[keysA[j]]);
}
}
}
i--;
return result;
}
};
BDFDB.UserUtils = {};
var myDataUser = LibraryModules.CurrentUserStore ? LibraryModules.CurrentUserStore.getCurrentUser() : null;
BDFDB.UserUtils.me = new Proxy(myDataUser || {}, {
get: function (list, item) {
if (!myDataUser) myDataUser = LibraryModules.CurrentUserStore.getCurrentUser();
return myDataUser ? myDataUser[item] : null;
}
});
BDFDB.UserUtils.getStatus = function (id = BDFDB.UserUtils.me.id) {
id = typeof id == "number" ? id.toFixed() : id;
let activity = BDFDB.UserUtils.getActivitiy(id);
return activity && activity.type == BDFDB.DiscordConstants.ActivityTypes.STREAMING ? "streaming" : LibraryModules.StatusMetaUtils.getStatus(id);
};
BDFDB.UserUtils.getStatusColor = function (status) {
status = typeof status == "string" ? status.toLowerCase() : null;
switch (status) {
case "online": return BDFDB.DiscordConstants.Colors.STATUS_GREEN;
case "mobile": return BDFDB.DiscordConstants.Colors.STATUS_GREEN;
case "idle": return BDFDB.DiscordConstants.Colors.STATUS_YELLOW;
case "dnd": return BDFDB.DiscordConstants.Colors.STATUS_RED;
case "playing": return BDFDB.DiscordConstants.Colors.BRAND;
case "listening": return BDFDB.DiscordConstants.Colors.SPOTIFY;
case "streaming": return BDFDB.DiscordConstants.Colors.TWITCH;
default: return BDFDB.DiscordConstants.Colors.STATUS_GREY;
}
};
BDFDB.UserUtils.getActivitiy = function (id = BDFDB.UserUtils.me.id) {
for (let activity of LibraryModules.StatusMetaUtils.getActivities(id)) if (activity.type != BDFDB.DiscordConstants.ActivityTypes.CUSTOM_STATUS) return activity;
return null;
};
BDFDB.UserUtils.getAvatar = function (id = BDFDB.UserUtils.me.id) {
var user = LibraryModules.UserStore.getUser(typeof id == "number" ? id.toFixed() : id);
if (!user) return window.location.origin + "/assets/322c936a8c8be1b803cd94861bdfa868.png";
else return ((user.avatar ? "" : window.location.origin) + LibraryModules.IconUtils.getUserAvatarURL(user)).split("?")[0];
};
BDFDB.UserUtils.can = function (permission, id = BDFDB.UserUtils.me.id, channelid = LibraryModules.LastChannelStore.getChannelId()) {
if (!BDFDB.DiscordConstants.Permissions[permission]) BDFDB.LogUtils.warn(permission + " not found in Permissions");
else {
var channel = LibraryModules.ChannelStore.getChannel(channelid);
if (channel) return LibraryModules.PermissionUtils.canUser(id, BDFDB.DiscordConstants.Permissions[permission], channel);
}
return false;
};
BDFDB.GuildUtils = {};
BDFDB.GuildUtils.getIcon = function (id) {
var guild = LibraryModules.GuildStore.getGuild(typeof id == "number" ? id.toFixed() : id);
if (!guild || !guild.icon) return null;
return LibraryModules.IconUtils.getGuildIconURL(guild).split("?")[0];
};
BDFDB.GuildUtils.getBanner = function (id) {
var guild = LibraryModules.GuildStore.getGuild(typeof id == "number" ? id.toFixed() : id);
if (!guild || !guild.banner) return null;
return LibraryModules.IconUtils.getGuildBannerURL(guild).split("?")[0];
};
BDFDB.GuildUtils.getFolder = function (id) {
return BDFDB.LibraryModules.FolderStore.guildFolders.filter(n => n.folderId).find(n => n.guildIds.includes(id));
};
BDFDB.GuildUtils.getId = function (div) {
if (!Node.prototype.isPrototypeOf(div) || !BDFDB.ReactUtils.getInstance(div)) return;
let guilddiv = BDFDB.DOMUtils.getParent(BDFDB.dotCN.guildouter, div);
if (!guilddiv) return;
var iconwrap = guilddiv.querySelector(BDFDB.dotCN.guildiconwrapper);
var id = iconwrap && iconwrap.href ? iconwrap.href.split("/").slice(-2)[0] : null;
return id && !isNaN(parseInt(id)) ? id.toString() : null;
};
BDFDB.GuildUtils.getData = function (eleOrInfoOrId) {
if (!eleOrInfoOrId) return null;
let id = Node.prototype.isPrototypeOf(eleOrInfoOrId) ? BDFDB.GuildUtils.getId(eleOrInfoOrId) : (typeof eleOrInfoOrId == "object" ? eleOrInfoOrId.id : eleOrInfoOrId);
id = typeof id == "number" ? id.toFixed() : id;
for (let info of BDFDB.GuildUtils.getAll()) if (info && info.id == id) return info;
return null;
};
BDFDB.GuildUtils.getAll = function () {
var found = [], objs = [];
for (let ins of BDFDB.ReactUtils.findOwner(document.querySelector(BDFDB.dotCN.guilds), {name:["Guild","GuildIcon"], all:true, unlimited:true})) {
if (ins.props && ins.props.guild) objs.push(Object.assign(new ins.props.guild.constructor(ins.props.guild), {div:ins.handleContextMenu && BDFDB.ReactUtils.findDOMNode(ins), instance:ins}));
}
for (let id of BDFDB.LibraryModules.FolderStore.getFlattenedGuildIds()) {
let foundobj = null;
for (let obj of objs) if (obj.id == id) {
foundobj = obj
break;
}
if (foundobj) found.push(foundobj);
else {
let guild = BDFDB.LibraryModules.GuildStore.getGuild(id);
found.push(Object.assign(new guild.constructor(guild), {div:null, instance:null}))
}
}
return found;
};
BDFDB.GuildUtils.getUnread = function (servers) {
var found = [];
for (let eleOrInfoOrId of servers === undefined || !BDFDB.ArrayUtils.is(servers) ? BDFDB.GuildUtils.getAll() : servers) {
if (!eleOrInfoOrId) return null;
let id = Node.prototype.isPrototypeOf(eleOrInfoOrId) ? BDFDB.GuildUtils.getId(eleOrInfoOrId) : (typeof eleOrInfoOrId == "object" ? eleOrInfoOrId.id : eleOrInfoOrId);
id = typeof id == "number" ? id.toFixed() : id;
if (id && (LibraryModules.UnreadGuildUtils.hasUnread(id) || LibraryModules.UnreadGuildUtils.getMentionCount(id) > 0)) found.push(eleOrInfoOrId);
}
return found;
};
BDFDB.GuildUtils.getPinged = function (servers) {
var found = [];
for (let eleOrInfoOrId of servers === undefined || !BDFDB.ArrayUtils.is(servers) ? BDFDB.GuildUtils.getAll() : servers) {
if (!eleOrInfoOrId) return null;
let id = Node.prototype.isPrototypeOf(eleOrInfoOrId) ? BDFDB.GuildUtils.getId(eleOrInfoOrId) : (typeof eleOrInfoOrId == "object" ? eleOrInfoOrId.id : eleOrInfoOrId);
id = typeof id == "number" ? id.toFixed() : id;
if (id && LibraryModules.UnreadGuildUtils.getMentionCount(id) > 0) found.push(eleOrInfoOrId);
}
return found;
};
BDFDB.GuildUtils.getMuted = function (servers) {
var found = [];
for (let eleOrInfoOrId of servers === undefined || !BDFDB.ArrayUtils.is(servers) ? BDFDB.GuildUtils.getAll() : servers) {
if (!eleOrInfoOrId) return null;
let id = Node.prototype.isPrototypeOf(eleOrInfoOrId) ? BDFDB.GuildUtils.getId(eleOrInfoOrId) : (typeof eleOrInfoOrId == "object" ? eleOrInfoOrId.id : eleOrInfoOrId);
id = typeof id == "number" ? id.toFixed() : id;
if (id && LibraryModules.MutedUtils.isGuildOrCategoryOrChannelMuted(id)) found.push(eleOrInfoOrId);
}
return found;
};
BDFDB.GuildUtils.getSelected = function () {
var info = LibraryModules.GuildStore.getGuild(LibraryModules.LastGuildStore.getGuildId());
if (info) return BDFDB.GuildUtils.getData(info.id) || Object.assign(new info.constructor(info), {div:null, instance:null});
else return null;
};
BDFDB.GuildUtils.openMenu = function (eleOrInfoOrId, e = BDFDB.InternalData.mousePosition) {
if (!eleOrInfoOrId) return;
let id = Node.prototype.isPrototypeOf(eleOrInfoOrId) ? BDFDB.GuildUtils.getId(eleOrInfoOrId) : (typeof eleOrInfoOrId == "object" ? eleOrInfoOrId.id : eleOrInfoOrId);
let guild = LibraryModules.GuildStore.getGuild(id);
if (guild) LibraryModules.ContextMenuUtils.openContextMenu(e, function (e) {
return BDFDB.ReactUtils.createElement(BDFDB.ReactUtils.getValue(LibraryComponents, "ContextMenus._Modules.GuildContextMenu.exports.default"), Object.assign({}, e, {
type: BDFDB.DiscordConstants.ContextMenuTypes.GUILD_ICON_BAR,
guild: guild,
badge: LibraryModules.UnreadGuildUtils.getMentionCount(guild.id),
link: BDFDB.DiscordConstants.Routes.CHANNEL(guild.id, LibraryModules.LastChannelStore.getChannelId(guild.id)),
selected: guild.id == LibraryModules.LastGuildStore.getGuildId()
}));
});
};
BDFDB.GuildUtils.markAsRead = function (guilds) {
if (!guilds) return;
var unreadchannels = [];
for (let guild of BDFDB.ArrayUtils.is(guilds) ? guilds : (typeof guilds == "string" || typeof guilds == "number" ? Array.of(guilds) : Array.from(guilds))) {
let id = Node.prototype.isPrototypeOf(guild) ? BDFDB.GuildUtils.getId(guild) : (guild && typeof guild == "object" ? guild.id : guild);
let channels = id && LibraryModules.GuildChannelStore.getChannels(id);
if (channels) for (let type in channels) if (BDFDB.ArrayUtils.is(channels[type])) for (let channelobj of channels[type]) unreadchannels.push(channelobj.channel.id);
}
if (unreadchannels.length) LibraryModules.AckUtils.bulkAck(unreadchannels);
};
BDFDB.FolderUtils = {};
BDFDB.FolderUtils.getId = function (div) {
if (!Node.prototype.isPrototypeOf(div) || !BDFDB.ReactUtils.getInstance(div)) return;
div = BDFDB.DOMUtils.getParent(BDFDB.dotCN.guildfolderwrapper, div);
if (!div) return;
return BDFDB.ReactUtils.findValue(div, "folderId", {up:true});
};
BDFDB.FolderUtils.getDefaultName = function (folderId) {
let folder = BDFDB.LibraryModules.FolderStore.getGuildFolderById(folderId);
if (!folder) return "";
let rest = 2 * BDFDB.DiscordConstants.MAX_GUILD_FOLDER_NAME_LENGTH;
let names = [], allNames = folder.guildIds.map(guildId => (BDFDB.LibraryModules.GuildStore.getGuild(guildId) || {}).name).filter(n => n);
for (let name of allNames) if (name.length < rest || names.length === 0) {
names.push(name);
rest -= name.length;
}
return names.join(", ") + (names.length < allNames.length ? ", ..." : "");
};
BDFDB.FolderUtils.getDiv = function (eleOrInfoOrId) {
if (!eleOrInfoOrId) return null;
let info = BDFDB.FolderUtils.getData(eleOrInfoOrId);
return info ? info.div : null;
};
BDFDB.FolderUtils.getData = function (eleOrInfoOrId) {
if (!eleOrInfoOrId) return null;
let id = Node.prototype.isPrototypeOf(eleOrInfoOrId) ? BDFDB.FolderUtils.getId(eleOrInfoOrId) : (typeof eleOrInfoOrId == "object" ? eleOrInfoOrId.id : eleOrInfoOrId);
id = typeof id == "number" ? id.toFixed() : id;
for (let info of BDFDB.FolderUtils.getAll()) if (info && info.folderId == id) return info;
return null;
};
BDFDB.FolderUtils.getAll = function () {
var found = [];
for (let ins of BDFDB.ReactUtils.findOwner(document.querySelector(BDFDB.dotCN.guildswrapper), {name:"GuildFolder", all:true, unlimited:true})) {
if (ins.props && ins.props.folderId) found.push(Object.assign({}, ins.props, {div:BDFDB.ReactUtils.findDOMNode(ins), instance:ins}));
}
return found;
};
BDFDB.ChannelUtils = {};
BDFDB.ChannelUtils.getId = function (div) {
if (!Node.prototype.isPrototypeOf(div) || !BDFDB.ReactUtils.getInstance(div)) return;
div = BDFDB.DOMUtils.getParent(BDFDB.dotCNC.categorycontainerdefault + BDFDB.dotCNC.channelcontainerdefault + BDFDB.dotCN.dmchannel, div);
if (!div) return;
var info = BDFDB.ReactUtils.findValue(div, "channel");
return info ? info.id.toString() : null;
};
BDFDB.ChannelUtils.getDiv = function (eleOrInfoOrId) {
if (!eleOrInfoOrId) return null;
let info = BDFDB.ChannelUtils.getData(eleOrInfoOrId);
return info ? info.div : null;
};
BDFDB.ChannelUtils.getData = function (eleOrInfoOrId) {
if (!eleOrInfoOrId) return null;
let id = Node.prototype.isPrototypeOf(eleOrInfoOrId) ? BDFDB.ChannelUtils.getId(eleOrInfoOrId) : (typeof eleOrInfoOrId == "object" ? eleOrInfoOrId.id : eleOrInfoOrId);
id = typeof id == "number" ? id.toFixed() : id;
for (let info of BDFDB.ChannelUtils.getAll()) if (info && info.id == id) return info;
return null;
};
BDFDB.ChannelUtils.getAll = function () {
var found = [];
for (let ins of BDFDB.ReactUtils.findOwner(document.querySelector(BDFDB.dotCN.channels), {name: ["ChannelCategoryItem", "ChannelItem", "PrivateChannel"], all:true, unlimited:true})) if (ins.props && !ins.props.ispin && ins.props.channel && ins._reactInternalFiber.return) {
var div = BDFDB.ReactUtils.findDOMNode(ins);
div = div && BDFDB.DOMUtils.containsClass(div.parentElement, BDFDB.disCN.categorycontainerdefault, BDFDB.disCN.channelcontainerdefault, false) ? div.parentElement : div;
found.push(Object.assign(new ins.props.channel.constructor(ins.props.channel), {div, instance:ins}));
}
return found;
};
BDFDB.ChannelUtils.getSelected = function () {
var info = LibraryModules.ChannelStore.getChannel(LibraryModules.LastChannelStore.getChannelId());
if (info) return BDFDB.ChannelUtils.getData(info.id) || Object.assign(new info.constructor(info), {div:null, instance:null});
else return null;
};
BDFDB.ChannelUtils.openMenu = function (eleOrInfoOrId, e = BDFDB.InternalData.mousePosition) {
if (!eleOrInfoOrId) return;
let id = Node.prototype.isPrototypeOf(eleOrInfoOrId) ? BDFDB.ChannelUtils.getId(eleOrInfoOrId) : (typeof eleOrInfoOrId == "object" ? eleOrInfoOrId.id : eleOrInfoOrId);
let channel = LibraryModules.ChannelStore.getChannel(id);
if (channel) {
let type = null;
for (let t in BDFDB.DiscordConstants.ChannelTypes) if (BDFDB.DiscordConstants.ChannelTypes[t] == channel.type) {
type = BDFDB.DiscordConstants.ContextMenuTypes[(t == "GUILD_CATEGORY" ? "CHANNEL_" : "CHANNEL_LIST_") + t.replace("GUILD_", "")];
break;
}
if (type) LibraryModules.ContextMenuUtils.openContextMenu(e, function (e) {
return BDFDB.ReactUtils.createElement(BDFDB.ReactUtils.getValue(LibraryComponents, "ContextMenus._Modules.ChannelContextMenu.exports.default"), Object.assign({}, e, {
type: type,
channel: channel,
guild: LibraryModules.GuildStore.getGuild(channel.guild_id),
selected: channel.id == LibraryModules.LastChannelStore.getChannelId()
}));
});
}
};
BDFDB.ChannelUtils.markAsRead = function (channels) {
if (!channels) return;
var unreadchannels = [];
for (let channel of channels = BDFDB.ArrayUtils.is(channels) ? channels : (typeof channels == "string" || typeof channels == "number" ? Array.of(channels) : Array.from(channels))) {
let id = Node.prototype.isPrototypeOf(channel) ? BDFDB.ChannelUtils.getId(channel) : (channel && typeof channel == "object" ? channel.id : channel);
if (id) unreadchannels.push(id);
}
if (unreadchannels.length) LibraryModules.AckUtils.bulkAck(unreadchannels);
};
BDFDB.DMUtils = {};
BDFDB.DMUtils.getIcon = function (id) {
var channel = LibraryModules.ChannelStore.getChannel(id = typeof id == "number" ? id.toFixed() : id);
if (!channel) return null;
if (!channel.icon) return channel.type == 1 ? BDFDB.UserUtils.getAvatar(channel.recipients[0]) : (channel.type == 3 ? window.location.origin + LibraryModules.IconUtils.getChannelIconURL(channel).split("?")[0] : null);
return LibraryModules.IconUtils.getChannelIconURL(channel).split("?")[0];
};
BDFDB.DMUtils.getId = function (div) {
if (!Node.prototype.isPrototypeOf(div) || !BDFDB.ReactUtils.getInstance(div)) return;
let dmdiv = BDFDB.DOMUtils.getParent(BDFDB.dotCN.guildouter, div);
if (!dmdiv) return;
var iconwrap = dmdiv.querySelector(BDFDB.dotCN.guildiconwrapper);
var id = iconwrap && iconwrap.href ? iconwrap.href.split("/").slice(-1)[0] : null;
return id && !isNaN(parseInt(id)) ? id.toString() : null;
};
BDFDB.DMUtils.getDiv = function (eleOrInfoOrId) {
if (!eleOrInfoOrId) return null;
if (Node.prototype.isPrototypeOf(eleOrInfoOrId)) {
var div = BDFDB.DOMUtils.getParent(BDFDB.dotCN.guildouter, eleOrInfoOrId);
return div ? div.parentElement : div;
}
else {
let id = typeof eleOrInfoOrId == "object" ? eleOrInfoOrId.id : eleOrInfoOrId;
if (id) {
var div = BDFDB.DOMUtils.getParent(BDFDB.dotCN.guildouter, document.querySelector(`${BDFDB.dotCNS.guilds + BDFDB.dotCN.dmpill + " + * " + BDFDB.dotCN.guildiconwrapper}[href*="/channels/@me/${id}"]`));
return div && BDFDB? div.parentElement : div;
}
}
return null;
};
BDFDB.DMUtils.getData = function (eleOrInfoOrId) {
if (!eleOrInfoOrId) return null;
let id = Node.prototype.isPrototypeOf(eleOrInfoOrId) ? BDFDB.BDFDB.DMUtils.getId(eleOrInfoOrId) : (typeof eleOrInfoOrId == "object" ? eleOrInfoOrId.id : eleOrInfoOrId);
id = typeof id == "number" ? id.toFixed() : id;
for (let info of BDFDB.DMUtils.getAll()) if (info && info.id == id) return info;
return null;
};
BDFDB.DMUtils.getAll = function () {
var found = [];
for (let ins of BDFDB.ReactUtils.findOwner(document.querySelector(BDFDB.dotCN.guilds), {name:"DirectMessage", all:true, unlimited:true})) {
if (ins.props && ins.props.channel) found.push(Object.assign(new ins.props.channel.constructor(ins.props.channel), {div:BDFDB.ReactUtils.findDOMNode(ins), instance:ins}));
}
return found;
};
BDFDB.DMUtils.openMenu = function (eleOrInfoOrId, e = BDFDB.InternalData.mousePosition) {
if (!eleOrInfoOrId) return;
let id = Node.prototype.isPrototypeOf(eleOrInfoOrId) ? BDFDB.ChannelUtils.getId(eleOrInfoOrId) : (typeof eleOrInfoOrId == "object" ? eleOrInfoOrId.id : eleOrInfoOrId);
let channel = LibraryModules.ChannelStore.getChannel(id);
if (channel) {
if (channel.isMultiUserDM()) LibraryModules.ContextMenuUtils.openContextMenu(e, function (e) {
return BDFDB.ReactUtils.createElement(LibraryComponents.ContextMenus.GroupDMContextMenu, Object.assign({}, e, {
channelId: channel.id,
selected: channel.id == LibraryModules.LastChannelStore.getChannelId()
}));
}, {noBlurEvent: true});
else LibraryModules.ContextMenuUtils.openContextMenu(e, function (e) {
return BDFDB.ReactUtils.createElement(BDFDB.ReactUtils.getValue(LibraryComponents, "ContextMenus._Modules.UserContextMenu.exports.default"), Object.assign({}, e, {
type: BDFDB.DiscordConstants.ContextMenuTypes.USER_PRIVATE_CHANNELS,
user: LibraryModules.UserStore.getUser(channel.recipients[0]),
channelId: channel.id,
selected: channel.id == LibraryModules.LastChannelStore.getChannelId()
}));
});
}
};
BDFDB.DMUtils.markAsRead = function (dms) {
if (!dms) return;
var unreadchannels = [];
for (let dm of dms = BDFDB.ArrayUtils.is(dms) ? dms : (typeof dms == "string" || typeof dms == "number" ? Array.of(dms) : Array.from(dms))) {
let id = Node.prototype.isPrototypeOf(dm) ? BDFDB.BDFDB.DMUtils.getId(dm) : (dm && typeof dm == "object" ? dm.id : dm);
if (id) unreadchannels.push(id);
}
for (let i in unreadchannels) BDFDB.TimeUtils.timeout(_ => {LibraryModules.AckUtils.ack(unreadchannels[i]);}, i * 1000);
};
BDFDB.DataUtils = {};
BDFDB.DataUtils.cached = {};
BDFDB.DataUtils.save = function (data, plugin, key, id) {
var configpath, pluginname;
if (!BDFDB.BDUtils.isBDv2()) {
pluginname = typeof plugin === "string" ? plugin : plugin.name;
configpath = LibraryRequires.path.join(BDFDB.BDUtils.getPluginsFolder(), pluginname + ".config.json");
}
else {
pluginname = typeof plugin === "string" ? plugin.toLowerCase() : null;
var contentpath = pluginname ? BDFDB.Plugins[pluginname] ? BDFDB.Plugins[pluginname].contentPath : null : plugin.contentPath;
if (!contentpath) return;
configpath = LibraryRequires.path.join(contentpath, "settings.json");
}
var exists = LibraryRequires.fs.existsSync(configpath);
var config = !exists ? {} : typeof BDFDB.DataUtils.cached[pluginname] !== "undefined" ? BDFDB.DataUtils.cached[pluginname] : InternalBDFDB.readConfig(configpath);
if (id === undefined) config[key] = BDFDB.ObjectUtils.is(data) ? BDFDB.ObjectUtils.sort(data) : data;
else {
if (!BDFDB.ObjectUtils.is(config[key])) config[key] = {};
config[key][id] = BDFDB.ObjectUtils.is(data) ? BDFDB.ObjectUtils.sort(data) : data;
}
if (BDFDB.ObjectUtils.isEmpty(config[key])) delete config[key];
if (BDFDB.ObjectUtils.isEmpty(config)) {
delete BDFDB.DataUtils.cached[pluginname];
if (exists) LibraryRequires.fs.unlinkSync(configpath);
}
else {
config = BDFDB.ObjectUtils.sort(config);
BDFDB.DataUtils.cached[pluginname] = BDFDB.ObjectUtils.deepAssign({}, config);
LibraryRequires.fs.writeFileSync(configpath, JSON.stringify(config, null, " "));
}
};
BDFDB.DataUtils.load = function (plugin, key, id) {
var configpath, pluginname;
if (!BDFDB.BDUtils.isBDv2()) {
pluginname = typeof plugin === "string" ? plugin : plugin.name;
configpath = LibraryRequires.path.join(BDFDB.BDUtils.getPluginsFolder(), pluginname + ".config.json");
}
else {
pluginname = typeof plugin === "string" ? plugin.toLowerCase() : null;
var contentpath = pluginname ? BDFDB.Plugins[pluginname] ? BDFDB.Plugins[pluginname].contentPath : null : plugin.contentPath;
if (!contentpath) return {};
configpath = LibraryRequires.path.join(contentpath, "settings.json");
}
if (!LibraryRequires.fs.existsSync(configpath)) {
delete BDFDB.DataUtils.cached[pluginname];
return {};
}
var config = typeof BDFDB.DataUtils.cached[pluginname] !== "undefined" && typeof BDFDB.DataUtils.cached[pluginname][key] !== "undefined" ? BDFDB.DataUtils.cached[pluginname] : InternalBDFDB.readConfig(configpath);
BDFDB.DataUtils.cached[pluginname] = BDFDB.ObjectUtils.deepAssign({}, config);
let keydata = BDFDB.ObjectUtils.deepAssign({}, config && typeof config[key] !== "undefined" ? config[key] : {});
if (id === undefined) return keydata;
else return keydata[id] === undefined ? null : keydata[id];
};
BDFDB.DataUtils.remove = function (plugin, key, id) {
var configpath, pluginname;
if (!BDFDB.BDUtils.isBDv2()) {
pluginname = typeof plugin === "string" ? plugin : plugin.name;
configpath = LibraryRequires.path.join(BDFDB.BDUtils.getPluginsFolder(), pluginname + ".config.json");
}
else {
pluginname = typeof plugin === "string" ? plugin.toLowerCase() : null;
var contentpath = pluginname ? BDFDB.Plugins[pluginname] ? BDFDB.Plugins[pluginname].contentPath : null : plugin.contentPath;
if (!contentpath) return;
configpath = LibraryRequires.path.join(contentpath, "settings.json");
}
var exists = LibraryRequires.fs.existsSync(configpath);
var config = !exists ? {} : typeof BDFDB.DataUtils.cached[pluginname] !== "undefined" ? BDFDB.DataUtils.cached[pluginname] : InternalBDFDB.readConfig(configpath);
if (id === undefined) delete config[key];
else if (BDFDB.ObjectUtils.is(config[key])) delete config[key][id];
if (BDFDB.ObjectUtils.isEmpty(config[key])) delete config[key];
if (BDFDB.ObjectUtils.isEmpty(config)) {
delete BDFDB.DataUtils.cached[pluginname];
if (exists) LibraryRequires.fs.unlinkSync(configpath);
}
else {
config = BDFDB.ObjectUtils.sort(config);
BDFDB.DataUtils.cached[pluginname] = config;
LibraryRequires.fs.writeFileSync(configpath, JSON.stringify(config, null, " "));
}
};
BDFDB.DataUtils.get = function (plugin, key, id) {
plugin = typeof plugin == "string" ? BDFDB.BDUtils.getPlugin(plugin) : plugin;
if (!BDFDB.ObjectUtils.is(plugin) || !plugin.defaults || !plugin.defaults[key]) return id === undefined ? {} : null;
var oldconfig = BDFDB.DataUtils.load(plugin, key), newconfig = {}, update = false;
for (let k in plugin.defaults[key]) {
if (oldconfig[k] == null) {
newconfig[k] = BDFDB.ObjectUtils.is(plugin.defaults[key][k].value) ? BDFDB.ObjectUtils.deepAssign({}, plugin.defaults[key][k].value) : plugin.defaults[key][k].value;
update = true;
}
else newconfig[k] = oldconfig[k];
}
if (update) BDFDB.DataUtils.save(newconfig, plugin, key);
if (id === undefined) return newconfig;
else return newconfig[id] === undefined ? null : newconfig[id];
};
InternalBDFDB.readConfig = function (path) {
try {return JSON.parse(LibraryRequires.fs.readFileSync(path));}
catch (err) {return {};}
};
BDFDB.ColorUtils = {};
BDFDB.ColorUtils.convert = function (color, conv, type) {
if (BDFDB.ObjectUtils.is(color)) {
var newcolor = {};
for (let pos in color) newcolor[pos] = BDFDB.ColorUtils.convert(color[pos], conv, type);
return newcolor;
}
else {
conv = conv === undefined || !conv ? conv = "RGBCOMP" : conv.toUpperCase();
type = type === undefined || !type || !["RGB", "RGBA", "RGBCOMP", "HSL", "HSLA", "HSLCOMP", "HEX", "HEXA", "INT"].includes(type.toUpperCase()) ? BDFDB.ColorUtils.getType(color) : type.toUpperCase();
if (conv == "RGBCOMP") {
switch (type) {
case "RGBCOMP":
if (color.length == 3) return processRGB(color);
else if (color.length == 4) {
let a = processA(color.pop());
return processRGB(color).concat(a);
}
break;
case "RGB":
return processRGB(color.replace(/\s/g, "").slice(4, -1).split(","));
case "RGBA":
let comp = color.replace(/\s/g, "").slice(5, -1).split(",");
let a = processA(comp.pop());
return processRGB(comp).concat(a);
case "HSLCOMP":
if (color.length == 3) return BDFDB.ColorUtils.convert(`hsl(${processHSL(color).join(",")})`, "RGBCOMP");
else if (color.length == 4) {
let a = processA(color.pop());
return BDFDB.ColorUtils.convert(`hsl(${processHSL(color).join(",")})`, "RGBCOMP").concat(a);
}
break;
case "HSL":
var hslcomp = processHSL(color.replace(/\s/g, "").slice(4, -1).split(","));
var r, g, b, m, c, x, p, q;
var h = hslcomp[0] / 360, l = parseInt(hslcomp[1]) / 100, s = parseInt(hslcomp[2]) / 100; m = Math.floor(h * 6); c = h * 6 - m; x = s * (1 - l); p = s * (1 - c * l); q = s * (1 - (1 - c) * l);
switch (m % 6) {
case 0: r = s, g = q, b = x; break;
case 1: r = p, g = s, b = x; break;
case 2: r = x, g = s, b = q; break;
case 3: r = x, g = p, b = s; break;
case 4: r = q, g = x, b = s; break;
case 5: r = s, g = x, b = p; break;
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
case "HSLA":
var hslcomp = color.replace(/\s/g, "").slice(5, -1).split(",");
return BDFDB.ColorUtils.convert(`hsl(${hslcomp.slice(0, 3).join(",")})`, "RGBCOMP").concat(processA(hslcomp.pop()));
case "HEX":
var hex = /^#([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})$|^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);
return [parseInt(hex[1] + hex[1] || hex[4], 16).toString(), parseInt(hex[2] + hex[2] || hex[5], 16).toString(), parseInt(hex[3] + hex[3] || hex[6], 16).toString()];
case "HEXA":
var hex = /^#([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})$|^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);
return [parseInt(hex[1] + hex[1] || hex[5], 16).toString(), parseInt(hex[2] + hex[2] || hex[6], 16).toString(), parseInt(hex[3] + hex[3] || hex[7], 16).toString(), Math.floor(BDFDB.NumberUtils.mapRange([0, 255], [0, 100], parseInt(hex[4] + hex[4] || hex[8], 16).toString()))/100];
case "INT":
color = processINT(color);
return [(color >> 16 & 255).toString(), (color >> 8 & 255).toString(), (color & 255).toString()];
default:
return null;
}
}
else {
var rgbcomp = type == "RGBCOMP" ? color : BDFDB.ColorUtils.convert(color, "RGBCOMP", type);
if (rgbcomp) switch (conv) {
case "RGB":
return `rgb(${processRGB(rgbcomp.slice(0, 3)).join(",")})`;
case "RGBA":
rgbcomp = rgbcomp.slice(0, 4);
var a = rgbcomp.length == 4 ? processA(rgbcomp.pop()) : 1;
return `rgba(${processRGB(rgbcomp).concat(a).join(",")})`;
case "HSLCOMP":
var a = rgbcomp.length == 4 ? processA(rgbcomp.pop()) : null;
var hslcomp = processHSL(BDFDB.ColorUtils.convert(rgbcomp, "HSL").replace(/\s/g, "").split(","));
return a != null ? hslcomp.concat(a) : hslcomp;
case "HSL":
var r = processC(rgbcomp[0]), g = processC(rgbcomp[1]), b = processC(rgbcomp[2]);
var max = Math.max(r, g, b), min = Math.min(r, g, b), dif = max - min, h, l = max === 0 ? 0 : dif / max, s = max / 255;
switch (max) {
case min: h = 0; break;
case r: h = g - b + dif * (g < b ? 6 : 0); h /= 6 * dif; break;
case g: h = b - r + dif * 2; h /= 6 * dif; break;
case b: h = r - g + dif * 4; h /= 6 * dif; break;
}
return `hsl(${processHSL([Math.round(h * 360), l * 100, s * 100]).join(",")})`;
case "HSLA":
var j0 = rgbcomp.length == 4 ? processA(rgbcomp.pop()) : 1;
return `hsla(${BDFDB.ColorUtils.convert(rgbcomp, "HSL").slice(4, -1).split(",").concat(j0).join(",")})`;
case "HEX":
return ("#" + (0x1000000 + (rgbcomp[2] | rgbcomp[1] << 8 | rgbcomp[0] << 16)).toString(16).slice(1)).toUpperCase();
case "HEXA":
return ("#" + (0x1000000 + (rgbcomp[2] | rgbcomp[1] << 8 | rgbcomp[0] << 16)).toString(16).slice(1) + (0x100 + Math.round(BDFDB.NumberUtils.mapRange([0, 100], [0, 255], processA(rgbcomp[3]) * 100))).toString(16).slice(1)).toUpperCase();
case "INT":
return processINT(rgbcomp[2] | rgbcomp[1] << 8 | rgbcomp[0] << 16);
default:
return null;
}
}
}
return null;
function processC(c) {if (c == null) {return 255;} else {c = parseInt(c.toString().replace(/[^0-9\-]/g, ""));return isNaN(c) || c > 255 ? 255 : c < 0 ? 0 : c;}};
function processRGB(comp) {return comp.map(c => {return processC(c);});};
function processA(a) {if (a == null) {return 1;} else {a = a.toString();a = (a.indexOf("%") > -1 ? 0.01 : 1) * parseFloat(a.replace(/[^0-9\.\-]/g, ""));return isNaN(a) || a > 1 ? 1 : a < 0 ? 0 : a;}};
function processSL(sl) {if (sl == null) {return "100%";} else {sl = parseFloat(sl.toString().replace(/[^0-9\.\-]/g, ""));return (isNaN(sl) || sl > 100 ? 100 : sl < 0 ? 0 : sl) + "%";}};
function processHSL(comp) {let h = parseFloat(comp.shift().toString().replace(/[^0-9\.\-]/g, ""));h = isNaN(h) || h > 360 ? 360 : h < 0 ? 0 : h;return [h].concat(comp.map(sl => {return processSL(sl);}));};
function processINT(c) {if (c == null) {return 16777215;} else {c = parseInt(c.toString().replace(/[^0-9]/g, ""));return isNaN(c) || c > 16777215 ? 16777215 : c < 0 ? 0 : c;}};
};
BDFDB.ColorUtils.setAlpha = function (color, a, conv) {
if (BDFDB.ObjectUtils.is(color)) {
var newcolor = {};
for (let pos in color) newcolor[pos] = BDFDB.ColorUtils.setAlpha(color[pos], a, conv);
return newcolor;
}
else {
var comp = BDFDB.ColorUtils.convert(color, "RGBCOMP");
if (comp) {
a = a.toString();
a = (a.indexOf("%") > -1 ? 0.01 : 1) * parseFloat(a.replace(/[^0-9\.\-]/g, ""));
a = isNaN(a) || a > 1 ? 1 : a < 0 ? 0 : a;
comp[3] = a;
conv = (conv || BDFDB.ColorUtils.getType(color)).toUpperCase();
conv = conv == "RGB" || conv == "HSL" || conv == "HEX" ? conv + "A" : conv;
return BDFDB.ColorUtils.convert(comp, conv);
}
}
return null;
};
BDFDB.ColorUtils.getAlpha = function (color) {
var comp = BDFDB.ColorUtils.convert(color, "RGBCOMP");
if (comp) {
if (comp.length == 3) return 1;
else if (comp.length == 4) {
let a = comp[3].toString();
a = (a.indexOf("%") > -1 ? 0.01 : 1) * parseFloat(a.replace(/[^0-9\.\-]/g, ""));
return isNaN(a) || a > 1 ? 1 : a < 0 ? 0 : a;
}
}
return null;
};
BDFDB.ColorUtils.change = function (color, value, conv) {
value = parseFloat(value);
if (color != null && typeof value == "number" && !isNaN(value)) {
if (BDFDB.ObjectUtils.is(color)) {
var newcolor = {};
for (let pos in color) newcolor[pos] = BDFDB.ColorUtils.change(color[pos], value, conv);
return newcolor;
}
else {
var comp = BDFDB.ColorUtils.convert(color, "RGBCOMP");
if (comp) {
if (parseInt(value) !== value) {
value = value.toString();
value = (value.indexOf("%") > -1 ? 0.01 : 1) * parseFloat(value.replace(/[^0-9\.\-]/g, ""));
value = isNaN(value) ? 0 : value;
return BDFDB.ColorUtils.convert([Math.round(comp[0] * (1 + value)), Math.round(comp[1] * (1 + value)), Math.round(comp[2] * (1 + value))], conv || BDFDB.ColorUtils.getType(color));
}
else return BDFDB.ColorUtils.convert([Math.round(comp[0] + value), Math.round(comp[1] + value), Math.round(comp[2] + value)], conv || BDFDB.ColorUtils.getType(color));
}
}
}
return null;
};
BDFDB.ColorUtils.invert = function (color, conv) {
if (BDFDB.ObjectUtils.is(color)) {
var newcolor = {};
for (let pos in color) newcolor[pos] = BDFDB.ColorUtils.invert(color[pos], conv);
return newcolor;
}
else {
var comp = BDFDB.ColorUtils.convert(color, "RGBCOMP");
if (comp) return BDFDB.ColorUtils.convert([255 - comp[0], 255 - comp[1], 255 - comp[2]], conv || BDFDB.ColorUtils.getType(color));
}
return null;
};
BDFDB.ColorUtils.compare = function (color1, color2) {
if (color1 && color2) {
color1 = BDFDB.ColorUtils.convert(color1, "RGBA");
color2 = BDFDB.ColorUtils.convert(color2, "RGBA");
if (color1 && color2) return BDFDB.equals(color1, color2);
}
return null;
};
BDFDB.ColorUtils.isBright = function (color, compare = 160) {
color = BDFDB.ColorUtils.convert(color, "RGBCOMP");
if (!color) return false;
return parseInt(compare) < Math.sqrt(0.299 * color[0]**2 + 0.587 * color[1]**2 + 0.144 * color[2]**2);
};
BDFDB.ColorUtils.getType = function (color) {
if (color != null) {
if (typeof color === "object" && (color.length == 3 || color.length == 4)) {
if (isRGB(color)) return "RGBCOMP";
else if (isHSL(color)) return "HSLCOMP";
}
else if (typeof color === "string") {
if (/^#[a-f\d]{3}$|^#[a-f\d]{6}$/i.test(color)) return "HEX";
else if (/^#[a-f\d]{4}$|^#[a-f\d]{8}$/i.test(color)) return "HEXA";
else {
color = color.toUpperCase();
var comp = color.replace(/[^0-9\.\-\,\%]/g, "").split(",");
if (color.indexOf("RGB(") == 0 && comp.length == 3 && isRGB(comp)) return "RGB";
else if (color.indexOf("RGBA(") == 0 && comp.length == 4 && isRGB(comp)) return "RGBA";
else if (color.indexOf("HSL(") == 0 && comp.length == 3 && isHSL(comp)) return "HSL";
else if (color.indexOf("HSLA(") == 0 && comp.length == 4 && isHSL(comp)) return "HSLA";
}
}
else if (typeof color === "number" && parseInt(color) == color && color > -1 && color < 16777216) return "INT";
}
return null;
function isRGB(comp) {return comp.slice(0, 3).every(rgb => rgb.toString().indexOf("%") == -1 && parseFloat(rgb) == parseInt(rgb));};
function isHSL(comp) {return comp.slice(1, 3).every(hsl => hsl.toString().indexOf("%") == hsl.length - 1);};
};
BDFDB.ColorUtils.createGradient = function (colorobj, direction = "to right") {
var sortedgradient = {};
var gradientstring = "linear-gradient(" + direction;
for (let pos of Object.keys(colorobj).sort()) {
let color = BDFDB.ColorUtils.convert(colorobj[pos], "RGBA");
gradientstring += color ? `, ${color} ${pos*100}%` : ''
}
return gradientstring += ")";
};
BDFDB.ColorUtils.getSwatchColor = function (container, number) {
if (!Node.prototype.isPrototypeOf(container)) return;
var swatches = container.querySelector(`${BDFDB.dotCN.colorpickerswatches}[number="${number}"], ${BDFDB.dotCN.colorpickerswatch}[number="${number}"]`);
if (!swatches) return null;
var ins = BDFDB.ReactUtils.getInstance(swatches);
if (ins) return BDFDB.ColorUtils.convert(BDFDB.ReactUtils.findValue(ins, "selectedColor", {up:true, blacklist:{"props":true}}));
else { // REMOVE ONCE REWRITTEN
var swatch = swatches.querySelector(`${BDFDB.dotCN.colorpickerswatch + BDFDB.dotCN.colorpickerswatchselected}`);
return swatch ? BDFDB.ColorUtils.convert(swatch.gradient || swatch.style.getPropertyValue("background-color"), "RGBCOMP") : null;
}
};
BDFDB.ColorUtils.openPicker = function (container, target, color, options = {gradient: true, alpha: true, callback: _ => {}}) {
if (!container || !target) return;
if (typeof options.callback != "function") options.callback = _ => {};
var hexformat = options.alpha ? "HEXA" : "HEX";
var hexregex = options.alpha ? /^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i : /^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
var isreact = BDFDB.ObjectUtils.is(container) && !!container._reactInternalFiber;
var isswatches = !isreact && BDFDB.DOMUtils.containsClass(container, "swatches");
var isgradient = color && BDFDB.ObjectUtils.is(color);
var selectedcolor = BDFDB.ColorUtils.convert(isgradient ? color[Object.keys(color)[0]] : color, hexformat) || (options.alpha ? "#000000FF" : "#000000");
var [h, s, l] = BDFDB.ColorUtils.convert(selectedcolor, "HSLCOMP");
var a = BDFDB.ColorUtils.getAlpha(isgradient ? color[Object.keys(color)[0]] : color);
a = a == null ? 1 : a;
var targetrects = BDFDB.DOMUtils.getRects(target);
var colorPicker = BDFDB.DOMUtils.create(`
`);
document.querySelector(BDFDB.dotCN.popouts).appendChild(colorPicker);
var removePopout = e => {
if (!colorPicker.contains(e.target)) {
document.removeEventListener("mousedown", removePopout);
colorPicker.remove();
}
};
document.addEventListener("mousedown", removePopout);
var hexinput = colorPicker.querySelector(BDFDB.dotCNS.colorpickerhexinput + BDFDB.dotCN.input);
var satpane = colorPicker.querySelector(".saturation-color");
var satcursor = colorPicker.querySelector(".saturation-cursor");
var huepane = colorPicker.querySelector(".hue-horizontal");
var huecursor = colorPicker.querySelector(".hue-cursor");
var alphabar = colorPicker.querySelector(".alpha-bar");
var alphapane = colorPicker.querySelector(".alpha-horizontal");
var alphacursor = colorPicker.querySelector(".alpha-cursor");
var gradientbutton = colorPicker.querySelector(".gradient-button");
var gradientbar = colorPicker.querySelector(".gradient-bar");
var gradientpane = colorPicker.querySelector(".gradient-horizontal");
var sMinX, sMaxX, sMinY, sMaxY, hMinX, hMaxX, aMinX, aMaxX, gMinX, gMaxX;
updateRects();
if (isgradient) for (let pos in color) if (pos > 0 && pos < 1) gradientpane.appendChild(BDFDB.DOMUtils.create(`
`));
updateColors(false);
if (!options.gradient) BDFDB.DOMUtils.remove(colorPicker.querySelectorAll(".gradient-button, .gradient-bar"));
if (!options.alpha) BDFDB.DOMUtils.remove(colorPicker.querySelectorAll(".alpha-bar"));
BDFDB.ListenerUtils.addToChildren(colorPicker, "mousedown", ".move-corner", e => {
var rects = BDFDB.DOMUtils.getRects(colorPicker);
var transform = getComputedStyle(colorPicker, null).getPropertyValue("transform").replace(/[^0-9,-]/g,"").split(",");
var left = rects.left - (transform.length > 4 ? parseFloat(transform[4]) : 0);
var top = rects.top - (transform.length > 4 ? parseFloat(transform[5]) : 0);
var oldX = e.pageX;
var oldY = e.pageY;
var mouseup = _ => {
BDFDB.DOMUtils.removeLocalStyle("disableTextSelection");
document.removeEventListener("mouseup", mouseup);
document.removeEventListener("mousemove", mousemove);
};
var mousemove = e2 => {
left = left - (oldX - e2.pageX);
top = top - (oldY - e2.pageY);
oldX = e2.pageX;
oldY = e2.pageY;
colorPicker.style.setProperty("left", left + "px", "important");
colorPicker.style.setProperty("top", top + "px", "important");
updateRects();
};
document.addEventListener("mouseup", mouseup);
document.addEventListener("mousemove", mousemove);
});
satpane.addEventListener("mousedown", e => {
s = BDFDB.NumberUtils.mapRange([sMinX, sMaxX], [0, 100], e.clientX) + "%";
l = BDFDB.NumberUtils.mapRange([sMinY, sMaxY], [100, 0], e.clientY) + "%";
updateColors(true);
var mouseup = _ => {
document.removeEventListener("mouseup", mouseup);
document.removeEventListener("mousemove", mousemove);
};
var mousemove = e2 => {
s = BDFDB.NumberUtils.mapRange([sMinX, sMaxX], [0, 100], e2.clientX) + "%";
l = BDFDB.NumberUtils.mapRange([sMinY, sMaxY], [100, 0], e2.clientY) + "%";
updateColors(true);
};
document.addEventListener("mouseup", mouseup);
document.addEventListener("mousemove", mousemove);
});
huepane.addEventListener("mousedown", e => {
h = BDFDB.NumberUtils.mapRange([hMinX, hMaxX], [0, 360], e.clientX);
updateColors(true);
var mouseup = _ => {
document.removeEventListener("mouseup", mouseup);
document.removeEventListener("mousemove", mousemove);
};
var mousemove = e2 => {
h = BDFDB.NumberUtils.mapRange([hMinX, hMaxX], [0, 360], e2.clientX);
updateColors(true);
};
document.addEventListener("mouseup", mouseup);
document.addEventListener("mousemove", mousemove);
});
alphapane.addEventListener("mousedown", e => {
a = BDFDB.NumberUtils.mapRange([aMinX, aMaxX], [0, 1], e.clientX);
updateColors(true);
var bubble = BDFDB.DOMUtils.create(``);
var mouseup = _ => {
bubble.remove();
document.removeEventListener("mouseup", mouseup);
document.removeEventListener("mousemove", mousemove);
};
var mousemove = e2 => {
if (!bubble.parentElement) alphacursor.appendChild(bubble);
a = Math.floor(BDFDB.NumberUtils.mapRange([aMinX, aMaxX], [0, 100], e2.clientX))/100;
bubble.innerText = a;
updateColors(true);
};
document.addEventListener("mouseup", mouseup);
document.addEventListener("mousemove", mousemove);
});
gradientpane.addEventListener("mousedown", e => {
BDFDB.TimeUtils.timeout(_ => {
if (BDFDB.DOMUtils.containsClass(e.target.parentElement, "gradient-cursor")) {
if (e.which == 1) {
if (!BDFDB.DOMUtils.containsClass(e.target.parentElement, "selected")) {
BDFDB.DOMUtils.removeClass(gradientpane.querySelectorAll(".gradient-cursor.selected"), "selected");
BDFDB.DOMUtils.addClass(e.target.parentElement, "selected");
[h, s, l] = BDFDB.ColorUtils.convert(e.target.style.getPropertyValue("background-color"), "HSLCOMP");
a = BDFDB.ColorUtils.getAlpha(e.target.style.getPropertyValue("background-color"));
updateColors(true);
}
if (!BDFDB.DOMUtils.containsClass(e.target.parentElement, "edge")) {
var mouseup = _ => {
document.removeEventListener("mouseup", mouseup);
document.removeEventListener("mousemove", mousemove);
};
var mousemove = e2 => {
e.target.parentElement.style.setProperty("left", BDFDB.NumberUtils.mapRange([gMinX, gMaxX], [1, 99], e2.clientX) + "%");
updateGradient();
};
document.addEventListener("mouseup", mouseup);
document.addEventListener("mousemove", mousemove);
}
}
else if (e.which == 3 && !BDFDB.DOMUtils.containsClass(e.target.parentElement, "edge")) {
BDFDB.DOMUtils.remove(e.target.parentElement);
if (BDFDB.DOMUtils.containsClass(e.target.parentElement, "selected")) {
var firstcursor = gradientpane.querySelector(".gradient-cursor");
BDFDB.DOMUtils.addClass(firstcursor, "selected");
[h, s, l] = BDFDB.ColorUtils.convert(firstcursor.firstElementChild.style.getPropertyValue("background-color"), "HSLCOMP");
a = BDFDB.ColorUtils.getAlpha(firstElementChild.style.getPropertyValue("background-color"));
}
updateColors(true);
}
}
else if (gradientpane == e.target && e.which == 1) {
BDFDB.DOMUtils.removeClass(gradientpane.querySelectorAll(".gradient-cursor.selected"), "selected");
var newcursor = BDFDB.DOMUtils.create(`
`);
gradientpane.appendChild(newcursor);
[h, s, l] = [0, "0%", "0%"];
a = 1;
updateColors(true);
var mouseup = _ => {
document.removeEventListener("mouseup", mouseup);
document.removeEventListener("mousemove", mousemove);
};
var mousemove = e2 => {
newcursor.style.setProperty("left", BDFDB.NumberUtils.mapRange([gMinX, gMaxX], [1, 99], e2.clientX) + "%");
updateGradient();
};
document.addEventListener("mouseup", mouseup);
document.addEventListener("mousemove", mousemove);
}
});
});
hexinput.addEventListener("input", e => {
if (hexregex.test(hexinput.value)) {
[h, s, l, a] = BDFDB.ColorUtils.convert(hexinput.value, "HSLCOMP");
if (a == null) a = 1;
updateColors(false);
}
});
gradientbutton.addEventListener("click", e => {
isgradient = !isgradient;
BDFDB.DOMUtils.toggle(gradientbar, isgradient);
BDFDB.DOMUtils.toggleClass(gradientbutton, "selected", isgradient);
updateColors(true);
});
gradientbutton.addEventListener("mouseenter", e => {
BDFDB.TooltipUtils.create(gradientbutton, "Color Gradient", {type: "bottom"});
});
function updateRects () {
var satpanerects = BDFDB.DOMUtils.getRects(satpane);
sMinX = satpanerects.left;
sMaxX = sMinX + satpanerects.width;
sMinY = satpanerects.top;
sMaxY = sMinY + satpanerects.height;
var huepanerects = BDFDB.DOMUtils.getRects(huepane);
hMinX = huepanerects.left;
hMaxX = hMinX + huepanerects.width;
var alphapanerects = BDFDB.DOMUtils.getRects(alphapane);
aMinX = alphapanerects.left;
aMaxX = aMinX + alphapanerects.width;
var gradientpanerects = BDFDB.DOMUtils.getRects(gradientpane);
gMinX = gradientpanerects.left;
gMaxX = gMinX + gradientpanerects.width;
}
function updateColors (setinput) {
satpane.style.setProperty("background", BDFDB.ColorUtils.convert([h, "100%", "100%"], "RGB"), "important");
satcursor.style.setProperty("left", s, "important");
satcursor.style.setProperty("top", BDFDB.NumberUtils.mapRange([0, 100], [100, 0], parseFloat(l)) + "%", "important");
huecursor.style.setProperty("left", BDFDB.NumberUtils.mapRange([0, 360], [0, 100], h) + "%", "important");
alphapane.style.setProperty("background", `linear-gradient(to right, ${BDFDB.ColorUtils.setAlpha([h, s, l], 0, "RGBA")}, ${BDFDB.ColorUtils.setAlpha([h, s, l], 1, "RGBA")}`, "important");
alphacursor.style.setProperty("left", (a * 100) + "%", "important");
var hex = BDFDB.ColorUtils.convert([h, s, l, a], hexformat);
var rgb = BDFDB.ColorUtils.convert(hex, "RGBA");
if (isreact) {
if (isgradient) {
gradientpane.querySelector(".gradient-cursor.selected").firstElementChild.style.setProperty("background-color", rgb);
updateGradient();
}
else {
container.setState({
selectedColor: rgb,
customColor: rgb
});
if (container.refInput) {
container.refInput.props.value = !rgb ? "" : (container.state.compMode ? BDFDB.ColorUtils.convert(rgb, "RGBCOMP").slice(0,3).join(",") : rgb);
BDFDB.ReactUtils.forceUpdate(container.refInput);
}
}
}
else if (isswatches) {
setSwatch(container.querySelector(BDFDB.dotCN.colorpickerswatch + BDFDB.dotCN.colorpickerswatchselected), null, false);
if (isgradient) {
gradientpane.querySelector(".gradient-cursor.selected").firstElementChild.style.setProperty("background-color", rgb);
updateGradient();
}
else setSwatch(container.querySelector(BDFDB.dotCN.colorpickerswatch + BDFDB.dotCN.colorpickerswatch), rgb, true);
}
if (setinput) hexinput.value = hex;
options.callback(rgb);
}
function updateGradient () {
gradientpane.style.removeProperty("background-color");
var gradient = {};
for (let cursor of gradientpane.querySelectorAll(".gradient-cursor")) gradient[parseFloat(cursor.style.getPropertyValue("left"))/100] = cursor.firstElementChild.style.getPropertyValue("background-color");
gradientpane.style.setProperty("background-image", BDFDB.ColorUtils.createGradient(gradient));
if (isreact) container.setState({
selectedColor: gradient,
customColor: gradient
});
else setSwatch(container.querySelector(BDFDB.dotCN.colorpickerswatch + BDFDB.dotCN.colorpickerswatch), gradient, true);
}
};
BDFDB.DOMUtils = {};
BDFDB.DOMUtils.getSelection = function () {
let selection = document.getSelection();
return selection && selection.anchorNode ? selection.getRangeAt(0).toString() : "";
};
BDFDB.DOMUtils.addClass = function (eles, ...classes) {
if (!eles || !classes) return;
for (let ele of [eles].flat(10).filter(n => n)) {
if (Node.prototype.isPrototypeOf(ele)) add(ele);
else if (NodeList.prototype.isPrototypeOf(ele)) for (let e of ele) add(e);
else if (typeof ele == "string") for (let e of ele.split(",")) if (e && (e = e.trim())) for (let n of document.querySelectorAll(e)) add(n);
}
function add(node) {
if (node && node.classList) for (let cla of classes) for (let cl of [cla].flat(10).filter(n => n)) if (typeof cl == "string") for (let c of cl.split(" ")) if (c) node.classList.add(c);
}
};
BDFDB.DOMUtils.removeClass = function (eles, ...classes) {
if (!eles || !classes) return;
for (let ele of [eles].flat(10).filter(n => n)) {
if (Node.prototype.isPrototypeOf(ele)) remove(ele);
else if (NodeList.prototype.isPrototypeOf(ele)) for (let e of ele) remove(e);
else if (typeof ele == "string") for (let e of ele.split(",")) if (e && (e = e.trim())) for (let n of document.querySelectorAll(e)) remove(n);
}
function remove(node) {
if (node && node.classList) for (let cla of classes) for (let cl of [cla].flat(10).filter(n => n)) if (typeof cl == "string") for (let c of cl.split(" ")) if (c) node.classList.remove(c);
}
};
BDFDB.DOMUtils.toggleClass = function (eles, ...classes) {
if (!eles || !classes) return;
var force = classes.pop();
if (typeof force != "boolean") {
classes.push(force);
force = undefined;
}
if (!classes.length) return;
for (let ele of [eles].flat(10).filter(n => n)) {
if (!ele) {}
else if (Node.prototype.isPrototypeOf(ele)) toggle(ele);
else if (NodeList.prototype.isPrototypeOf(ele)) for (let e of ele) toggle(e);
else if (typeof ele == "string") for (let e of ele.split(",")) if (e && (e = e.trim())) for (let n of document.querySelectorAll(e)) toggle(n);
}
function toggle(node) {
if (node && node.classList) for (let cla of classes) for (let cl of [cla].flat(10).filter(n => n)) if (typeof cl == "string") for (let c of cl.split(" ")) if (c) node.classList.toggle(c, force);
}
};
BDFDB.DOMUtils.containsClass = function (eles, ...classes) {
if (!eles || !classes) return;
var all = classes.pop();
if (typeof all != "boolean") {
classes.push(all);
all = true;
}
if (!classes.length) return;
var contained = undefined;
for (let ele of BDFDB.ArrayUtils.is(eles) ? eles : Array.of(eles)) {
if (!ele) {}
else if (Node.prototype.isPrototypeOf(ele)) contains(ele);
else if (NodeList.prototype.isPrototypeOf(ele)) for (let e of ele) contains(e);
else if (typeof ele == "string") for (let c of ele.split(",")) if (c && (c = c.trim())) for (let n of document.querySelectorAll(c)) contains(n);
}
return contained;
function contains(node) {
if (node && node.classList) for (let cla of classes) if (typeof cla == "string") for (let c of cla.split(" ")) if (c) {
if (contained === undefined) contained = all;
if (all && !node.classList.contains(c)) contained = false;
if (!all && node.classList.contains(c)) contained = true;
}
}
};
BDFDB.DOMUtils.replaceClass = function (eles, oldclass, newclass) {
if (!eles || typeof oldclass != "string" || typeof newclass != "string") return;
for (let ele of [eles].flat(10).filter(n => n)) {
if (Node.prototype.isPrototypeOf(ele)) replace(ele);
else if (NodeList.prototype.isPrototypeOf(ele)) for (let e of ele) replace(e);
else if (typeof ele == "string") for (let e of ele.split(",")) if (e && (e = e.trim())) for (let n of document.querySelectorAll(e)) replace(n);
}
function replace(node) {
if (node && node.tagName && node.className) node.className = node.className.replace(new RegExp(oldclass, "g"), newclass).trim();
}
};
BDFDB.DOMUtils.formatClassName = function (...classes) {
return BDFDB.ArrayUtils.removeCopies(classes.flat(10).filter(n => n).join(" ").split(" ")).join(" ").trim();
};
BDFDB.DOMUtils.removeClassFromDOM = function (...classes) {
for (let c of classes.flat(10).filter(n => n)) if (typeof c == "string") for (let a of c.split(",")) if (a && (a = a.replace(/\.|\s/g, ""))) BDFDB.DOMUtils.removeClass(document.querySelectorAll("." + a), a);
};
BDFDB.DOMUtils.show = function (...eles) {
BDFDB.DOMUtils.toggle(...eles, true);
};
BDFDB.DOMUtils.hide = function (...eles) {
BDFDB.DOMUtils.toggle(...eles, false);
};
BDFDB.DOMUtils.toggle = function (...eles) {
if (!eles) return;
var force = eles.pop();
if (typeof force != "boolean") {
eles.push(force);
force = undefined;
}
if (!eles.length) return;
for (let ele of eles.flat(10).filter(n => n)) {
if (Node.prototype.isPrototypeOf(ele)) toggle(ele);
else if (NodeList.prototype.isPrototypeOf(ele)) for (let node of ele) toggle(node);
else if (typeof ele == "string") for (let c of ele.split(",")) if (c && (c = c.trim())) for (let node of document.querySelectorAll(c)) toggle(node);
}
function toggle(node) {
if (!node || !Node.prototype.isPrototypeOf(node)) return;
var hidden = force === undefined ? !BDFDB.DOMUtils.isHidden(node) : !force;
if (hidden) node.style.setProperty("display", "none", "important");
else node.style.removeProperty("display");
}
};
BDFDB.DOMUtils.isHidden = function (node) {
if (Node.prototype.isPrototypeOf(node) && node.nodeType != Node.TEXT_NODE) return getComputedStyle(node, null).getPropertyValue("display") == "none";
};
BDFDB.DOMUtils.remove = function (...eles) {
for (let ele of eles.flat(10).filter(n => n)) {
if (Node.prototype.isPrototypeOf(ele)) ele.remove();
else if (NodeList.prototype.isPrototypeOf(ele)) {
let nodes = Array.from(ele);
while (nodes.length) nodes.shift().remove();
}
else if (typeof ele == "string") for (let c of ele.split(",")) if (c && (c = c.trim())) {
let nodes = Array.from(document.querySelectorAll(c));
while (nodes.length) nodes.shift().remove();
}
}
};
BDFDB.DOMUtils.create = function (html) {
if (typeof html != "string" || !html.trim()) return null;
let template = document.createElement("template");
try {template.innerHTML = html.replace(/(?[\t\r\n]+<(?!pre)/g, "><");}
catch (err) {template.innerHTML = html.replace(/>[\t\r\n]+<(?!pre)/g, "><");}
if (template.content.childNodes.length == 1) return template.content.firstElementChild;
else {
var wrapper = document.createElement("span");
var nodes = Array.from(template.content.childNodes);
while (nodes.length) wrapper.appendChild(nodes.shift());
return wrapper;
}
};
BDFDB.DOMUtils.getParent = function (listOrSelector, node) {
var parent = null;
if (Node.prototype.isPrototypeOf(node) && listOrSelector) {
var list = NodeList.prototype.isPrototypeOf(listOrSelector) ? listOrSelector : typeof listOrSelector == "string" ? document.querySelectorAll(listOrSelector) : null;
if (list) for (let listnode of list) if (listnode.contains(node)) {
parent = listnode;
break;
}
}
return parent;
};
BDFDB.DOMUtils.setText = function (node, stringOrNode) {
if (!node || !Node.prototype.isPrototypeOf(node)) return;
var textnode = node.nodeType == Node.TEXT_NODE ? node : null;
if (!textnode) for (let child of node.childNodes) if (child.nodeType == Node.TEXT_NODE || BDFDB.DOMUtils.containsClass(child, "BDFDB-textnode")) {
textnode = child;
break;
}
if (textnode) {
if (Node.prototype.isPrototypeOf(stringOrNode) && stringOrNode.nodeType != Node.TEXT_NODE) {
BDFDB.DOMUtils.addClass(stringOrNode, "BDFDB-textnode");
node.replaceChild(stringOrNode, textnode);
}
else if (Node.prototype.isPrototypeOf(textnode) && textnode.nodeType != Node.TEXT_NODE) node.replaceChild(document.createTextNode(stringOrNode), textnode);
else textnode.textContent = stringOrNode;
}
else node.appendChild(Node.prototype.isPrototypeOf(stringOrNode) ? stringOrNode : document.createTextNode(stringOrNode));
};
BDFDB.DOMUtils.getText = function (node) {
if (!node || !Node.prototype.isPrototypeOf(node)) return;
for (let child of node.childNodes) if (child.nodeType == Node.TEXT_NODE) return child.textContent;
};
BDFDB.DOMUtils.getRects = function (node) {
var rects = {};
if (Node.prototype.isPrototypeOf(node) && node.nodeType != Node.TEXT_NODE) {
var hidenode = node;
while (hidenode) {
var hidden = BDFDB.DOMUtils.isHidden(hidenode);
if (hidden) {
BDFDB.DOMUtils.toggle(hidenode, true);
hidenode.BDFDBgetRectsHidden = true;
}
hidenode = hidenode.parentElement;
}
rects = node.getBoundingClientRect();
hidenode = node;
while (hidenode) {
if (hidenode.BDFDBgetRectsHidden) {
BDFDB.DOMUtils.toggle(hidenode, false);
delete hidenode.BDFDBgetRectsHidden;
}
hidenode = hidenode.parentElement;
}
}
return rects;
};
BDFDB.DOMUtils.getHeight = function (node) {
if (Node.prototype.isPrototypeOf(node) && node.nodeType != Node.TEXT_NODE) {
var rects = BDFDB.DOMUtils.getRects(node);
var style = getComputedStyle(node);
return rects.height + parseInt(style.marginTop) + parseInt(style.marginBottom);
}
return 0;
};
BDFDB.DOMUtils.getWidth = function (node) {
if (Node.prototype.isPrototypeOf(node) && node.nodeType != Node.TEXT_NODE) {
var rects = BDFDB.DOMUtils.getRects(node);
var style = getComputedStyle(node);
return rects.width + parseInt(style.marginLeft) + parseInt(style.marginRight);
}
return 0;
};
BDFDB.DOMUtils.appendWebScript = function (path, container) {
if (!container && !document.head.querySelector("bd-head bd-scripts")) document.head.appendChild(BDFDB.DOMUtils.create(``));
container = container || document.head.querySelector("bd-head bd-scripts") || document.head;
container = Node.prototype.isPrototypeOf(container) ? container : document.head;
BDFDB.DOMUtils.removeWebScript(path, container);
container.appendChild(BDFDB.DOMUtils.create(``));
};
BDFDB.DOMUtils.removeWebScript = function (path, container) {
container = container || document.head.querySelector("bd-head bd-scripts") || document.head;
container = Node.prototype.isPrototypeOf(container) ? container : document.head;
BDFDB.DOMUtils.remove(container.querySelectorAll(`script[src="${path}"]`));
};
BDFDB.DOMUtils.appendWebStyle = function (path, container) {
if (!container && !document.head.querySelector("bd-head bd-styles")) document.head.appendChild(BDFDB.DOMUtils.create(``));
container = container || document.head.querySelector("bd-head bd-styles") || document.head;
container = Node.prototype.isPrototypeOf(container) ? container : document.head;
BDFDB.DOMUtils.removeWebStyle(path, container);
container.appendChild(BDFDB.DOMUtils.create(``));
};
BDFDB.DOMUtils.removeWebStyle = function (path, container) {
container = container || document.head.querySelector("bd-head bd-styles") || document.head;
container = Node.prototype.isPrototypeOf(container) ? container : document.head;
BDFDB.DOMUtils.remove(container.querySelectorAll(`link[href="${path}"]`));
};
BDFDB.DOMUtils.appendLocalStyle = function (id, css, container) {
if (!container && !document.head.querySelector("bd-head bd-styles")) document.head.appendChild(BDFDB.DOMUtils.create(``));
container = container || document.head.querySelector("bd-head bd-styles") || document.head;
container = Node.prototype.isPrototypeOf(container) ? container : document.head;
BDFDB.DOMUtils.removeLocalStyle(id, container);
container.appendChild(BDFDB.DOMUtils.create(``));
};
BDFDB.DOMUtils.removeLocalStyle = function (id, container) {
container = container || document.head.querySelector("bd-head bd-styles") || document.head;
container = Node.prototype.isPrototypeOf(container) ? container : document.head;
BDFDB.DOMUtils.remove(container.querySelectorAll(`style[id="${id}CSS"]`));
};
BDFDB.triggerSend = function (textarea) {
if (!textarea) return;
BDFDB.TimeUtils.timeout(_ => {
var e = new KeyboardEvent("keypress", {key:"Enter", code:"Enter", which:13, keyCode:13, bubbles:true });
Object.defineProperty(e, "keyCode", {value:13});
Object.defineProperty(e, "which", {value:13});
textarea.dispatchEvent(e);
});
};
BDFDB.initElements = function (container, plugin) {
if (!Node.prototype.isPrototypeOf(container)) return;
var islighttheme = BDFDB.DiscordUtils.getTheme() == BDFDB.disCN.themelight;
container.querySelectorAll(".BDFDB-containertext").forEach(ele => {
if (BDFDB.DOMUtils.containsClass(ele.nextElementSibling, "BDFDB-collapsecontainer")) {
if (BDFDB.DOMUtils.containsClass(ele.firstElementChild, "closed")) BDFDB.DOMUtils.toggle(ele.nextElementSibling, false);
ele.BDFDBupdateElement = _ => {
BDFDB.DOMUtils.toggle(ele.nextElementSibling, BDFDB.DOMUtils.containsClass(ele.firstElementChild, "closed"));
BDFDB.DOMUtils.toggleClass(ele.firstElementChild, "closed");
};
addInitEventListener(ele, "click", ele.BDFDBupdateElement);
}
});
container.querySelectorAll(BDFDB.dotCN.switchinner).forEach(ele => {
setSwitch(ele, false);
ele.BDFDBupdateElement = _ => {
setSwitch(ele, true);
};
addInitEventListener(ele, "click", ele.BDFDBupdateElement);
});
container.querySelectorAll(BDFDB.dotCNS.checkboxwrapper + BDFDB.dotCN.checkboxinput).forEach(ele => {
setCheckbox(ele);
ele.BDFDBupdateElement = _ => {
setCheckbox(ele);
};
addInitEventListener(ele, "click", ele.BDFDBupdateElement);
});
container.querySelectorAll(BDFDB.dotCN.giffavoritebutton).forEach(ele => {
setGifFavButton(ele);
ele.BDFDBupdateElement = _ => {
BDFDB.DOMUtils.toggleClass(ele, BDFDB.disCN.giffavoriteselected);
setGifFavButton(ele);
};
addInitEventListener(ele, "click", ele.BDFDBupdateElement);
var id = "FAV_s" + Math.round(Math.random() * 10000000000000000);
addInitEventListener(ele, "mouseenter", _ => {
BDFDB.DOMUtils.remove(`#${id}_tooltip`);
BDFDB.TooltipUtils.create(ele, BDFDB.LanguageUtils.LanguageStrings[`GIF_TOOLTIP_${BDFDB.DOMUtils.containsClass(ele, BDFDB.disCN.giffavoriteselected) ? "REMOVE_FROM" : "ADD_TO"}_FAVORITES`], {type:"top", id:id+"_tooltip"});
});
});
container.querySelectorAll(".file-navigator").forEach(ele => {
ele.BDFDBupdateElement = _ => {
var input = ele.querySelector(`input[type="file"]`);
if (input) input.click();
};
addInitEventListener(ele, "click", ele.BDFDBupdateElement);
});
container.querySelectorAll(`input[type="file"]`).forEach(ele => {
addInitEventListener(ele, "change", e => {
var input = ele.parentElement.parentElement.querySelector(`input[type="text"]`);
var file = ele.files[0];
if (input && file) input.value = file.path;
});
});
container.querySelectorAll(BDFDB.dotCN.input).forEach(ele => {
addInitEventListener(ele, "keydown", e => {
e.stopPropagation();
});
});
container.querySelectorAll(BDFDB.dotCNS.searchbar + BDFDB.dotCN.searchbarinput).forEach(ele => {
ele.setAttribute("placeholder", BDFDB.LanguageUtils.LanguageStrings.SEARCHING);
addInitEventListener(ele, "keyup", e => {
let icons = ele.parentElement.querySelectorAll(BDFDB.dotCN.searchbaricon);
BDFDB.DOMUtils.toggleClass(icons[0], BDFDB.disCN.searchbarvisible, ele.value.length == 0);
BDFDB.DOMUtils.toggleClass(icons[1], BDFDB.disCN.searchbarvisible, ele.value.length);
});
});
container.querySelectorAll(BDFDB.dotCNS.searchbar + BDFDB.dotCN.searchbarclear).forEach(ele => {
addInitEventListener(ele, "click", e => {
if (BDFDB.DOMUtils.containsClass(ele, BDFDB.disCN.searchbarvisible)) {
var input = BDFDB.DOMUtils.getParent(BDFDB.dotCN.searchbar, ele).querySelector(BDFDB.dotCN.searchbarinput);
input.value = "";
input.dispatchEvent(new Event("change"));
input.dispatchEvent(new Event("input"));
input.dispatchEvent(new Event("keydown"));
input.dispatchEvent(new Event("keyup"));
input.dispatchEvent(new Event("keypressed"));
BDFDB.DOMUtils.addClass(ele.parentElement.querySelectorAll(BDFDB.dotCN.searchbaricon)[0], BDFDB.disCN.searchbarvisible);
BDFDB.DOMUtils.removeClass(ele, BDFDB.disCN.searchbarvisible);
}
});
});
container.querySelectorAll(".numberinput-button-up").forEach(ele => {
addInitEventListener(ele, "click", e => {
var input = ele.parentElement.parentElement.querySelector("input");
var min = parseInt(input.getAttribute("min"));
var max = parseInt(input.getAttribute("max"));
var newv = parseInt(input.value) + 1;
if (isNaN(max) || !isNaN(max) && newv <= max) {
BDFDB.DOMUtils.addClass(ele.parentElement, "pressed");
BDFDB.TimeUtils.clear(ele.parentElement.pressedTimeout);
input.value = isNaN(min) || !isNaN(min) && newv >= min ? newv : min;
input.dispatchEvent(new Event("change"));
input.dispatchEvent(new Event("input"));
input.dispatchEvent(new Event("keydown"));
input.dispatchEvent(new Event("keyup"));
input.dispatchEvent(new Event("keypressed"));
ele.parentElement.pressedTimeout = BDFDB.TimeUtils.timeout(_ => {BDFDB.DOMUtils.removeClass(ele.parentElement, "pressed");}, 3000);
}
});
});
container.querySelectorAll(".numberinput-button-down").forEach(ele => {
addInitEventListener(ele, "click", e => {
var input = ele.parentElement.parentElement.querySelector("input");
var min = parseInt(input.getAttribute("min"));
var max = parseInt(input.getAttribute("max"));
var newv = parseInt(input.value) - 1;
if (isNaN(min) || !isNaN(min) && newv >= min) {
BDFDB.DOMUtils.addClass(ele.parentElement, "pressed");
BDFDB.TimeUtils.clear(ele.parentElement.pressedTimeout);
input.value = isNaN(max) || !isNaN(max) && newv <= max ? newv : max;
input.dispatchEvent(new Event("change"));
input.dispatchEvent(new Event("input"));
input.dispatchEvent(new Event("keydown"));
input.dispatchEvent(new Event("keyup"));
input.dispatchEvent(new Event("keypressed"));
ele.parentElement.pressedTimeout = BDFDB.TimeUtils.timeout(_ => {BDFDB.DOMUtils.removeClass(ele.parentElement, "pressed");}, 3000);
}
});
});
container.querySelectorAll(".amount-input").forEach(ele => {
addInitEventListener(ele, "input", e => {
if (BDFDB.ObjectUtils.is(plugin)) {
var option = ele.getAttribute("option");
var newv = parseInt(ele.value);
var min = parseInt(ele.getAttribute("min"));
var max = parseInt(ele.getAttribute("max"));
if (option && !isNaN(newv) && (isNaN(min) || !isNaN(min) && newv >= min) && (isNaN(max) || !isNaN(max) && newv <= max)) {
BDFDB.DataUtils.save(newv, plugin, "amounts", option);
plugin.SettingsUpdated = true;
}
}
});
});
container.querySelectorAll(BDFDB.dotCNC.tabbaritem + BDFDB.dotCN.tabbarheaderitem).forEach(ele => {
setTabitem(ele, ele.parentElement.querySelector(BDFDB.dotCNC.tabbaritem + BDFDB.dotCN.tabbarheaderitem) == ele ? 2 : 0);
addInitEventListener(ele, "click", e => {
BDFDB.DOMUtils.removeClass(container.querySelectorAll(BDFDB.dotCN.modaltabcontent + BDFDB.dotCN.modaltabcontentopen), BDFDB.disCN.modaltabcontentopen);
ele.parentElement.querySelectorAll(BDFDB.dotCNC.tabbaritem + BDFDB.dotCN.tabbarheaderitem).forEach(ele => {setTabitem(ele, 0);});
var tab = container.querySelector(`${BDFDB.dotCN.modaltabcontent}[tab="${ele.getAttribute("tab")}"]`);
if (tab) BDFDB.DOMUtils.addClass(tab, BDFDB.disCN.modaltabcontentopen);
setTabitem(ele, 2);
});
addInitEventListener(ele, "mouseenter", e => {
if (!BDFDB.DOMUtils.containsClass(ele, BDFDB.disCN.settingsitemselected)) setTabitem(ele, 1);
});
addInitEventListener(ele, "mouseleave", e => {
if (!BDFDB.DOMUtils.containsClass(ele, BDFDB.disCN.settingsitemselected)) setTabitem(ele, 0);
});
});
container.querySelectorAll(".BDFDB-textscrollwrapper").forEach(ele => {
var inner = ele.querySelector(".BDFDB-textscroll");
if (inner) {
if (BDFDB.DOMUtils.containsClass(ele.parentElement, BDFDB.disCN.contextmenuitemsubmenu)) ele.style.setProperty("margin-right", "10px");
if (BDFDB.DOMUtils.getRects(ele).width > 100) ele.style.setProperty("text-overflow", "ellipsis", "important");
ele.style.setProperty("position", "relative", "important");
ele.style.setProperty("display", "block", "important");
ele.style.setProperty("overflow", "hidden", "important");
inner.style.setProperty("left", "0px", "important");
inner.style.setProperty("position", "relative", "important");
inner.style.setProperty("white-space", "nowrap", "important");
inner.style.setProperty("display", "inline", "important");
var animate, Animation;
addInitEventListener(ele, "mouseenter", e => {
if (BDFDB.DOMUtils.getRects(ele).width < BDFDB.DOMUtils.getRects(inner).width) {
BDFDB.DOMUtils.addClass(ele, "scrolling");
if (!Animation || !animate) initAnimation();
animate(1);
inner.style.setProperty("display", "block", "important");
}
});
addInitEventListener(ele, "mouseleave", e => {
if (BDFDB.DOMUtils.containsClass(ele, "scrolling")) {
BDFDB.DOMUtils.removeClass(ele, "scrolling");
inner.style.setProperty("display", "inline", "important");
if (!Animation || !animate) initAnimation();
animate(0);
}
});
function initAnimation() {
Animation = new LibraryModules.AnimationUtils.Value(0);
Animation
.interpolate({inputRange:[0, 1], outputRange:[0, (BDFDB.DOMUtils.getRects(inner).width - BDFDB.DOMUtils.getRects(ele).width) * -1]})
.addListener(v => {inner.style.setProperty("left", v.value + "px", "important");});
animate = p => {
var w = p + parseFloat(inner.style.getPropertyValue("left")) / (BDFDB.DOMUtils.getRects(inner).width - BDFDB.DOMUtils.getRects(ele).width);
w = isNaN(w) || !isFinite(w) ? p : w;
w *= BDFDB.DOMUtils.getRects(inner).width / (BDFDB.DOMUtils.getRects(ele).width * 2);
LibraryModules.AnimationUtils.parallel([LibraryModules.AnimationUtils.timing(Animation, {toValue:p, duration:Math.sqrt(w**2) * 4000 / (ele.getAttribute("speed") || 1)})]).start();
};
}
}
});
BDFDB.DOMUtils.removeClass(container.querySelectorAll(BDFDB.dotCN.modaltabcontent), BDFDB.disCN.modaltabcontentopen);
BDFDB.DOMUtils.addClass(container.querySelector(BDFDB.dotCN.modaltabcontent), BDFDB.disCN.modaltabcontentopen);
container.querySelectorAll(".btn-add " + BDFDB.dotCN.buttoncontents).forEach(ele => {ele.innerText = BDFDB.LanguageUtils.LanguageStrings.ADD;});
container.querySelectorAll(".btn-all " + BDFDB.dotCN.buttoncontents).forEach(ele => {ele.innerText = BDFDB.LanguageUtils.LanguageStrings.FORM_LABEL_ALL;});
container.querySelectorAll(".btn-cancel " + BDFDB.dotCN.buttoncontents).forEach(ele => {ele.innerText = BDFDB.LanguageUtils.LanguageStrings.CANCEL;});
container.querySelectorAll(".btn-done " + BDFDB.dotCN.buttoncontents).forEach(ele => {ele.innerText = BDFDB.LanguageUtils.LanguageStrings.DONE;});
container.querySelectorAll(".btn-download " + BDFDB.dotCN.buttoncontents).forEach(ele => {ele.innerText = BDFDB.LanguageUtils.LanguageStrings.DOWNLOAD;});
container.querySelectorAll(".btn-ok " + BDFDB.dotCN.buttoncontents).forEach(ele => {ele.innerText = BDFDB.LanguageUtils.LanguageStrings.OKAY;});
container.querySelectorAll(".btn-save " + BDFDB.dotCN.buttoncontents).forEach(ele => {ele.innerText = BDFDB.LanguageUtils.LanguageStrings.SAVE;});
container.querySelectorAll(".btn-send " + BDFDB.dotCN.buttoncontents).forEach(ele => {ele.innerText = BDFDB.LanguageUtils.LanguageStrings.SEND;});
container.querySelectorAll(".file-navigator " + BDFDB.dotCN.buttoncontents).forEach(ele => {ele.innerText = BDFDB.LanguageUtils.LibraryStrings.file_navigator_text;});
if (islighttheme) {
BDFDB.DOMUtils.replaceClass(container.querySelectorAll(BDFDB.dotCN.selectcontroldark), BDFDB.disCN.selectcontroldark, BDFDB.disCN.selectcontrollight);
BDFDB.DOMUtils.replaceClass(container.querySelectorAll(BDFDB.dotCN.selectsingledark), BDFDB.disCN.selectsingledark, BDFDB.disCN.selectsinglelight);
BDFDB.DOMUtils.replaceClass(container.querySelectorAll(BDFDB.dotCN.selectarrowcontainerdark), BDFDB.disCN.selectarrowcontainerdark, BDFDB.disCN.selectarrowcontainerlight);
}
else {
BDFDB.DOMUtils.replaceClass(container.querySelectorAll(BDFDB.dotCN.selectcontrollight), BDFDB.disCN.selectcontrollight, BDFDB.disCN.selectcontroldark);
BDFDB.DOMUtils.replaceClass(container.querySelectorAll(BDFDB.dotCN.selectsinglelight), BDFDB.disCN.selectsinglelight, BDFDB.disCN.selectsingledark);
BDFDB.DOMUtils.replaceClass(container.querySelectorAll(BDFDB.dotCN.selectarrowcontainerlight), BDFDB.disCN.selectarrowcontainerlight, BDFDB.disCN.selectarrowcontainerdark);
}
var executeDelayedIfNotAppened = _ => {
container.querySelectorAll(".BDFDB-tableheader").forEach(ele => {
var panel = BDFDB.DOMUtils.getParent(".BDFDB-modal, .BDFDB-settings", ele);
var tableid = ele.getAttribute("table-id");
var text = ele.querySelector(".BDFDB-tableheadertext");
var columns = ele.querySelectorAll(".BDFDB-tableheadercolumns .BDFDB-tableheadercolumn");
if (panel && tableid && text && columns.length) {
let toobig = false, maxwidth = BDFDB.ObjectUtils.is(panel["BDFDB-tableheader-maxwidth"]) ? panel["BDFDB-tableheader-maxwidth"][tableid] : 0;
if (!maxwidth) {
for (let column of columns) {
let width = BDFDB.DOMUtils.getRects(column).width;
maxwidth = width > maxwidth ? width : maxwidth;
}
maxwidth += 4;
}
if (columns.length * maxwidth > 300) {
toobig = true;
maxwidth = parseInt(290 / columns.length);
}
else if (maxwidth < 36) {
maxwidth = 36;
}
columns.forEach((column, i) => {
column.style.setProperty("flex", `0 0 ${maxwidth}px`, "important");
if (toobig) {
if (i == 0) column.style.setProperty("margin-left", `${-1 * (10 + maxwidth/2)}px`, "important");
column.style.setProperty("margin-top", "0", "important");
column.style.setProperty("text-align", "right", "important");
column.style.setProperty("writing-mode", "vertical-rl", "important");
}
else column.style.setProperty("text-align", "center", "important");
});
text.style.setProperty("flex", `0 0 ${556 - (columns.length * maxwidth)}px`, "important");
columns[0].parentElement.style.setProperty("flex", `0 0 ${columns.length * maxwidth}px`, "important");
if (!BDFDB.ObjectUtils.is(panel["BDFDB-tableheader-maxwidth"])) panel["BDFDB-tableheader-maxwidth"] = {}
panel["BDFDB-tableheader-maxwidth"][tableid] = maxwidth;
}
});
container.querySelectorAll(".BDFDB-tablecheckbox").forEach(ele => {
var panel = BDFDB.DOMUtils.getParent(".BDFDB-modal, .BDFDB-settings", ele);
var tableid = ele.getAttribute("table-id");
if (panel && tableid && BDFDB.ObjectUtils.is(panel["BDFDB-tableheader-maxwidth"]) && panel["BDFDB-tableheader-maxwidth"][tableid]) {
var style = getComputedStyle(ele);
ele.style.setProperty("flex", `0 0 ${panel["BDFDB-tableheader-maxwidth"][tableid] - parseInt(style.marginLeft) - parseInt(style.marginRight)}px`, "important");
}
});
};
if (document.contains(container)) executeDelayedIfNotAppened();
else BDFDB.TimeUtils.timeout(_ => {executeDelayedIfNotAppened();});
function setSwitch(switchitem, triggered) {
if (!switchitem) return;
var checked = switchitem.checked;
BDFDB.DOMUtils.toggleClass(switchitem.parentElement, BDFDB.disCN.switchvaluechecked, checked);
BDFDB.DOMUtils.toggleClass(switchitem.parentElement, BDFDB.disCN.switchvalueunchecked, !checked);
if (triggered && BDFDB.ObjectUtils.is(plugin) && BDFDB.DOMUtils.containsClass(switchitem, "settings-switch")) {
let keys = switchitem.getAttribute("value").trim().split(" ").filter(n => n);
let option = keys.shift();
if (option) {
var data = BDFDB.DataUtils.load(plugin, option);
var newdata = "";
for (let key of keys) newdata += `{"${key}":`;
newdata += checked + "}".repeat(keys.length);
newdata = JSON.parse(newdata);
if (BDFDB.ObjectUtils.is(newdata)) BDFDB.ObjectUtils.deepAssign(data, newdata);
else data = newdata;
BDFDB.DataUtils.save(data, plugin, option);
plugin.SettingsUpdated = true;
}
}
};
function setCheckbox(checkbox) {
if (!checkbox) return;
var checkboxstyle = checkbox.parentElement.querySelector(BDFDB.dotCN.checkbox);
var checkboxstyleinner = checkboxstyle.querySelector("polyline");
if (checkbox.checked) {
BDFDB.DOMUtils.addClass(checkboxstyle, BDFDB.disCN.checkboxchecked);
checkboxstyle.style.setProperty("background-color", "rgb(67, 181, 129)");
checkboxstyle.style.setProperty("border-color", "rgb(67, 181, 129)");
if (checkboxstyleinner) checkboxstyleinner.setAttribute("stroke", "#ffffff");
}
else {
BDFDB.DOMUtils.removeClass(checkboxstyle, BDFDB.disCN.checkboxchecked);
checkboxstyle.style.removeProperty("background-color");
checkboxstyle.style.removeProperty("border-color");
if (checkboxstyleinner) checkboxstyleinner.setAttribute("stroke", "transparent");
}
};
function setGifFavButton(button) {
var selected = BDFDB.DOMUtils.containsClass(button, BDFDB.disCN.giffavoriteselected);
var icon = button.querySelector(BDFDB.dotCN.giffavoriteicon);
if (icon) {
icon.setAttribute("name", selected ? "FavoriteFilled" : "Favorite");
icon.innerHTML = selected ? `` : ``;
}
if (selected) {
BDFDB.DOMUtils.addClass(button, BDFDB.disCN.giffavoriteshowpulse);
BDFDB.TimeUtils.timeout(_ => {BDFDB.DOMUtils.removeClass(button, BDFDB.disCN.giffavoriteshowpulse);}, 500);
}
};
function setTabitem(item, state) {
if (!item) return;
switch (state) {
case 0:
BDFDB.DOMUtils.removeClass(item, BDFDB.disCN.settingsitemselected);
item.style.setProperty("border-color", "transparent");
item.style.setProperty("color", islighttheme ? "rgba(79, 84, 92, 0.4)" : "rgba(255, 255, 255, 0.4)");
break;
case 1:
BDFDB.DOMUtils.removeClass(item, BDFDB.disCN.settingsitemselected);
item.style.setProperty("border-color", islighttheme ? "rgba(79, 84, 92, 0.6)" : "rgba(255, 255, 255, 0.6)");
item.style.setProperty("color", islighttheme ? "rgba(79, 84, 92, 0.6)" : "rgba(255, 255, 255, 0.6)");
break;
case 2:
BDFDB.DOMUtils.addClass(item, BDFDB.disCN.settingsitemselected);
item.style.setProperty("border-color", islighttheme ? "rgb(79, 84, 92)" : "rgb(255, 255, 255)");
item.style.setProperty("color", islighttheme ? "rgb(79, 84, 92)" : "rgb(255, 255, 255)");
break;
}
};
function addInitEventListener(ele, action, callback) {
if (!ele.BDFDBupdateElementsListeners) ele.BDFDBupdateElementsListeners = {};
if (ele.BDFDBupdateElementsListeners[action]) ele.removeEventListener(action, ele.BDFDBupdateElementsListeners[action]);
ele.BDFDBupdateElementsListeners[action] = callback;
ele.addEventListener(action, callback, true);
};
};
// REMOVE ONCE REWRITTEN
BDFDB.appendModal = function (modalwrapper) {
if (!Node.prototype.isPrototypeOf(modalwrapper)) return;
if (!BDFDB.appendModal.modals || !document.contains(BDFDB.appendModal.modals)) BDFDB.appendModal.modals = BDFDB.ReactUtils.findDOMNode(BDFDB.ReactUtils.findOwner(document.querySelector(BDFDB.dotCN.app), {name:"Modals", unlimited:true}));
if (!BDFDB.appendModal.modals) return;
var modal = BDFDB.DOMUtils.containsClass(modalwrapper, BDFDB.disCN.modal) ? modalwrapper : modalwrapper.querySelector(BDFDB.dotCN.modal);
var backdrop = modal ? modal.previousElementSibling : null;
var modalOpacity = new LibraryModules.AnimationUtils.Value(0);
modalOpacity
.interpolate({inputRange: [0, 1], outputRange: [0, 1]})
.addListener((value) => {if (modal) modal.style.setProperty("opacity", `${value.value}`);});
var modalTransform = new LibraryModules.AnimationUtils.Value(0);
modalTransform
.interpolate({inputRange: [0, 1], outputRange: [0.7, 1]})
.addListener((value) => {if (modal) modal.style.setProperty("transform", `scale(${value.value}) translateZ(0px)`);});
var backdropOpacity = new LibraryModules.AnimationUtils.Value(0);
backdropOpacity
.interpolate({inputRange: [0, 1], outputRange: [0, 0.85]})
.addListener((value) => {if (backdrop) {
backdrop.style.setProperty("opacity", `${value.value}`);
backdrop.style.setProperty("background-color", "rgb(0, 0, 0)");
backdrop.style.setProperty("z-index", "1000");
backdrop.style.setProperty("transform", "translateZ(0px)");
}});
var animate = (v) => {
LibraryModules.AnimationUtils.parallel([
LibraryModules.AnimationUtils.timing(modalOpacity, {toValue: v, duration: 250, easing: LibraryModules.AnimationUtils.Easing.inOut(LibraryModules.AnimationUtils.Easing.ease)}),
LibraryModules.AnimationUtils.timing(modalTransform, {toValue: v, duration: 250, easing: LibraryModules.AnimationUtils.Easing.inOut(LibraryModules.AnimationUtils.Easing.ease)}),
LibraryModules.AnimationUtils.timing(backdropOpacity, {toValue: v, duration: 200, delay:50}),
]).start();
};
var keydown = e => {
if (!document.contains(modalwrapper)) document.removeEventListener("keydown", keydown);
else if (e.which == 27 && backdrop) backdrop.click();
};
document.addEventListener("keydown", keydown);
BDFDB.ListenerUtils.addToChildren(modalwrapper, "click", BDFDB.dotCNC.backdrop + BDFDB.dotCNC.modalclose + ".btn-close, .btn-save, .btn-send, .btn-cancel, .btn-ok, .btn-done", _ => {
document.removeEventListener("keydown", keydown);
animate(0);
BDFDB.TimeUtils.timeout(_ => {modalwrapper.remove();}, 300);
});
BDFDB.appendModal.modals.appendChild(modalwrapper);
BDFDB.initElements(modalwrapper);
animate(1);
};
BDFDB.createSearchBar = function (size = "small") {
if (typeof size != "string" || !["small","medium","large"].includes(size.toLowerCase())) size = "small";
var sizeclass = DiscordClassModules.SearchBar[size] ? (" " + BDFDB.disCN["searchbar" + size]) : "";
var searchBar = BDFDB.DOMUtils.create(`
`);
BDFDB.initElements(searchBar);
return searchBar;
};
BDFDB.createSelectMenu = function (inner, value, type = "", dark = BDFDB.DiscordUtils.getTheme() == BDFDB.disCN.themedark) {
if (typeof inner != "string" || (typeof value != "string" && typeof value != "number")) return BDFDB.DOMUtils.create(``);
var suffix = dark ? "dark" : "light";
return `
${inner}
`;
};
BDFDB.openDropdownMenu = function (e, callback, createinner, values, above = false, dark = BDFDB.DiscordUtils.getTheme() == BDFDB.disCN.themedark) {
if (typeof callback != "function" || typeof createinner != "function" || !values || typeof values != "object") return;
let selectControl = (BDFDB.DOMUtils.getParent(BDFDB.dotCN.selectwrap, e.currentTarget) || e.currentTarget).querySelector(BDFDB.dotCN.selectcontrol);
let selectWrap = selectControl.parentElement;
if (BDFDB.DOMUtils.containsClass(selectWrap, BDFDB.disCN.selectisopen)) return;
BDFDB.DOMUtils.addClass(selectWrap, BDFDB.disCN.selectisopen);
var type = selectWrap.getAttribute("type");
var oldchoice = selectWrap.getAttribute("value");
var suffix = dark ? "dark" : "light";
var menuhtml = `
`;
for (var key in values) menuhtml += `
${createinner(key)}
`;
menuhtml += `
`;
var selectMenu = BDFDB.DOMUtils.create(menuhtml);
if (above) {
BDFDB.DOMUtils.addClass(selectMenu, "above-select");
selectMenu.style.setProperty("top", "unset", "important");
selectMenu.style.setProperty("bottom", BDFDB.DOMUtils.getRects(selectWrap).height + "px", "important");
}
selectWrap.appendChild(selectMenu);
BDFDB.initElements(selectMenu);
BDFDB.ListenerUtils.addToChildren(selectMenu, "mouseenter", BDFDB.dotCN.selectoption + BDFDB.notCN.selectoptionselectlight + BDFDB.notCN.selectoptionselectdark, e2 => {
if (dark) {
BDFDB.DOMUtils.removeClass(e2.currentTarget, BDFDB.disCN.selectoptiondark);
BDFDB.DOMUtils.addClass(e2.currentTarget, BDFDB.disCN.selectoptionhoverdark);
}
else {
BDFDB.DOMUtils.removeClass(e2.currentTarget, BDFDB.disCN.selectoptionlight);
BDFDB.DOMUtils.addClass(e2.currentTarget, BDFDB.disCN.selectoptionhoverlight);
}
});
BDFDB.ListenerUtils.addToChildren(selectMenu, "mouseleave", BDFDB.dotCN.selectoption + BDFDB.notCN.selectoptionselectlight + BDFDB.notCN.selectoptionselectdark, e2 => {
if (dark) {
BDFDB.DOMUtils.removeClass(e2.currentTarget, BDFDB.disCN.selectoptionhoverdark);
BDFDB.DOMUtils.addClass(e2.currentTarget, BDFDB.disCN.selectoptiondark);
}
else {
BDFDB.DOMUtils.removeClass(e2.currentTarget, BDFDB.disCN.selectoptionhoverlight);
BDFDB.DOMUtils.addClass(e2.currentTarget, BDFDB.disCN.selectoptionlight);
}
});
BDFDB.ListenerUtils.addToChildren(selectMenu, "mousedown", BDFDB.dotCN.selectoption, e2 => {
if (!BDFDB.DOMUtils.getParent(BDFDB.dotCN.giffavoritebutton, e2.target)) {
var newchoice = e2.currentTarget.getAttribute("value");
selectWrap.setAttribute("value", newchoice);
callback(selectWrap, type, newchoice);
}
});
var removeMenu = e2 => {
if (e2.target.parentElement != selectMenu && !BDFDB.DOMUtils.getParent(BDFDB.dotCN.giffavoritebutton, e2.target)) {
document.removeEventListener("mousedown", removeMenu);
selectMenu.remove();
BDFDB.TimeUtils.timeout(_ => {BDFDB.DOMUtils.removeClass(selectWrap, BDFDB.disCN.selectisopen);},100);
}
};
document.addEventListener("mousedown", removeMenu);
return selectMenu;
};
BDFDB.ModalUtils = {};
BDFDB.ModalUtils.open = function (plugin, config) {
if (!BDFDB.ObjectUtils.is(plugin) || !BDFDB.ObjectUtils.is(config)) return;
var modal, modalInstance, headerchildren = [], contentchildren = [], footerchildren = [], modalprops, cancels = [], closeModal = _ => {
if (BDFDB.ObjectUtils.is(modalprops) && typeof modalprops.onClose == "function") modalprops.onClose();
};
if (typeof config.text == "string") {
contentchildren.push(BDFDB.ReactUtils.createElement(LibraryComponents.TextElement, {
color: LibraryComponents.TextElement.Colors.PRIMARY,
children: config.text
}));
}
if (config.children) {
let selectedtab, tabbaritems = [];
for (let child of [config.children].flat(10).filter(n => n)) if (LibraryModules.React.isValidElement(child)) {
if (child.type == LibraryComponents.ModalComponents.ModalTabContent) {
if (!tabbaritems.length) child.props.open = true;
else delete child.props.open;
tabbaritems.push({value:child.props.tab});
}
contentchildren.push(child);
}
if (tabbaritems.length) headerchildren.push(BDFDB.ReactUtils.createElement(LibraryComponents.Flex, {
className: BDFDB.disCN.tabbarcontainer,
children: BDFDB.ReactUtils.createElement(LibraryComponents.TabBar, {
className: BDFDB.disCN.tabbar,
itemClassName: BDFDB.disCN.tabbaritem,
type: LibraryComponents.TabBar.Types.TOP,
items: tabbaritems,
onItemSelect: (value, instance) => {
let tabContentInstances = BDFDB.ReactUtils.findOwner(modal, {name:"BDFDB_ModalTabContent", all:true, unlimited:true});
for (let ins of tabContentInstances) {
if (ins.props.tab == value) ins.props.open = true;
else delete ins.props.open;
}
BDFDB.ReactUtils.forceUpdate(tabContentInstances);
}
})
}));
}
if (BDFDB.ArrayUtils.is(config.buttons)) for (let button of config.buttons) {
let contents = typeof button.contents == "string" ? button.contents : null;
if (contents) {
let color = typeof button.color == "string" && LibraryComponents.Button.Colors[button.color.toUpperCase()];
let look = typeof button.look == "string" && LibraryComponents.Button.Looks[button.look.toUpperCase()];
let click = typeof button.click == "function" ? button.click : _ => {};
if (button.cancel) cancels.push(click);
footerchildren.push(BDFDB.ReactUtils.createElement(LibraryComponents.Button, {
look: look || (color ? LibraryComponents.Button.Looks.FILLED : LibraryComponents.Button.Looks.LINK),
color: color || LibraryComponents.Button.Colors.PRIMARY,
onClick: _ => {
if (button.close) closeModal();
if (!(button.close && button.cancel)) click(modal, modalInstance);
},
children: contents
}));
}
}
contentchildren = contentchildren.filter(n => n && (typeof n == "string" || BDFDB.ReactUtils.isValidElement(n)));
headerchildren = headerchildren.filter(n => n && (typeof n == "string" || BDFDB.ReactUtils.isValidElement(n)));
footerchildren = footerchildren.filter(n => n && (typeof n == "string" || BDFDB.ReactUtils.isValidElement(n)));
if (contentchildren.length) {
if (typeof config.onClose != "function") config.onClose = _ => {};
if (typeof config.onOpen != "function") config.onOpen = _ => {};
let name = plugin.name || (typeof plugin.getName == "function" ? plugin.getName() : null);
name = typeof name == "string" ? name : null;
let size = typeof config.size == "string" && LibraryComponents.ModalComponents.ModalSize[config.size.toUpperCase()];
let oldTransitionState = 0;
LibraryModules.ModalUtils.openModal(props => {
modalprops = props;
return BDFDB.ReactUtils.createElement(class BDFDB_Modal extends LibraryModules.React.Component {
render () {
return BDFDB.ReactUtils.createElement(LibraryComponents.ModalComponents.ModalRoot, {
className: BDFDB.DOMUtils.formatClassName(name && `${name}-modal`, BDFDB.disCN.modalwrapper, config.className),
size: size || LibraryComponents.ModalComponents.ModalSize.SMALL,
transitionState: props.transitionState,
children: [
BDFDB.ReactUtils.createElement(LibraryComponents.ModalComponents.ModalHeader, {
className: BDFDB.DOMUtils.formatClassName(config.headerClassName, headerchildren.length && BDFDB.disCN.modalheaderhassibling),
separator: config.headerSeparator || false,
children: [
BDFDB.ReactUtils.createElement(LibraryComponents.Flex.Child, {
children: [
BDFDB.ReactUtils.createElement(LibraryComponents.FormComponents.FormTitle, {
tag: LibraryComponents.FormComponents.FormTitle.Tags.H4,
children: typeof config.header == "string" ? config.header : ""
}),
BDFDB.ReactUtils.createElement(LibraryComponents.TextElement, {
size: LibraryComponents.TextElement.Sizes.SMALL,
color: LibraryComponents.TextElement.Colors.PRIMARY,
children: typeof config.subheader == "string" ? config.subheader : (name || "")
})
]
}),
BDFDB.ReactUtils.createElement(LibraryComponents.ModalComponents.ModalCloseButton, {
onClick: closeModal
})
]
}),
headerchildren.length ? BDFDB.ReactUtils.createElement(LibraryComponents.Flex, {
grow: 0,
shrink: 0,
children: headerchildren
}) : null,
BDFDB.ReactUtils.createElement(LibraryComponents.ModalComponents.ModalContent, {
className: config.contentClassName,
scroller: config.scroller,
children: contentchildren
}),
footerchildren.length ? BDFDB.ReactUtils.createElement(LibraryComponents.ModalComponents.ModalFooter, {
className: config.footerClassName,
children: footerchildren
}) : null
]
});
}
componentDidMount () {
modalInstance = this;
modal = BDFDB.ReactUtils.findDOMNode(this);
modal = modal && modal.parentElement ? modal.parentElement.querySelector(BDFDB.dotCN.modalwrapper) : null;
if (modal && props.transitionState == 2 && props.transitionState > oldTransitionState) config.onOpen(modal, this);
oldTransitionState = props.transitionState;
}
componentWillUnmount () {
if (modal && props.transitionState == 4) {
for (let cancel of cancels) cancel(modal);
config.onClose(modal, this);
}
}
}, props);
}, {
onCloseRequest: closeModal
});
}
};
BDFDB.ModalUtils.confirm = function (plugin, text, callback) {
if (!BDFDB.ObjectUtils.is(plugin) || typeof text != "string") return;
callback = typeof callback == "function" ? callback : _ => {};
BDFDB.ModalUtils.open(plugin, {text, header:"Are you sure?", className:BDFDB.disCN.modalconfirmmodal, scroller:false, buttons:[
{contents: BDFDB.LanguageUtils.LanguageStrings.OKAY, close:true, color:"RED", click:callback},
{contents: BDFDB.LanguageUtils.LanguageStrings.CANCEL, close:true}
]});
};
BDFDB.ContextMenuUtils = {};
BDFDB.ContextMenuUtils.open = function (plugin, e, children) {
LibraryModules.ContextMenuUtils.openContextMenu(e, function (e) {
return BDFDB.ReactUtils.createElement(LibraryComponents.ContextMenus.NativeContextMenu, Object.assign({}, e, {
BDFDBcontextMenu: true,
type: BDFDB.DiscordConstants.ContextMenuTypes.NATIVE_TEXT,
value: "",
className: BDFDB.disCN.contextmenu,
children: children
}));
});
};
BDFDB.ContextMenuUtils.close = function (nodeOrInstance) {
if (!BDFDB.ObjectUtils.is(nodeOrInstance)) return;
var instance = BDFDB.ReactUtils.findOwner(nodeOrInstance, {props:"closeContextMenu", up:true});
if (BDFDB.ObjectUtils.is(instance) && instance.props && typeof instance.props.closeContextMenu == "function") instance.props.closeContextMenu();
};
BDFDB.createMessageOptionPopout = function (button) {
if (!button) return;
var popouts = document.querySelector(BDFDB.dotCN.popouts);
if (!popouts) return;
button = BDFDB.DOMUtils.containsClass(button, BDFDB.disCN.optionpopoutbutton) ? button : button.querySelector(BDFDB.dotCN.optionpopoutbutton);
var containerins = BDFDB.ReactUtils.getInstance(BDFDB.DOMUtils.getParent(BDFDB.dotCN.messagebuttoncontainer, button));
containerins = containerins && containerins.child ? containerins.child : null;
containerins = containerins && containerins.stateNode && typeof containerins.stateNode.renderReactionPopout == "function" ? containerins.sibling : containerins;
if (containerins && containerins.stateNode && typeof containerins.stateNode.renderOptionPopout == "function") {
BDFDB.DOMUtils.addClass(button, "popout-open");
var popout = BDFDB.DOMUtils.create(``);
popouts.appendChild(popout);
var popoutinstance = containerins.stateNode.renderOptionPopout(containerins.stateNode.props);
popoutinstance.props.target = button;
popoutinstance.props.onClose = _ => {
BDFDB.DOMUtils.removeClass(button, "popout-open");
popout.remove();
};
BDFDB.ReactUtils.render(popoutinstance, popout);
var buttonrects = BDFDB.DOMUtils.getRects(button);
popout.style.setProperty("left", buttonrects.left + buttonrects.width / 2 + "px");
popout.style.setProperty("top", buttonrects.top + buttonrects.height / 2 + "px");
var mousedown = e => {
document.removeEventListener("mousedown", mousedown);
if (!popout.contains(e.target)) popoutinstance.props.onClose();
};
document.addEventListener("mousedown", mousedown);
}
};
BDFDB.createSortPopout = function (anker, markup, callback) {
if (!anker || !markup || typeof callback != "function" || BDFDB.DOMUtils.containsClass(anker, "popout-open")) return;
var popouts = document.querySelector(BDFDB.dotCN.popouts);
var valueinput = anker.querySelector(BDFDB.dotCNC.quickselectvalue + BDFDB.dotCN.recentmentionsmentionfiltervalue);
if (!popouts || !valueinput) return;
BDFDB.DOMUtils.addClass(anker, "popout-open");
var popout = BDFDB.DOMUtils.create(markup);
var ankerrects = BDFDB.DOMUtils.getRects(anker);
popout.style.setProperty("left", ankerrects.left + ankerrects.width + "px");
popout.style.setProperty("top", ankerrects.top + BDFDB.DOMUtils.getRects(valueinput).height + "px");
BDFDB.DOMUtils.addClass(popout.querySelector(BDFDB.dotCN.contextmenu), BDFDB.DiscordUtils.getTheme());
BDFDB.ListenerUtils.addToChildren(popout, "click", BDFDB.dotCN.contextmenuitem, e => {
valueinput.innerText = e.currentTarget.innerText;
valueinput.setAttribute("option", e.currentTarget.getAttribute("option"));
document.removeEventListener("mousedown", mousedown);
popout.remove();
BDFDB.TimeUtils.timeout(_ => {BDFDB.DOMUtils.removeClass(anker, "popout-open");}, 300);
callback();
});
popouts.appendChild(popout);
BDFDB.initElements(popout);
var mousedown = e => {
if (!document.contains(popout)) document.removeEventListener("mousedown", mousedown);
else if (!popout.contains(e.target)) {
document.removeEventListener("mousedown", mousedown);
popout.remove();
BDFDB.TimeUtils.timeout(_ => {BDFDB.DOMUtils.removeClass(anker, "popout-open");}, 300);
}
};
document.addEventListener("mousedown", mousedown);
};
// REMOVE ONCE REWRITTEN
var setSwatch = (swatch, color, selected) => {
if (!swatch) return;
else if (selected) {
BDFDB.DOMUtils.addClass(swatch, BDFDB.disCN.colorpickerswatchselected);
var iscustom = BDFDB.DOMUtils.containsClass(swatch, BDFDB.disCN.colorpickerswatchcustom);
var isgradient = color && BDFDB.ObjectUtils.is(color);
var selectedcolor = BDFDB.ObjectUtils.is(color) ? BDFDB.ColorUtils.createGradient(color) : BDFDB.ColorUtils.convert(color, "RGBA");
var bright = selectedcolor && !isgradient ? BDFDB.ColorUtils.isBright(selectedcolor) : false;
if (!swatch.querySelector(`svg[name="Checkmark"]`)) swatch.appendChild(BDFDB.DOMUtils.create(``));
if (iscustom) {
BDFDB.DOMUtils.removeClass(swatch, BDFDB.disCN.colorpickerswatchnocolor);
swatch.querySelector(BDFDB.dotCN.colorpickerswatchdropperfg).setAttribute("fill", bright ? "#000000" : "#ffffff");
if (selectedcolor) {
if (isgradient) swatch.gradient = color;
swatch.style.setProperty(isgradient ? "background-image" : "background-color", selectedcolor, "important");
}
}
}
else {
delete swatch.gradient;
BDFDB.DOMUtils.removeClass(swatch, BDFDB.disCN.colorpickerswatchselected);
BDFDB.DOMUtils.remove(swatch.querySelectorAll(".swatch-checkmark"));
if (BDFDB.DOMUtils.containsClass(swatch, BDFDB.disCN.colorpickerswatchcustom)) {
BDFDB.DOMUtils.addClass(swatch, BDFDB.disCN.colorpickerswatchnocolor);
swatch.querySelector(BDFDB.dotCN.colorpickerswatchdropperfg).setAttribute("fill", "#ffffff");
swatch.style.removeProperty("background-color");
swatch.style.removeProperty("background-image");
}
}
};
// REMOVE ONCE REWRITTEN
BDFDB.setColorSwatches = function (container, currentcolor) {
if (!Node.prototype.isPrototypeOf(container)) return;
var swatches = container.querySelector(`${BDFDB.dotCN.colorpickerswatches}:not([number])`);
if (!swatches) return;
swatches.setAttribute("number", parseInt(container.querySelectorAll(`${BDFDB.dotCN.colorpickerswatches}[number]`).length + 1));
var colorlist = [null, "rgba(82,233,30,1)", "rgba(46,204,113,1)", "rgba(26,188,156,1)", "rgba(52,152,219,1)", "rgba(52,84,219,1)", "rgba(134,30,233,1)", "rgba(155,89,182,1)", "rgba(233,30,99,1)", "rgba(233,65,30,1)", "rgba(231,76,60,1)", "rgba(230,126,34,1)", "rgba(241,196,15,1)", "rgba(199,204,205,1)", "rgba(112,128,136,1)", "rgba(99,99,99,1)", "rgba(255,255,255,1)", "rgba(59,173,20,1)", "rgba(31,139,76,1)", "rgba(17,128,106,1)", "rgba(32,102,148,1)", "rgba(32,57,148,1)", "rgba(109,20,173,1)", "rgba(113,54,138,1)", "rgba(173,20,87,1)", "rgba(173,32,20,1)", "rgba(153,45,34,1)", "rgba(168,67,0,1)", "rgba(194,124,14,1)", "rgba(151,156,159,1)", "rgba(93,104,109,1)", "rgba(44,44,44,1)"];
var colorrows = [colorlist.slice(0, parseInt(colorlist.length/2)), colorlist.slice(parseInt(colorlist.length/2))];
colorlist.shift();
swatches.appendChild(BDFDB.DOMUtils.create(`