Fiction.Live Merged

An attempt to improve fiction.live through the addition of various features.

2021-08-25 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

// ==UserScript==
// @name         Fiction.Live Merged
// @namespace    http://tampermonkey.net/
// @version      59
// @description  An attempt to improve fiction.live through the addition of various features.
// @author       You
// @match        https://fiction.live/*
// @grant        none
// @run-at       document-idle
// @noframes
// ==/UserScript==
(function () {
    'use strict';
    function insertCSS() {
        var css = `
.borderBottom {
	width: 100%;
	border-bottom: thin solid white;
	margin: 5px 0 0 0;
}

#confBox * {
	color: white;
}

#innerAlertSearch {
	background: rgb(42, 44, 59) none repeat scroll 0% 0%;
	padding-top: 10px;
	margin-top: 0px;
	display: inline-block;
	width: 100%;
}
}

.listView-grid {
	grid-auto-rows: unset;
}

#loginMenu .dropdown-menu {
	right: -6.2em;
}

#confBox,
#scriptTitle,
#scriptTitle h1,
#reportDiv,
#reportDiv *,
#settingsAlertBox,
#settingsAlertBox *,
#styleEntries,
#styleEntries *,
.settingsBlacklist,
#settingsBox,
#settingsBox *,
#styleInput,
.toggleBtn,
.cssBtn,
.settingsToggle,
.settingsToggle div,
.settingsTab,
.settingsTab .entryTitle,
.settingsSelect,
.blacklistEntry {
	background: #2a2c3b !important;
	color: white !important;
}

.cssBtn {
	height: 30px;
}

.chatListed {
	display: none;
}

#scriptTitle h1 {
	margin: 0;
}

.blacklistEntry p.colors {
	display: inline-block;
	width: 85%;
}

#reportDiv {
	font-size: 1.25rem;
	padding: 5px;
}

#confScript {
	text-shadow='-1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000';
	font-weight='bold';
}

#confDisp {
	height: 100%;
	position: fixed;
	top: 0;
	bottom: 0;
	left: 0;
	right: 0;
	z-index: 9999;
	display: none;
	overflow-y: auto;
	pointer-events: auto;
}

#confBox * {
	background: #2a2c3b;
}

#confBox {
	height: auto;
	min-height: 60%;
	background: #2a2c3b;
	width: auto;
	min-width: 60%;
	position: relative;
	top: 10px;
	margin: 10%;
	padding: 1%;
	display: flex;
	flex-flow: column;
	background: #2a2c3b;
	box-shadow: 0 0 10px #000000;
	pointer-events: auto;
}

#scriptTitle * {
	margin: 0;
	display: inline;
}

#scriptTitle {}
.settingsSelect {
	max-height: 80px;
	padding-top: 5px;
}

.settingsSelectDiv {
	display: inline-block;
	background: #4b4f6b;
	box-sizing: border-box;
	height: 2em;
}

.settingsSelectBTN {
	width: 100% !important;
	height: 100%;
	font-size: 1.25rem;
	color: white !important;
	text-decoration: none;
	background: #373952 !important;
	box-sizing: border-box;
	border: 1px #21222b solid;
}

.settingsSelectBTN:disabled {
	background: #4b4f6b !important;
}

.settingsTab {
	padding: 5px;
	display: none;
}

.entryTitle {
	min-width: 100%;
	font-size: 1.25rem;
	color: white !important;
	float: left;
}

.settingsToggle {
	min-height: 37px;
	max-height: 37px;
	min-width: 25%;
	max-width: 25%;
	color: white;
	border: thin solid silver;
	padding: 5px;
	float: left;
}

.settingsToggle div {
	display: inline;
}

.toggleCheck {
	-webkit-appearance: none;
	background: white !important;
	color: black !important;
	padding: 9px;
	display: inline-block;
	position: relative;
	height: 100% !important;
	max-height: 100% !important;
	margin-top: 0 !important;
	margin-bottom: 0 !important;
	margin-left: 5px !important;
	margin-right: 0 !important;
	color: black;
	font-size: 1.25rem;
}

.toggleCheck:active,
.toggleCheck:checked:active {}
.toggleCheck:checked {}
.toggleCheck:checked:after {
	content: '\\2714';
}

.toggleCheck:after {
	content: '\\2716';
	position: absolute;
	top: -5px;
	left: 1px;
}

.settingsBlacklist {
	padding: 5px;
}

#settingsBox {
	margin-bottom: 5px;
}

.settingsInput {
	color: white;
	max-width: 40%;
	height: 30px;
	margin: 0 !important;
}

.blacklistEntry {
	font-size: 1.25rem;
	/*
    float: left;
    */
	min-width: 50%;
	color: white;
	display: inline-block;
	border: thin solid silver;
	padding: 5px;
}

.blacklistEntry p {
	margin: 0;
	display: inline;
	font-size: 1.25rem !important;
}

.blacklistRemove {
	color: white !important;
	font-size: 1.25rem;
	display: inline-block;
	border: 3px solid red;
	background: red !important;
	float: right;
	padding-left: 5px;
	padding-right: 5px;
	-webkit-touch-callout: none;
	-webkit-user-select: none;
	-khtml-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}

.blacklistRemove:hover {
	color: white;
}

#settingsAlertBox {
	margin-bottom: 5px;
}

#styleEntries {}
.styleEntry * {
	display: inline-block;
	vertical-align: unset;
}

.styleEntry {
	display: inline-block;
	border: thin solid black;
	padding: 2px 4px 0 4px;
	margin: 0 5px 5px 5px;
	background: #373952;
}

.styleTitle {
	margin: 0;
	height: 100%;
}

.colorSet {
	width: 7em;
	margin: 0 1em 0.25em 1em !important;
	color: white;
	max-width: 40%;
	height: 30px;
}

.colorPick * {
	all: unset;
}

.colorPick {
	width: 25px !important;
	height: 1.5em !important;
	border: none !important;
	padding: 0 !important;
	margin: 0 0 0.25em 0 !important;
}

#styleInput {
	height: 500px;
	resize: none;
}

#liveBox {
	display: block;
	height: 100%;
	width: auto;
	float: right;
	padding-left: 1%;
	padding-right: 1%;
	border-left: solid;
	border-Right: solid;
	border-color: #ebf3f7;
	box-sizing: border-box;
	font-weight: bold;
	color: black;
	text-shadow: -1px -1px 0 #ebf3f7, 1px -1px 0 #ebf3f7, -1px 1px 0 #ebf3f7, 1px 1px 0 #ebf3f7;
}

#liveBox.dark {
	border-color: #36394d;
	color: white !important;
	text-shadow: -1px -1px 0 #36394d, 1px -1px 0 #36394d, -1px 1px 0 #36394d, 1px 1px 0 #36394d !important;
}

.blacklist {
	height: auto;
	width: 0px;
}

.linkDiv {
	width: 100%;
	overflow: auto;
}

.linkDiv img {
	width: 100%;
	display: block;
}

.functionalLink {
	padding: 0.5em;
}

.functionalContainer {
	position: relative;
	width: 100%;
	padding-bottom: 100%;
}

.functionalVideo {
	position: absolute;
	width: 100%;
	height: 100%;
}

.toggleBtn {
	//-webkit-appearance: none;
	//padding: 9px;
	//border-radius: 3px;
	//display: inline-block;
	//position: relative;
	//height:100% !important;
	//max-height:100% !important;
	//margin-top:0 !important;
	//margin-bottom:0 !important;
	margin-left: 10px; //margin-right:0 !important;
	border: solid #393a4d;
	border-width: 1px 1px 1px 1px;
	box-shadow: 1px 1px 1px 1px #4f516b;
}

.msgModBox {
	display: none;
	padding-bottom: 0.5em;
}

.dark > .msgMod {
	color: unset;
}

.msgMod {
	width: auto;
	color: white;
	font-weight: bold;
	padding: 0 0.5em 0 0.5em;
	margin: 0 3em 0 0;
}

.msgMod.edit {
	display: none;
}

.vis .msgModBox {
	display: initial;
}

.vis.editMode .msgModBox .msgMod.edit {
	display: initial;
}

.editMode textarea {
	resize: none;
	height: 100px;
}

.contactMain, .contactL, .contactR, .topicMessage {
	background: #2a2c3b !important;
	color: white !important;
}

.contactL {
	float: left;
	width: 50%;
}

.contactR {
	float: right;
	width: 50%;
}

.contactR input {
	background: #2a2c3b !important;
}

.topicMessage {
	resize: none;
}

.colors {
	background: #2a2c3b !important;
	color: white !important;
}

input[type="button"].textModBtn,
.textModBtn {
	height: 100%;
	width: 25%;
	display: inline-block;
	text-align: center;
	-moz-user-select: none;
	-khtml-user-select: none;
	-webkit-user-select: none;
	-ms-user-select: none;
	user-select: none;
}

.textMod {
	display: none;
	position: relative;
	height: auto;
	width: 100%;
	z-index: 20;
	background-color: #428bca;
	color: white;
	-moz-user-select: none;
	-khtml-user-select: none;
	-webkit-user-select: none;
	-ms-user-select: none;
	user-select: none;
}

.textMod.vis {
	display: block;
	-moz-user-select: none;
	-khtml-user-select: none;
	-webkit-user-select: none;
	-ms-user-select: none;
	user-select: none;
}

.linkImg:before {
	content: '\\1F517';
	display: block;
	position: absolute;
	right: 50px;
	top: 25px;
	cursor: pointer;
	font: normal normal normal 0.9rem/1 FontAwesome;
}

.linkInput {
	display: block;
	bottom: 5em;
	width: 100%;
	height: auto;
	background: #323448;
	z-index: 10000;
	margin: 0 !important;
}

.linkInput > textarea {
	padding: 0.25em !important;
	margin: 0 !important;
	resize: none;
	height: 50px;
	width: 90%;
	float: left;
}

.linkInput > input {
	display: block !important;
	float: left;
	padding: 0 !important;
	margin: 0 !important;
	height: 25px;
	width: 10%;
}

.eCSSRow {
	margin-bottom: 10px;
}

.ExternalLink:first-of-type {
	width: 80%;
}

input.ExternalLink {
	height: 31px;
	width: 10%;
	margin: 0 !important;
}

.eCSS {
	margin: none;
}
            `;
        var style = document.createElement('style');

        if (style.styleSheet) {
            style.styleSheet.cssText = css;
        } else {
            style.appendChild(document.createTextNode(css));
        };
        document.getElementsByTagName('head')[0].appendChild(style);
    };
    insertCSS();

    function darkCheck(){
        if (/\-dark/.test(document.head.querySelector('link[rel="stylesheet"]').href)){
            window.darkMode=true;
        }
        else{
            window.darkMode=false;
        }
    };

    var rolled = false;
    var lastURL = window.location.href;
    var settings = JSON.parse(localStorage.getItem('FL_Settings'));
    var defaultSettings = {
        'imageResize': true,
        'questRemove': true,
        'questAuthorRemove': true,
        'removeTaggedAuthor': false,
        'anonToggle': false,
        'removeUsernames': false,
        'autoRoller': false,
        'removeTopicForm': true,
        'removeBlankTopics': true,
        'authorHighlight': true,
        'authorBlacklist': ['0jordinio0','vexin980'],
        'chatBlacklist': false,
        'chatBlacklistReplies': true,
        'chatBlacklisted': [],
        'tagBlacklist': [],
        'alertBlacklist': [],
        'sortAlerts': false,
        'highlightColor': '#393c59',
        'highlightLight': '#fc8c03',
        'highlightLightToggle': false,
        'liveRestore': true,
        'liveLight': false,
        'functionalLinks': false,
        'functionalVideos': false,
        'removeNSFW': false,
        'updateRequestDismiss': false,
        'alertContainer': 999,
        'akunPlus': 'Ignore',
        'customCSS': [{}, ``],
        'userReveal':false,
        'unpublishBTN':false,
        'messageEdit':false,
        'textStyle':false,
        'diceButton':false,
        'imageLink':false,
        'reviewDismiss':false,
        'followDismiss':false,
        'followLike':false,
        'alertFilter':false,
        'externalCSS':[],
        'spamRemoval':false,
        'maxWords':500,
        'bannedString':[],
        'deletedString':[],
        'messageBlacklist':false
    };

    //Updates settings when there is a change between versions.
    if (!settings) {
        console.log('Settings set to defaults.');
        settings = defaultSettings
    }
    else if (Object.keys(settings).length !== Object.keys(defaultSettings).length) {
        console.log('Settings differ in length.');
        Object.keys(defaultSettings).forEach(
            function (key) {
                if (!(key in settings)) {
                    settings[key] = defaultSettings[key];
                    console.log('Added ' + key + ' to the current settings.');
                };
            });
        if (Object.keys(settings).length > Object.keys(defaultSettings).length) {
            Object.keys(settings).forEach(
                function (key) {
                    if (!(key in defaultSettings)) {
                        //console.log(`Removed invalid variable and value from settings, ${key}:${settings[key]}.`);
                        //delete settings[key]
                    };
                });
        }
    };

    //settings.uiden={}
    //console.log(settings.uiden)

    localStorage.setItem('FL_Settings', JSON.stringify(settings));
    window.USERNAME = getUser();
    var USERNAME = window.USERNAME

    function getUser(){
        if (document.querySelector('.user')){
            //console.log(document.querySelector('.user').href.replace(/.*user\//,''))
            try{
                USERNAME = document.querySelector('.user').href.replace(/.*user\//,'')
                return USERNAME
            }catch(error){
                console.log('Username detect 1 failed',error);
            };}
        try{
            var cookies = document.cookie;
            cookies = cookies.split("; ")
            for (let i = 0; i < cookies.length; i++) {
                var cookie = cookies[i].split("=")
                if (/.*distinct_id.*/.test(cookie)) {
                    var cookieName = cookie[0].replace(/_posthog/, '')
                    cookieName = cookieName.replace('ph_', '')
                    USERNAME = JSON.parse(decodeURIComponent(cookie[1])).distinct_id
                    break
                }
            }
            return USERNAME
        }catch(error){
            console.log('Username detect 1 failed',error);
            return '-'
        };
    };

    function sortQuestTags() {
        //ignore this
        var list = document.querySelector('span.tags');
        var l2 = [...list.children];
        var l3 = l2.filter(
            function (value, index, arr) {
                if (value.className !== 'tag more ng-scope') {
                    return value
                };
            });
        l3.sort((a, b) => a.innerText > b.innerText ? 1 : -1).forEach(node => list.appendChild(node));
    };

    function blacklistRemove(item) {
        if (settings.alertBlacklist.includes(item)) {
            let position = settings.alertBlacklist.indexOf(item);
            settings.alertBlacklist.splice(position, 1);
            localStorage.setItem('FL_Settings', JSON.stringify(settings));
        };
    };

    function removeNSFW(){
        if (settings.removeNSFW == true) {
            Array.from(document.getElementsByClassName('nsfwCover')).forEach(qst=>qst.classList.remove('nsfwCover'));
        }
    }

    function repeatChecker() {
        try {
            let thisPage = window.location.href;
            if (thisPage !== lastURL) {
                try {
                    questCheck.observerQst.disconnect();
                } catch (error) {}
                try {
                    questCheck.observerTopic.disconnect();
                } catch (error) {}
                pageCheck();
                lastURL = window.location.href;
            };
        } catch (error) {
            console.log('Error with repeatChecker', error);
        };
    };
    setInterval(repeatChecker, 500);

    function chatSend(info) {
        let body = info[1]
        try {
            //var encodedBody = encodeURI(body);
            fetch("https://fiction.live/api/anonkun/dice", {
                "credentials": "include",
                "headers": {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0",
                    "Accept": "*/*",
                    "Accept-Language": "en-GB,en;q=0.5",
                    "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                    "X-Requested-With": "XMLHttpRequest"
                },
                "referrer": window.location.href,
                "body": body,
                "method": "POST",
                "mode": "cors"
            });
        } catch (error) {
            console.log('Error with chatSend', error);
        }
        try {
            let chapterID = info[0][0]
            let dataID = info[0][1]
            let roll = info[0][2]
            var cookies = document.cookie;
            cookies = cookies.split("; ")
            for (let i = 0; i < cookies.length; i++) {
                var cookie = cookies[i].split("=")
                if (/.*distinct_id.*/.test(cookie)) {
                    var cookieName = cookie[0].replace(/_posthog/, '')
                    cookieName = cookieName.replace('ph_', '')
                }
            }
            fetch("https://fiction.live/api/node", {
                "credentials": "include",
                "headers": {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0",
                    "Accept": "*/*",
                    "Accept-Language": "en-GB,en;q=0.5",
                    "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                    "X-Requested-With": "XMLHttpRequest"
                },
                "referrer": `https://fiction.live/stories/${body}`,
                "body": encodeURI(`r[]=${chapterID}&r[]=${dataID}&nt=chat&b=%2Froll+`) + encodeURIComponent(`${roll}`) + encodeURI(`&ra[hide]=true&ra[_id]=${dataID}&ra[b]=chapter+${dataID}&token=${cookieName}`),
                "method": "POST",
                "mode": "cors"
            });
        } catch (error) {
            console.log('Error with RollSend', error);
        }
    };

    function authorCheck(quest) {
        if (/fiction.live\/explore|reviews.*/.test(window.location)){return}
        let author = quest.querySelector('div.authorPane');
        if (author == null) {
            try {
                author = quest.parentNode.parentNode.querySelector('span.name').innerText
                quest = quest.parentNode.parentNode.parentNode
            } catch (error) {
                //console.log('authorCheck Null', error)
            };
        } else {
            author = author.innerText;
        }

        if (settings.authorBlacklist.includes(author)) {
            try {
                while (true) {
                    if (quest.parentNode == null ) {
                        break
                    }
                    if (quest.parentNode.classList.contains('ng-scope') && quest.parentNode.tagName == 'LI') {
                        quest.parentNode.remove()
                        break
                    } else {
                        quest = quest.parentNode
                    }
                }
                return
            } catch (error) {
                console.log('authorCheck remove',error)
            };
            return;
        };
    };

    function tagCheck(quest) {
        let tags = quest.querySelector('div.tags');
        if (tags == null) {
            let tag = quest.parentNode.parentNode.querySelector('div.displayedTag');
            if (tag != null | '' | undefined) {
                if (settings.tagBlacklist.includes(tag.innerText)) {
                    try {
                        while (true) {
                            if (quest.parentNode == null) {
                                break
                            }
                            if (quest.parentNode.classList.contains('ng-scope') && quest.parentNode.tagName == 'LI') {
                                quest.parentNode.remove()
                                break
                            } else {
                                quest = quest.parentNode
                            }
                        }
                        return
                    } catch (error) {
                        console.log('tagCheck remove', error)
                    };
                };
                return

            } else {
                return
            }
        };
        tags = tags.children;
        for (let i = 0; i < tags.length; i++) {
            let tag = tags[i]
            if (settings.tagBlacklist.includes(tag.innerText)) {
                try {
                    //quest.parentNode.parentNode.remove();
                    quest.closest('.storyListItem').parentNode.remove()
                } catch (error) {
                    console.log('tagCheck remove',quest.closest('.storyListItem'), error)
                };
                break;
            };
        };
    };

    function removeBlacklisted() {
        let quests = document.querySelectorAll('div.storyListItem');
        for (let i = 0; i < quests.length; i++) {
            if (settings.questRemove == true) {
                tagCheck(quests[i].children[0]);
            }
            if (settings.questAuthorRemove == true) {
                authorCheck(quests[i].children[0]);
            }
        };
    };

    function liveRestore() {
        var navBar = document.querySelector('[id="mainMenuReplacement"][class="navbar navbar-default navbar-fixed-top"]');
        var liveTimer = document.querySelectorAll('[class="next-live ng-scope"]');
        var myLive = document.createElement('div');
        myLive.setAttribute('id', 'liveBox');
        if (document.querySelector('#liveBox')){
            document.querySelector('#liveBox').appendChild(liveTimer[0].children[0])
            return;
        }
        darkCheck()
        if (window.darkMode == true) {
            myLive.classList.add('dark')
        }
        while (liveTimer[0].children.length > 0) {
            myLive.appendChild(liveTimer[0].children[0]);
        }
        navBar.appendChild(myLive);
        liveTimer[0].style.display = 'none';
    };

    function waitForTimer() {
        if (settings.liveRestore == false) {
            return
        };

        var observerTimer = new MutationObserver(awaitTimer);
        function awaitTimer(mutations) {
            for (let mutation of mutations) {
                try {
                    var canvas = document.querySelector('header[class="next-live ng-scope"]');
                } catch (error) {}
                if (canvas && (canvas !== undefined && canvas.length != 0)) {
                    observerTimer.disconnect(); // stop observing
                    liveRestore()
                    return;
                };
            };
        };
        observerTimer.observe(document, {
            childList: true,
            subtree: true
        });
        setTimeout(function () {
            try {
                observerTimer.disconnect();
            } catch (error) {}
        }, 1000);
    };

    function questCheck() {
        if (settings.questRemove !== true && settings.questAuthorRemove !== true && settings.removeNSFW !== true) {
            return;
        }
        try {
            var options = {
                childList: true,
                subtree: true
            };
            function qstMod(mutations) {
                for (let mutation of mutations) {
                    try {
                        let quest = mutation.addedNodes[0];
                        //console.log(mutation.addedNodes[0])
                        if (quest) {
                            try {
                                if (quest.classList.contains('storyListItem')){
                                    if (settings.questRemove == true) {
                                        tagCheck(quest);
                                    }
                                    if (settings.questAuthorRemove == true) {
                                        authorCheck(quest);
                                    }
                                    removeNSFW();
                                }
                                else if (quest.parentNode.classList.contains('storyListItem')) {
                                    try{
                                        if (settings.questRemove == true) {
                                            tagCheck(quest);
                                        }
                                        if (settings.questAuthorRemove == true) {

                                            authorCheck(quest);
                                        }
                                        removeNSFW();
                                    }catch(error){console.log('error',error)}

                                }
                                else if (quest.parentNode.parentNode.parentNode.parentNode.classList.contains('storyListItem') && /.*fiction.live\/$/.test(URL)) {
                                    if (settings.questRemove == true) {
                                        if (quest) {
                                            tagCheck(quest);
                                        }
                                    }
                                    try {
                                        if (settings.questAuthorRemove == true) {
                                            if (quest) {
                                                authorCheck(quest);
                                            }
                                        }
                                    } catch (error) {
                                        console.log(error)
                                    }

                                }
                                else if (quest.querySelector('.storyListItem')){
                                    //return
                                    // For fiction.live
                                    if (settings.questRemove == true) {
                                        if (quest) {
                                            tagCheck(quest.querySelector('.storyListItem'));
                                        }
                                    }
                                    try {
                                        if (settings.questAuthorRemove == true) {
                                            if (quest) {
                                                authorCheck(quest.querySelector('.storyListItem'));
                                            }
                                        }
                                    } catch (error) {
                                        console.log(error)
                                    }
                                    removeNSFW();

                                }
                            } catch (error) {
                                //console.log('If this appears more than twice, make an issue.')
                                if (error instanceof TypeError) {}
                                else {
                                    console.log(error)
                                }
                            }

                        }
                        //observerMessage.disconnect();
                    } catch (error) {
                        console.log('New quest Error', error);
                    }

                };
            };
            let observerQst = new MutationObserver(qstMod);
            observerQst.observe(document, options);
            questCheck.observerQst = observerQst;
            removeBlacklisted();
        } catch (error) {
            console.log('questCheck', error)
        };

    };

    function exploreBlacklistCheck(){
        function checkTagGroup(x){
            if (settings.tagBlacklist.includes(x.querySelector('h2').innerText.replace('/',''))){
                x.remove();
            }else{
                var tags = x.getElementsByClassName('displayedTag');
                let tt=function(tag){
                    if (settings.tagBlacklist.includes(tag.innerText)){
                        tag.closest('.embla__slide').remove()
                    }
                }
                Array.from(tags).forEach(tag=>{tt(tag)});
            }

        }

        function elementAwaitExplore(mutations) {
            for (let mutation of mutations) {
                try {
                    let topic = mutation.addedNodes[0];
                    if (topic) {
                        try {
                            if (!topic.classList){continue};
                            if (topic.classList.contains('popular-tags-list')){
                                observerTopic.disconnect();
                                Array.from(topic.children).forEach(tag=>{checkTagGroup(tag)});
                                removeNSFW()
                            };

                        } catch (error) {
                            console.log(error)
                        }

                    }
                } catch (error) {
                    console.log('New quest Error', error);
                }

            };
        };

        let observerTopic = new MutationObserver(elementAwaitExplore);
        observerTopic.observe(document, {childList: true, subtree: true});
        questCheck.observerTopic = observerTopic;
    };

    function foryouBlacklistCheck(){
        function checkTag(storyListing){
            try{
                var tag = storyListing.getElementsByClassName('displayedTag')[0]
                if (!tag || tag.length == 0){return}
                if (settings.tagBlacklist.includes(tag.innerText)){
                    storyListing.parentNode.remove()
                }}catch(error){}
        };
        function checkAuthor(storyListing){
            try{
                var name = storyListing.querySelector('span.name').innerText
                if (!name || name.length == 0){return}
                if (settings.authorBlacklist.includes(name)){
                    storyListing.parentNode.remove()
                }}catch(error){}
        };

        function elementAwaitForYou(mutations) {
            for (let mutation of mutations) {
                try {
                    var topic = mutation.addedNodes[0];
                    if (topic) {
                        try {
                            if (!topic.classList){return}
                            if (topic.classList.contains('storyListItem')){}
                            var SLIs=document.getElementsByClassName('storyListItem');
                            //console.log('SLIs',SLIs)
                            if (!SLIs || topic.id != 'main'){continue};
                            if (SLIs){
                                observerTopicx.disconnect();
                                Array.from(SLIs).forEach(SLI=>{checkTag(SLI)});
                                Array.from(SLIs).forEach(SLI=>{checkAuthor(SLI)});
                                removeNSFW();
                            };
                        } catch (error) {
                            console.log(error);
                        }
                    }
                    removeNSFW();
                } catch (error) {
                    console.log('New quest Error', error);
                }
            };
        };

        let observerTopicx = new MutationObserver(elementAwaitForYou);
        observerTopicx.observe(document, {childList: true, subtree: true});
        questCheck.observerTopic = observerTopicx;
    };

    function storyThings(){
        //Detects when the content of a quest is displayed, the rolls/text
        var options = {
            childList: true,subtree:true
        };
        var observeDoc = new MutationObserver(function(mutations){
            for (let mutation of mutations) {
                try{
                    var storyPosts = document.getElementById('storyPosts').children[0]
                    if (typeof(storyPosts) != undefined && storyPosts != undefined){
                        observeDoc.disconnect();
                        checkStory(storyPosts);
                        monitorStory(storyPosts);
                        break;
                    }
                } catch (error) {};
            }
        });
        observeDoc.observe(document, options);

        function createRollButton(roll){
            var inp=document.createElement('input');
            inp.setAttribute('type','button');
            inp.setAttribute('class','rollButton');
            if (window.darkMode == true){
                inp.style = 'height:auto;width:auto;margin:1;padding:1;background:rgb(57, 60, 89);';
            }else{
                inp.style = 'height:auto;width:auto;margin:1;padding:1;background:rgb(255, 172, 71);';
            }
            inp.value = 'Roll '+roll;
            inp.onclick = function (){
                var latestUpdate = document.querySelector('div#storyPosts').firstChild.lastChild;
                var poll = latestUpdate.firstChild.firstChild;
                if (latestUpdate.classList.contains('readerPost') == false || poll.classList.contains('closed')) {
                    return;
                } else if (!(poll.classList.contains('closed'))) {
                    var dataID = this.closest('article').getAttribute('data-id');
                    var chapterID = document.querySelector('article.threads').getAttribute('threads');
                    chapterID = chapterID.replace(/\/.*/, '');
                    var rollSend = `/roll ${roll}`;
                    var template = `sid=${chapterID}&dice=${encodeURIComponent(rollSend)}`;
                    chatSend([[chapterID, dataID, roll], template]);
                }
                this.style.display='none';
            };
            return inp
        };

        function imageInsert(element){
            try{
                if (/\[.*\]/.test(element.innerText)){
                    let info = element.innerText.replace(/(\[|\])/g,'').split(',')
                    if (!/.*\.(gif|jpe?g|bmp|png|webp|webm|apng|jfif|pjpeg|pjp|svg|bmp|cur|ico|tif|tiff)$/igm.test(info[0])){return};
                    let image = document.createElement('img');
                    image.src = info[0]
                    let q = document.createElement('br');
                    console.log(info)
                    if (info[1].toString().toLowerCase() == 'hide'){
                        let hidden = document.createElement('input');
                        hidden.value = 'Show hidden image, potential spoilers.'
                        hidden.setAttribute('type','button');
                        hidden.onclick = function(){
                            try{
                                if (this.parentNode.lastChild != this){this.parentNode.insertBefore(q, this.nextSibling)};
                                this.replaceWith(this.children[0]);
                            }catch(error){console.log(error)};
                        };
                        hidden.appendChild(image);
                        element.replaceWith(hidden);
                    }
                    else{
                        if (element.parentNode.lastChild != element){
                            element.parentNode.insertBefore(q, element.nextSibling);
                        }
                        element.replaceWith(image);
                    }
                };
            }catch(error){console.log(error)};
        };

        function imageInsertbtn(){
            let li = document.createElement('li')
            let btn = document.createElement('button');
            btn.setAttribute('class','fa fa-photo');
            btn.setAttribute('tooltip-position','top');
            btn.setAttribute('tooltip-content','Add an image to the quest visible only to script users. Pick show or hide depending if the image is a spoiler.');
            btn.onclick = function(){
                let p = document.createElement('p')
                p.setAttribute('class','aaaaax');
                p.innerText = '[ImageURLhere,Show/Hide]';
                try{
                    if (window.getSelection().anchorNode.tagName != 'DIV'){
                        window.getSelection().anchorNode.parentNode.append(p);
                    }
                    else{
                        window.getSelection().anchorNode.append(p);
                    }
                }catch(error){
                    console.log(error)
                    console.log(window.getSelection().anchorNode)
                }

            };
            li.appendChild(btn);
            return li;
        };

        function checkStory(storyPosts){
            try{
                for (let post of storyPosts.childNodes){
                    if (post.className.includes('chapter') && post.innerText.match(/\[.*\]/)){
                        post.querySelectorAll('p').forEach(p=>imageInsert(p))
                    };
                }
            }catch(error){
                console.log('Error with checkStory');
            }
        }

        function monitorStoryQM(){
            document.querySelectorAll('.medium-editor-toolbar').forEach(tb=>{
                let btn = new imageInsertbtn;
                tb.children[0].insertBefore(btn,tb.children[0].children[tb.children[0].children.length-1]);
            });

            let A = document.createElement('div');
            A.setAttribute('class','monitorStoryQM');
            document.body.appendChild(A);
            let options = {childList: true};
            let observeToolbars = new MutationObserver(function (mutations) {
                for (let mutation of mutations) {
                    try {
                        if (mutation.addedNodes.length != 0){
                            let node=mutation.addedNodes[0];
                            if (node.classList.contains('medium-editor-toolbar')){
                                let btn = new imageInsertbtn;
                                node.children[0].insertBefore(btn,node.children[0].children[node.children[0].children.length-1]);
                            };
                        }
                    } catch (error) {
                        console.log('monitorStory Error',error);
                    };
                };
            });
            observeToolbars.observe(document.body, options);
        };
        let addInsert = function (event) {
            document.removeEventListener("dblclick", addInsert, false);
            let QM = document.querySelector('.goLive');
            let Started = document.querySelector('.monitorStoryQM');
            if (Started){return};
            if (QM){monitorStoryQM()};
        };
        document.addEventListener("dblclick", addInsert, false);

        function monitorStory(storyPosts){
            function rollPro(roll,elm){
                elm.querySelector('.chapterContent').appendChild(createRollButton(roll));
                setTimeout(function(){elm.querySelector('.rollButton').remove()},60000);
            };

            function sortPoll(table){
                var l3 = [...table.children].filter(
                    function (value, index, arr) {
                        if (value.className !== '') {
                            //Ignore the 'Votes' header
                            return value;
                        };
                    });
                //Order the poll by total votes
                l3.sort((a, b) => parseInt(a.querySelector('span[data-hint="Total Votes"]').innerText) < parseInt(b.querySelector('span[data-hint="Total Votes"]').innerText) ? 1 : -1).forEach(node => table.appendChild(node));};
            //Checks if new posts are saying that there is a roll, if so, add a button to roll.
            let options = {childList: true};
            let observerPosts = new MutationObserver(function (mutations) {
                for (let mutation of mutations) {
                    try {
                        try{
                            if (!window.customA){
                                window.customA = true;
                            }
                        }catch(error){}
                        if (mutation.addedNodes.length != 0){
                            let elm = mutation.addedNodes[0];
                            var diceRegex = /[0-9]+d[0-9]+(?<!1d1)((\+|\-)[0-9]+)?( ?)(([ie]+)?([ut][0-9]+)?)+/g;
                            //If text post like an update
                            if (elm.className.includes('chapter')){
                                if (elm.innerText.match(/\[.*\]/)){
                                    elm.querySelectorAll('p').forEach(p=>imageInsert(p))
                                };
                                continue
                            }
                            //Auto sort poll results by votes
                            else if (elm.className.includes('chapter choice')){
                                console.log('A poll has been created.')
                                let pollState = elm.children[0].children[0];
                                let observePoll = new MutationObserver(function(mutations){
                                    for (let mutation of mutations) {
                                        try{
                                            //When the poll gets closed, sort the results and start a timer to stop monitoring.
                                            //console.log(mutation)
                                            if (pollState.className.includes('closed')){
                                                //console.log('sort')
                                                let table = pollState.querySelector('tbody');
                                                sortPoll(table);
                                                setInterval(function(){try{observePoll.disconnect}catch(e){}},120000)
                                            };
                                        } catch (error) {
                                            console.log(error);
                                        };
                                    };
                                });
                                observePoll.observe(pollState, {attributes: true});
                            }
                            //a
                            else if (elm.querySelector('.fieldBody > b')){continue;}
                            else if (diceRegex.test(elm.innerText)){
                                if (settings.diceButton == true){
                                    let rolls = elm.innerText.match(diceRegex);
                                    rolls.forEach(roll => rollPro(roll,elm))
                                };
                            };
                        };
                    } catch (error) {
                        console.log('monitorStory Error',error);
                    };
                };
            });
            if (window.monSto != undefined){observerPosts.disconnect();};
            observerPosts.observe(storyPosts, options);
            window.monSto = observerPosts;
        };
    };

    function pageCheck(){
        try {
            let URL = window.location.href;
            if ((/.*(fiction.live\/stories\/).*/.test(URL))) {
                chatThings();
                waitForTimer();
                storyThings();
            } else if (/.*(fiction.live$)/.test(URL)) {
                questCheck();
            } else if (/.*(fiction.live\/stories\/?).*/.test(URL)) {
                questCheck();
            } else if (/.*(fiction.live\/social\/threads\/).*/.test(URL)) {
                chatThings();
            } else if (/.*(fiction.live\/live\?).*/.test(URL)) {
                questCheck();
            } else if (/.*(fiction.live\/social).*/.test(URL)) {
                removeBlankTopics();
            } else if (/.*fiction.live\/$/.test(URL)) {
                questCheck();
            } else if (/.*fiction.live\/explore/.test(URL)) {
                exploreBlacklistCheck();
            } else if (/.*fiction.live\/foryou/.test(URL)) {
                foryouBlacklistCheck();
            } else if (/.*fiction.live\/user\/.*\/(stories$||collections\/.*)/.test(URL)) {
                if (settings.removeTaggedAuthor == true) {questCheck();};
            } else if (/.*fiction.live\/reviews/.test(URL)) {
                console.log('work on me dummy');
                questCheck()
            } else {
                console.log('Page currently has no specific functions.');
            }
        } catch (error) {
            console.log('Error with pageCheck', error);
        };
    };

    function removeBlankTopics() {
        if (settings.removeBlankTopics !== true) {
            return;
        };
        try {
            var options = {
                childList: true,
                subtree: true
            };
            function topicWatch(mutations) {
                for (let mutation of mutations) {
                    try {
                        let topic = mutation.addedNodes[0];
                        if (topic) {
                            try {
                                if (typeof(topic.classList) == 'undefined') {}
                                else if (topic.classList.contains('threadList')) {
                                    let topicItem = topic.querySelectorAll('li.threadListItem');
                                    for (let i = 0; i < topicItem.length; i++) {
                                        if (topicItem[i].querySelector('div.row.title.header').innerText.length == 0) {
                                            topicItem[i].remove();
                                        };
                                    };
                                };
                            } catch (error) {
                                console.log(error);
                            };
                        };
                    } catch (error) {
                        console.log('New quest Error', error);
                    };
                };
            };
            let observerTopic = new MutationObserver(topicWatch);
            observerTopic.observe(document, options);
            questCheck.observerTopic = observerTopic;
        } catch (error) {
            console.log('topicCheck', error)
        };
    };

    function newThemeChange(){
        if (settings.useThemeChange != true){
            return;
        };
        if (window.TChange == true){
            return;
        };
        //return
        function cookieCreate(name,value,days){
            var expires;
            if (days) {
                var date = new Date();
                date.setTime(date.getTime() + (days * 24 * 60 * 60 *1000));
                expires = "; expires=" + date.toGMTString();
            } else {
                expires = "";
            }
            document.cookie = name + "=" + value + expires + "; path=/";
        };
        document.addEventListener("mousedown", function (event) {
            if (settings.useThemeChange != true){
                return;
            };
            try{
                let themeBTN = document.querySelector('[ng-click="changeTheme()"]');
                if (themeBTN == (null || undefined) || !themeBTN.contains(event.target)){
                    return;
                }
                darkCheck();
                let style=document.head.querySelector('link[rel="stylesheet"]')
                if (window.darkMode==true){
                    style.href=style.href.replace('style-dark.css','style.css');
                    cookieCreate('themeColor','default','300')
                }
                else{
                    style.href=style.href.replace('style.css','style-dark.css');
                    cookieCreate('themeColor','dark','300')
                }
            }catch(error){
                console.log('newThemeChange.',error)
            };
        });
        try{
            let themeBTN = document.querySelector('[ng-click="changeTheme()"]');
            if (themeBTN != null || undefined){
                themeBTN.outerHTML = themeBTN.outerHTML;
            }
        }catch(error){console.log(error)};
    };

    function imageLinkButton(){
        if (settings.imageLink != true){try{document.querySelector('.linkImg').remove()}catch(error){};return;};
        //if (!/.*fiction.live.stories\/.*\/.*/.test(window.location)){return;};
        if (document.querySelector('.chatInputContainer') == null){setTimeout(imageLinkButton(),1000);return;}
        if (document.querySelectorAll('.chatInputContainer').length == null){setTimeout(imageLinkButton(),1000);return;};
        //if (document.querySelector('.linkImg')){return;}
        function imageSend(info) {
            try {
                let chapterID = info[0]
                let dataID = info[1]
                let imageURL = info[2]
                let body = encodeURI(`r[]=${chapterID}&r[]=${dataID}&nt=chat&`) + `i=${imageURL}` + encodeURI(`&ra[hide]=true&ra[_id]=${dataID}&ra[b]=chapter+${dataID}`)
                if (!chapterID){
                    body = encodeURI(`&r[]=${dataID}&nt=chat&`) + `i=${imageURL}`
                }
                fetch("https://fiction.live/api/node", {
                    "headers": {
                        "User-Agent": "",
                        "Accept": "*/*",
                        "Accept-Language": "en-GB,en;q=0.5",
                        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                        "X-Requested-With": "XMLHttpRequest"
                    },
                    "body": body,
                    "method": "POST",
                    "mode": "cors"
                });
            } catch (error) {
                console.log('Error with RollSend', error);
            }
        };
        document.querySelectorAll('.chatInputContainer').forEach(x=>{
            try{
                var inp=document.createElement('div');
                inp.setAttribute('class','linkImg');
                inp.onclick=function(){
                    if (settings.imageLink != true){try{document.querySelector('.linkImg').remove()}catch(error){};return;};
                    try{
                        //if (document.querySelector('.linkInput')){return;};

                        var linkInputCont=document.createElement('div');
                        linkInputCont.setAttribute('class','linkInput');
                        var linkInputSend=document.createElement('input');
                        linkInputSend.setAttribute('type','button');
                        linkInputSend.value = 'Send';
                        linkInputSend.onclick = function(){
                            try{
                                let reply='';
                                let imageURL = linkInput.value;
                                if (imageURL == '' || !/.*\.(gif|jpe?g|bmp|png|webp)$/i.test(imageURL)){return;};
                                let dataID;
                                if (/.*\/threads\/.*/.test(window.location)){
                                    dataID = document.querySelector('#page-body').querySelector('article[chat]').getAttribute('chat');
                                    imageSend(['', dataID, imageURL, reply]);
                                }
                                else{
                                    //Old? Doesnt work now anyway
                                    //dataID = document.querySelector('div#storyPosts').firstChild.lastChild.firstChild.firstChild.getAttribute('data-id');
                                    if (this.closest('.chatItemDetail')){
                                        let ArticleID, ReplyID, ImageURL, MessageText, MessageAuthor, MessageAuthorID;
                                        ReplyID = this.closest('.chatItemDetail').getAttribute('data-id');
                                        ArticleID = document.querySelector('div#storyPosts').firstChild.lastChild.getAttribute('data-id');
                                        let ChapterID = document.querySelector('article.threads').getAttribute('threads');
                                        //MessageAuthor = this.closest('.chatItemDetail').querySelector('.user > .content a').innerText;
                                        MessageText = this.closest('.chatItemDetail').querySelector('.fieldBody').innerText;
                                        ChapterID = ChapterID.replace(/\/.*/, '');
                                        MessageAuthorID='';


                                        ImageURL = imageURL
                                        let body = "r%5B%5D="+ChapterID+"&r%5B%5D="+ArticleID+"&r%5B%5D="+ReplyID+"&nt=chat&i="+ImageURL+
                                            "&ra%5B_id%5D="+ReplyID+"&ra%5Bb%5D="+MessageText+"&ra%5Bu%5D%5Bn%5D="+MessageAuthor+"&ra%5Bu%5D%5B_id%5D="+MessageAuthorID
                                        //+"&token=phc_yFaXlxPuv5BU2WbCujfLxNFetXTmh5DjtUesJyA28TF"
                                        console.log(body)
                                        //return

                                        fetch("https://fiction.live/api/node", {
                                            "headers": {
                                                "User-Agent": "",
                                                "Accept": "*/*",
                                                "Accept-Language": "en-GB,en;q=0.5",
                                                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                                                "X-Requested-With": "XMLHttpRequest"
                                            },
                                            "body": body,
                                            "method": "POST",
                                            "mode": "cors"
                                        });
                                        return
                                    }else{
                                        dataID = document.querySelector('div#storyPosts').firstChild.lastChild.getAttribute('data-id');
                                        console.log('this',document.querySelector('div#storyPosts').firstChild.lastChild.firstChild.firstChild)
                                        let chapterID = document.querySelector('article.threads').getAttribute('threads');
                                        chapterID = chapterID.replace(/\/.*/, '');
                                        imageSend([chapterID, dataID, imageURL]);
                                    }
                                }
                            }catch(error){
                                console.log(error);
                            }
                        }

                        var linkInputExit=document.createElement('input');
                        linkInputExit.setAttribute('type','button');
                        linkInputExit.value = 'Exit';
                        linkInputExit.onclick = function(){this.parentNode.remove()}

                        var linkInput=document.createElement('textarea');
                        linkInput.setAttribute("placeholder", "Input the image link here.");
                        linkInput.setAttribute("cols", "1");
                        linkInput.setAttribute("rows", "2");

                        linkInputCont.appendChild(linkInput);
                        linkInputCont.appendChild(linkInputSend);
                        linkInputCont.appendChild(linkInputExit);



                        //document.querySelector('#right').appendChild(linkInputCont);
                        this.parentNode.appendChild(linkInputCont);

                        //imageSend([chapterID, dataID, imageURL]);

                    }catch(error){console.log(error)};
                };
                x.children[0].after(inp);
            }catch(error){console.log(error)};

        })
    };

    function chatThings() {
        try{}catch(error){};

        try{
            document.addEventListener("mousedown", function (e) {
                //console.log('clicked',e.target)
                try{
                    function fetchMessages() {
                        if (target.querySelector('.jadeRepeat') == null){
                            setTimeout(fetchMessages, 500);
                        }
                        target.querySelector('.jadeRepeat').childNodes.forEach(d => handleMsg(d));
                    };
                    //If the users clicked a chat button below a story post.
                    let target;
                    if (e.target.matches(".expandComments.showWhenDiscussionOpened")) {
                        //var b = e.target.parentNode.parentNode.parentNode;
                        target = e.target.closest('.tabbable')
                        setTimeout(fetchMessages, 500);
                    }
                    else if (e.target.matches(".btn.expandComments")) {
                        target = e.target.closest('footer')
                        setTimeout(fetchMessages, 500);
                    }
                    else if (e.target.parentNode.matches(".btn.expandComments")) {
                        target = e.target.parentNode.closest('footer')
                        setTimeout(fetchMessages, 500);
                    }
                }catch(error){
                    console.log('Error with CT discussions.',error)
                };
            });

            function chatBlacklist(message) {
                try{
                    let username = message.querySelector('.user span').innerText;
                    if (settings.chatBlacklist != true || settings.chatBlacklisted.length == 0) {return;};
                    if (settings.chatBlacklisted.includes(username)) {
                        message.classList.add('chatListed');
                        return;
                    } else {
                        if (settings.chatBlacklistReplies == true) {
                            replyCheck();
                        };
                    };

                    async function replyCheck() {
                        let msgData = '';
                        let msgData2 = '';
                        if (message.querySelector('.replyAt')) {
                            await fetch(`https://fiction.live/api/node/${message.firstChild.getAttribute('data-id')}`).then(response => response.json()).then(data => {
                                msgData = data
                            })
                            await fetch(`https://fiction.live/api/node/${msgData.ra._id}`).then(response => response.json()).then(data => {
                                msgData2 = data
                            });
                            try{
                                if (settings.chatBlacklisted.includes(msgData2)) {
                                    message.classList.add('chatListed');
                                    setTimeout(function () {
                                        try {
                                            document.querySelectorAll('.chatListed').forEach(mm => mm.remove());
                                        } catch (error) {
                                            //console.log(error);
                                        };
                                    }, 500);
                                };
                            }catch(error){
                                console.log(message)}
                        };
                    };

                    async function delMSG(name) {
                        try {
                            var msgID = message.firstChild.getAttribute('data-id');
                        } catch (error) {
                            console.log('id fail');
                        };
                        try {
                            if (name == message.querySelector('div.user span').innerText) {
                                message.remove();
                                return;
                            } else {
                                var commentName = '', replyName = '', msgData = '';
                                await fetch("https://fiction.live/api/node/" + msgID, {}).then(response => response.json()).then(data => {msgData = data});
                                commentName = msgData.u[0].n;
                                try {
                                    replyName = msgData.ra.u.n;
                                } catch (error) {
                                    console.log('reply fail');
                                };
                                if (settings.chatBlacklisted.includes(replyName)) {
                                    message.remove();
                                } else if (settings.chatBlacklisted.includes(commentName)) {
                                    message.remove();
                                };
                            };
                        } catch (error) {
                            console.log('total fail', message.parentNode);
                        };
                    };
                } catch (error) {};
            };

            function akunPlus(message) {
                try {
                    if (settings.akunPlus == 'Ignore') {
                        return;
                    } else if (settings.akunPlus == 'Remove') {
                        message.querySelector('.chatMsg').removeAttribute('plan');
                    } else {
                        message.querySelector('.chatMsg').setAttribute('plan', '1');
                    }
                } catch (error) {
                    //console.log(message.querySelector('span.name'),message.querySelector('.message').innerText,error)
                }
            };

            function functionalLinks(message) {
                function isVisible(element){
                    try{
                        let bounding = element.getBoundingClientRect();
                        if(bounding.top >= 0 && bounding.left >= 0 &&
                           bounding.right <= (window.innerWidth || document.documentElement.clientWidth) &&
                           bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight))
                        {
                            return true;
                        }else{
                            return false;
                        }

                    } catch (error) {}
                };

                try{
                    try {
                        if (message.querySelector('.message').querySelector('img') || message.querySelector('.linkDiv')){
                            return;
                        }
                    } catch (error) {
                    }
                    let Control = [0, 0, 0]
                    var elmDiv = document.createElement('div');
                    elmDiv.setAttribute('class', 'linkDiv');
                    var elmDivControl = document.createElement('div');

                    var elmDivControlA = document.createElement('input');
                    elmDivControlA.setAttribute("type", "button");
                    elmDivControlA.setAttribute("hide", 'false');
                    elmDivControlA.value = 'Disable Link(s)'
                    elmDivControlA.onclick = function () {
                        if (this.getAttribute('hide') == 'true' || null) {
                            this.setAttribute('hide', 'false');
                            this.value = 'Disable Link(s)';
                            this.parentNode.parentNode.querySelector('.linkDivA').style.display = 'initial';
                        } else {
                            this.setAttribute('hide', 'true');
                            this.value = 'Enable Link(s)';
                            this.parentNode.parentNode.querySelector('.linkDivA').style.display = 'none';
                        }
                    }

                    var elmDivControlB = document.createElement('input');
                    elmDivControlB.setAttribute("type", "button");
                    elmDivControlB.setAttribute("hide", 'false');
                    elmDivControlB.value = 'Disable Image(s)'
                    elmDivControlB.onclick = function () {
                        if (this.getAttribute('hide') == 'true' || null) {
                            this.setAttribute('hide', 'false');
                            this.value = 'Disable Image(s)';
                            this.parentNode.parentNode.querySelector('.linkDivB').style.display = 'initial';
                        } else {
                            this.setAttribute('hide', 'true');
                            this.value = 'Enable Image(s)';
                            this.parentNode.parentNode.querySelector('.linkDivB').style.display = 'none';
                        }
                    }

                    var elmDivControlC = document.createElement('input');
                    elmDivControlC.setAttribute("type", "button");
                    elmDivControlC.setAttribute("hide", 'false');
                    elmDivControlC.value = 'Disable Video(s)'
                    elmDivControlC.onclick = function () {
                        if (this.getAttribute('hide') == 'true' || null) {
                            this.setAttribute('hide', 'false');
                            this.value = 'Disable Video(s)';
                            this.parentNode.parentNode.querySelector('.linkDivC').style.display = 'initial';
                        } else {
                            this.setAttribute('hide', 'true');
                            this.value = 'Enable Video(s)';
                            this.parentNode.parentNode.querySelector('.linkDivC').style.display = 'none';
                        }
                    }

                    var elmDivA = document.createElement('div');
                    elmDivA.setAttribute('class', 'linkDivA');
                    elmDiv.appendChild(elmDivA);

                    var elmDivB = document.createElement('div');
                    elmDivB.setAttribute('class', 'linkDivB');
                    elmDiv.appendChild(elmDivB);

                    var elmDivC = document.createElement('div');
                    elmDivC.setAttribute('class', 'linkDivC');
                    elmDiv.appendChild(elmDivC);

                    function link(type, type2, link) {
                        var elm = document.createElement(type);
                        if (type2 == 1) {
                            elm.src = link;
                            elmDiv.childNodes[1].appendChild(elm);
                        } else if (type2 == 2) {
                            elm.href = link;
                            elm.innerHTML = 'Link';
                            elm.setAttribute('class', 'functionalLink');
                            elm.rel = "noopener noreferrer";
                            elm.target = "_blank";
                            elmDiv.childNodes[0].appendChild(elm);
                        } else if (type2 == 3) {
                            elm = document.createElement('iframe');
                            elm.setAttribute('frameborder', '0')
                            elm.setAttribute('allowFullScreen', '')
                            elm.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture';
                            elm.src = link;
                            elm.setAttribute('class', 'functionalVideo');
                            let functionalContainer = document.createElement('div');
                            functionalContainer.setAttribute('class', 'functionalContainer');
                            functionalContainer.appendChild(elm);
                            elmDiv.childNodes[2].appendChild(functionalContainer);
                        }
                        return elmDiv
                    }

                    function linkProcess(match) {
                        try {
                            //If theres already a link container, check if the links been embedded
                            if (message.querySelector('.linkDiv')) {
                                var qq = message.querySelector('.linkDiv').querySelectorAll('a').forEach(
                                    x => {
                                        if (x.href == match) {
                                            return;
                                        };
                                    });
                            };
                        } catch (error) {
                            console.log(error);
                        };
                        if (typeof match == 'undefined' || match.startsWith('/') || match.length < 5 || /.+\..+/.test(match) == false) {}
                        else {
                            try {
                                if (/([a-z]*\.{2,}[a-z]*)/.test(match) == true) {
                                    return
                                };
                                var elm;
                                if (/https?:\/\//.test(match) == false) {
                                    match = 'https://'.concat(match)
                                };
                                if (/.*(jpg|jpeg|png|gif|webm|webp)/.test(match)) {
                                    elm = new link('img', 1, match);
                                    Control[1] = 1;

                                } else if (settings.functionalVideos == true && (/youtu\.?be/.test(match))) {
                                    if (/.*v=(\w+).*/.test(match)) {
                                        let src = `https://www.youtube.com/embed/${(match.match(/v=(\w+)/)[1])}`;
                                        elm = new link('iframe', 3, `https://www.youtube.com/embed/${(match.match(/v=(\w+)/)[1])}`);
                                        message.querySelector('.chatMsg').parentNode.appendChild(elm);
                                    } else if (/be\/(\w+)/.test(match)) {
                                        let src = `https://www.youtube.com/embed/${(match.match(/be\/(\w+)/)[1])}`;
                                        elm = new link('iframe', 3, `https://www.youtube.com/embed/${(match.match(/be\/(\w+)/)[1])}`)
                                        message.querySelector('.chatMsg').parentNode.appendChild(elm);
                                    }
                                    Control[2] = 1;
                                } else {
                                    elm = new link('a', 2, match);
                                    Control[0] = 1;
                                }
                            } catch (error) {
                                console.log(error)
                            };
                        }
                    };

                    if (settings.functionalLinks != true) {return;};
                    try {
                        //var regex = new RegExp(/(https?:\/\/(www\.)?)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)*/g);
                        var regex = new RegExp(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)*/g);
                        var text = message.querySelector('div.fieldBody').innerText;
                        if (regex.test(text)) {
                            var matches = text.match(regex), mCount = 0;
                            matches.forEach(match => linkProcess(match));

                            if (Control[0] == 1) {
                                elmDivControl.appendChild(elmDivControlA);
                            };
                            if (Control[1] == 1) {
                                elmDivControl.appendChild(elmDivControlB);
                            };
                            if (Control[2] == 1) {
                                elmDivControl.appendChild(elmDivControlC);
                            };
                            elmDiv.prepend(elmDivControl);
                            message.querySelector('.chatMsg').parentNode.appendChild(elmDiv);
                            let bounding = message.getBoundingClientRect();
                            if(isVisible(message)){
                                message.scrollIntoView();
                            }
                        };
                    } catch (error) {
                        //console.log(error)
                    }
                } catch (error) {}
            };

            function removeUsernames(message) {
                //return;
                //console.log('this shouldnt be seen')
                if (settings.removeUsernames == true && message.querySelector('span.name')) {
                    message.querySelector('span.name').style.display = 'none';
                    let authorList = document.querySelectorAll('.page-author')[0].children
                    let authors = []
                    //authorList.forEach(element => authors.push(element.querySelector('span.name').innerText))
                    Array.from(authorList).forEach(
                        element=>{
                            if (element.innerText != ''){
                                authors.push(element.querySelector('span.name').innerText)
                            }
                        }
                    )
                    try {
                        if (authors.includes(message.querySelector('span.name').innerText)) {
                            message.querySelector('span.name').style.display = 'initial';
                            return;
                        } else {
                            setTimeout(function () {
                                try {
                                    message.querySelector('img.avatar').remove()
                                } catch (error) {};
                                try {
                                    message.querySelector('span.name').innerText = 'anon'
                                    message.querySelector('span.name').style.display = 'initial';
                                } catch (error) {
                                    console.log('Error forcing anon', error);
                                };
                                setTimeout(function () {
                                    if (message.querySelector('span.name').innerText != 'anon') {
                                        message.querySelector('span.name').innerText = 'anon'
                                    }
                                }, 100);
                            }, 100);

                        }
                    } catch (error) {
                        console.log('removeUsernames failed', error);
                    };
                } else{
                    return}

            };

            function authorHighlight(message) {
                try{
                    if (settings.authorHighlight == true && message.querySelector('span.name')) {
                        var currentColor;
                        if (window.darkMode == false) {
                            currentColor = settings.highlightLight;
                        }else{
                            currentColor = settings.highlightColor;
                        }
                        let authorList = document.querySelectorAll('.page-author')[0].children
                        let authors = []
                        Array.from(authorList).forEach(
                            element=>{
                                if (element.innerText != ''){
                                    authors.push(element.querySelector('span.name').innerText)
                                }
                            }
                        )
                        try {
                            if (authors.includes(message.querySelector('span.name').innerText)) {
                                if (settings.highlightColor) {
                                    try {
                                        message.style.backgroundColor = currentColor;
                                    } catch (error) {
                                        console.log('Failed using custom color', error);
                                    }
                                }
                            };
                        } catch (error) {
                            console.log('Author highlighter failed', error);
                        };
                    }
                    else{
                        return;
                    };
                }catch(error){};

            };

            function imageResize(message) {
                if (settings.imageResize == true) {
                    let msgImage = message.querySelector('div.message').querySelector('img');
                    if (msgImage !== null && msgImage !== undefined) {
                        let image = message.querySelector('div.message').querySelector('img');
                        image.src = image.src.replace(/(h[0-9]+\-w[0-9]+)/, 'h5600-w5600');
                        let page = image.src;
                        image.setAttribute('onclick', "window.open('" + page + "', '_blank');")
                        try {
                            image.onerror = (function () {
                                setTimeout(this.src = this.src, 100)
                            })
                        } catch (error) {
                            console.log('img error add fail',error)
                        };
                    };
                } else{
                    return}
            };

            async function userReveal(message){
                if (settings.userReveal != true){return}
                try{
                    var messageID=message.firstChild.getAttribute('data-id')
                    var returnedData=message.firstChild.getAttribute('data-id')
                    try{
                        await fetch(`https://fiction.live/api/node/${messageID}`).then(response => response.json()).then(data => {returnedData=data});
                        if (!returnedData.u[0]._id){
                            //console.log('no _id')
                            //console.log(returnedData.u)
                            return;
                        };
                        //console.log('got_id',returnedData.u[0]._id)
                        var userID=returnedData.u[0]._id;
                        await fetch(`https://fiction.live/api/anonkun/userCollections/${userID}`, {
                        }).then(response => response.json()).then(data => {userID=data});
                        if (userID.length == 0){
                            //console.log('len=0',userID,message);
                            return
                        }
                        if (userID[0].u[0].n == 'Anon'){
                            return;
                        }
                        message.querySelector('.user span').innerText=userID[0].u[0].n;
                    }catch(error){
                        //console.log('no collections',message,error);
                        return;
                    }
                }catch(error){
                    //console.log(error);
                    return;
                }
            };

            function messageEdit(message){
                try{
                    if (!message.querySelector('span.name') || message.querySelector('.message img') != null|| USERNAME == ''){return}
                } catch (error) {
                    //console.log('err',error);
                }
                try{
                    if (message.querySelector('span.name').innerText != USERNAME){return;}
                    let messageID=message.firstChild.getAttribute('data-id');
                    let messageCont = document.createElement('div');
                    messageCont.setAttribute('class','msgModBox')

                    let messageEdit = document.createElement('input');
                    messageEdit.setAttribute('type','button')
                    messageEdit.setAttribute('class','msgMod const')
                    messageEdit.onclick = editMsg;
                    messageEdit.value = 'Open Edit Mode';
                    function editMsg(){
                        if (settings.messageEdit != true){return}
                        if (messageEdit.closest('.logItem').classList.contains('editMode')){
                            messageEdit.value = 'Open Edit Mode';
                            messageEdit.closest('.logItem').classList.remove('editMode');
                            message.querySelector('textarea').remove();
                            message.querySelector('.chatMsg').style.display = '';
                        }
                        else{
                            messageEdit.value = 'Close Edit Mode';
                            messageEdit.closest('.logItem').classList.add('editMode')
                            var messageText = document.createElement('textarea');
                            messageText.setAttribute('placeholder', 'Add text to alter the message.');
                            messageText.setAttribute("cols", "1");
                            messageText.setAttribute("rows", "5");
                            messageText.addEventListener("keydown", function(press) {
                                // 13 = Enter, 27 = Escape
                                if (press.keyCode === 13 &! (press.keyCode === 13 && press.shiftKey)) {
                                    press.preventDefault(); // Cancel the default action, if needed
                                    messageSave.click();
                                }
                                else if (press.keyCode === 27) {
                                    press.preventDefault();
                                    messageEdit.click();
                                }
                            });
                            fetch(`https://fiction.live/api/node/${messageID}`).then(response => response.json()).then(data => {messageText.value = data.b});
                            message.querySelector('.chatMsg').style.display = 'none';
                            message.appendChild(messageText)
                        }


                    };

                    let messageSave = document.createElement('input');
                    messageSave.setAttribute('type','button')
                    messageSave.setAttribute('class','msgMod edit')
                    messageSave.onclick = saveMsg;
                    messageSave.value = 'Save';
                    function saveMsg(){
                        let messageContent = encodeURI(message.children[2].value);
                        fetch("https://fiction.live/api/node", {
                            "headers": {
                                "User-Agent": "",
                                "Accept": "application/json, text/javascript, */*; q=0.01",
                                "Accept-Language": "en-GB,en;q=0.5",
                                "Content-Type": "application/json",
                                "X-Requested-With": "XMLHttpRequest"
                            },
                            "body": `{\"_id\":\"${messageID}\",\"b\":\"${messageContent}\"}`,
                            "method": "PUT",
                            "mode": "cors"
                        });

                        messageCont.closest('.logItem').classList.remove('editMode');
                        messageEdit.value = 'Open Edit Mode';
                        message.children[2].remove();
                        message.children[1].style.display = '';
                    };

                    let messageDiscard = document.createElement('input');
                    messageDiscard.setAttribute('type','button')
                    messageDiscard.setAttribute('class','msgMod edit')
                    messageDiscard.onclick = discardMsg;
                    messageDiscard.value = 'Discard';
                    function discardMsg(){
                        message.children[2].value = '';
                    };

                    let messageDelete = document.createElement('input');
                    messageDelete.setAttribute('type','button')
                    messageDelete.setAttribute('class','msgMod const')
                    messageDelete.onclick = deleteMsg;
                    messageDelete.value = 'Delete';
                    function deleteMsg(){
                        if (settings.unpublishBTN != true){return}
                        fetch("https://fiction.live/api/node", {
                            "headers": {
                                "User-Agent": "",
                                "Accept": "application/json, text/javascript, */*; q=0.01",
                                "Content-Type": "application/json",
                                "X-Requested-With": "XMLHttpRequest"
                            },
                            "body": `{\"_id\":\"${messageID}\",\"trash\":true}`,
                            "method": "PUT",
                            "mode": "cors"
                        });
                        //messageDelete.remove()
                        message.remove()
                    };

                    if (window.darkMode != true){
                        messageCont.classList.add('dark');
                    }
                    messageCont.appendChild(messageEdit);
                    messageCont.appendChild(messageSave)
                    messageCont.appendChild(messageDiscard)
                    messageCont.appendChild(messageDelete)
                    message.prepend(messageCont)
                } catch (error) {
                    console.log('Error',error);
                }
            };

            function onX(message){
                try{
                    if (!message.querySelector('span.name') || message.querySelector('.message img') != null|| USERNAME == ''){return}
                } catch (error) {
                    //console.log('err',error);
                }
                try{
                    message.addEventListener('mouseover',function(){
                        if (this.querySelector('div.user span').innerText!=USERNAME){return}
                        if (this.querySelectorAll('input').length <= 3){messageEdit(this)};
                        this.classList.add('vis');
                        if (message.querySelector('.msgModBox').isReallyVisible() == true && message.querySelector('footer').isReallyVisible() == false){
                            //console.log('1')
                            //console.log(message.offsetHeight)
                            if (message.offsetHeight < 300){
                                if (message.classList.contains('editMode')){return}
                                message.closest('article.chatLog').scrollTop += message.querySelector('.msgModBox').offsetHeight
                            }
                        }
                    })}
                catch (error) {
                    //console.log('Er0',error);
                }
                try{
                    message.addEventListener('mouseout',function(){
                        this.classList.remove('vis');
                    })
                } catch (error) {
                    //console.log('Er1',error);
                }
            };

            function spamCheck(message){
                if (settings.spamRemoval != true){return}
                if (message){

                    try{
                        if (message.innerText.length > settings.maxWords){
                            message.innerHTML='';
                        }
                    }catch(error){
                        console.log('SC',error);
                    }}
            };


            async function messageBlacklist(message){
                if (settings.messageBlacklist != true){return}
                try{
                    let questIDregex = '.*\/stories\/.*\/(.*)\/?';
                    let questID = window.location.href.match('.*\/stories\/.*\/(.*)\/?')[1];
                    let messageID = message.childNodes[0].getAttribute('data-id');
                    if (settings.bannedString.includes(message.childNodes[0].childNodes[1].innerText)){
                        fetch("https://fiction.live/api/anonkun/ban", {
                            "credentials": "include",
                            "headers": {
                                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0",
                                "Accept": "*/*",
                                "Accept-Language": "en-GB,en;q=0.5",
                                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                                "X-Requested-With": "XMLHttpRequest"
                            },
                            "body": "blockFor="+messageID+"&blockFrom="+questID,
                            "method": "POST",
                            "mode": "cors"
                        });
                        fetch("https://fiction.live/api/anonkun/node", {
                            "credentials": "include",
                            "headers": {
                                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0",
                                "Accept": "application/json, text/javascript, */*; q=0.01",
                                "Accept-Language": "en-GB,en;q=0.5",
                                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                                "X-Requested-With": "XMLHttpRequest"
                            },
                            "referrer": "https://fiction.live/stories/X/fD9TaJwHrfoqb6jBQ",
                            "body": "deleteFrom="+questID+"&nid="+messageID,
                            "method": "DELETE",
                            "mode": "cors"
                        });

                    };
                    if (settings.deletedString.includes(message.childNodes[0].childNodes[1].innerText)){
                        fetch("https://fiction.live/api/anonkun/node", {
                            "credentials": "include",
                            "headers": {
                                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0",
                                "Accept": "application/json, text/javascript, */*; q=0.01",
                                "Accept-Language": "en-GB,en;q=0.5",
                                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                                "X-Requested-With": "XMLHttpRequest"
                            },
                            "referrer": "https://fiction.live/stories/X/fD9TaJwHrfoqb6jBQ",
                            "body": "deleteFrom="+questID+"&nid="+messageID,
                            "method": "DELETE",
                            "mode": "cors"
                        });
                    };
                }catch(error){console.log('messageBlacklist',error)}
            };

            function whenNewMessage(chat) {
                try{
                    function autoRoll(change) {
                        if (settings.autoRoller !== true) {
                            return;
                        }
                        else{
                            try {
                                var rollRegex = /[0-9]+d[0-9]+(?<!1d1)((\+|\-)[0-9]+)?( ?)(([ie]+)?([ut][0-9]+)?)+/
                                if (rollRegex.test(change.innerText)) {
                                    var roll = change.innerText.match(rollRegex)[0];
                                    var latestUpdate = document.querySelector('div#storyPosts').firstChild.lastChild;
                                    var poll = latestUpdate.firstChild.firstChild;
                                    if (latestUpdate.classList.contains('readerPost') == false || poll.classList.contains('closed') || poll.classList.contains('rolled')) {
                                        return
                                    } else if (!(poll.classList.contains('closed'))) {
                                        var dataID = latestUpdate.getAttribute('data-id');
                                        var chapterID = document.querySelector('article.threads').getAttribute('threads');
                                        chapterID = chapterID.replace(/\/.*/, '');
                                        var rollSend = `/roll ${roll}`;
                                        var template = `sid=${chapterID}&dice=${encodeURIComponent(rollSend)}`;
                                        chatSend([[chapterID, dataID, roll], template]);
                                        poll.classList.add('rolled');
                                    }
                                }
                            } catch (error) {}
                        };
                    };

                    var options = {
                        childList: true
                    };
                    function messageMod(mutations) {
                        for (let mutation of mutations) {
                            try {
                                var message = mutation.addedNodes[0];

                                messageBlacklist(message);
                                spamCheck(message);
                                chatBlacklist(message);
                                userReveal(message);
                                removeUsernames(message);
                                userReveal(message);
                                authorHighlight(message);
                                imageResize(message);
                                autoRoll(message);
                                functionalLinks(message);
                                akunPlus(message);
                                onX(message);
                                messageFocus(message);
                                //observerMessage.disconnect();
                            } catch (error) {
                                console.log('New Message Error',error);
                            }

                        };
                    };
                    let observerMessage = new MutationObserver(messageMod);
                    observerMessage.observe(chat, options);
                }catch(error){
                    if (error instanceof TypeError){
                        return
                    };
                    console.log(error)
                }
            };

            function withOldMessage(chat) {
                var messages = chat.childNodes;
                try {
                    messages.forEach(message => {
                        try {
                            spamCheck(message);
                            chatBlacklist(message);
                            imageResize(message);
                            userReveal(message);
                            authorHighlight(message);
                            removeUsernames(message);
                            functionalLinks(message);
                            akunPlus(message);
                            onX(message);
                            messageFocus(message);
                        } catch (error) {};
                    });
                } catch (error) {
                    console.log('OldMsg', error)
                };
            };

            function handleMsg(message) {
                if (message.tagName == 'HEADER') {
                    return;
                }try{
                    spamCheck(message);
                    chatBlacklist(message);
                    imageResize(message);
                    authorHighlight(message);
                    functionalLinks(message);
                    removeUsernames(message);
                    akunPlus(message);
                } catch (error) {};
            };

            function textStyle(){
                function getSelectionText(){
                    var text = "";
                    var activeEl = document.activeElement;
                    var activeElTagName = activeEl ? activeEl.tagName.toLowerCase() : null;
                    if ((activeElTagName == "textarea") || (activeElTagName == "input" && /^(?:text|search|password|tel|url)$/i.test(activeEl.type)) && (typeof activeEl.selectionStart == "number")){
                        text = activeEl.value.slice(activeEl.selectionStart, activeEl.selectionEnd);
                    } else if (window.getSelection) {
                        text = window.getSelection().toString();
                    }
                    return text;
                };

                function textMod(){
                    function textEffect(){
                        let selected = getSelectionText();
                        let text = this.closest('form').querySelector('textarea');
                        let effect = this.getAttribute('name')
                        let regex = new RegExp(`<${effect}>|<\/${effect}>`,'g')
                        let selectedN;
                        if (selected == '' ){return;}
                        else if (regex.test(selected)){
                            selectedN=selected.replace(regex,'');
                            let activeEl = document.activeElement;
                            let len = Math.abs(selectedN.length - selected.length)
                            let SS=activeEl.selectionStart,SE=activeEl.selectionEnd-len;
                            text.value = text.value.replace(selected,selectedN);
                            activeEl.selectionStart = SS
                            activeEl.selectionEnd = SE
                        }
                        else{
                            selectedN=`<${effect}>${selected}</${effect}>`
                        let activeEl = document.activeElement;
                            let len = Math.abs(selectedN.length - selected.length)
                            let SS=activeEl.selectionStart,SE=activeEl.selectionEnd+len;
                            text.value = text.value.replace(selected,selectedN)
                            activeEl.selectionStart = SS
                            activeEl.selectionEnd=SE
                        }
                    };

                    var textMod = document.createElement('div')
                    textMod.setAttribute('class','textMod');

                    var textModB = document.createElement('input')
                    textModB.setAttribute('class','textModBtn');
                    textModB.setAttribute('name','b');
                    textModB.setAttribute('type','button');
                    textModB.value = 'Bold'
                    textModB.onclick = textEffect

                    var textModI = document.createElement('input')
                    textModI.setAttribute('class','textModBtn');
                    textModI.setAttribute('name','i');
                    textModI.setAttribute('type','button');
                    textModI.value = 'Italicize'
                    textModI.onclick = textEffect

                    var textModU = document.createElement('input')
                    textModU.setAttribute('class','textModBtn');
                    textModU.setAttribute('name','u');
                    textModU.setAttribute('type','button');
                    textModU.value = 'Underline'
                    textModU.onclick = textEffect

                    var textModS = document.createElement('input')
                    textModS.setAttribute('class','textModBtn');
                    textModS.setAttribute('name','strike');
                    textModS.setAttribute('type','button');
                    textModS.value = 'Strikethrough'
                    textModS.onclick = textEffect

                    textMod.appendChild(textModB);
                    textMod.appendChild(textModI);
                    textMod.appendChild(textModU);
                    textMod.appendChild(textModS);
                    return textMod
                };

                if (settings.textStyle != true){return;}
                try{
                    var chatInput = document.querySelectorAll('form.chatInputContainer');
                    Array.from(chatInput).forEach(CI=>{
                        CI.addEventListener('select',function(event){
                            try{
                                if (document.querySelector('.textMod') != null){
                                    return
                                }
                                var T = event.target
                                var elem = new textMod()
                                if(document.querySelector('#mainChat').contains(T)){
                                    elem.style.bottom = elem.offsetHeight+'px';
                                }
                                elem.classList.add('vis');
                                T.parentNode.prepend(elem);
                            }catch(error){
                                console.log('erx',error)
                            };
                        });
                        CI.querySelector('textarea').addEventListener('keyup',function(event){
                            if (!CI.querySelector('.textMod') == null){return;};
                            if (CI.querySelector('.textMod') != null && CI.querySelector('textarea').value == ''){
                                CI.querySelector('.textMod').remove();
                            }
                        })
                    });

                    document.addEventListener('mousedown',function(event){
                        if (
                            event.target.getAttribute('name')=='chapterTitle' ||
                            event.target.closest('.addAchievement') ||
                            event.target.closest('.nextLive') ||
                            event.target.closest('.editStory') ||
                            event.target.closest('.collectionForm') ||
                            event.target.closest('.choicesInterface') ||
                            event.target.closest('#storyTagsAndFilters')||
                            event.target.closest('#innerAlertSearch')
                        ){
                            return
                        }
                        try{
                            if (document.querySelector('#confBox').contains(event.target)){
                                return;
                            };
                        }catch(error){};
                        var list = event.target.classList;
                        if (event.target.tagName == 'INPUT' || list.contains('textModBtn')){
                            event.preventDefault();
                        }
                        else if (list.contains('textMod') || list.contains('chatInput') || event.target.closest('form') != null ){
                            if (getSelectionText() == ''){
                                if (document.querySelector('.textMod') != null){
                                    document.querySelector('.textMod').remove()
                                }
                            }
                        }
                        else{
                            if (document.querySelector('.textMod') != null){
                                document.querySelector('.textMod').remove()
                            }
                        }
                    });
                }catch(error){console.log(error)};
            };

            function chatHide(){
                if (settings.autoHide != true){
                    return;
                };
                if (window.observerTC != undefined){
                    observerTC.disconnect();
                }
                try{

                }catch(error){
                }
                var observerTC = new MutationObserver(function (mutations){
                    for (let mutation of mutations) {
                        if (!document.querySelector('#mainChat')){continue}
                        try{
                            let hideChatBTN=document.getElementsByClassName('section row themeControls')[0].children[3];
                            if (hideChatBTN != (undefined || null)){
                                //console.log('hideChatBTN')
                                hideChatBTN.click();
                                observerTC.disconnect();
                            }
                        }catch(error){
                        };
                    }
                });
                observerTC.observe(document, {
                    childList: true,
                    subtree: true
                })

            };

            function messageFocus(message){
                try{
                    message.addEventListener('mouseup',function(event){
                        var messageAwait = new MutationObserver(function (mutations){
                            for (let mutation of mutations) {
                                try{
                                    let id=message.querySelector('.chatMsg').getAttribute('data-id')
                                    let focus;
                                    try{
                                        focus = document.querySelector('.chatItemDetail[data-id="'+id+'"]')
                                        if (focus != (null || undefined)){
                                            messageAwait.disconnect();
                                            imageLinkButton();
                                        }}catch(error){console.log('messageFocus error',error)}
                                }catch(error){
                                };
                            }
                        });
                        messageAwait.observe(document.body, {childList: true})},false);
                }catch(error){}
            };

            function waitForChat() {
                //waits for chat to exist
                var observerChat = new MutationObserver(awaitChat);
                observerChat.observe(document, {
                    childList: true,
                    subtree: true
                })
                function awaitChat(mutations) {
                    function observeChat(){
                        try{
                            var chat=document.querySelector('#mainChat').querySelector('article.chatLog').children[0];
                            var observerChatExist = new MutationObserver(function(mutations){
                                for (let mutation of mutations) {
                                    try{
                                        if (mutation.removedNodes.length != 0 && mutation.removedNodes[0].tagName != undefined){
                                            //console.log(mutation.removedNodes[0])
                                        }
                                        if (mutation.addedNodes.length != 0){
                                            if (mutation.addedNodes[0].tagName == 'DIV' &&
                                                mutation.addedNodes[0].classList.contains('jadeRepeat')){
                                                whenNewMessage(chat.querySelector('div.jadeRepeat'));
                                                withOldMessage(chat.querySelector('div.jadeRepeat'));

                                            }
                                        }} catch (error) {console.log('new thing error')};
                                }});
                            observerChatExist.observe(document.querySelector('#mainChat').querySelector('article.chatLog'), {childList: true, subtree: true})
                        }catch(error){console.log(error)}
                    };
                    for (let mutation of mutations) {
                        try {
                            var chat = document.querySelector('article.chatLog').querySelector('div.jadeRepeat');
                        } catch (TypeError) {};
                        if (chat && chat !== (undefined || null) && chat.length != 0) {
                            observerChat.disconnect();
                            var chatLog = document.querySelectorAll('article.chatLog');
                            for (var i = 0; i < chatLog.length; i++) {
                                whenNewMessage(chatLog[i].querySelector('div.jadeRepeat'));
                                withOldMessage(chatLog[i].querySelector('div.jadeRepeat'));
                                textStyle();
                                setTimeout(function(){observeChat();},1000);
                                chatHide();
                                newThemeChange();
                                imageLinkButton();
                            }
                            break;
                        };
                    };
                };
            };

            waitForChat();
        }
        catch(error){console.log(error)};
    };


    function deleteTopicCreate() {
        try {
            if (settings.removeTopicForm == true) {
                let formItem = document.querySelector('div.formItem');
                if (formItem) {
                    formItem.parentNode.remove();
                };
            };
        } catch (error) {
            console.log('Error with removing topic form', error);
        };

    };

    function blacklistAdd() {
        let title = this.parentNode.querySelector('[set-text="item.value.value"]').textContent.replace(' went live', '');
        let author = this.parentNode.querySelector('span.user').innerText;
        let entry = title + '___' + author;
        settings.alertBlacklist.push(entry);
        localStorage.setItem('FL_Settings', JSON.stringify(settings));
        let dismiss = this.parentNode.querySelector('a.dismiss');
        simClick(dismiss);
        document.querySelector('.settingsTab[name="Alerts"]').querySelector('div#settingsBlacklist').appendChild(elementBlacklisted(entry));
    };

    function blacklistCheck(alert) {
        function alertBlacklistButton(alert) {
            function createBlacklistButton() {
                var blacklistButton = document.createElement('a');
                blacklistButton.setAttribute('class', 'blacklist');
                blacklistButton.innerText = '∅';
                blacklistButton.onclick = blacklistAdd;
                return blacklistButton
            }
            alert.childNodes[0].after(createBlacklistButton());
        };
        try {
            var title = alert.querySelector('[set-text="item.value.value"]').textContent.replace(' went live', '');
            var author = alert.querySelector('span.user').innerText;
            var dismiss = alert.querySelector('a.dismiss');
            if (settings.alertBlacklist.includes(title + '___' + author)) {
                simClick(dismiss);
            } else {
                if (!alert.querySelector('a.blacklist')){
                    alertBlacklistButton(alert);
                }
            };
        } catch (error) {
            console.log('blacklist checker error', error)
        };
    };

    function updateCheck(alert) {
        if (settings.updateRequestDismiss == false) {
            return;
        }
        else if (alert.classList.length == 0) {
            return
        }
        try {
            var title = alert.querySelector('[set-text="item.value.value"]').innerText;
            if (/.*Looks forward to the next update for.*/.test(title)) {
                var dismiss = alert.querySelector('a.dismiss');
                simClick(dismiss);
            }
        } catch (error) {
            console.log('updateCheck error', error)
        };
    };

    function simClick(elem) {
        var evt = new MouseEvent('click', {
            bubbles: true,
            cancelable: true,
            view: window
        });
        var canceled = !elem.dispatchEvent(evt);
    };

    function sortAlerts() {
        if(true){return;};
        //this is broken
        try {
            var sort_by_name = function (a, b) {
                let sort=a.querySelector('.user').innerText.localeCompare(b.querySelector('.user').innerText);
                return sort
            };
            var list = Array.from(document.querySelectorAll('ul.feedType.ng-scope')[1].querySelectorAll('li'));
            list.sort(sort_by_name);
            for (var i = 0; i < list.length; i++) {
                list[i].parentNode.appendChild(list[i]);
            }
        } catch (error) {}

    };

    function alertUpdate(alert){
        try{
            //console.log('alert up',alert)
            if (alert.classList.length == 0) {
                return
            }
            var dismiss = alert.querySelector('a.dismiss');
            simClick(dismiss);
        }catch(error){console.log('AU Error',error)}
    };

    function awaitAlerts(){
        try{
            var alerts = document.querySelector('span.feedCount')
            if (alerts){
                //console.log('Alerts Exist');
                try{
                    observerFCP.disconnect();
                }catch(error){};
                monitorFeedCount(alerts.parentNode);
                monitorFeeds();

                let alertContainer = document.querySelectorAll('li.feedItem');
                alertContainer.forEach(alert => {
                    if (/.*went live.*/.test(alert.innerText)) {
                        blacklistCheck(alert);
                    }
                    else if (/.*Looks forward to the next update for.*/.test(alert.innerText) && settings.updateRequestDismiss == true) {
                        alertUpdate(alert)
                    }
                    else if (/.*New review for.*/.test(alert.innerText) && settings.reviewDismiss == true) {
                        alertUpdate(alert)
                    }
                    else if (/.*Is now a new follower of yours.*/.test(alert.innerText) && settings.followDismiss == true) {
                        alertUpdate(alert)
                    }
                    else if (/.*Likes \".*\".*/.test(alert.innerText) && settings.followLike == true) {
                        alertUpdate(alert)
                    }
                    else if (/.*PM:.*/.test(alert.innerText)) {
                    }
                });
            }
            else{
                //console.log('Alerts Dont Exist');
                var observerFCP = new MutationObserver(awaitFeedCount);
                observerFCP.observe(document, {
                    childList: true,
                    subtree: true
                });
            };

            function awaitFeedCount(mutations){
                //Wait for the feed count, when found stop and start the FC monitor
                try{
                    for (let mutation of mutations) {
                        let alerts = document.querySelector('span.feedCount')
                        if (mutation.addedNodes.length > 0){
                            var elm = mutation.addedNodes[0];
                            if (elm.tagName == 'SPAN' && elm.classList.contains('feedCount')){
                                observerFCP.disconnect();
                                monitorFeedCount(alerts.parentNode);
                                monitorFeeds();
                            };
                        };
                    };
                }
                catch(error){
                    console.log('AFC',error)
                };
            };

            function monitorFeedCount(FC){
                //Monitors feed count parent for when alerts appear or disappear.
                try{
                    var observerFC = new MutationObserver(function(x){
                        if (x[0].removedNodes.length > 0){
                            //console.log('Alerts Removed.');
                            try{
                                window.alertWatcher.disconnect();
                                //console.log('AW');
                            }catch(error){}
                            try{
                                window.observerDrop.disconnect();
                                //console.log('DW');
                            }catch(error){}
                        }
                        else if (x[0].addedNodes.length > 0){
                            //console.log('Alerts Added.',x[0].addedNodes);
                            monitorFeeds();
                        }
                    })
                    observerFC.observe(FC, {childList:true})
                }catch(error){console.log('MFC',error)}
            };

            function monitorFeeds(){
                //Alerts are stored in feeds, this monitors them
                function dropdownWatch(mutations){
                    try{
                        if (dropdown.length == 1){
                            //console.log('Dropdown has a single child.')
                            return
                        }
                        for (let mutation of mutations){
                            if (mutation.addedNodes.length > 0 && mutation.addedNodes[0].tagName == 'LI'){
                                let text=mutation.addedNodes[0].innerText
                                let alert = mutation.addedNodes[0]
                                if (/.*went live.*/.test(text)) {
                                    blacklistCheck(alert);
                                }
                                else if (/.*Looks forward to the next update for.*/.test(text) && settings.updateRequestDismiss == true) {
                                    alertUpdate(alert)
                                }
                                else if (/.*New review for.*/.test(text) && settings.reviewDismiss == true) {
                                    alertUpdate(alert)
                                }
                                else if (/.*Is now a new follower of yours.*/.test(text) && settings.followDismiss == true) {
                                    alertUpdate(alert)
                                }
                                else if (/.*Likes \".*\".*/.test(alert.innerText) && settings.followLike == true) {
                                    alertUpdate(alert)
                                }
                                else if (/.*PM:.*/.test(text)) {
                                }
                            }
                        };
                    }
                    catch(error){
                        console.log('DW',error)
                    };
                };

                var dropdown = document.querySelector('#loginMenu').children[1];
                //console.log('dropdown',dropdown);
                var observerDrop = new MutationObserver(dropdownWatch);
                observerDrop.observe(dropdown, {childList:true,subtree:true});
                window.observerDrop = observerDrop;

                let alertContainer = document.querySelectorAll('li.feedItem');
                alertContainer.forEach(alert => {
                    if (/.*went live.*/.test(alert.innerText)) {
                        blacklistCheck(alert);
                    }
                    else if (/.*Looks forward to the next update for.*/.test(alert.innerText) && settings.updateRequestDismiss == true) {
                        alertUpdate(alert)
                    }
                    else if (/.*New review for.*/.test(alert.innerText) && settings.reviewDismiss == true) {
                        alertUpdate(alert)
                    }
                    else if (/.*Is now a new follower of yours.*/.test(alert.innerText) && settings.followDismiss == true) {
                        alertUpdate(alert)
                    }
                    else if (/.*Likes \".*\".*/.test(alert.innerText) && settings.followLike == true) {
                        alertUpdate(alert)
                    }
                    else if (/.*PM:.*/.test(alert.innerText)) {
                    }
                });
            }
        }catch(error){console.log('AAlerts',error)}
    };

    function awaitMainMenu() {
        try {
            var options = {
                childList: true,
                subtree: true
            };
            let observerMenu = new MutationObserver(awaitMenu);
            observerMenu.observe(document, options);
            function awaitMenu(mutations) {
                for (let mutation of mutations) {
                    try {
                        var mainMenu = document.querySelector('nav#mainMenu');
                    } catch (error) {};
                    if (mainMenu) {
                        observerMenu.disconnect();
                        settingsContainer();
                        deleteTopicCreate();
                        darkCheck();
                        alertSearch();
                    };
                };
            };
        } catch (error) {
            console.log('Error awaiting main menu', error)
        };

    };

    function alertSearch(){
        if (settings.alertFilter != true){return}
        if (document.querySelector('#innerAlertSearch')){return}
        var dropdown = document.querySelector('.dropdown-menu.ng-scope.dropdown');

        var settingsSearchBox = document.createElement('div');
        settingsSearchBox.setAttribute('id', 'innerAlertSearch');
        settingsSearchBox.style.width = dropdown.offsetWidth.toString();
        settingsSearchBox.style = 'background:#2a2c3b;padding-top:10px;margin-top:0;';
        settingsSearchBox.addEventListener("click", function(event) {
            event.stopPropagation();
            event.preventDefault();
        });

        var settingsAlertSearchInput = document.createElement('input');
        settingsAlertSearchInput.setAttribute("type", "text");
        settingsAlertSearchInput.setAttribute("name", "alertSearch");
        settingsAlertSearchInput.style = 'margin-bottom:10px;';
        settingsAlertSearchInput.setAttribute("placeholder", "Enter a title or QM to search.");
        settingsAlertSearchInput.oninput = function(){
            let alerts = document.querySelectorAll('.dropdown-menu ul.feedType li.feedItem');
            alerts.forEach(x => {
                x.style.display = 'table';
            })
            let search = this.parentNode.querySelector('[name="alertSearch"]').value.toLowerCase();
            alerts.forEach(alert => {
                let text = alert.firstChild.textContent.toLowerCase().replace('author:')
                if (!text.includes(search)) {
                    alert.style.display = 'none';
                } else {}
            })
        }

        var settingsAlertSearch = document.createElement('input');
        settingsAlertSearch.setAttribute("type", "button");
        settingsAlertSearch.setAttribute("class", "cssBtn");
        settingsAlertSearch.value = 'Search';
        settingsAlertSearch.style ='font-weight: 700;border:none;';
        settingsAlertSearch.onclick = function () {
            let alerts = document.querySelectorAll('.dropdown-menu ul.feedType li.feedItem');
            alerts.forEach(x => {
                x.style.display = 'table';
            })
            let search = this.parentNode.querySelector('[name="alertSearch"]').value.toLowerCase();
            alerts.forEach(alert => {
                let text = alert.firstChild.textContent.toLowerCase().replace('author:')
                if (!text.includes(search)) {
                    alert.style.display = 'none';
                } else {}
            })
        }

        var settingsAlertSearchClear = document.createElement('input');
        settingsAlertSearchClear.setAttribute("type", "button");
        settingsAlertSearchClear.setAttribute("class", "cssBtn");
        settingsAlertSearchClear.value = 'Clear Search';
        settingsAlertSearchClear.style ='font-weight: 700;border:none;float:right;';
        settingsAlertSearchClear.onclick = function () {
            this.parentNode.querySelector('[name="alertSearch"]').value = '';
            let alerts = document.querySelectorAll('.dropdown-menu ul.feedType li.feedItem');
            alerts.forEach(x => {
                x.style.display = 'table';
            })

        }

        settingsSearchBox.appendChild(settingsAlertSearchInput);
        //settingsSearchBox.appendChild(settingsAlertSearch);
        settingsSearchBox.appendChild(settingsAlertSearchClear);
        dropdown.insertBefore(settingsSearchBox,dropdown.children[1])
    };

    function elementBlacklisted(element) {
        var settingsBlacklisted = document.createElement('div');
        settingsBlacklisted.setAttribute('class', 'blacklistEntry');

        var settingsBlacklistedText = document.createElement('p');
        settingsBlacklistedText.setAttribute('class', 'colors');
        settingsBlacklistedText.innerText = element;
        settingsBlacklistedText.innerText = settingsBlacklistedText.innerText.replace('___', '\nAuthor: ');

        var settingsBlacklistRemove = document.createElement('a');
        settingsBlacklistRemove.setAttribute('class', 'blacklistRemove')
        settingsBlacklistRemove.innerText = 'Remove'
        settingsBlacklistRemove.onclick = function () {
            blacklistRemove(element);
            this.parentNode.remove();
        }

        settingsBlacklisted.appendChild(settingsBlacklistedText)
        settingsBlacklisted.appendChild(settingsBlacklistRemove)
        return settingsBlacklisted
    };

    function settingsContainer() {
        function settingsDisplay() {
            try {
                if (!document.querySelector('#confDisp')) {
                    function configDisplay() {
                        var confDisp = document.createElement('div');
                        confDisp.setAttribute('id', 'confDisp');
                        return confDisp
                    };
                    function configBox() {
                        var confBox = document.createElement('div');
                        confBox.setAttribute('id', 'confBox');
                        if (window.darkMode == true){
                            confBox.setAttribute('class', 'dark');}
                        return confBox
                    };

                    //Blacklists start here
                    //Blacklists start here
                    //Blacklists start here
                    //Blacklists start here
                    //Blacklists start here

                    function settingsUserBlacklist() {
                        var settingsTab = document.createElement('div');
                        settingsTab.setAttribute('class', 'settingsTab');
                        settingsTab.setAttribute('name', 'Chat');
                        function chatBlacklistRemove(item) {
                            if (settings.chatBlacklisted.includes(item)) {
                                let position = settings.chatBlacklisted.indexOf(item);
                                settings.chatBlacklisted.splice(position, 1);
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                            };
                        };

                        function chatBlacklisted(element) {
                            try {
                                var chatBlacklisted = document.createElement('div');
                                chatBlacklisted.setAttribute('class', 'blacklistEntry');

                                var chatBlacklistedText = document.createElement('p');
                                chatBlacklistedText.setAttribute('class', 'colors');
                                chatBlacklistedText.innerText = element;

                                var settingsUserRemove = document.createElement('a');
                                settingsUserRemove.setAttribute('class', 'blacklistRemove');
                                settingsUserRemove.innerText = 'Remove';
                                settingsUserRemove.onclick = function () {
                                    try {
                                        chatBlacklistRemove(element);
                                        this.parentNode.remove();
                                    } catch (error) {
                                        console.log('Error removing user', error)
                                    }
                                };
                                chatBlacklisted.appendChild(chatBlacklistedText);
                                chatBlacklisted.appendChild(settingsUserRemove);
                                return chatBlacklisted;
                            } catch (error) {
                                console.log('44', error)
                            }
                        };

                        function userAddBlacklist() {
                            var settingsUserBox = document.createElement('div');
                            settingsUserBox.setAttribute('id', 'settingsBox');

                            var settingsUserInput = document.createElement('input');
                            settingsUserInput.setAttribute("type", "text");
                            settingsUserInput.setAttribute("class", "settingsInput");
                            settingsUserInput.setAttribute("placeholder", "Input username here.");

                            var settingsUserAdd = document.createElement('input');
                            settingsUserAdd.setAttribute("class", "cssBtn");
                            settingsUserAdd.setAttribute("type", "button");
                            settingsUserAdd.value = 'Add User';
                            settingsUserAdd.onclick = function () {
                                if (settings.chatBlacklisted.includes(this.parentNode.childNodes[0].value)) {
                                    return;
                                }
                                settings.chatBlacklisted.push(this.parentNode.childNodes[0].value);
                                this.parentNode.parentNode.appendChild(chatBlacklisted(this.parentNode.childNodes[0].value));
                                this.parentNode.childNodes[0].value = "";
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                                removeBlacklisted();
                            };

                            settingsUserBox.appendChild(settingsUserInput);
                            settingsUserBox.appendChild(settingsUserAdd);

                            return settingsUserBox
                        };

                        function maxWordCount(){
                            var settingsBox = document.createElement('div');
                            settingsBox.setAttribute('id', 'settingsBox');

                            var settingsText = document.createElement('div');
                            settingsText.setAttribute('class', 'entryTitle');
                            settingsText.innerText = 'Message Max Character Count';

                            var settingsInput = document.createElement('input');
                            settingsInput.setAttribute("type", "text");
                            settingsInput.setAttribute("class", "settingsInput");
                            settingsInput.setAttribute("placeholder", "Maximum character count per message.");
                            settingsInput.value = settings.maxWords;

                            var settingsAdd = document.createElement('input');
                            settingsAdd.setAttribute("class", "cssBtn");
                            settingsAdd.setAttribute("type", "button");
                            settingsAdd.value = 'Set Maximum';
                            settingsAdd.onclick = function () {
                                settings.maxWords = this.parentNode.childNodes[0].value
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                            };

                            var borderBottom = document.createElement('div');
                            borderBottom.setAttribute('class', 'borderBottom');

                            settingsBox.appendChild(settingsText);
                            settingsBox.appendChild(settingsInput);
                            settingsBox.appendChild(settingsAdd);
                            settingsBox.appendChild(borderBottom);

                            return settingsBox

                        };

                        function wordList(word,array){
                            try {
                                var blacklistContainer = document.createElement('div');
                                blacklistContainer.setAttribute('class', 'blacklistEntry');

                                var blacklistedText = document.createElement('p');
                                blacklistedText.setAttribute('class', 'colors');
                                blacklistedText.innerText = word;

                                var blacklistRemove = document.createElement('a');
                                blacklistRemove.setAttribute('class', 'blacklistRemove');
                                blacklistRemove.innerText = 'Remove';
                                blacklistRemove.onclick = function () {
                                    try {
                                        if (!settings[array].includes(word)){return}
                                        let index = settings[array].indexOf(word);
                                        settings[array].splice(index, 1);
                                        localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                        settings = JSON.parse(localStorage.getItem('FL_Settings'));
                                        this.parentNode.remove();
                                    } catch (error) {
                                        console.log('Error with wordList removal', error)
                                    }
                                };
                                blacklistContainer.appendChild(blacklistedText);
                                blacklistContainer.appendChild(blacklistRemove);
                                return blacklistContainer;
                            } catch (error) {
                                console.log('Error with wordList', error)
                            }
                        };

                        function wordBlacklist(){
                            var divOuter = document.createElement('div');
                            divOuter.setAttribute('class', 'settingsBlacklist');

                            var info = document.createElement('div');
                            var title = document.createElement('div');
                            title.setAttribute('class', 'entryTitle');
                            title.innerText = 'Word Blacklist';

                            var description = document.createElement('div');
                            description.innerText = 'Any messages containing any of these phrases will be deleted. QM/Mod required.';
                            info.append(title)
                            info.append(description)
                            divOuter.append(info)


                            var input = document.createElement('input');
                            input.setAttribute("type", "text");
                            input.setAttribute("class", "settingsInput");
                            input.setAttribute("placeholder", "Input Phrase Here.");

                            var inputAdd = document.createElement('input');
                            inputAdd.setAttribute("class", "cssBtn");
                            inputAdd.setAttribute("type", "button");
                            inputAdd.value = 'Add A Phrase To Be Auto-Deleteted';
                            inputAdd.onclick = function () {
                                if (settings.deletedString.includes(input.value)) {
                                    return;
                                }
                                settings.deletedString.push(input.value);
                                divBL.appendChild(wordList(input.value,'deletedString'));
                                input.value = "";
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                            };

                            divOuter.append(input)
                            divOuter.append(inputAdd)


                            var divBL = document.createElement('div');
                            //bannedString + deletedString
                            settings.deletedString.forEach(element => divBL.appendChild(wordList(element,'deletedString')));
                            divOuter.appendChild(divBL)

                            var borderBottom = document.createElement('div');
                            borderBottom.setAttribute('class', 'borderBottom');
                            divOuter.appendChild(borderBottom);

                            return divOuter
                        };

                        function wordBanlist(){
                            var divOuter = document.createElement('div');
                            divOuter.setAttribute('class', 'settingsBlacklist');

                            var info = document.createElement('div');
                            var title = document.createElement('div');
                            title.setAttribute('class', 'entryTitle');
                            title.innerText = 'Word Banlist';

                            var description = document.createElement('div');
                            description.innerText = 'Any messages containing any of these phrases will be deleted and the user banned. QM/Mod required.';
                            info.append(title)
                            info.append(description)
                            divOuter.append(info)


                            var input = document.createElement('input');
                            input.setAttribute("type", "text");
                            input.setAttribute("class", "settingsInput");
                            input.setAttribute("placeholder", "Input Phrase Here.");

                            var inputAdd = document.createElement('input');
                            inputAdd.setAttribute("class", "cssBtn");
                            inputAdd.setAttribute("type", "button");
                            inputAdd.value = 'Add A Phrase To Be Auto-Deleteted.';
                            inputAdd.onclick = function () {
                                if (settings.bannedString.includes(input.value)) {
                                    return;
                                }
                                settings.bannedString.push(input.value);
                                divBL.appendChild(wordList(input.value,'bannedString'));
                                input.value = "";
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                            };

                            divOuter.append(input)
                            divOuter.append(inputAdd)

                            var divBL = document.createElement('div');
                            settings.bannedString.forEach(element => divBL.appendChild(wordList(element,'bannedString')));
                            divOuter.appendChild(divBL)

                            var borderBottom = document.createElement('div');
                            borderBottom.setAttribute('class', 'borderBottom');
                            divOuter.appendChild(borderBottom);

                            return divOuter
                        };

                        var settingsUserBlacklist = document.createElement('div');
                        settingsUserBlacklist.setAttribute('class', 'settingsBlacklist');
                        settings.chatBlacklisted = [...new Set(settings.chatBlacklisted)]
                        settings.chatBlacklisted.forEach(element => settingsUserBlacklist.appendChild(chatBlacklisted(element)));

                        var settingsUserBlacklistText = document.createElement('div');
                        settingsUserBlacklistText.setAttribute('class', 'entryTitle');
                        settingsUserBlacklistText.innerText = 'Chat User Blacklist';

                        settingsUserBlacklist.prepend(userAddBlacklist());
                        settingsUserBlacklist.prepend(settingsUserBlacklistText);
                        settingsTab.appendChild(maxWordCount());
                        settingsTab.appendChild(wordBlacklist());
                        settingsTab.appendChild(wordBanlist());

                        settingsTab.appendChild(settingsUserBlacklist);
                        return settingsTab;
                    };

                    function settingsAuthorsBlacklist() {
                        var settingsTab = document.createElement('div');
                        settingsTab.setAttribute('class', 'settingsTab');
                        settingsTab.setAttribute('name', 'Author');
                        function authorBlacklistRemove(item) {
                            if (settings.authorBlacklist.includes(item)) {
                                let position = settings.authorBlacklist.indexOf(item);
                                settings.authorBlacklist.splice(position, 1);
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                            };
                        };
                        function authorBlacklisted(element) {
                            try {
                                var authorBlacklisted = document.createElement('div');
                                authorBlacklisted.setAttribute('class', 'blacklistEntry')
                                var authorBlacklistedText = document.createElement('p');
                                authorBlacklistedText.setAttribute('class', 'colors');
                                authorBlacklistedText.innerText = element;

                                var settingsAuthorRemove = document.createElement('a');
                                settingsAuthorRemove.setAttribute('class', 'blacklistRemove');
                                settingsAuthorRemove.innerText = 'Remove';
                                settingsAuthorRemove.onclick = function () {
                                    try {
                                        authorBlacklistRemove(element);
                                        this.parentNode.remove();
                                    } catch (error) {
                                        console.log('Error removing author', error)
                                    }
                                };
                                authorBlacklisted.appendChild(authorBlacklistedText);
                                authorBlacklisted.appendChild(settingsAuthorRemove);
                                return authorBlacklisted;
                            } catch (error) {
                                console.log('55', error)
                            }
                        };

                        function authorAddBlacklist() {
                            var settingsAuthorBox = document.createElement('div');
                            settingsAuthorBox.setAttribute('id', 'settingsBox');

                            var settingsAuthorsInput = document.createElement('input');
                            settingsAuthorsInput.setAttribute("type", "text");
                            settingsAuthorsInput.setAttribute("class", "settingsInput");
                            settingsAuthorsInput.setAttribute("placeholder", "Input author here.");

                            var settingsAuthorsAdd = document.createElement('input');
                            settingsAuthorsAdd.setAttribute("class", "cssBtn");
                            settingsAuthorsAdd.setAttribute("type", "button");
                            settingsAuthorsAdd.value = 'Add Author';
                            settingsAuthorsAdd.onclick = function () {
                                if (settings.authorBlacklist.includes(this.parentNode.childNodes[0].value)) {
                                    return;
                                }
                                settings.authorBlacklist.push(this.parentNode.childNodes[0].value);
                                this.parentNode.parentNode.appendChild(authorBlacklisted(this.parentNode.childNodes[0].value));
                                this.parentNode.childNodes[0].value = "";
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                                removeBlacklisted();
                            };

                            settingsAuthorBox.appendChild(settingsAuthorsInput);
                            settingsAuthorBox.appendChild(settingsAuthorsAdd);

                            return settingsAuthorBox
                        };

                        var settingsAuthorsBlacklist = document.createElement('div');
                        settingsAuthorsBlacklist.setAttribute('id', 'settingsBlacklist');
                        settings.authorBlacklist = [...new Set(settings.authorBlacklist)]
                        settings.authorBlacklist.sort().forEach(element => settingsAuthorsBlacklist.appendChild(authorBlacklisted(element)));

                        var settingsAuthorsBlacklistText = document.createElement('div');
                        settingsAuthorsBlacklistText.innerText = 'Authors Blacklist';
                        settingsAuthorsBlacklistText.setAttribute('class', 'entryTitle');
                        settingsAuthorsBlacklist.prepend(authorAddBlacklist());
                        settingsAuthorsBlacklist.prepend(settingsAuthorsBlacklistText);

                        settingsTab.appendChild(settingsAuthorsBlacklist)
                        return settingsTab;
                    };

                    function settingsTagsBlacklist() {
                        var settingsTab = document.createElement('div');
                        settingsTab.setAttribute('class', 'settingsTab');
                        settingsTab.setAttribute('name', 'Tags');
                        function tagBlacklistRemove(item) {
                            if (settings.tagBlacklist.includes(item)) {
                                let position = settings.tagBlacklist.indexOf(item);
                                settings.tagBlacklist.splice(position, 1);
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                            };
                        };
                        function tagBlacklisted(element) {
                            try {
                                var tagBlacklisted = document.createElement('div');
                                tagBlacklisted.setAttribute('class', 'blacklistEntry');
                                var tagBlacklistedText = document.createElement('p');
                                tagBlacklistedText.setAttribute('class', 'colors');
                                tagBlacklistedText.innerText = element;

                                var settingsTagRemove = document.createElement('a');
                                settingsTagRemove.setAttribute('class', 'blacklistRemove');
                                settingsTagRemove.innerText = 'Remove';
                                settingsTagRemove.onclick = function () {
                                    try {
                                        tagBlacklistRemove(element);
                                        this.parentNode.remove();
                                    } catch (error) {
                                        console.log('Error removing tag', error)
                                    }
                                };
                                tagBlacklisted.appendChild(tagBlacklistedText);
                                tagBlacklisted.appendChild(settingsTagRemove);
                                return tagBlacklisted;
                            } catch (error) {
                                console.log('78', error)
                            }
                        };

                        function tagAddBlacklist() {
                            var settingsTagBox = document.createElement('div');
                            settingsTagBox.setAttribute('id', 'settingsBox');

                            var settingsTagsInput = document.createElement('input');
                            settingsTagsInput.setAttribute("type", "text");
                            settingsTagsInput.setAttribute("class", "settingsInput");
                            settingsTagsInput.setAttribute("placeholder", "Input tag here.");

                            var settingsTagsAdd = document.createElement('input');
                            settingsTagsAdd.setAttribute("class", "cssBtn");
                            settingsTagsAdd.setAttribute("type", "button");
                            settingsTagsAdd.value = 'Add Tag';
                            settingsTagsAdd.onclick = function () {
                                if (settings.tagBlacklist.includes(this.parentNode.childNodes[0].value)) {
                                    return;
                                }
                                settings.tagBlacklist.push(this.parentNode.childNodes[0].value);
                                this.parentNode.parentNode.appendChild(tagBlacklisted(this.parentNode.childNodes[0].value));
                                this.parentNode.childNodes[0].value = "";
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                                removeBlacklisted();
                            };

                            settingsTagBox.appendChild(settingsTagsInput);
                            settingsTagBox.appendChild(settingsTagsAdd);

                            return settingsTagBox
                        };

                        var settingsTagsBlacklist = document.createElement('div');
                        settingsTagsBlacklist.setAttribute('id', 'settingsBlacklist');
                        settings.tagBlacklist = [...new Set(settings.tagBlacklist)]
                        settings.tagBlacklist.sort().forEach(element => settingsTagsBlacklist.appendChild(tagBlacklisted(element)));

                        var settingsTagsBlacklistText = document.createElement('div');
                        settingsTagsBlacklistText.innerText = 'Tags Blacklist';
                        settingsTagsBlacklistText.setAttribute('class', 'entryTitle');
                        settingsTagsBlacklist.prepend(tagAddBlacklist());
                        settingsTagsBlacklist.prepend(settingsTagsBlacklistText);

                        settingsTab.appendChild(settingsTagsBlacklist)
                        return settingsTab;
                    };

                    function settingsBlacklist() {
                        var settingsTab = document.createElement('div');
                        settingsTab.setAttribute('class', 'settingsTab');
                        settingsTab.setAttribute('name', 'Alerts');
                        var settingsAlertBox = document.createElement('div');
                        settingsAlertBox.setAttribute('id', 'settingsAlertBox');

                        var settingsAlertAdd = document.createElement('input');
                        settingsAlertAdd.setAttribute("type", "button");
                        settingsAlertAdd.setAttribute("class", "cssBtn");
                        settingsAlertAdd.value = 'Blacklist Current Quest';
                        settingsAlertAdd.onclick = function () {
                            try {
                                let author = document.querySelector('span.author span.name').innerText;
                                let title = document.querySelector('header.page-title').innerText;
                                let entry = title + '___' + author;
                                settings.alertBlacklist.push(entry);
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settingsBlacklist.appendChild(elementBlacklisted(entry));

                            } catch (error) {
                                console.log('Something went wrong when trying to blacklist this quest.', error);
                            }
                        };

                        var settingsBlacklist = document.createElement('div');
                        settingsBlacklist.setAttribute('id', 'settingsBlacklist');
                        settings.alertBlacklist = [...new Set(settings.alertBlacklist)]
                        settings.alertBlacklist.forEach(element => settingsBlacklist.appendChild(elementBlacklisted(element)));

                        var settingsBlacklistText = document.createElement('div');
                        settingsBlacklistText.innerText = 'Alert Blacklist';
                        settingsBlacklistText.setAttribute('class', 'entryTitle');

                        var settingsSearchBox = document.createElement('div');
                        settingsSearchBox.setAttribute('id', 'settingsBox');

                        var settingsAlertSearchInput = document.createElement('input');
                        settingsAlertSearchInput.setAttribute("type", "text");
                        settingsAlertSearchInput.setAttribute("class", "settingsInput");
                        settingsAlertSearchInput.setAttribute("name", "alertSearch");
                        settingsAlertSearchInput.setAttribute("placeholder", "Enter a title or QM to search.");

                        var settingsAlertSearch = document.createElement('input');
                        settingsAlertSearch.setAttribute("type", "button");
                        settingsAlertSearch.setAttribute("class", "cssBtn");
                        settingsAlertSearch.value = 'Search';
                        settingsAlertSearch.onclick = function () {
                            this.closest('#settingsBlacklist').querySelectorAll('.blacklistEntry').forEach(x => {
                                x.style.display = 'initial';
                            })
                            let search = this.parentNode.querySelector('[name="alertSearch"]').value.toLowerCase();
                            let xx = this.closest('#settingsBlacklist').querySelectorAll('.blacklistEntry');
                            xx.forEach(x => {
                                let text = x.firstChild.textContent.toLowerCase().replace('author:')
                                if (!text.includes(search)) {
                                    x.style.display = 'none';
                                } else {}
                            })
                        }

                        var settingsAlertSearchClear = document.createElement('input');
                        settingsAlertSearchClear.setAttribute("type", "button");
                        settingsAlertSearchClear.setAttribute("class", "cssBtn");
                        settingsAlertSearchClear.value = 'Clear Search';
                        settingsAlertSearchClear.onclick = function () {
                            this.parentNode.querySelector('[name="alertSearch"]').value = '';
                            this.closest('#settingsBlacklist').querySelectorAll('.blacklistEntry').forEach(x => {
                                x.style.display = 'initial';
                            })

                        }

                        settingsSearchBox.appendChild(settingsAlertSearchInput);
                        settingsSearchBox.appendChild(settingsAlertSearch);
                        settingsSearchBox.appendChild(settingsAlertSearchClear);
                        settingsAlertBox.appendChild(settingsSearchBox);
                        settingsAlertBox.appendChild(settingsAlertAdd);
                        settingsBlacklist.prepend(settingsAlertBox);
                        settingsBlacklist.prepend(settingsBlacklistText);
                        settingsTab.appendChild(settingsBlacklist)
                        return settingsTab;
                    };


                    function settingsStyle() {
                        function genStyle(styleAttribute, styleText) {
                            var settingsStyleEntryText = document.createElement('p');
                            settingsStyleEntryText.setAttribute('class', 'styleTitle');
                            settingsStyleEntryText.innerText = styleText;

                            var settingsStylePicker = document.createElement('input');
                            settingsStylePicker.setAttribute('class', 'colorPick');
                            settingsStylePicker.setAttribute('type', 'color');
                            settingsStylePicker.onchange = function () {
                                this.parentNode.querySelector('.colorSet').value = this.value
                            };

                            var settingsStyleInput = document.createElement('input');
                            settingsStyleInput.setAttribute('class', 'colorSet');
                            settingsStyleInput.setAttribute('type', 'text');

                            if ([styleAttribute]in settings.customCSS[0]) {
                                settingsStyleInput.value = settings.customCSS[0][styleAttribute]
                                settingsStylePicker.value = settings.customCSS[0][styleAttribute]
                            };

                            var settingsStyleEntry = document.createElement('div');
                            settingsStyleEntry.setAttribute('class', 'styleEntry');
                            settingsStyleEntry.setAttribute('name', styleAttribute);
                            settingsStyleEntry.appendChild(settingsStyleEntryText);
                            settingsStyleEntry.appendChild(settingsStyleInput);
                            settingsStyleEntry.appendChild(settingsStylePicker);

                            return settingsStyleEntry;
                        };

                        var settingsStyle = document.createElement('div');
                        settingsStyle.setAttribute('class', 'settingsTab');
                        settingsStyle.setAttribute('name', 'Site Style');

                        var settingsStyleText = document.createElement('div');
                        settingsStyleText.setAttribute('class', 'entryTitle');
                        settingsStyleText.innerText = 'Custom Site Style - Beta';

                        var settingsStyleTextBox = new genStyle('color', 'Text Color');
                        var settingsStyleBackgroundBox = new genStyle('background', 'Background Color');

                        var settingsStyleSave = document.createElement('input');
                        settingsStyleSave.setAttribute("type", "button");
                        settingsStyleSave.setAttribute('class', 'cssBtn');
                        settingsStyleSave.setAttribute("class", "cssBtn");
                        settingsStyleSave.onclick = function () {
                            try{
                                try{
                                    document.querySelectorAll('.styleEntry').forEach(
                                        x => {
                                            let name = x.getAttribute("name");
                                            let value = x.querySelector('.colorSet').value;
                                            if (value !== undefined) {
                                                settings.customCSS[0][name] = value;
                                            }
                                        });
                                }catch(error){}

                                try{
                                    for (var key in settings.customCSS[0]) {
                                        if (settings.customCSS[0].hasOwnProperty(key)) {
                                            console.log(key, settings.customCSS[0][key]);
                                        }
                                    }
                                }catch(error){
                                }

                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                let styleS = `*{color:${settings.customCSS[0].color}!important;background:${settings.customCSS[0].background} !important;}`;

                                let style = document.createElement('style');
                                style.setAttribute("name", "styleSheet");
                                if (document.querySelector('[name="styleSheet"]')) {
                                    document.querySelector('[name="styleSheet"]').remove();
                                    style.appendChild(document.createTextNode(styleS));
                                } else {
                                    style.appendChild(document.createTextNode(styleS));
                                }
                                document.getElementsByTagName('head')[0].appendChild(style);
                            }catch(error){
                            }
                        };
                        settingsStyleSave.value = 'Apply Styling';


                        //External CSS Stuff
                        function settingsStyleEx(){
                            function applyCSS(index,cssFile){
                                var style = document.createElement('link');
                                let check = document.querySelector(`link[name="${index}"]`)
                                if (check){check.remove()}
                                style.setAttribute('name','eCSS'+index);
                                style.setAttribute('rel','stylesheet');
                                style.setAttribute('type','text/css');
                                style.href = cssFile
                                style.appendChild(document.createTextNode(style));
                                document.getElementsByTagName('head')[0].appendChild(style);
                            };
                            var settingsStyleEx = document.createElement('div');
                            settingsStyleEx.setAttribute('class', 'settingsStyleEx');

                            var settingsStyleExText = document.createElement('div');
                            settingsStyleExText.setAttribute('class', 'entryTitle');
                            settingsStyleExText.innerText = 'External Style Sheets';

                            var settingsStyleExDesc = document.createElement('p');
                            settingsStyleExDesc.style = 'margin:0px;font-size:12px;'
                            settingsStyleExDesc.innerText = 'Paste links to CSS files below to have them applied, in order, to the page.';

                            function externalStyleLink(ival){
                                if (!ival){ival=''}
                                var settingsStyleExCon = document.createElement('div');
                                settingsStyleExCon.classList.add('eCSSRow')

                                var settingsStyleExLink = document.createElement('input');
                                settingsStyleExLink.setAttribute('type', 'text');
                                settingsStyleExLink.classList.add('ExternalLink','eCSS')
                                settingsStyleExLink.setAttribute('placeholder', 'Place a link to a CSS file to have it applied to the page.');
                                settingsStyleExLink.value = ival
                                settingsStyleExLink.onchange = function(){
                                    let inp = document.querySelectorAll('.eCSS')
                                    if (inp.length > 1){
                                        inp.forEach(i=>{
                                            if (i == this){return}
                                            if (i.value == this.value){this.value='Duplicate found and removed.'}
                                        })
                                    }
                                    if (/.*\.css/.test(this.value)){
                                        let i = Array.from(settingsStyleEx.querySelectorAll('.eCSS')).indexOf(this);
                                        if (!settings.externalCSS[i]){
                                            settings.externalCSS.push(this.value);
                                            applyCSS(i.toString(),this.value);
                                        }else{
                                            settings.externalCSS[i] = this.value;
                                            applyCSS(i.toString(),this.value);
                                        }
                                        localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                        settings = JSON.parse(localStorage.getItem('FL_Settings'));
                                    }
                                };

                                var settingsStyleExLinkAdd = document.createElement('input');
                                settingsStyleExLinkAdd.setAttribute('type', 'button');
                                settingsStyleExLinkAdd.classList.add('class', 'ExternalLink','cssBtn');
                                settingsStyleExLinkAdd.value = 'Add new Link';
                                settingsStyleExLinkAdd.style = 'display:inline-block;';
                                settingsStyleExLinkAdd.onclick = function(){settingsStyleEx.appendChild(new externalStyleLink)};

                                var settingsStyleExLinkRem = document.createElement('input');
                                settingsStyleExLinkRem.setAttribute('type', 'button');
                                settingsStyleExLinkRem.classList.add('class', 'ExternalLink','cssBtn');
                                settingsStyleExLinkRem.value = 'Remove This Link';
                                settingsStyleExLinkRem.style = 'display:inline-block;';
                                settingsStyleExLinkRem.onclick = function(){
                                    let i = Array.from(settingsStyleEx.querySelectorAll('.eCSS')).indexOf(this.parentNode.children[0]);
                                    settings.externalCSS.splice(i, 1);
                                    try{
                                        document.querySelector(`link[name="${'eCSS'+i}"]`).remove()
                                    }catch(error){}
                                    let rows = document.querySelectorAll('.eCSSRow').length
                                    if (rows == 1)(this.parentNode.children[0].value='')
                                    else{this.parentNode.remove()}
                                    localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                    settings = JSON.parse(localStorage.getItem('FL_Settings'));
                                };

                                settingsStyleExCon.appendChild(settingsStyleExLink);
                                settingsStyleExCon.appendChild(settingsStyleExLinkAdd);
                                settingsStyleExCon.appendChild(settingsStyleExLinkRem);

                                return settingsStyleExCon;
                            };

                            settingsStyleExText.appendChild(settingsStyleExDesc);
                            settingsStyleEx.appendChild(settingsStyleExText);
                            if (settings.externalCSS){
                                settings.externalCSS.forEach(css=>{
                                    try{
                                        let i = settings.externalCSS.indexOf(css);
                                        var eCSS = new externalStyleLink(css);
                                        settingsStyleEx.appendChild(eCSS);
                                        applyCSS(i,css);
                                    }catch(error){console.log('Error going over externalCSS')}
                                })}
                            settingsStyleEx.appendChild(new externalStyleLink());

                            var settingsStyleEntries = document.createElement('div');
                            settingsStyleEntries.setAttribute('id', 'styleEntries');
                            settingsStyleEntries.appendChild(settingsStyleTextBox);
                            settingsStyleEntries.appendChild(settingsStyleBackgroundBox);

                            settingsStyle.appendChild(settingsStyleText);
                            settingsStyle.appendChild(settingsStyleEntries);
                            settingsStyle.appendChild(settingsStyleSave);
                            return settingsStyleEx;
                        };

                        //Complicated CSS Stuff
                        var settingsExternalStyles = document.createElement('input');
                        settingsExternalStyles.setAttribute("type", "button");
                        settingsExternalStyles.setAttribute('class', 'cssBtn');
                        settingsExternalStyles.value = 'Toggle CSS Input';

                        var settingsStyleToggle = document.createElement('input');
                        settingsStyleToggle.setAttribute("type", "button");
                        settingsStyleToggle.setAttribute('class', 'cssBtn');
                        settingsStyleToggle.value = 'Toggle CSS Input';
                        settingsStyleToggle.onclick = function () {
                            let styleInput = document.querySelector('#styleInput');
                            let styleSaveCSS = document.querySelector('#styleSaveCSS');
                            if (styleInput.style.display != 'none') {
                                styleInput.style.display = 'none';
                                styleSaveCSS.style.display = 'none';
                            } else {
                                styleInput.style.display = 'initial';
                                styleSaveCSS.style.display = 'initial';
                            }
                        };

                        var settingsStyleBoxSave = document.createElement('input');
                        settingsStyleBoxSave.setAttribute("type", "button");
                        settingsStyleBoxSave.setAttribute('id', 'styleSaveCSS');
                        settingsStyleBoxSave.setAttribute('class', 'cssBtn');
                        settingsStyleBoxSave.value = 'Save CSS Input';
                        settingsStyleBoxSave.style.display = 'none';
                        settingsStyleBoxSave.style.height = '30px';
                        settingsStyleBoxSave.onclick = function () {
                            let styleS = document.querySelector('#styleInput').value
                            if (styleS !== undefined) {
                                settings.customCSS[1] = styleS;
                            }
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));

                            let style = document.createElement('style');
                            style.setAttribute("name", "styleSheet");
                            if (document.querySelector('[name="styleSheet"]')) {
                                document.querySelector('[name="styleSheet"]').remove();
                                style.appendChild(document.createTextNode(styleS));
                            } else {
                                style.appendChild(document.createTextNode(styleS));
                            }
                            document.getElementsByTagName('head')[0].appendChild(style);
                        };

                        var settingsStyleClear = document.createElement('input');
                        settingsStyleClear.setAttribute("type", "button");
                        settingsStyleClear.setAttribute('class', 'cssBtn');
                        settingsStyleClear.value = 'Reset Style Settings';
                        settingsStyleClear.style.height = '30px';
                        settingsStyleClear.onclick = function () {
                            try{
                                document.querySelector('[name="styleSheet"]').remove();
                                document.querySelectorAll('.colorPick').forEach(x => {
                                    x.value = ''
                                });
                                document.querySelectorAll('.colorSet').forEach(x => {
                                    x.value = ''
                                });
                                document.querySelector('#styleInput').value = '';
                                settings.customCSS = [{}, ``];
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            }catch(error){}
                        };

                        var settingsStyleBox = document.createElement('textarea');
                        settingsStyleBox.setAttribute('id', 'styleInput');
                        settingsStyleBox.setAttribute('placeholder', 'Add any more complicated CSS here.');
                        settingsStyleBox.setAttribute("cols", "50");
                        settingsStyleBox.setAttribute("rows", "50");
                        settingsStyleBox.style.display = 'none';
                        if (settings.customCSS[1] !== ``) {
                            settingsStyleBox.value = settings.customCSS[1];
                        }

                        settingsStyle.appendChild(new settingsStyleEx);

                        settingsStyle.appendChild(settingsStyleToggle);
                        settingsStyle.appendChild(settingsStyleBoxSave);
                        settingsStyle.appendChild(settingsStyleClear);
                        settingsStyle.appendChild(settingsStyleBox);
                        try {
                            if (settings.customCSS[0] != {}) {
                                let A=''
                                let B=''
                                if (settings.customCSS[0].color != undefined){A=`color:${settings.customCSS[0].color}!important;`}
                                if (settings.customCSS[0].background != undefined){B=`background:${settings.customCSS[0].background} !important;}`}
                                var styleS = `*{${A}${B}}`;
                                if (styleS!='*{}'){
                                    var style = document.createElement('style');
                                    style.setAttribute("name", "styleSheet");
                                    if (document.querySelector('[name="styleSheet"]')) {
                                        document.querySelector('[name="styleSheet"]').remove();
                                        style.setAttribute("name", "styleSheet");
                                        style.appendChild(document.createTextNode(styleS));
                                    } else {
                                        style.appendChild(document.createTextNode(styleS));
                                    }
                                    document.getElementsByTagName('head')[0].appendChild(style);
                                }
                            };
                        } catch (error) {
                            console.log(error)
                        }

                        try {
                            if (settings.customCSS[1] != ``) {
                                var style2 = document.createElement('style');
                                var styleS2 = settings.customCSS[1]
                                if (document.querySelector('[name="styleSheet"]')) {
                                    document.querySelector('[name="styleSheet"]').remove();
                                    style2.setAttribute("name", "styleSheet");
                                    style2.appendChild(document.createTextNode(styleS2));
                                }
                                else {
                                    style2.setAttribute("name", "styleSheet");
                                    style2.appendChild(document.createTextNode(styleS2));
                                }
                                document.getElementsByTagName('head')[0].appendChild(style2);
                            }
                        } catch (error) {
                            console.log('customcss',error)
                        }

                        return settingsStyle;
                    }

                    //Toggles for features start here
                    //Toggles for features start here
                    //Toggles for features start here
                    //Toggles for features start here
                    //Toggles for features start here

                    function settingsNamefagToggle() {

                        var settingsNamefagToggle = document.createElement('div');
                        settingsNamefagToggle.setAttribute('class', 'settingsToggle');

                        var settingsNamefagToggleText = document.createElement('div');
                        settingsNamefagToggleText.innerText = 'Make everyone Anon.';

                        var settingsNamefagToggleCheckbox = document.createElement('input');
                        settingsNamefagToggleCheckbox.setAttribute("type", "checkbox");
                        settingsNamefagToggleCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.removeUsernames == true) {
                            settingsNamefagToggleCheckbox.checked = true;
                        };
                        settingsNamefagToggleCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.removeUsernames = true;
                                try{
                                    let authorList = document.querySelectorAll('span.author.ng-scope');
                                    let authors = []
                                    authorList.forEach(element => authors.push(element.querySelector('span.name').innerText))
                                    let names = document.querySelectorAll('div.user span.name')
                                    names.forEach(name => {
                                        let txt = name.innerText;
                                        if (!authors.includes(txt)){
                                            name.innerText = 'anon';
                                        }
                                    })
                                }catch(error){console.log('anonForce',error)}
                            } else {
                                settings.removeUsernames = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsNamefagToggle.appendChild(settingsNamefagToggleText);
                        settingsNamefagToggle.appendChild(settingsNamefagToggleCheckbox);
                        return settingsNamefagToggle
                    };

                    function settingsAnonToggle() {
                        function toggleAnonStatus() {
                            var x = 1
                            try {
                                try {
                                    var username = localStorage.getItem('username');
                                    var refURL = "https://fiction.live/user/" + username;
                                    var profile = window.ty.currentUser.profile;
                                    profile.asAnon = settings.anonToggle;
                                } catch (error) {
                                    console.log('Toggle Anon Prep', error);
                                    x = 2;
                                };
                                if (x = 1) {
                                    fetch("https://fiction.live/api/user", {
                                        "credentials": "include",
                                        "headers": {
                                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0",
                                            "Accept": "application/json, text/javascript, */*; q=0.01",
                                            "Accept-Language": "en-GB,en;q=0.5",
                                            "Content-Type": "application/json",
                                            "X-Requested-With": "XMLHttpRequest"
                                        },
                                        "referrer": refURL,
                                        "body": JSON.stringify(profile),
                                        "method": "PUT",
                                        "mode": "cors"
                                    });
                                };
                            } catch (error) {
                                console.log('Toggle Anon Set', error);
                            };
                        };

                        var settingsAnonToggle = document.createElement('div');
                        settingsAnonToggle.setAttribute('class', 'settingsToggle');

                        var settingsAnonToggleText = document.createElement('div');
                        settingsAnonToggleText.innerText = 'Toggle Anon status.';

                        var settingsAnonToggleCheckbox = document.createElement('input');
                        settingsAnonToggleCheckbox.setAttribute("type", "checkbox");
                        settingsAnonToggleCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.anonToggle == true) {
                            settingsAnonToggleCheckbox.checked = true;
                        };
                        settingsAnonToggleCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.anonToggle = true;
                                toggleAnonStatus();
                            } else {
                                settings.anonToggle = false;
                                toggleAnonStatus();
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsAnonToggle.appendChild(settingsAnonToggleText);
                        settingsAnonToggle.appendChild(settingsAnonToggleCheckbox);
                        return settingsAnonToggle
                    };

                    function settingsLiveRestore() {
                        var settingsLiveRestore = document.createElement('div');
                        settingsLiveRestore.setAttribute('class', 'settingsToggle');

                        var settingsLiveRestoreText = document.createElement('div');
                        settingsLiveRestoreText.innerText = 'Restore live timer to nav bar.';

                        var settingsLiveRestoreCheckbox = document.createElement('input');
                        settingsLiveRestoreCheckbox.setAttribute("type", "checkbox");
                        settingsLiveRestoreCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.liveRestore == true) {
                            settingsLiveRestoreCheckbox.checked = true;
                        };
                        settingsLiveRestoreCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.liveRestore = true;
                                let canvas = document.querySelector('header[class="next-live ng-scope"]');
                                if (canvas){
                                    liveRestore()
                                }
                            } else {
                                settings.liveRestore = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsLiveRestore.appendChild(settingsLiveRestoreText);
                        settingsLiveRestore.appendChild(settingsLiveRestoreCheckbox);
                        return settingsLiveRestore
                    };

                    function settingsLiveLight() {
                        var settingsLiveLight = document.createElement('div');
                        settingsLiveLight.setAttribute('class', 'settingsToggle');

                        var settingsLiveLightText = document.createElement('div');
                        settingsLiveLightText.innerText = 'Light mode live timer.';

                        var settingsLiveLightCheckbox = document.createElement('input');
                        settingsLiveLightCheckbox.setAttribute("type", "checkbox");
                        settingsLiveLightCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.liveLight == true) {
                            settingsLiveLightCheckbox.checked = true;
                        };
                        settingsLiveLightCheckbox.addEventListener('change', (event) => {
                            let myLive = document.querySelector('#liveBox')
                            if (event.target.checked) {
                                settings.liveLight = true;
                            } else {
                                settings.liveLight = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsLiveLight.appendChild(settingsLiveLightText);
                        settingsLiveLight.appendChild(settingsLiveLightCheckbox);
                        return settingsLiveLight
                    };

                    function settingsAuthorHighlight() {
                        var settingsAuthorHighlight = document.createElement('div');
                        settingsAuthorHighlight.setAttribute('class', 'settingsToggle');

                        var settingsAuthorHighlightText = document.createElement('div');
                        settingsAuthorHighlightText.innerText = 'Highlight author(s) in chat.';

                        var settingsAuthorHighlightCheckbox = document.createElement('input');
                        settingsAuthorHighlightCheckbox.setAttribute("type", "checkbox");
                        settingsAuthorHighlightCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.authorHighlight == true) {
                            settingsAuthorHighlightCheckbox.checked = true;
                        };
                        settingsAuthorHighlightCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.authorHighlight = true;
                                try{
                                    let authorList = document.querySelectorAll('span.author.ng-scope');
                                    let authors = []
                                    authorList.forEach(element => authors.push(element.querySelector('span.name').innerText))
                                    var currentColor = settings.highlightColor;
                                    if (settings.highlightLightToggle == true) {
                                        currentColor = settings.highlightLight;
                                    }
                                    document.querySelectorAll('div.user span.name').forEach(name => {
                                        if (authors.includes(name.innerText)){
                                            name.closest('.logItem').style.background = currentColor
                                        }
                                    })
                                }catch(error){}
                            } else {
                                settings.authorHighlight = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsAuthorHighlight.appendChild(settingsAuthorHighlightText);
                        settingsAuthorHighlight.appendChild(settingsAuthorHighlightCheckbox);
                        return settingsAuthorHighlight
                    };

                    function settingsLightHighlight() {
                        var settingsLightHighlight = document.createElement('div');
                        settingsLightHighlight.setAttribute('class', 'settingsToggle');

                        var settingsLightHighlightText = document.createElement('div');
                        settingsLightHighlightText.innerText = 'Light mode highlighting.';

                        var settingsLightHighlightCheckbox = document.createElement('input');
                        settingsLightHighlightCheckbox.setAttribute("type", "checkbox");
                        settingsLightHighlightCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.highlightLightToggle == true) {
                            settingsLightHighlightCheckbox.checked = true;
                        };
                        settingsLightHighlightCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.highlightLightToggle = true;
                                try{
                                    let authorList = document.querySelectorAll('span.author.ng-scope');
                                    let authors = []
                                    authorList.forEach(element => authors.push(element.querySelector('span.name').innerText))
                                    var currentColor = settings.highlightColor;
                                    if (settings.highlightLightToggle == true) {
                                        currentColor = settings.highlightLight;
                                    }
                                    document.querySelectorAll('div.user span.name').forEach(name => {
                                        if (authors.includes(name.innerText)){
                                            name.closest('.logItem').style.background = currentColor
                                        }
                                    })
                                }catch(error){}
                            } else {
                                settings.highlightLightToggle = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsLightHighlight.appendChild(settingsLightHighlightText);
                        settingsLightHighlight.appendChild(settingsLightHighlightCheckbox);
                        return settingsLightHighlight
                    };

                    function settingsNSFWToggle() {
                        var settingsNSFWToggle = document.createElement('div');
                        settingsNSFWToggle.setAttribute('class', 'settingsToggle');

                        var settingsNSFWToggleText = document.createElement('div');
                        settingsNSFWToggleText.innerText = 'Remove NSFW covers from quests.';

                        var settingsNSFWToggleCheckbox = document.createElement('input');
                        settingsNSFWToggleCheckbox.setAttribute("type", "checkbox");
                        settingsNSFWToggleCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.removeNSFW == true) {
                            settingsNSFWToggleCheckbox.checked = true;
                        };
                        settingsNSFWToggleCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.removeNSFW = true;
                                removeNSFW();
                            } else {
                                settings.removeNSFW = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsNSFWToggle.appendChild(settingsNSFWToggleText);
                        settingsNSFWToggle.appendChild(settingsNSFWToggleCheckbox);
                        return settingsNSFWToggle
                    };

                    function settingsUpdateRequestDismissToggle() {
                        var settingsUpdateRequestDismissToggle = document.createElement('div');
                        settingsUpdateRequestDismissToggle.setAttribute('class', 'settingsToggle');

                        var settingsUpdateRequestText = document.createElement('div');
                        settingsUpdateRequestText.innerText = 'Auto dismiss update requests.';

                        var settingsUpdateRequestDismissToggleCheckbox = document.createElement('input');
                        settingsUpdateRequestDismissToggleCheckbox.setAttribute("type", "checkbox");
                        settingsUpdateRequestDismissToggleCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.updateRequestDismiss == true) {
                            settingsUpdateRequestDismissToggleCheckbox.checked = true;
                        };
                        settingsUpdateRequestDismissToggleCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.updateRequestDismiss = true;
                                let alertContainer = document.querySelectorAll('li.feedItem');
                                alertContainer.forEach(alert => {
                                    if (/.*Looks forward to the next update for.*/.test(alert.innerText)) {
                                        alertUpdate(alert)
                                    }
                                });
                            } else {
                                settings.updateRequestDismiss = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsUpdateRequestDismissToggle.appendChild(settingsUpdateRequestText);
                        settingsUpdateRequestDismissToggle.appendChild(settingsUpdateRequestDismissToggleCheckbox);
                        return settingsUpdateRequestDismissToggle
                    };


                    function settingsReviewDismissToggle() {
                        var div = document.createElement('div');
                        div.setAttribute('class', 'settingsToggle');

                        var text = document.createElement('div');
                        text.style.display = 'inline';
                        text.innerText = 'Auto dismiss review notifications.';

                        var toggle = document.createElement('input');
                        toggle.setAttribute("type", "checkbox");
                        toggle.setAttribute("class", "toggleCheck");
                        if (settings.reviewDismiss == true) {
                            toggle.checked = true;
                        };
                        toggle.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.reviewDismiss = true;
                                let alertContainer = document.querySelectorAll('li.feedItem');
                                alertContainer.forEach(alert => {
                                    if (/.*New review for.*/.test(alert.innerText)) {
                                        alertUpdate(alert)
                                    }
                                });
                            } else {
                                settings.reviewDismiss = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        div.appendChild(text);
                        div.appendChild(toggle);
                        return div
                    };


                    function settingsFollowDismissToggle() {
                        var div = document.createElement('div');
                        div.setAttribute('class', 'settingsToggle');

                        var text = document.createElement('div');
                        text.style.display = 'inline';
                        text.innerText = 'Auto dismiss follow notifications.';

                        var toggle = document.createElement('input');
                        toggle.setAttribute("type", "checkbox");
                        toggle.setAttribute("class", "toggleCheck");
                        if (settings.followDismiss == true) {
                            toggle.checked = true;
                        };
                        toggle.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.followDismiss = true;
                                let alertContainer = document.querySelectorAll('li.feedItem');
                                alertContainer.forEach(alert => {
                                    if (/.*Is now a new follower of yours.*/.test(alert.innerText)) {
                                        alertUpdate(alert)
                                    }
                                });
                            } else {
                                settings.followDismiss = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        div.appendChild(text);
                        div.appendChild(toggle);
                        return div
                    };


                    function settingsLikesDismissToggle() {
                        var div = document.createElement('div');
                        div.setAttribute('class', 'settingsToggle');

                        var text = document.createElement('div');
                        text.style.display = 'inline';
                        text.innerText = 'Auto dismiss like notifications.';

                        var toggle = document.createElement('input');
                        toggle.setAttribute("type", "checkbox");
                        toggle.setAttribute("class", "toggleCheck");
                        if (settings.followLike == true) {
                            toggle.checked = true;
                        };
                        toggle.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.followLike = true;
                                let alertContainer = document.querySelectorAll('li.feedItem');
                                alertContainer.forEach(alert => {
                                    if (/.*Likes \".*\".*/.test(alert.innerText)) {
                                        alertUpdate(alert)
                                    }
                                });
                            } else {
                                settings.followLike = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        div.appendChild(text);
                        div.appendChild(toggle);
                        return div
                    };

                    function settingsAkunPlusToggle() {
                        var settingsAkunPlusToggle = document.createElement('div');
                        settingsAkunPlusToggle.setAttribute('class', 'settingsToggle');

                        var settingsAkunPlusToggleText = document.createElement('div');

                        var settingsAkunPlusToggleBtn = document.createElement('input');
                        settingsAkunPlusToggleBtn.setAttribute("type", "button");
                        settingsAkunPlusToggleBtn.setAttribute("class", "toggleBtn");

                        if (settings.akunPlus == 'Ignore') {
                            settingsAkunPlusToggleText.innerText = '(Chat) Ignore Akun Premium';
                            settingsAkunPlusToggleBtn.value = 'Remove';
                        } else if (settings.akunPlus == 'Remove') {
                            settingsAkunPlusToggleText.innerText = '(Chat) Remove Akun Premium';
                            settingsAkunPlusToggleBtn.value = 'Global';
                        } else {
                            settingsAkunPlusToggleText.innerText = '(Chat) Global Akun Premium';
                            settingsAkunPlusToggleBtn.value = 'Ignore';
                        };
                        settingsAkunPlusToggleBtn.onclick = function () {
                            try {
                                if (settings.akunPlus == 'Ignore') {
                                    this.parentNode.childNodes[0].innerText = '(Chat) Remove Akun Premium';
                                    this.value = 'Global';
                                    settings.akunPlus = 'Remove';
                                } else if (settings.akunPlus == 'Remove') {
                                    this.parentNode.childNodes[0].innerText = '(Chat) Global Akun Premium';
                                    this.value = 'Ignore';
                                    settings.akunPlus = 'Global';
                                } else {
                                    this.parentNode.childNodes[0].innerText = '(Chat) Ignore Akun Premium';
                                    this.value = 'Remove';
                                    settings.akunPlus = 'Ignore';
                                };
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                            } catch (error) {
                                console.log('Error changin akunPlus', error);
                            };
                        };
                        settingsAkunPlusToggle.appendChild(settingsAkunPlusToggleText);
                        settingsAkunPlusToggle.appendChild(settingsAkunPlusToggleBtn);
                        return settingsAkunPlusToggle
                    };

                    function settingsSortAlerts() {
                        var settingsSortAlerts = document.createElement('div');
                        settingsSortAlerts.setAttribute('class', 'settingsToggle');

                        var settingsSortAlertsText = document.createElement('div');
                        settingsSortAlertsText.innerText = 'Sort alerts by author name.';

                        var settingsSortAlertsCheckbox = document.createElement('input');
                        settingsSortAlertsCheckbox.setAttribute("type", "checkbox");
                        settingsSortAlertsCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.sortAlerts == true) {
                            settingsSortAlertsCheckbox.checked = true;
                            //sortAlerts();
                        };

                        settingsSortAlertsCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.sortAlerts = true;
                                //sortAlerts();
                            } else {
                                settings.sortAlerts = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsSortAlerts.appendChild(settingsSortAlertsText);
                        settingsSortAlerts.appendChild(settingsSortAlertsCheckbox);
                        return settingsSortAlerts
                    };

                    function settingsNewThemeChangeToggle() {
                        var settingsToggle = document.createElement('div');
                        settingsToggle.setAttribute('class', 'settingsToggle');

                        var settingsText = document.createElement('div');
                        settingsText.innerText = 'Change themes without page reload.';

                        var settingsCheckbox = document.createElement('input');
                        settingsCheckbox.setAttribute("type", "checkbox");
                        settingsCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.useThemeChange == true) {
                            settingsCheckbox.checked = true;
                        };

                        settingsCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.useThemeChange = true;
                                try{
                                    newThemeChange();
                                }catch(error){console.log(error)}
                            } else {
                                settings.useThemeChange = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsToggle.appendChild(settingsText);
                        settingsToggle.appendChild(settingsCheckbox);
                        return settingsToggle
                    };

                    function settingsImageLinkToggle() {
                        var settingsToggle = document.createElement('div');
                        settingsToggle.setAttribute('class', 'settingsToggle');

                        var settingsText = document.createElement('div');
                        settingsText.innerText = 'Display off-site image poster in chat input.';

                        var settingsCheckbox = document.createElement('input');
                        settingsCheckbox.setAttribute("type", "checkbox");
                        settingsCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.imageLink == true) {
                            settingsCheckbox.checked = true;
                        };

                        settingsCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.imageLink = true;
                                imageLinkButton();
                            } else {
                                settings.imageLink = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsToggle.appendChild(settingsText);
                        settingsToggle.appendChild(settingsCheckbox);
                        return settingsToggle
                    };

                    //Toggle Template/Example
                    function settingsToggle(text, toggled) {
                        try{
                            var settingsToggle = document.createElement('div');
                            settingsToggle.setAttribute('class', 'settingsToggle');

                            var settingsText = document.createElement('div');
                            settingsText.innerText = text;

                            var settingsCheckbox = document.createElement('input');
                            settingsCheckbox.setAttribute("type", "checkbox");
                            settingsCheckbox.setAttribute("class", "toggleCheck");
                            if (settings[toggled] == true) {
                                settingsCheckbox.checked = true;
                            };

                            settingsCheckbox.addEventListener('change', (event) => {
                                if (event.target.checked) {
                                    settings[toggled] = true;
                                } else {
                                    settings[toggled] = false;
                                };
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                            });
                            settingsToggle.appendChild(settingsText);
                            settingsToggle.appendChild(settingsCheckbox);
                            return settingsToggle
                        }
                        catch(error){
                            console.log('Error, does',toggled, 'exist?')
                        }
                    };

                    function settingsActual() {
                        var settingsActual = document.createElement('div');
                        settingsActual.setAttribute('class', 'settingsTab');
                        settingsActual.setAttribute('name', 'General');
                        settingsActual.style.display = 'initial';

                        var settingsActualText = document.createElement('div');
                        settingsActualText.innerText = 'General Script Settings';
                        settingsActualText.setAttribute('class', 'entryTitle');

                        var settingsText = document.createElement('div');
                        settingsText.innerText = 'Chat Settings';
                        settingsText.setAttribute('class', 'entryTitle');

                        //Settings Checkboxes
                        settingsActual.appendChild(settingsUpdateRequestDismissToggle());
                        settingsActual.appendChild(settingsReviewDismissToggle());
                        settingsActual.appendChild(settingsFollowDismissToggle());
                        settingsActual.appendChild(settingsLikesDismissToggle());
                        //settingsActual.appendChild(settingsSortAlerts());
                        settingsActual.appendChild(settingsNSFWToggle());
                        settingsActual.appendChild(settingsLiveRestore());
                        //Hidden because of dark mode detection
                        //settingsActual.appendChild(settingsLiveLight());
                        settingsActual.appendChild(new settingsToggle('Toggle creation of dice buttons.','diceButton'));
                        settingsActual.appendChild(new settingsToggle('Remove blank topics.','removeBlankTopics'));
                        settingsActual.appendChild(new settingsToggle('Remove topic submission form.','removeTopicForm'));
                        settingsActual.appendChild(new settingsToggle('Hide quests with blacklisted tags.','questRemove'));
                        settingsActual.appendChild(new settingsToggle('Hide tagged on author pages.','removeTaggedAuthor'));
                        settingsActual.appendChild(new settingsToggle('Hide quests with blacklisted authors.','questAuthorRemove'));
                        settingsActual.appendChild(new settingsToggle('Enable alert filtering.','alertFilter'));
                        settingsActual.appendChild(settingsNewThemeChangeToggle());
                        settingsActual.appendChild(settingsText);

                        settingsActual.appendChild(settingsAnonToggle());
                        settingsActual.appendChild(new settingsToggle('Toggle Auto Roller.','autoRoller'));
                        settingsActual.appendChild(settingsAuthorHighlight());
                        //Hidden because of dark mode detection
                        //settingsActual.appendChild(settingsLightHighlight());
                        settingsActual.appendChild(settingsNamefagToggle());
                        settingsActual.appendChild(new settingsToggle('Attempt to reveal anon usernames in chat.','userReveal'));
                        settingsActual.appendChild(new settingsToggle('Add delete button to your messages.','unpublishBTN'));
                        settingsActual.appendChild(new settingsToggle('Hide blacklisted users in chat.','chatBlacklist'));
                        settingsActual.appendChild(new settingsToggle('Remove replies to blacklisted users.','chatBlacklistReplies'));
                        settingsActual.appendChild(settingsAkunPlusToggle());
                        settingsActual.appendChild(new settingsToggle('Resize images in chat.','imageResize'));
                        settingsActual.appendChild(new settingsToggle('Make text links functional.','functionalLinks'));
                        settingsActual.appendChild(new settingsToggle('Make video links functional.','functionalVideos'));
                        settingsActual.appendChild(new settingsToggle('Allow message editing in chat.','messageEdit'));
                        settingsActual.appendChild(new settingsToggle('Toggle in-chat text options (bold, italic).','textStyle'));
                        settingsActual.appendChild(new settingsToggle('Enable automatic chat hide.','autoHide'));
                        settingsActual.appendChild(settingsImageLinkToggle());
                        settingsActual.appendChild(new settingsToggle('Enable spam auto delete.','spamRemoval'));
                        settingsActual.appendChild(new settingsToggle('Enable auto-delete and ban phrases.','messageBlacklist'));
                        //settingsActual.appendChild(new settingsToggle('test',));


                        //settingsActual.appendChild(new settingsToggle('Resize images in chat.','imageResize'));

                        settingsActual.prepend(settingsActualText);

                        return settingsActual
                    }

                    var settingsTop = document.createElement('div');
                    settingsTop.setAttribute('id', 'scriptTitle');
                    var settingsTopText = document.createElement('h1');

                    settingsTopText.innerText = 'Script Config';
                    settingsTop.appendChild(settingsTopText)

                    try {
                        var settingsSelect = document.createElement('div');
                        settingsSelect.setAttribute("class", "settingsSelect");
                        var settingsTabs = ['General', 'Tags', 'Chat', 'Alerts', 'Author', 'Site Style'];
                        let tabC = 0;
                        function createTab(tab) {
                            let settingsSelectBTN = document.createElement('input');
                            settingsSelectBTN.setAttribute("type", "button");
                            settingsSelectBTN.setAttribute("class", "settingsSelectBTN");
                            settingsSelectBTN.value = String(tab);
                            if (tabC == 0) {
                                settingsSelectBTN.style.backgroundColor = '#4b4f6b';
                                settingsSelectBTN.disabled = true;
                                tabC = 1;
                                var settingTab = document.querySelector(`.settingsTab[name="${String(tab)}"]`)

                                }
                            settingsSelectBTN.onclick = function () {
                                let len = document.querySelectorAll('input.settingsSelectBTN');
                                for (let i = 0; i < len.length; i++) {
                                    if (len[i].disabled == true) {
                                        len[i].disabled = false;
                                        len[i].style.backgroundColor = '#373952';
                                    }
                                };
                                this.disabled = true;
                                this.style.backgroundColor = '#4b4f6b';
                                try {
                                    var settingTab = document.querySelector(`.settingsTab[name="${String(tab)}"]`)
                                    if (settingTab) {
                                        var tabs = document.querySelectorAll(`div.settingsTab`)
                                        for (let i = 0; i < tabs.length; i++) {
                                            tabs[i].style.display = 'none';
                                        };
                                        settingTab.style.display = 'initial'
                                    }
                                } catch (error) {
                                    console.log(error);
                                };
                            };

                            let settingsSelectDiv = document.createElement('div');
                            settingsSelectDiv.setAttribute('class', 'settingsSelectDiv');
                            settingsSelectDiv.style.width = String(100 / settingsTabs.length) + '%';
                            settingsSelectDiv.appendChild(settingsSelectBTN);
                            settingsSelect.appendChild(settingsSelectDiv);
                        }
                        settingsTabs.forEach(tab => createTab(tab));
                    } catch (error) {
                        console.log(error);
                    }

                    var settingsExit = document.createElement('a');
                    settingsExit.setAttribute('class', 'blacklistRemove');
                    settingsExit.innerText = 'Exit'
                    settingsExit.onclick = function () {
                        document.querySelector('#confDisp').style.display = 'none'
                    };

                    function contact() {
                        var contactLeft = document.createElement('div');
                        contactLeft.setAttribute('class', 'contactL');

                        var contactContainer = document.createElement('div');
                        contactContainer.setAttribute('id', 'reportDiv');
                        contactContainer.innerText = 'Report any issues you encounter to me through either of the links below, though the quest is preferred.';

                        var contactAkun = document.createElement('a');
                        contactAkun.innerText = 'Akun Script Quest';
                        contactAkun.href = 'https://fiction.live/stories/Fiction-live-Merged-Script/2pqyotSpKTcPF9dz8';
                        contactAkun.rel = "noopener noreferrer";
                        contactAkun.target = "_blank";

                        var contactGreasyfork = document.createElement('a');
                        contactGreasyfork.innerText = 'Greasyfork Page';
                        contactGreasyfork.href = 'https://greasyfork.org/en/scripts/418607-fiction-live-merged';
                        contactGreasyfork.rel = "noopener noreferrer";
                        contactGreasyfork.target = "_blank";

                        var contactRight = document.createElement('div');
                        contactRight.setAttribute('class', 'contactR');

                        function download(data) {
                            var file = new Blob([data], {type: '.txt'});
                            if (window.navigator.msSaveOrOpenBlob){// IE10+
                                window.navigator.msSaveOrOpenBlob(file, 'FictionLiveMerged-Settings');
                            }
                            else { // Others
                                var a = document.createElement("a"),
                                    url = URL.createObjectURL(file);
                                a.href = url;
                                a.download = 'FictionLiveMerged-Settings.txt';
                                document.body.appendChild(a);
                                a.click();
                                setTimeout(function() {
                                    document.body.removeChild(a);
                                    window.URL.revokeObjectURL(url);
                                }, 0);
                            }
                        }

                        var exportSettings = document.createElement('a');
                        exportSettings.setAttribute("class", "exportSettings");
                        exportSettings.innerText='Export settings to file.'
                        exportSettings.onclick = function(){download(localStorage.getItem('FL_Settings'))};


                        var importSettings = document.createElement('a');
                        importSettings.setAttribute("class", "exportSettings");
                        importSettings.innerText='Import settings from file.';
                        importSettings.onclick = function(){
                            this.parentNode.querySelector('#fileImport').click();
                        };

                        var importContainer = document.createElement('div');
                        var importFile = document.createElement('input');
                        importFile.setAttribute("id", "fileImport");
                        importFile.setAttribute("type", "file");
                        importFile.setAttribute("name", "files[]");
                        importFile.setAttribute("accept", ".txt");
                        importFile.style = 'display:none !important; visibility:hidden !important;'
                        importFile.onchange = function(){
                            var files = event.target.files; // FileList object
                            //console.log(files[0]);
                            //return;
                            var reader = new FileReader();
                            if(files && files[0]) {
                                reader.onload = function (e) {
                                    let data = e.target.result;
                                    localStorage.setItem('FL_Settings', data);
                                    return
                                    //displayContents(output);
                                };//end onload()
                                reader.readAsText(files[0]);
                                location.reload();
                            }

                        };
                        importContainer.appendChild(importSettings)
                        importContainer.appendChild(importFile)


                        var contact = document.createElement('div');
                        contact.setAttribute('class', 'contactMain');
                        contactContainer.appendChild(document.createElement('br'));
                        contactContainer.appendChild(contactAkun);
                        contactContainer.appendChild(document.createElement('br'));
                        contactContainer.appendChild(contactGreasyfork);
                        contactLeft.appendChild(contactContainer);
                        contactRight.appendChild(exportSettings);
                        contactRight.appendChild(importContainer);
                        contact.appendChild(contactLeft);
                        contact.appendChild(contactRight);

                        return contact;
                    };

                    settingsTop.appendChild(settingsExit)
                    var confDisp = configDisplay();
                    var confBox = configBox();
                    confBox.appendChild(settingsTop);
                    confBox.appendChild(settingsSelect);
                    confBox.appendChild(settingsActual());
                    confBox.appendChild(settingsTagsBlacklist());
                    confBox.appendChild(settingsUserBlacklist());
                    confBox.appendChild(settingsAuthorsBlacklist());
                    confBox.appendChild(settingsStyle());
                    confBox.appendChild(settingsBlacklist());
                    confBox.appendChild(contact());
                    confDisp.appendChild(confBox);
                    document.querySelector('body').prepend(confDisp);

                }
            } catch (error) {
                console.log('Settings Display Error', error);
            };
        };

        function settingsOpen() {
            var myLive = document.createElement('li');
            myLive.setAttribute('id', 'confScript');

            var configOpen = document.createElement('a');
            configOpen.innerText = 'Config';
            configOpen.onclick = function () {
                document.querySelector('#confDisp').style.display = 'block'
            };
            myLive.appendChild(configOpen);
            return myLive
        };

        function settingsInsert() {
            try {
                let mainMenu = document.querySelector('nav#mainMenu');
                settingsDisplay()
                if (!(mainMenu.querySelector('#confScript'))) {
                    mainMenu.childNodes[2].appendChild(settingsOpen());
                }
            } catch (error) {
                console.log('Errors inserting Settings', error)
            };
        };

        settingsInsert()
    };

    pageCheck();
    awaitAlerts()
    awaitMainMenu();

    //Source - https://github.com/proxy-m/real-visibility
    Element.prototype.isReallyNear = function(otherEl) {
        let el = this;
        if (!el || !otherEl) {
            return null;
        }
        return el.contains(otherEl) || otherEl.contains(el);
    };
    Element.prototype.isReallyVisible = function() {
        let el = this;
        let debug = false;
        if (!document.body.contains(el)) {
            return null;
        }
        if (document.hidden===true) {
            return false;
        } else if (document.hidden!==false) {
            console.warn("NOT FATAL WARNING: Page Visibility API is not supported by your browser.");
        }

        let rectPos = el.getBoundingClientRect();
        if (debug) {
            console.debug("Bounding of: ", el, rectPos);
        }

        let result = 0;
        if (el.isReallyNear(document.elementFromPoint(rectPos.left, rectPos.top))) {
            result++;
        }
        if (el.isReallyNear(document.elementFromPoint(rectPos.left, rectPos.bottom - 1))) {
            result++;
        }
        if (el.isReallyNear(document.elementFromPoint(rectPos.right - 1, rectPos.top))) {
            result++;
        }
        if (el.isReallyNear(document.elementFromPoint(rectPos.right - 1, rectPos.bottom - 1))) {
            result++;
        }

        let info;
        let r = true;
        if (result == 4) {
            info = 'visible';
        } else if (result === 0) {
            info = 'hidden';
            r = false;
        } else {
            info = 'partially visible';
        }
        if (debug) {
            console.debug(info, el);
        }
        return r;
    };
})();