New MangaDex Follows

Manage your follows

La data de 12-04-2022. Vezi ultima versiune.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         New MangaDex Follows
// @namespace    https://greasyfork.org/scripts/430295-new-mangadex-follows
// @version      1.2.6
// @description  Manage your follows
// @author       Australis
// @match        https://mangadex.org/*
// @icon         https://www.google.com/s2/favicons?domain=mangadex.org
// @grant        none
// @license      MIT
// ==/UserScript==
function LoadSD(){
    if(localStorage.getItem("seriesdex") == null) seriesdex = []
    else seriesdex = JSON.parse(localStorage.getItem("seriesdex"))
    //1.2
    if(localStorage.getItem("forbidden") == null) forbidden = []
    else forbidden = JSON.parse(localStorage.getItem("forbidden"))
}
LoadSD()

//GLOBAL VARIABLES
// var seriesdex,forbidden,whitelist,blacklist,titlepage,frutyloop,repeat,lista,new_r,new_c,new_d,new_o,new_p,follows,trigger,fstatus,funky
var classChapter = "flex chapter" //class of the elements containing the chapters
var classFeed = "chapter-feed__chapters-list" //class containing the chapter cluster
var grouptagclass = "group-tag line-clamp-1 -my-1"
var loadedp = "flex gap-2 sm:mb-0 mb-2" //status
var feedone = "mb-2"//mb-4
var MAXNUM = 10000
var MINNUM = -10
var disURL = ""
var unchecked = true
var preevent = null
whitelist = []
blacklist = []
var orphans = []
titlepage = null
var filter,pikapika
handler = false

var newStyle = newInner("style","text/css",".hideme {\ndisplay: none;\n} .levy {\nwhite-space: nowrap;\noverflow: hidden;\ntext-overflow: ellipsis;\nmax-width: 30vw;\ndisplay: block;} .centered{\ntext-align: center;} .yellow{\ncolor: yellow !important}") //1.2
document.querySelector("head").append(newStyle)

filter = LoadCheckers("filter")
pikapika = LoadCheckers("pikapika")

//FUNCTIONS
function LoadCheckers(name){//1.2
    let varr = JSON.parse(localStorage.getItem(name))
    if(varr == undefined || varr == null) {
        console.info(`${name}: ${JSON.stringify(varr)}`)
        varr = true
        SafeSave(name,varr)
    }
    return varr
}

function SafeLoad(name){//1.2
    let temp = []
    if(localStorage.getItem(name)) temp = JSON.parse(localStorage.getItem(name))
    return temp
}

function GetNumero(text){
    let skip = false
    if(text.includes("Ch.") && text.includes(" - ")) text = text.split("Ch. ")[1]//1.2.4 //text = text.split(" - ")[0] //1.2
    for(let t of text.replaceAll("\n"," ").replaceAll("\t"," ").split(" ")){
        if(t == "Vol.") skip = true
        else if(t.includes(".")){//1.2
            let num = t.split(".")
            if(num.length > 2){
                let resto = ""
                for(let i = 1; i<num.length; i++) resto+=num[i]
                t = num[0]+"."+resto
            }
        }
        if(t!="" && Number.isFinite(t*1)){//1.2
            if(skip){
                skip = false
            }
            else return t*1
        }
    }
    console.warn(`no number found in ${text}`)
    return NaN
}

function createModal(){
    if(!document.getElementById("daModal")){
        console.log("creating modal")
        var modal = newInner("div","modal",'<div class="modal-content"></div>')
        modal.id = "daModal"
        var body = document.querySelector("body")
        body.insertBefore(modal,body.firstElementChild) //1.2
        var daStyle = newInner("style","text/css",'.modal {display: none;position: fixed;z-index: 500;padding-top: 100px;right: 0;top: 0;width: 100%;height: 100%;overflow: auto;background-color: rgb(0,0,0);background-color: rgba(0,0,0,0.4);}.modal-content {background-color: var(--bg-color);margin: auto;padding: 20px;border: 1px solid #888;width: 80%;}.close {color: #aaaaaa;float: right;font-size: 28px;font-weight: bold;}.close:hover,.close:focus {color: #000;text-decoration: none;cursor: pointer;}')
        document.querySelector("head").append(daStyle)
        var daTableStyle = newInner("style","text/css",'table {border-collapse: collapse;border-spacing: 0;width: 100%;border: 1px solid #ddd;}th, td {text-align: left;padding: 16px;}')
        document.querySelector("head").append(daTableStyle)
    }
    else console.info("modal already exists")
}

function FS(array, number){//FindSeries
    return array.findIndex(q => q.id == number)
}

function HideThis(series,group){
    for(let g of group){//1.2
        if(blacklist.findIndex(q => q[0] == series && q[1] == g) >= 0){ //q[1] == group
            console.info("hide this!")
            return true
        }
        if(blacklist.findIndex(q => q[0] == 0 && q[1] == g) >= 0){
            console.info(`group ${g} globally blocked`)
            return true
        }
    }
    return false
}

function OnlyThis(series,group){
    let result = 0
    for(let g of group){//1.2
        if(whitelist.findIndex(q => q[0] == series && q[1] == g) >= 0) { //the series is listed with this group
            console.info("onlythis!")
            return 2
        }
        if(whitelist.findIndex(q => q[0] == series && q[1] != g) >= 0) { //the series is listed but not this group
            console.info("not whitelisted")
            result = 1
        }
    }
    return result
}

function newInner(tag,classN,inner){
    var temp = document.createElement(tag)
    if(classN == "text/css") temp.type = classN
    else temp.className = classN
    temp.innerHTML = inner
    return temp
}

function cloneDOM(tag,nodo){
    var temp = document.createElement(tag)
    temp = nodo.cloneNode(true)
    return temp
}

function newDOM(tag,classN,style){
    var temp = document.createElement(tag)
    temp.className = classN
    temp.style.display = style
    return temp
}

function InverseIt(nodo){//ShowItgain
    let hideme = getCN2(nodo,"hideme")[0]
    let showme = getCN2(nodo,"showme")[0]
    if(!!hideme && !!showme){
        console.log("inversing in process")
        hideme.className = nodo.children[2].className.replace("hideme","showme")
        showme.className = nodo.children[3].className.replace("showme","hideme")
    }
}

function getTID(nodo){//1.2 //getID
    let result = null
    if(nodo && getTAG(nodo,"a").length) result = getTAG(nodo,"a")[0].href.split("/")[4] //1.2
    if(result && result.includes("?")) result = result.split("?")[0]
    return result
}

function getGID(nodo){//1.2 //getID2
    let result = []
    function Push(x){
        result.push(x)
        if(result.length == 0) result = [x]
    }
    if(nodo){
        for(let a of getTAG(nodo,"a")){
            let b = a.href
            if(b.includes("?")) b = b.split("?")[0]
            if(b.includes("/group/")) Push(getID3(b))
        }
        if(getCN("cursor-default").length) Push(0)
    }
    else return null
    return result
}

function getID3(text){
    return text.split("/")[4]
}

function HasBeenRead(nodo){
    if(!getTAG(nodo,"svg")[0].parentElement.innerHTML.includes(" feather-eye ")) {
        // CleanFB(nodo)
        return true
    }
    else return false
}

function FollowsFeed(){
    whitelist = SafeLoad("whitelist")
    blacklist = SafeLoad("blacklist")
    LoadSD()//1.1.3.3
    unreads = 0
    follows = []

    if(document.URL.includes("titles/feed")) {
        var feedwhole = "mb-12"

        if(getCN(feedwhole).length){//if page is loaded
            console.log("FollowsFeed")
            lista = getCN2(getCN(feedwhole)[0],feedone)
            console.log("lista loaded")
            createModal()

            for(let i = seriesdex.length-1; i>=0; i--){//to correct previous bugs
                if(seriesdex[i].id.includes("/") || seriesdex[i].id.includes("?")) {
                    console.log("bug correction! removing this one:")
                    console.log(seriesdex[i])
                    seriesdex.splice(i,1)
                }
                else{
                    if(seriesdex[i].last == null) seriesdex[i].last = MINNUM
                    if(seriesdex[i].nextc == MAXNUM || seriesdex[i].nextc == null || forbidden.includes(seriesdex[i].nextl)) seriesdex[i] = DefaultNext(seriesdex[i])
                    if(!seriesdex[i].mu) seriesdex[i].mu = 0 //1.2
                    if(!Number.isFinite(seriesdex[i].last)){
                        if(Number.isFinite(seriesdex[i].last*1)) seriesdex[i].last*=1
                        else{
                            let digits = ["1","2","3","4","5","6","7","8","9","0","."]
                            let daNumber = ""
                            for(let j of seriesdex[i].last){
                                if(!digits.includes(j)) break
                                else daNumber+=j
                            }
                            if(daNumber.length) seriesdex[i].last = daNumber*1
                            else seriesdex[i].last = MINNUM
                        }
                    }
                    if(seriesdex[i].last == seriesdex[i].nextc) seriesdex[i] = DefaultNext(seriesdex[i])
                }
            }

            let rep = 0

            function DecideNext(pseries,nextc,nextl,last,link,id_series,l,nextv,lastv){//nextv added - 1.2.5 //moved - 1.2
                let daName = l.children[1].title //1.2
                if(forbidden.includes(nextl)){
                    nextl = null
                    nextc = MAXNUM
                    if(nextv) nextv = MAXNUM
                }
                if(daName[0] == " ") daName = daName.slice(1)
                if(pseries >= 0) {
                    if(!!nextv) RevisaNext2(seriesdex[pseries],[nextc,nextl,nextv]) //1.2.5
                    else RevisaNext2(seriesdex[pseries],[nextc,nextl])
                }
                else {
                    if(!!nextv) seriesdex.push({id:id_series, mu:0, name:daName, last:last, nextc:nextc, nextl:nextl, time:0, nextv:nextv, lastv:lastv})
                    else seriesdex.push({id:id_series, mu:0, name:daName, last:last, nextc:nextc, nextl:nextl, time:0})
                }

                let index = FS(follows,id_series)
                if(index >= 0){
                    if(!!nextv){//1.2.5
                        if((seriesdex[pseries].last < last && nextv == seriesdex[pseries].lastv) || seriesdex[pseries].last == null) {
                            seriesdex[pseries].last = last
                            seriesdex[pseries].lastv = lastv
                            seriesdex[pseries].nextv = nextv
                        }
                        if(nextc > last && nextv == seriesdex[pseries].lastv){
                            RevisaNext2(follows[index],[nextc,nextl,nextv])
                            RevisaNext2(seriesdex[pseries],[nextc,nextl,nextv])
                        }
                        else seriesdex[pseries] = DefaultNext(seriesdex[pseries])
                        if(l != follows[index].pointer){//1.2
                            for(let n of getCN2(l,classChapter)){
                                let temp = cloneDOM("div",n)
                                if(!l.className.includes("dummy") && !follows[index].pointer.innerText.includes(n.innerText)) {//1.2.1
                                    getCN2(follows[index].pointer,classChapter)[0].parentElement.append(temp)
                                }
                            }
                            l.style.display = "none"
                        }
                    }
                    else{
                        if(seriesdex[pseries].last < last || seriesdex[pseries].last == null) seriesdex[pseries].last = last
                        if(nextc > last){
                            RevisaNext2(follows[index],[nextc,nextl])
                            RevisaNext2(seriesdex[pseries],[nextc,nextl])
                        }
                        else seriesdex[pseries] = DefaultNext(seriesdex[pseries])
                        if(l != follows[index].pointer){
                            //while(getCN2(l,classChapter)[0] != undefined) getCN2(follows[index].pointer,classChapter)[0].parentElement.append(getCN2(l,classChapter)[0])
                            //1.2
                            for(let n of getCN2(l,classChapter)){
                                let temp = cloneDOM("div",n)
                                if(!l.className.includes("dummy") && !follows[index].pointer.innerText.includes(n.innerText)) {//1.2.1
                                    getCN2(follows[index].pointer,classChapter)[0].parentElement.append(temp)
                                }
                            }
                            l.style.display = "none"
                        }
                    }
                }
                else{
                    if(!!nextv) follows.push({id:id_series, ch:last, url:link, nextc:nextc, nextl:nextl, pointer:l, nextv:nextv, lastv:lastv})
                    else follows.push({id:id_series, ch:last, url:link, nextc:nextc, nextl:nextl, pointer:l})
                }

                if(pseries == -1) pseries = FS(seriesdex,id_series) //should be the last
                let ati = seriesdex[pseries].nextc //1.2
                if(ati == 0 || ati == null || ati == MAXNUM || (ati > nextc && seriesdex[pseries].last < nextc)){
                    seriesdex[pseries].nextc = nextc
                    seriesdex[pseries].nextl = nextl
                }
            }

            function ProcessGroups(batchi,id_series){
                if(filter){
                    var icono,newdiv
                    var gid = getGID(batchi)
                    let OTresult = OnlyThis(id_series,gid)
                    if(OTresult == 2) {
                        console.log("whitelisted!!")
                        return true
                    }
                    if(HideThis(id_series,gid)) {
                        console.log("blacklisted!! hidethis")
                        funky = "BLACKLIST"
                        return false
                    }
                    if(OTresult == 1) {
                        console.log("not in whitelist!!")
                        funky = "WHITELIST"
                        return false
                    }
                    //not part of any list
                    return true
                }
                else return true
            }

            function ChangeToBL(nodo){//moved - 1.2
                if(getCN2(nodo.parentElement,"showme").length) console.log("still blacklisted?")
                else {
                    var parche = newInner("a","font-bold truncate showme blacklisted",`BLOCKED (${funky})`)
                    nodo.parentElement.append(parche)
                    nodo.className += " hideme"
                }
            }

            let lastnode
            if(!getCN("dummy").length) lastnode = cloneDOM("div",lista[lista.length-1])
            else lastnode = null
            do{//1.1.3.2
                for(let l of lista){//check the list
                    try{
                        var id_series = getTID(l)
                        var batch = getCN2(l,classChapter)
                        var chap, link, read, nextc, nextl, last, nextv, lastv
                        nextv = false
                        nextc = MAXNUM
                        nextl = null
                        lastv = MINNUM //1.2.5
                        let pseries = FS(seriesdex,id_series)
                        if(pseries < 0) {
                            last = MINNUM
                            //1.2.6
                            let sdummy = DefaultObj()
                            sdummy.name = l.children[1].title
                            sdummy.id = id_series
                            seriesdex.push(sdummy)
                            pseries = FS(seriesdex,id_series)
                        }
                        else {
                            last = seriesdex[pseries].last
                            if(seriesdex[pseries].name == "") seriesdex[pseries].name = l.children[1].title //1.2
                        }

                        function GetVol(text){//1.1.3.2
                            if(text.includes("Vol.")){//1.2.4
                                let t = text.split("Vol. ")[1].split(" ")[0]*1
                                if(!Number.isNaN(t)) {
                                    // console.info(`GetVol: ${t}`)
                                    return t*1
                                }
                            }
                            else {
                                // console.info(`GetVol: FALSE`)
                                return false
                            }
                        }

                        if(batch.length){//if there's chapters
                            let prevgid = false
                            for(let i=0; i<batch.length; i++){
                                var name = getTAG(batch[i],"a")[0].innerText.replace("\n"," ")
                                // console.info(`name: ${name}`)
                                var current = GetNumero(name)
                                var vol = GetVol(name)
                                var process = true //1.2 //false
                                var timestamp = 0
                                getTAG(batch[i],"a")[0].setAttribute("title",name.replaceAll('"','$').replaceAll('<','[').replaceAll('>',']'))

                                if(filter) process = ProcessGroups(batch[i],id_series)

                                if(process){//should be shown
                                    if(!HasBeenRead(batch[i])){
                                        thisLink = getTAG(batch[i],"a")[0].href.split("chapter/")[1] //1.2.3
                                        if(!getTAG(batch[i],"a")[0].href.includes("mangadex")) thisLink = getTAG(batch[i],"a")[0].href
                                        if(last > current && (name.toLowerCase().includes("extra") || name.toLowerCase().includes("omake") || Number.isInteger(current - 0.5) || Number.isInteger(current - 0.9))) {
                                            getTAG(batch[i],"svg")[0].classList.add("amarillo") //1.2
                                        }
                                        if(pseries >= 0 && !!seriesdex[pseries].lastv && vol){//1.1.3.2
                                            if(vol == seriesdex[pseries].lastv+1 || (vol == seriesdex[pseries].lastv && last < current && nextc > last && nextc >= current)){
                                                nextc = current
                                                nextl = thisLink//getTAG(batch[i],"a")[0].href.split("chapter/")[1]
                                                nextv = vol //1.2.5
                                                // console.info(`${name} has ${nextv}`) //1.2.5
                                            }
                                        }
                                        else if(last < current && nextc >= last && nextc > current){
                                            nextc = current
                                            nextl = thisLink//getTAG(batch[i],"a")[0].href.split("chapter/")[1]
                                            if(forbidden.includes(nextl)) CleanFB(batch[i]) //1.2.1 //shouldn't be part of forbidden
                                            prevgid = getGID(batch[i]) //1.1.3.3
                                        }
                                        else if(current == nextc){//1.1.3.3
                                            let gids = getGID(batch[i])
                                            if(prevgid == [0]){//give priority to real groups
                                                nextl = thisLink//getTAG(batch[i],"a")[0].href.split("chapter/")[1]
                                            }
                                            prevgid = gids
                                        }
                                    }
                                    else{// if(HasBeenRead(batch[i])){
                                        if(getTAG(batch[i],"svg")[0].classList.contains("yellow")) {//1.2
                                            getTAG(batch[i],"svg")[0].classList.remove("yellow")
                                        }
                                        if(last < current) last = current
                                        if(vol && lastv < vol) lastv = vol //1.2.5
                                        let thistmp = (new Date(getTAG(batch[i],"time")[0].dateTime)).getTime()
                                        if(thistmp > timestamp) timestamp = thistmp
                                    }
                                    if(filter) InverseIt(getTAG(batch[i],"a")[0].parentElement)
                                }
                                else{//has to be hidden
                                    console.log("not to process")
                                    console.log(batch[i])
                                    console.log(seriesdex[pseries])
                                    let cid = getTID(batch[i])
                                    if((!seriesdex[pseries].lastv && current > last) || (seriesdex[pseries].lastv && (vol > seriesdex[pseries].lastv || (vol == seriesdex[pseries].lastv && current > last)))){//1.2.1
                                        FBPush(cid)
                                        getTAG(batch[i],"svg")[0].style.color = "red"
                                        if(forbidden.includes(nextl)) {
                                            console.log("reseting due forbidden")
                                            seriesdex[pseries] = DefaultNext(seriesdex[pseries])
                                        }
                                    }
                                    else{
                                        console.log(`${cid} less than last (${current} <= ${last}\n${name})`)
                                        if(vol) console.log(`vol: ${vol}`) //1.2.4
                                        CleanFB(batch[i])
                                        if(getTAG(batch[i],"svg")[0].style.color) getTAG(batch[i],"svg")[0].style.removeProperty("color")
                                    }
                                    let card = getCN2(l,"continue")
                                    if(card.length && card[0].firstChild.href == getTAG(batch[i],"a")[0].href.split("chapter/")[1]){
                                        nextc = MAXNUM
                                        nextl = null
                                    }
                                    if(filter) ChangeToBL(getTAG(batch[i],"a")[0])
                                }
                            }
                        }
                        DecideNext(pseries,nextc,nextl,last,link,id_series,l,nextv,lastv)
                    }
                    catch(e){
                        console.log("error processing lista")
                        console.log(e)
                    }
                }
            }while(rep++ < 1)

                for(let l of lista){//add the continue link if necessary and add filtering button
                    let fbtn = newInner("button","nmf-btn","🔧")
                    fbtn.style.float = "right"
                    fbtn.setAttribute("onclick","NMDFilter(event)")
                    let titu = getCN2(l,"chapter-feed__title")[0]
                    let fbtn_container = cloneDOM("a",titu)
                    fbtn_container.innerHTML = ""
                    fbtn_container.removeAttribute("href")
                    fbtn_container.append(fbtn)
                    fbtn_container.style.display = "block"
                    if(filter && !getCN2(l,"nmf-btn").length) {
                        titu.parentElement.insertBefore(fbtn_container,titu)
                        titu.style.width = "95%"
                    }
                    let elem = getTAG(l,"a")[0]
                    if(elem){
                        let daONE = seriesdex[FS(seriesdex,getID3(elem.href))]
                        let extrainfo = ""
                        let currLink = `/chapter/${daONE.nextl}` //1.2.3
                        if(daONE.nextl && daONE.nextl.includes(".")) currLink = daONE.nextl //1.2.3
                        if(getCN2(l,classFeed).length == 0) l.style.display = "none"
                        else if(daONE.nextc > daONE.last && daONE.nextl){
                            if(daONE.last != MINNUM && (daONE.nextc - daONE.last >= 1.2)) extrainfo = " (WARNING: skipped chapters)"
                            if(daONE.last == MINNUM && daONE.nextc != 1) extrainfo = " (WARNING: no previous info)"
                            if(daONE.last == MINNUM && daONE.nextc <= 1.1) extrainfo = " (Start reading!)"//1.1.3.2
                            let continuetext = `CONTINUE to Chapter ${daONE.nextc}${extrainfo}`
                            if(daONE.nextv) continuetext = `CONTINUE to Volume ${daONE.nextv} Chapter ${daONE.nextc}${extrainfo}`
                            let newbutton = newInner("div",classFeed,`<button class=\"continue\"><a href=\"${currLink}\">${continuetext}</button>`)
                            if(getCN2(l,"continue").length == 0) getCN2(l,"chapter-feed__chapters")[0].insertBefore(newbutton,getCN2(l,classFeed)[0])
                            else getCN2(l,"continue")[0].parentElement.innerHTML = newbutton.innerHTML
                        }
                        if(((daONE.nextl == null || daONE.nextl == "") || daONE.last >= daONE.nextc) && getCN2(l,"continue")[0] != undefined){
                            getCN2(l,"continue")[0].parentElement.remove()
                        }
                    }
                }

            //TopWoNerae()//1.2
            console.info("TOP WO NERAE!")
            let amor = []
            for(let o of getCN("amarillo")){
                amor.push(o)
            }
            for(let a of amor){
                a.classList.replace("amarillo","yellow")
            }
            for(let n=follows.length-1; n >= 0; n--){//put unread chapters on top of the list
                if(getCN2(follows[n].pointer,"yellow").length || follows[n].pointer.innerHTML.includes(" feather-eye ")) {
                    lista[0].parentElement.insertBefore(follows[n].pointer,lista[0]) //1.2
                    console.log("unread UP!")
                }
            }
            for(let n=follows.length-1; n >= 0; n--){//put unread series on top of the list
                if(getCN2(follows[n].pointer,"continue").length) {
                    lista[0].parentElement.insertBefore(follows[n].pointer,lista[0]) //1.2
                    console.log("continue UP!")
                }
            }
            for(let n=follows.length-1; n >= 0; n--){//put comikey's unread series on top of the list since they expire quicker
                if(getCN2(follows[n].pointer,"continue").length && follows[n].pointer.innerText.includes("Comikey")) {
                    lista[0].parentElement.insertBefore(follows[n].pointer,lista[0]) //1.2
                    console.log("comikey UP!")
                }
            }
            //end TopWoNerae
            if(lastnode && lista[lista.length-1].innerText != lastnode.innerText){//1.2 //to not mess up the pagination for some reason
                let ultimo = cloneDOM("div",lastnode)
                console.log("dummy this time:")
                console.log(ultimo)
                ultimo.style.display = "none"
                ultimo.className+= " dummy"
                lista[0].parentElement.append(ultimo)
            }

            if(!frutyloop) {
                frutyloop = true
                // for(let i=1; i<6; i++) setTimeout(KeepChecking,i*2000)
                e2o = lista[0].parentElement
                observer = new MutationObserver(function() {
                    KeepChecking()
                })
                observer.observe(e2o, {subtree: true, attributes: true})
            }

            SafeSave("seriesdex",seriesdex)
        }
        else setTimeout(FollowsFeed,1000)
    }
}

function KeepChecking(){//1.2
    if(frutyloop){
        let totales = getCN("flex-shrink-0 cursor-pointer").length
        let noleidos = getCN("flex-shrink-0 cursor-pointer feather-eye").length
        if(unreads != totales-noleidos){
            if(noleidos > 0) FollowsFeed()
            unreads = totales-noleidos
        }
        // setTimeout(KeepChecking,2000)
    }
}

function DefaultObj(){//moved - 1,2.6
    return {id:0,mu:0,name:"",last:MINNUM,nextc:MAXNUM,nextl:null, time:0}
}

function Llenar2(){//1.1.3.2
    function Walala(){
        // console.log("walala")
        let items = getCN("manga-card") //1.2.5 getCN("manga-card bg-accent")
        let temp = []

        function WaitElement(nodo){
            console.log("waiting")
            if(nodo.length) setTimeout(Primero,1000)
            else setTimeout(WaitElement(nodo),500)
        }

        function Primero(){
            try{
                for(let i of items){
                    let manga = DefaultObj()
                    manga.id = getTID(i)
                    manga.name = getTAG(i,"span")[0].innerText//1.2//i.firstChild.innerText
                    if(FS(temp,manga.id) < 0) temp.push(manga)
                }
                ClickSiguiente()
            }
            catch(e){
                console.warn("catch primero")
                console.error(e)
                setTimeout(Primero,500)
            }
        }

        function ClickSiguiente(){
            try{
                let pagination = getCN("flex justify-center flex-wrap gap-2 my-6")[0].children
                let final = pagination[pagination.length-1].innerText*1
                let actual = 0
                for(let p of pagination){
                    if(p.className.includes("bg-primary")) actual = p.innerText*1
                    if(!!actual && p.innerText*1 == actual+1) {
                        p.click()
                        Segundo()
                    }
                    if(!!actual && actual == final) {
                        NextTab()
                        console.log(temp)
                        return temp
                    }
                }
            }
            catch(e){
                if(!getCN("flex justify-center flex-wrap gap-2 my-6")[0]){
                    console.warn("no pagination")
                    NextTab()
                    return temp
                }
            }
        }

        function Segundo(){
            try{
                items = getCN("manga-card") //1.2.5 getCN("manga-card bg-accent")
                let dummy = DefaultObj()
                dummy.id = getTID(items[0])
                dummy.name = items[0].firstChild.innerText
                if(FS(temp,dummy.id)>=0) {
                    setTimeout(Segundo,500)
                }
                else Primero()
            }
            catch(e){
                console.warn("catch segundo")
                console.error(e)
                setTimeout(Segundo,5000)
            }
        }

        WaitElement(items)

        return temp
    }
    var tabs = getCN("select__tab")
    console.log(tabs)
    let firsttab = tabs[0]
    if(!firsttab.className.includes("active")) firsttab.click()
    function FillTitles(){
        try{
            console.info("Filling Titles")

            let oldr = SafeLoad("reading")
            let oldo = SafeLoad("onhold")
            let oldp = SafeLoad("planto")
            let oldd = SafeLoad("dropped")
            let oldc = SafeLoad("completed")

            function Copiar(arrA,argB){
                let indice = FS(arrA, argB.id)
                if(indice >= 0){
                    arrA[indice].last = argB.last
                    arrA[indice].nextc = argB.nextc
                    arrA[indice].nextl = argB.nextl
                    //1.2
                    if(!arrA[indice].mu) arrA[indice].mu = argB.mu
                    arrA[indice].time = argB.time
                }
            }

            for(let s of seriesdex){
                Copiar(new_c, s)
                Copiar(new_o, s)
                Copiar(new_r, s)
                Copiar(new_d, s)
            }

            function UpdateArrays(old,neww){
                for(let a of neww){
                    let indice = FS(old,a.id)
                    if(indice >= 0) {//1.2
                        let name = a.name
                        a = old[indice]
                        if(old[indice].name != name) a.name = name
                    }
                }
                return neww
            }

            new_r = UpdateArrays(oldr,new_r)
            new_p = UpdateArrays(oldp,new_p)
            new_o = UpdateArrays(oldo,new_o)
            new_d = UpdateArrays(oldd,new_d)
            new_c = UpdateArrays(oldc,new_c)

            SafeSave("reading",new_r)
            SafeSave("planto",new_p)
            SafeSave("onhold",new_o)
            SafeSave("dropped",new_d)
            SafeSave("completed",new_c)
            alert("Done!")
        }
        catch(e){
            console.log("error filling titles")
            console.log(e)
        }
    }
    function NextTab(){
        console.log("next tab")
        for(let x=0; x<tabs.length; x++){
            if(tabs[x].className.includes("active")){
                if(x+1 < tabs.length){
                    tabs[x+1].click()
                    setTimeout(Unbelievable,3000)
                }
                else{
                    console.log("End of loading mangas")
                    FillTitles()
                }
            }
        }
    }
    function Unbelievable(){
        console.log("unbelievable")
        try{
            getCN("flex justify-center flex-wrap gap-2 my-6")[0].children[0].click()
        }
        catch(e){
            console.warn("no pagination")
        }

        for(let t of tabs){
            if(t.className.includes("tab-active")){
                // console.log("checking active tab")
                console.info(t.innerText+":")
                if(t.innerText == "Reading") new_r = Walala()
                if(t.innerText == "Plan To Read") new_p = Walala()
                if(t.innerText == "Completed") new_c = Walala()
                if(t.innerText == "On Hold") new_o = Walala()
                if(t.innerText == "Re-reading"){
                    console.info("who gives a shit lol")
                    NextTab()
                }
                if(t.innerText == "Dropped") {
                    new_d = Walala()
                    console.info("END!!")
                }
            }
        }
    }

    Unbelievable()
}

filling = false

function Loop(){
    try{
        if(disURL != document.URL){
            if(!document.URL.includes("https://mangadex.org/titles/follows")){
                console.log("loop")
                setTimeout(main,5000)
                disURL = document.URL
                trigger = false
                filling = false
            }
            else{
                if(!filling){
                    console.log("preparing to fill")
                    setTimeout(main,5000)
                    disURL = document.URL
                    trigger = false
                    filling = true
                }
            }
        }
    }
    catch(e){
        console.warn("error loop")
    }
    setTimeout(Loop,1000)
}

setTimeout(Loop,1000)

function UpdateSD(arrayname,sd){//1.2
    console.log("updating "+arrayname+"with new changes")
    let array = SafeLoad(arrayname)
    let index = FS(array,sd.id)
    if(index >= 0){
        let nextl = array[index].nextl
        let nextc = array[index].nextc
        let last = array[index].last
        let mu = array[index].mu
        let time = array[index].time
        array[index].last = sd.last
        if(nextl && nextc > sd.last && nextc < sd.nextc){
            console.log("there's a new chapter to consider")
            array[index].nextl = nextl
            array[index].nextc = nextc
        }
        if(sd.lastv){
            array[index].lastv = sd.lastv
            if(sd.nextv) array[index].nextv = sd.nextv
            console.log("volume sorting in consideration")
        }
        if(time){
            if(sd.time && time > sd.time){
                console.log("there was a latter update")
                array[index].time = time
            }
            if(!sd.time){
                console.log("there was no previous time")
                array[index].time = time
            }
        }
        if(mu){
            if(!sd.mu){
                console.log("there was no mangaupdate link before")
                array[index].mu = mu
            }
        }
    }
    else console.log("there's nothing to process??")
    SafeSave(arrayname,array)
    console.log(arrayname+" updated with sd:")
    console.log(array[index])
}

function CompareSD(arrayname,sd){//1.2
    console.log("Comparing SD with "+arrayname)
    let array = SafeLoad(arrayname)
    let index = FS(array,sd.id)
    if(index >= 0){
        let nextl = array[index].nextl
        let nextc = array[index].nextc
        let last = array[index].last
        let mu = array[index].mu
        let time = array[index].time
        array[index] = sd
        if(nextl && nextc > sd.last && nextc < sd.nextc){
            console.log("there's a new chapter to consider")
            array[index].nextl = nextl
            array[index].nextc = nextc
        }
        if(last > sd.last){
            console.log("a new last")
            array[index].last = last
        }
        if(time){
            if(sd.time && time > sd.time){
                console.log("there was a latter update")
                array[index].time = time
            }
            if(!sd.time){
                console.log("there was no previous time")
                array[index].time = time
            }
        }
        if(mu){
            // console.log("mu "+arrayname+": "+mu)
            if(!sd.mu){
                console.log("there was no mangaupdate link before")
                array[index].mu = mu
            }
            else if(sd.mu && mu != sd.mu){
                console.log("mangaupdate link is different... updating it!")
                array[index].mu = mu
            }
        }
        else if(sd.mu){
            console.log(`adding mangaupdate link: ${sd.mu}`)
            array[index].mu = sd.mu
        }
    }
    else console.log("there's nothing to process??")
    SafeSave(arrayname,array)
    console.log(arrayname+" updated with seriesdex:")
    console.log(array[index])
}

function getCN(classname){//1.2
    return document.getElementsByClassName(classname)
}

function getCN2(nodo,classname){//1.2
    return nodo.getElementsByClassName(classname)
}

function getTAG(nodo,tagname){//1.2
    return nodo.getElementsByTagName(tagname)
}

function SafeSave(item,array){//1.2
    localStorage.setItem(item,JSON.stringify(array))
    console.log(`${item} was saved sucessfully`) //1.2.6
}

function getFstatus(fstatus){//1.2
    let arrayname = null
    if(fstatus == "Reading") arrayname = "reading"
    if(fstatus == "Completed") arrayname = "completed"
    if(fstatus == "Dropped") arrayname = "dropped"
    if(fstatus == "On Hold") arrayname = "onhold"
    if(fstatus == "Plan to Read") arrayname = "planto"
    return arrayname
}

function RevisaNext(nodo){//1.2
    if(nodo.last >= nodo.nextc) nodo = DefaultNext(nodo)
}

function RevisaNext2(nodo,xxx){//1.2
    if(xxx.length == 2){
        if(nodo.last >= xxx[0] || nodo.last >= nodo.nextc) nodo = DefaultNext(nodo)
        if(nodo.nextl == xxx[1] && nodo.nextc != xxx[0]){//1.2.4
            console.log("updated link?")
            nodo.nextc = xxx[0]
        }
        if(xxx[0] > nodo.last && xxx[0] <= nodo.nextc){
            nodo.nextc = xxx[0]
            nodo.nextl = xxx[1]
        }
    }
    else{
        if(xxx[2] > nodo.lastv){
            nodo.nextv = xxx[2]
            nodo.nextc = xxx[0]
            nodo.nextl = xxx[1]
        }
        if(xxx[2] == nodo.lastv){
            if(nodo.last >= xxx[0] || nodo.last >= nodo.nextc) nodo = DefaultNext(nodo)
            if(xxx[0] > nodo.last && xxx[0] <= nodo.nextc){
                nodo.nextc = xxx[0]
                nodo.nextl = xxx[1]
                nodo.nextv = xxx[2] //redundant?
            }
        }
    }
}

function DefaultNext(p){//1.2
    let q = p //1.2.2
    q.nextc = MAXNUM
    q.nextl = null
    if(q.lastv) q.nextv = MAXNUM
    return q
}

function CleanFB(nodo){
    let id = getTID(nodo)
    let index = forbidden.indexOf(id)
    if(index >= 0) {
        console.log(`deleting ${id} from forbidden`)
        forbidden.splice(index,1)
        console.log("length: "+forbidden.length)
    }
    // else console.log(`${id} not part of forbidden`)
    SafeSave("forbidden",forbidden)
}

function FBPush(x){//1.2
    if(!forbidden.includes(x)){
        console.log(`adding ${x} to forbidden`)
        forbidden.push(x)
    }
    else console.log(`${x} already forbidden`)
    SafeSave("forbidden",forbidden)
}

//WINDOW FUNCTIONS

window.SC = function(){
    filter = document.getElementById("filter").checked
    SafeSave("filter",filter)
    alert("Changes saved successfully")//1.2
}

window.ReadNext = function(){//1.1.3.3
    console.log("ReadNext")
    FollowsFeed()
    var daModal = document.getElementById("daModal")
    if(!daModal) createModal()
    let reading = SafeLoad("reading")
    let daTable = '<table><tr><th>Name</th><th class="text-align: center;">Unread Chapter</th></tr>'
    for(let s of seriesdex){
        if(s.nextl && s.last < s.nextc){
            let name = s.name
            let currLink = `/chapter/${s.nextl}` //1.2.3
            if(s.nextl && s.nextl.includes(".")) currLink = s.nextl //1.2.3
            if(name == ""){
                let index = FS(reading,s.id)
                if(index >= 0) name = reading[index].name
            }
            if(s.nextc > s.last+1.1) name+=" ‼️"
            daTable+=`<tr><td><a href="/title/${s.id}/${name.replace(/\W\S*/g, '').replaceAll(" ","-")}">${name}</a></td><td><a href="${currLink}">CH. ${s.nextc}</a></td></tr>` //1.2.5
        }
    }
    daTable+="</table>"
    let closebutton = '<span class="close">&times;</span>'
    daModal.firstChild.innerHTML= closebutton+daTable
    var closebtn = getCN("close")[0]
    closebtn.onclick = function() {
        daModal.style.display = "none"
    }
}

window.DisplayOrphans = function(){//1.2
    FollowsFeed()
    var daModal = document.getElementById("daModal")
    if(!daModal) createModal()
    let reading = SafeLoad("reading")
    let daTable = '<table><tr><th>Name</th><th style="text-align: center;">Unread Chapter</th></tr>'
    for(let o of orphans){
        let name = o.name
        let arl,kink
        if(o.nextc != MAXNUM) {
            //if(o.nextc > o.last+1.1) name+=" ‼️"
            arl = 'CH. '+o.nextc
            kink = ` href="/chapter/${o.nextl}"`
            if(o.nextl && o.nextl.includes(".")) kink = ` href="${o.nextl}"` //1.2.3
        }
        else {
            arl = '🚫'
            kink = ''
        }
        daTable+=`<tr><td><a href="/title/${o.id}/${name.replace(/\W/g, '').replaceAll(" ","-")}">${name}</a></td><td style="text-align: center;"><a${kink}>${arl}</a></td></tr>`
    }
    daTable+="</table>"
    let closebutton = '<span class="close">&times;</span><p>The following series aren\'t part of any list, they\'re just marked to be notified, visit their title page to add them to a list (like Reading, for example)</p>'
    daModal.firstChild.innerHTML= closebutton+daTable
    var closebtn = getCN("close")[0]
    closebtn.onclick = function() {
        daModal.style.display = "none"
    }
}

window.NMDF = function(){//1.1.3.3
    let fcheck,ycheck
    function Checkear(a){//1.2
        if(a) return " checked"
        else return ""
    }
    fcheck = Checkear(filter)
    ycheck = Checkear(pikapika)
    var daModal = document.getElementById("daModal")
    if(!daModal) createModal()
    let closebutton = '<span class="close" onclick="Close()">&times;</span>'
    let d1 = `<label><input type="checkbox" id="filter"${fcheck}> Filter by groups</label><details><summary>Description</summary><p>You can filter chapters by adding certain groups to a blacklist (so it\'s hidden) or whitelist (so it only shows that group releases), by clicking at the 🔧 besides the title. This only applies to 1 series at a time.</p></details>`
    let d2 = ''
    let body = `<h2>New MangaDex Follows Script Settings</h2>${d1+d2}<button id="nmdf_save" onclick="SC()" style="background-color: orangered;padding: 0.5rem;margin: 0.5rem;">Save Changes</button><button id="nmdf_exit" onclick="Close()">Exit</button>`
    let series = '<hr><button onclick="ReadNext()" style="padding: 0.5rem;background-color: var(--md-primary);">Check unread chapters</button><button onclick="ShowSD()" style="padding: 0.5rem;background-color: var(--md-secondary);margin: 0.5rem;">Check notification list</button>'

    function FindOrphans(){//1.2
        console.log("searching for orphans")
        let com = SafeLoad("completed")
        let ptr = SafeLoad("planto")
        let dro = SafeLoad("dropped")
        let rea = SafeLoad("reading")
        let onh = SafeLoad("onhold")

        let x = 0
        for(let s of seriesdex){
            let z = 0
            for(let y of [com,ptr,dro,rea,onh]) if(FS(y,s.id)>=0) z++
            if(z==0){
                console.log("an orphan!")
                console.log(s)
                if(FS(orphans,s.id) < 0) orphans.push(s)
                x++
            }
        }
        return x
    }

    if(FindOrphans()) series+='<button onclick="DisplayOrphans()">Orphan series</button>' //1.2
    daModal.firstChild.innerHTML= closebutton+body+series
    daModal.style.display = "block"
    if(unchecked){
        window.onclick = function(event) {
            var daModal = document.getElementById("daModal")
            if (event.target == daModal) {
                daModal.style.display = "none"
            }
        }
        unchecked = false
    }
}

window.Close = function(){
    document.getElementById("daModal").style.display = "none"
}

window.NMDFilter = function(event){
    if(document.URL.includes("/title/")) main()
    var daElement = event.target.parentElement.parentElement
    preevent = event //1.1.3.3
    var daModal = document.getElementById("daModal")
    let ttext
    let gtext = []
    let glink = []
    let id = getTID(daElement)
    if(document.URL.includes("/title/")) {
        id = getID3(document.URL)
        ttext = getCN("mb-1")[0].innerText
    }
    let daSeries = seriesdex[FS(seriesdex,id)]
    for(let link of getTAG(daElement,"a")){
        if(link.innerText != ""){
            if(link.href.includes("/title/")) ttext = link.innerText.replaceAll("\n","")
            if(link.href.includes("/group/")) {
                if(!gtext.includes(link.innerText.replaceAll("\n",""))){
                    gtext.push(link.innerText.replaceAll("\n",""))
                    glink.push(link.href)
                }
            }
        }
    }
    let gtags = getCN2(daElement,"flex items-center")
    for(let g of gtags){
        if(g.innerText.includes("No Group")){
            gtext.push("No Group")
            glink.push("0/0/0/0/0/0")
            break
        }
    }

    if(!daModal) createModal()
    let closebutton = '<span class="close" onclick="Close()">&times;</span>'
    let series = `<p id="${id}">SERIES NAME: ${ttext}</p>`
    if(document.URL.includes("/title/")){//1.2
        fstatus = getCN(loadedp)[0].firstChild.innerText //following status
        series+="<p>Status: "+fstatus.toUpperCase()+"</p>"
        let arrayname = getFstatus(fstatus)
        let temp
        if(arrayname != "planto") temp = SafeLoad(arrayname)
        daSeries = temp[FS(temp,id)]
    }
    if(daSeries.mu) series+=`<a href="https://www.mangaupdates.com/series.html?id=${daSeries.mu}">🔗 MangaUpdates Link 🔗</a>`
    if(daSeries.name == "") seriesdex[FS(seriesdex,id)].name = ttext
    let lastext = daSeries.last
    let lastvol = ""
    if(daSeries.lastv) {
        lastvol = "Vol "+daSeries.lastv
        lastext = " Ch "+daSeries.last //1.2
    }
    let nextext = daSeries.nextc
    if(daSeries.nextv) nextext = `Vol. ${daSeries.nextv} Ch. ${daSeries.nextc}`
    let nextlink = ''
    if(!!daSeries.nextl && !daSeries.nextl.includes(".")) nextlink = ` href="https://mangadex.org/chapter/${daSeries.nextl}"`
    if(daSeries.nextl && daSeries.nextl.includes(".")) nextlink = ` href="${daSeries.nextl}"` //1.2.3
    console.log(lastext)
    if(daSeries.last == MINNUM || daSeries.last == "-10" || JSON.parse(daSeries.last) == null) {
        lastext = "Not registered"
        nextext = "Not registered"
    }
    let last = `<div><span>Last chapter read: ${lastext}</span><button onclick="NewLast(event)">✍️</button></div>`
    if(daSeries.lastv) last = `<div><span>Last chapter read: ${lastvol}</span><button onclick="NewLastV(event)">✍️ </button><span>${lastext}</span><button onclick="NewLast(event)">✍️</button></div>`
    if(nextext == MAXNUM) nextext = "Up to date"
    let next = `<div><a${nextlink}>Next chapter: ${nextext}</a><button onclick="ReloadFF()">⟳</button></div>`
    let groups = '<p>Groups:</p>'
    let daTable = '<table><tr><th>Name</th><th style="text-align: center;">Whitelisted</th><th style="text-align: center;">Blacklisted</th></tr>'//1.1.3.3
    for(let w=0;w<gtext.length;w++){
        let gid = getID3(glink[w])
        let wcheck = ""
        let bcheck = ""
        if(OnlyThis(id,[gid])==2) {
            wcheck = "checked"
            console.log(gtext[w]+" whitelisted")
        }
        if(HideThis(id,[gid])) {
            bcheck = "checked"
            console.log(gtext[w]+" blacklisted")
        }
        daTable+=`<tr><td><a href="https://mangadex.org/group/${gid}/">${gtext[w]}</a></td><td style="text-align: center;"><input type="checkbox" id="wl${w}" name="wl${w}" ${wcheck}></td><td style="text-align: center;"><input type="checkbox" id="bl${w}" name="bl${w}" ${bcheck}></td></tr>`//1.1.3.
    }
    daTable+="</table>"
    let savebtn = '<div style="text-align: right;"><button onclick="SaveFilter(event)" style="margin: 0.5rem;">SAVE CHANGES</button></div>'

    daModal.firstChild.innerHTML= closebutton+series+next+last+groups+daTable+savebtn
    daModal.style.display = "block"
    if(unchecked){
        window.onclick = function(event) {
            var daModal = document.getElementById("daModal")
            if (event.target == daModal) {
                daModal.style.display = "none"
            }
        }
        unchecked = false
    }
}

window.SaveFilter = function(event){
    let nodo = event.target.parentElement.parentElement

    function AddtoArray(array,id,gid){
        if(array.findIndex(q => q[0] == id && q[1] == gid) < 0) array.push([id,gid])
        return array
    }

    function RemoveFromArray(array,id,gid){
        let index = array.findIndex(q => q[0] == id && q[1] == gid)
        if(index >= 0) {
            array.splice(index,1)
            alert("Removed from the list")
        }
        return array
    }
    let count = 0
    let latabla = getTAG(nodo,"table")[0] //1.2
    for(let j of latabla.firstChild.children){
        if(j.cells[2].firstChild.checked) count++
    }
    if(count > 1){
        alert("There can only be one whitelisted group per series. If you want to block more than one group then you should add them to the blacklist")
    }
    else{
        for(let x=1; x<latabla.firstChild.childElementCount; x++){//1.2
            let gid = getTID(latabla.firstChild.children[x].cells[0])//1.1.3.3
            let wl = JSON.parse(latabla.firstChild.children[x].cells[1].firstChild.checked)
            let bl = JSON.parse(latabla.firstChild.children[x].cells[2].firstChild.checked)
            let id = nodo.children[1].id
            if(wl&&bl) alert("It can't be part of both lists")
            else if(wl) {
                whitelist = AddtoArray(whitelist,id,gid)
                alert("Whitelisted")
            }
            else if(bl) {
                blacklist = AddtoArray(blacklist,id,gid)
                alert("Blacklisted")
            }
            if(!wl) whitelist = RemoveFromArray(whitelist,id,gid)
            if(!bl) blacklist = RemoveFromArray(blacklist,id,gid)
        }
        SafeSave("whitelist",whitelist)
        SafeSave("blacklist",blacklist)
    }
}

window.NewLast = function(event){//1.1.3.3
    LoadSD()
    var daElement = event.target.parentElement.parentElement
    // var daElement = event.target
    // while(daElement.tagName != "TR") daElement = daElement.parentElement
    var newvalue = prompt("Enter a new value for last read","1")
    var id = getTAG(daElement,"p")[0].id

    function Proceso(newvalue,i){
        if(i>=0){
            seriesdex[i].last = newvalue*1
            if(seriesdex[i].last >= seriesdex[i].nextc) seriesdex[i] = DefaultNext(seriesdex[i])
            if(document.URL.includes("/title/")){//1.2
                if(getCN(loadedp).length){
                    UpdateSD(getFstatus(getCN(loadedp)[0].firstChild.innerText),seriesdex[i])
                }
            }
            console.log("seriesdex entry:")
            console.log(seriesdex[i])
            SafeSave("seriesdex",seriesdex) //1.1.3.3
            ReloadFF()//1.1.3.3
        }
        else{
            if(document.URL.includes("/title/")){
                if(getCN(loadedp).length){
                    let arrayname = getFstatus(getCN(loadedp)[0].firstChild.innerText)
                    let temp = SafeLoad(arrayname)
                    let j = FS(temp,id)
                    temp[j].last = newvalue*1
                    if(temp[j].nextl && temp[j].nextc <= newvalue*1) temp[j] = DefaultNext(temp[j])
                    SafeSave(arrayname,temp)
                }
            }
            else console.log("error NewLast")
        }
    }

    if(Number.isNaN(newvalue*1)) alert("Enter a number!")
    else if(!newvalue){
        console.log("cancel by user")
    }
    else {
        console.log("New Last!")
        newvalue*=1
        let i = FS(seriesdex,id)
        if(newvalue < seriesdex[i].last){
            if(confirm("The new value is lower than the last one read, are you sure you want to set it to "+newvalue+"?")) Proceso(newvalue,i)
        }
        else{
            Proceso(newvalue,i)
        }
    }
}

window.NewLastV = function(event){//1.2
    LoadSD()
    var daElement = event.target.parentElement.parentElement
    var newvalue = prompt("Enter a new value for last vol","1")
    var id = getTAG(daElement,"p")[0].id
    if(Number.isNaN(newvalue*1)) alert("Enter a number!")
    else if(!newvalue){
        console.log("cancel by user")
    }
    else {
        console.log("New LastV!")
        newvalue*=1
        let i = FS(seriesdex,id)
        if(i >= 0){
            seriesdex[i].lastv = newvalue*1
            if(seriesdex[i].last >= seriesdex[i].nextc) seriesdex[i] = DefaultNext(seriesdex[i])
            if(document.URL.includes("/title/")){//1.2
                if(getCN(loadedp).length){
                    UpdateSD(getFstatus(getCN(loadedp)[0].firstChild.innerText),seriesdex[i])
                }
            }
            console.log("seriesdex entry:")
            console.log(seriesdex[i])
            SafeSave("seriesdex",seriesdex) //1.1.3.3
        }
        else{
            if(document.URL.includes("/title/")){
                if(getCN(loadedp).length){
                    let arrayname = getFstatus(getCN(loadedp)[0].firstChild.innerText)
                    let temp = SafeLoad(arrayname)
                    let j = FS(temp,id)
                    temp[j].lastv = newvalue
                    if(temp[j].nextv && temp[j].nextv < newvalue) temp[j] = DefaultNext(temp[j])
                    SafeSave(arrayname,temp)
                }
            }
            else console.log("error NewLastV")
        }

        ReloadFF()//1.1.3.3
    }
}

window.ReloadFF = function(){
    main()
    //FollowsFeed()
    NMDFilter(preevent)
}

window.ShowSD = function(){//1.1.3.3
    console.log("ShowSD")
    FollowsFeed()
    var daModal = document.getElementById("daModal")
    if(!daModal) createModal()
    let reading = SafeLoad("reading")
    let daTable = '<table><tr><th>Name</th><th style="text-align: center;">Last Read</th><th style="text-align: center;">Next Chapter</th></tr>'
    for(let s of seriesdex){
        let name = s.name
        if(name == ""){
            let index = FS(reading,s.id)
            if(index >= 0) name = reading[index].name
        }
        if(s.nextc != MAXNUM && s.nextc > s.last+1.1) name+=" ‼️"
        let lastone = s.last
        if(lastone < 0 || lastone == null) lastone = '🚫'
        let nextone, nextlink
        if(s.nextl == null || s.nextl == "") {
            nextlink = ''
            nextone = '🚫'
        }
        else {
            nextlink = ` href="/chapter/${s.nextl}"`
            if(s.nextl.includes(".")) nextlink = ` href="${s.nextl}"` //1.2.3
            nextone = 'CH. '+s.nextc
        }
        daTable+=`<tr><td><a href="/title/${s.id}/${name.replace(/\W/g, '').replaceAll(" ","-")}">${name}</a></td><td style="text-align: center;"><span>${lastone} </span><button onclick="NewLast2(event)">✍️</button></td><td style="text-align: center;"><a${nextlink}>${nextone}</a></td></tr>`
    }
    daTable+="</table>"
    let closebutton = '<span class="close">&times;</span>'
    daModal.firstChild.innerHTML= closebutton+daTable
    var closebtn = getCN("close")[0]
    closebtn.onclick = function() {
        daModal.style.display = "none"
    }
}

window.NewLast2 = function(event){//1.1.3.3
    LoadSD()
    var daElement = event.target
    while(daElement.tagName != "TR") daElement = daElement.parentElement //1.2
    var newvalue = prompt("Enter a new value for last read","1")
    var id = getTID(daElement)
    let sid = FS(seriesdex,id) //1.2
    if(Number.isNaN(newvalue*1)) alert("Enter a number!")
    else if(!newvalue){
        console.log("cancel by user")
    }
    else {
        console.log("New Last2!")
        function McCloud(arraynode){//1.2
            arraynode.last = newvalue*1
            if(arraynode.last >= arraynode.nextc) arraynode = DefaultNext(arraynode)
            return arraynode
        }
        seriesdex[sid] = McCloud(seriesdex[sid])

        console.log(seriesdex[sid])
        SafeSave("seriesdex",seriesdex) //1.1.3.3
        FollowsFeed()
        //1.2
        let arrays = ["reading","completed","planto","onhold","dropped"]
        for(let a of arrays){
            let temp = SafeLoad(a)
            let index = FS(temp,seriesdex[sid].id)
            if(index >= 0){
                temp[index] = McCloud(temp[index])
                SafeSave(a,temp)
            }
        }
        ShowSD() //1.2
    }
}

window.NewLast3 = function(event){//1.2
    LoadSD()
    var daElement = event.target
    while(daElement.tagName != "TR") daElement = daElement.parentElement
    var newvalue = prompt("Enter a new value for last read","1")
    var id = getTID(daElement)

    if(Number.isNaN(newvalue*1)) alert("Enter a number!")
    else if(!newvalue){
        console.log("cancel by user")
    }
    else {
        console.log("New Last3!")
        let stat = getTAG(daElement,"td")[2].innerText
        let temp = []
        let sid = FS(seriesdex,id)
        let arrayname = getFstatus(stat) //1.2
        temp = SafeLoad(arrayname)
        let tid = FS(temp,id)

        function UpdateData(array,index){
            array[index].last = newvalue*1
            if(array[index].last >= array[index].nextc) array[index] = DefaultNext(array[index])
        }

        if(sid >= 0) {
            UpdateData(seriesdex,sid)
            console.log("seriesdex entry:")
            console.log(seriesdex[sid])
        }
        UpdateData(temp,tid)
        console.log(arrayname+" entry:")
        console.log(temp[tid])
        SafeSave("seriesdex",seriesdex) //1.1.3.3
        SafeSave(arrayname,temp) //1.2
        main() //1.2
    }
}

window.FS = function(array,number){//for debugging
    FS(array, number)
}

window.FF = function(){//for debugging
    FollowsFeed()
}

//THE MAIN FUNCTION
function main(){
    let logo = "ml-4 cursor-pointer rounded-full overflow-hidden bg-accent flex items-center justify-center"
    if(getCN(logo).length && getCN(logo)[0].firstChild.tagName == "IMG"){//is logged
        LoadSD()
        frutyloop = false
        if(document.URL.includes("https://mangadex.org/titles/follows")){
            console.log("Script ready")

            function EsperaBotones(){
                try{
                    let botones = getTAG(getCN("px-6 mb-4 mt-2")[0],"a")
                    }
                catch(e){
                    setTimeout(EsperaBotones,500)
                }
            }

            EsperaBotones()

            document.Fill = function(){
                console.log("Loading series...")
                alert("Please wait until the next alert, this can take several minutes depending of how many series you follow.")
                Llenar2()
            }

            function NewButton(){//moved - 1.2
                try{
                    let newb = document.createElement("button")
                    newb.innerHTML = '<button id="fill-btn" data-v-621772ff="" type="button" class="bg-primary v-btn v-btn--is-elevated v-btn--has-bg theme--dark v-size--default"><span class="v-btn__content"><span data-v-621772ff="" aria-hidden="true" class="v-icon notranslate theme--dark" onclick="Fill()"><a>FILL</a></span></span></button>'
                    if(!document.getElementById("fill-btn")) getCN("controls mb-auto ml-auto")[0].appendChild(newb)

                    let titulo = getCN("flex items-center mb-4")[0]
                    let dl = cloneDOM('div',titulo)//document.createElement("div")
                    dl.id="dlbtn"
                    dl.innerHTML='<button class="rounded relative md-btn flex items-center px-3 my-6 justify-center text-white bg-primary hover:bg-primary-darken active:bg-primary-darken2 glow px-4 px-6" onclick="DownloadCSV()" style="margin-left: 0.5rem;margin-right: 1rem;background-color: var(--md-primary);border-width: 0.5rem;border-color: var(--md-primary);">Download CSV</button><button class="rounded relative md-btn flex items-center px-3 my-6 justify-center text-white bg-primary hover:bg-primary-darken active:bg-primary-darken2 glow px-4 px-6" onclick="DownloadJSON()" style="margin-left: 0.5rem;margin-right: 1rem;background-color: var(--md-primary);border-width: 0.5rem;border-color: var(--md-primary);">Download JSON</button>'
                    if(!!!document.getElementById("dlbtn") && !!dl) titulo.insertAdjacentElement('afterend',dl)
                }
                catch(e){
                    setTimeout(NewButton,500)
                }
            }
            if(!document.getElementById("dlbtn")) NewButton()
        }

        if(document.URL.includes("https://mangadex.org/titles/feed")){
            console.log("checking feed")
            function ScriptForm(){//moved - 1.2
                if(document.URL.includes("https://mangadex.org/titles/feed") && !document.getElementById("script_btn")){
                    console.log("executing ScriptForm")
                    var options_loc = "flex items-center mb-4"
                    if(getCN(options_loc).length){
                        var newButton = newInner("div","",'<button id="script_btn" onclick="NMDF()" style="right: 2rem;position: absolute;">📜 SCRIPT SETTINGS</button>')
                        getCN(options_loc)[0].append(newButton.children[0])
                        console.log("form added")
                    }
                    else setTimeout(ScriptForm,500)
                }
            }
            follows = []
            ScriptForm()

            if(getCN(feedone).length) FollowsFeed()
            else setTimeout(main,2000)
        }

        if(document.URL.includes("https://mangadex.org/title/")){
            console.log("Checking a series")
            var fstatus
            whitelist = SafeLoad("whitelist")
            blacklist = SafeLoad("blacklist")
            var chgrid = "chapter-grid"
            function UpdatingSeriesData(){
                var toConsider = ["Reading","Completed","On Hold","Dropped","Added To Library"]
                let timestamp = 0 //1.2
                let mu = 0 //1.2
                fstatus = getCN(loadedp)[0].firstChild.innerText //following status
                if(getCN(loadedp).length && getCN(chgrid).length){//if page is loaded
                    console.log("loaded")
                    var toProcess = false
                    var id_series = getID3(document.URL)//1.2 //document.URL.split("/")[4]
                    let daIndex = FS(seriesdex,id_series)
                    var daLast = MINNUM
                    if(daIndex >= 0) daLast = seriesdex[daIndex].last
                    var daLastV = null
                    var daNext,daNLink
                    DefNext()
                    var nextvol = MAXNUM
                    var tags = getCN("tag bg-accent")
                    var volChange = getCN("col-span-4")
                    var sus = false
                    let prevvol = null
                    console.log("fstatus: "+fstatus)
                    if(fstatus == ""){
                        setTimeout(UpdatingSeriesData,500)
                        return
                    }
                    for(let x of getTAG(getCN("readmore")[0],"a")){//1.2
                        if(x.href.includes("mangaupdates")) mu = x.href.split("=")[1]*1
                    }

                    function GetChapter(dc,dv){//1.2
                        let current
                        if(dc.innerText.toLowerCase().includes("oneshot")) current = 0 //1.1.3.3
                        else if(dc.innerText.includes("Ch.")) current = GetNumero(dc.innerText)
                        else {
                            let turkey = dc.parentElement
                            while(!turkey.innerText.includes("Chapter ") && turkey != dv) turkey = turkey.parentElement
                            if(turkey.innerText.includes("Volume ")) current = 0
                            else current = GetNumero(turkey.innerText)
                        }
                        return current
                    }

                    function DefNext(){//1.2
                        daNext = MAXNUM
                        daNLink = null
                    }

                    function getVol(txt){//moved 1.2.5
                        let temp = txt.replaceAll("\n"," ").replaceAll("\t"," ")
                        for(let t of temp.split(" ")){
                            if(Number.isFinite(t*1)) return t*1
                        }
                        return 0
                    }

                    if(!sus){
                        for(let v of document.getElementsByClassName("grid grid-cols-12 volume-head mb-2")){
                            if(v.innerText.includes("No Volume")){
                                console.log("volume sorting doesn't apply!")
                                break
                            }
                            if((v.innerText.includes("Ch. 1 -") || v.innerText.includes("Ch. 0 -")) && getVol(v.innerText) > 1){
                                console.log("SUS!")
                                sus = true
                                break
                            }
                        }
                    }

                    function Apoo(){
                        if(toConsider.includes(fstatus)){//(fstatus == "Reading"){
                            console.log("reading series:")
                            console.log(seriesdex[daIndex])
                            toProcess = true
                            let continuar = true //1.2

                            function DefaultProcess(dv,dc,current,currvol){//1.2
                                let cid = getTID(dc)
                                if(forbidden.includes(cid)){//if chapter is marked as forbidden
                                    console.log("forbidden chapter "+cid)
                                    if((!HideThis(id_series,getGID(dc)) || OnlyThis(id_series,getGID(dc))==2) && OnlyThis(id_series,getGID(dc))!=1 && !HasBeenRead(dc)){//1.2.5
                                        CleanFB(dc)
                                    }
                                    else if(GetChapter(dc,dv) > seriesdex[daIndex].last) getTAG(dc,"svg")[0].style.color = "red"
                                    else{
                                        if(getTAG(dc,"svg")[0].style.color) getTAG(dc,"svg")[0].style.removeProperty("color")
                                        CleanFB(dc)
                                    }
                                    if(seriesdex[daIndex].nextl == cid) {
                                        seriesdex[daIndex] = DefaultNext(seriesdex[daIndex]) //if it's stored as next one, ignore it
                                    }
                                }
                                else if((!HideThis(id_series,getGID(dc)) || OnlyThis(id_series,getGID(dc))==2) && OnlyThis(id_series,getGID(dc))!=1 && !HasBeenRead(dc) && daNext >= current && daNext > daLast && current > daLast){
                                    daNext = current
                                    console.log("daNext: "+daNext)
                                    daNLink = cid//getTID(dc)
                                    console.log("daNLink: "+daNLink)
                                }
                                else if((HideThis(id_series,getGID(dc)) || OnlyThis(id_series,getGID(dc))==1) && !HasBeenRead(dc)){// && daNext > current && daNext > daLast){//not consider if it's blacklisted
                                    if(daNext >= current && daNext > daLast && current > daLast){//1.2
                                        FBPush(cid)
                                    }
                                    if(current <= daLast){ //check for a forbidden chapter that can be ignored
                                        console.log(`ignore ${cid} for forbidden`)
                                        CleanFB(dc)
                                    }
                                    if(daIndex >= 0 && cid == seriesdex[daIndex].nextl){//ignores a next chapter if it's blacklisted
                                        console.log("reseting daNext")
                                        DefNext()
                                    }
                                }
                                //1.1.3.3
                                else if(!(HideThis(id_series,getGID(dc)) || OnlyThis(id_series,getGID(dc))==1) && HasBeenRead(dc) && daLast < current) {
                                    daLast = current
                                    let thistmp = (new Date(getTAG(dc,"time")[0].dateTime)).getTime()
                                    if(thistmp > timestamp) timestamp = thistmp
                                    if(daNext <= daLast) {
                                        DefNext()
                                    }
                                    console.log("found a last one: "+daLast)
                                }
                                else {
                                    // console.log(`${cid} shouldn't be forbidden`)
                                    CleanFB(dc)
                                }
                            }

                            function VolProcess(dv,dc,current,currvol){//1.2
                                function ASSign(){
                                    daNext = current
                                    console.log("daNext: vol "+currvol+" chap "+daNext)
                                    daNLink = getTID(dc)
                                    console.log("daNLink: "+daNLink)
                                }

                                function FoundLast(){
                                    daLast = current
                                    let thistmp = (new Date(getTAG(dc,"time")[0].dateTime)).getTime()
                                    if(thistmp > timestamp) timestamp = thistmp
                                    if(daNext <= daLast) DefNext()
                                    console.log("found a last one: "+daLast)
                                }

                                if(HasBeenRead(dc)){
                                    console.log("sus checking vol "+GetNumero(dv.parentElement.innerText)+" ch "+current)
                                    if(currvol > daLastV){
                                        daLastV = currvol
                                        FoundLast()
                                    }
                                    else if(currvol == daLastV){
                                        if(daLast < current) FoundLast()
                                    }
                                    //currvol < daLastV are irrelevant
                                }
                                else{//unread chapters
                                    let cid = getTID(dc)
                                    if((!HideThis(id_series,getGID(dc)) || OnlyThis(id_series,getGID(dc))==2) && OnlyThis(id_series,getGID(dc))!=1){//to consider
                                        if(daLastV == currvol && daNext >= current && daNext > daLast) ASSign()
                                        else if(daLastV < currvol && nextvol >= daLastV){
                                            if(nextvol > currvol) {
                                                nextvol = currvol
                                                ASSign()
                                            }
                                            else if(nextvol == currvol) ASSign()
                                        }
                                    }
                                    else if((HideThis(id_series,getGID(dc)) || OnlyThis(id_series,getGID(dc))==1)){// && daNext > current && daNext > daLast){//not consider if it's blacklisted
                                        if(daNext >= current && daNext > daLast){//1.2
                                            FBPush(cid)
                                            if(daIndex >= 0 && cid == seriesdex[daIndex].nextl){//ignores a next chapter if it's blacklisted
                                                console.log("reseting daNext")
                                                DefNext()
                                            }
                                        }
                                        if(current < daLast) {
                                            console.log(`${cid} can be ignored (sus)`)
                                            CleanFB(dc)
                                            dc.style.removeProperty("color")
                                        }
                                    }
                                }
                            }

                            if(daIndex >= 0) for(let dv of getCN("rounded flex flex-col gap-2")){
                                for(let dc of getCN2(dv,chgrid)){
                                    let current = GetChapter(dc,dv)
                                    let currvol = getVol(dv.parentElement.innerText) //1.2.5
                                    if(sus) VolProcess(dv,dc,current,currvol)
                                    else DefaultProcess(dv,dc,current,currvol) //1.2
                                }
                            }
                            return true
                        }
                        return false
                    }
                    function UpdateStorage(obj,item){//1.1.3.3
                        let temp = SafeLoad(item) //1.2
                        let index = FS(temp,obj.id)
                        if(index >= 0){//1.2
                            console.log("it's part of "+item)
                            console.log(obj)
                            if(obj.name == "MangaDex") obj.name = temp[index].name
                            if(obj.last >= temp[index].last){
                                console.log("new last is equal or greater than last registered")
                                console.log("old: "+temp[index].last)
                                console.log("new: "+obj.last)
                                if(obj.lastv == temp[index].lastv) {
                                    temp[index] = obj
                                    console.log("same volume, new chapter")
                                }
                                if(obj.lastv && temp[index].lastv && obj.lastv >= temp[index].lastv) {
                                    temp[index] = obj
                                    console.log("new volume")
                                }
                                if(!obj.lastv && temp[index].lastv){
                                    temp[index] = obj
                                    console.log("was stored as volume but it shouldn't")
                                }
                                if(!temp[index].lastv){
                                    temp[index] = obj
                                    if(obj.lastv) console.log("now consider with volume sorting")
                                    else console.log("no volume sorting")
                                }
                            }
                            else{
                                console.log("new last is lower than last registered, checking for volume sorting")
                                if(temp[index].lastv && obj.lastv && temp[index].lastv <= obj.lastv) {
                                    temp[index] = obj
                                    console.log("new volume")
                                }
                                if(!temp[index].nextv && obj.nextv) {
                                    temp[index] = obj
                                    console.log("new chapter")
                                }
                                if(temp[index].nextv && obj.nextv && temp[index].nextv < obj.nextv) {
                                    temp[index] = obj
                                    console.log("new unread chapter on new volume")
                                }
                                if(obj.nextl && temp[index].last < obj.nextc){
                                    temp[index].nextc = obj.nextc
                                    temp[index].nextl = obj.nextl
                                    console.log("new unread chapter but earlier last read")
                                }
                                if(!obj.nextl){
                                    temp[index].nextc = obj.nextc
                                    temp[index].nextl = obj.nextl
                                    console.log("no next unread chapter")
                                }
                                if(obj.mu && !temp[index].mu){
                                    temp[index].mu = obj.mu
                                    console.log("added mangaupdates link")
                                }
                                if(!temp[index].time && obj.time){
                                    temp[index].time = obj.time
                                    console.log("added update time")
                                }
                            }
                            RevisaNext(temp[index])
                        }
                        else{//if(index == -1)
                            temp.push(obj)
                            console.log("added to "+item+"!")
                        }
                        SafeSave(item,temp)
                        console.log("stored changes in "+item+"!")
                        console.log(temp[index])
                        console.log("index: "+index)
                        // return temp[index] //1.2
                    }
                    var removedsd = false

                    function RemoveFromSD(mangaid){//1.1.3.3
                        removedsd = false
                        let index = FS(seriesdex,mangaid)
                        if(index >= 0) {
                            console.log("removed from seriesdex:")
                            console.log(seriesdex[index])
                            seriesdex.splice(index,1)
                            SafeSave("seriesdex",seriesdex)
                            removedsd = true
                        }
                    }
                    function Registrar(){ //1.1.3.3
                        let manga
                        let marked = false
                        if(sus) manga = {id:id_series, mu:mu, name:document.title.replace(" - MangaDex",""), last:daLast, lastv: daLastV, nextv:nextvol, nextc:daNext, nextl:daNLink, time:timestamp}
                        else manga = {id:id_series, mu:mu, name:document.title.replace(" - MangaDex",""), last:daLast, nextc:daNext, nextl:daNLink, time:timestamp}

                        let campana = (getTAG(getCN("sm:ml-2")[0],"svg")[0].firstChild.getAttribute("d") == "M18 8A6 6 0 1 0 6 8c0 7-3 9-3 9h9m6.63-4A17.888 17.888 0 0 1 18 8m-4.27 13a2 2 0 0 1-3.46 0M17 18l2 2 4-4") //1.2.6
                        let blink = getFstatus(fstatus)
                        UpdateStorage(manga,blink)
                        if(daIndex >= 0) {
                            // LoadSD()
                            CompareSD(blink,seriesdex[daIndex]) //1.2
                        }
                        if(campana) {
                            UpdateStorage(manga,"seriesdex")
                        }
                        else marked = true
                        if(marked) RemoveFromSD(manga.id)

                        //Delete duplicates //1.2
                        console.log("Checking for duplicates")
                        for(let c of ["Completed","Plan to Read","On Hold","Dropped","Reading"]){
                            if(c != fstatus){
                                let namevar = getFstatus(c)
                                if(namevar){
                                    console.log("Checking "+namevar)
                                    let temp = SafeLoad(namevar) //1.2
                                    let index = FS(temp,id_series)
                                    if(index >= 0){
                                        console.log("Duplicated in "+namevar)
                                        console.log(temp[index])
                                        temp.splice(index,1)
                                        SafeSave(namevar,temp)
                                        console.log("Deleted from "+namevar)
                                    }
                                }
                            }
                        }
                        console.log("reference:")
                        console.log(manga)

                        console.log("the one registered in "+fstatus+":")
                        let final = SafeLoad(blink)
                        let k = FS(final,id_series)
                        console.log(final[k])
                        return true
                    }
                    function LoadWBS(){
                        let ww = getCN("flex gap-x-2")[0]
                        let newbtn = cloneDOM("div",ww)
                        newbtn.id="FilterG"
                        newbtn.innerHTML = '<button data-v-cae07f5c="" data-v-4e000227="" class="rounded relative md-btn flex items-center" style="min-height: 48px; min-width: 220px;" onclick="NMDFilter(event)"><!----> <span data-v-cae07f5c="" class="flex items-center justify-center font-medium select-none" style="pointer-events: none;"><!---->🔧 WHITE/BLACKLIST GROUPS HERE 🔧</span></button>'
                        if(!document.getElementById("FilterG")) ww.parentElement.insertBefore(newbtn,ww)
                        createModal()
                    }
                    if(Apoo() && daIndex >= 0){
                        LoadWBS()
                        if(seriesdex[daIndex].name != document.title.replace(" - MangaDex","") && document.title != "MangaDex") seriesdex[daIndex].name = document.title.replace(" - MangaDex","")
                        console.log("previous last: "+seriesdex[daIndex].last)
                        console.log("updating values")
                        if(Registrar() && !removedsd) console.log("new last: "+seriesdex[daIndex].last)
                    }
                    else if(daIndex >= 0){//fixes bug that adds everything
                        if(!toConsider.includes(fstatus)) seriesdex.splice(daIndex,1)//1.1.3.2
                        SafeSave("seriesdex",seriesdex)//1.1.3.3
                    }
                    else if(daIndex == -1 && toProcess){//not registered
                        if(fstatus == "Reading") console.log("new series!")//1.1.3.3
                        Registrar()
                        LoadWBS()
                    }
                    if(FS(seriesdex,id_series) >= 0) {
                        LoadWBS()
                        console.log("seriesdex entry:")
                        console.log(seriesdex[FS(seriesdex,id_series)])
                    }
                }
                else if(getCN("text-center").length && getCN("text-center")[0].innerText == "No Chapters"){
                    console.log("no chapters!")
                    let daIndex = FS(seriesdex,getID3(document.URL))
                    for(let x of getTAG(getCN("readmore")[0],"a")){//1.2
                        if(x.href.includes("mangaupdates")) {
                            mu = x.href.split("=")[1]*1
                            console.log("mu: "+mu)
                        }
                    }

                    function LoadWBS(){//1.2
                        let ww = getCN("text-center")[0].parentElement
                        let newbtn = cloneDOM("div",ww)
                        newbtn.id="FilterG"
                        newbtn.innerHTML = '<button data-v-cae07f5c="" data-v-4e000227="" class="rounded relative md-btn flex items-center" style="min-height: 48px; min-width: 220px;" onclick="NMDFilter(event)"><!----> <span data-v-cae07f5c="" class="flex items-center justify-center font-medium select-none" style="pointer-events: none;"><!---->🔧 WHITE/BLACKLIST GROUPS HERE 🔧</span></button>'
                        if(!document.getElementById("FilterG")) ww.parentElement.insertBefore(newbtn,ww)
                        createModal()
                    }

                    function Empty(){//1.2
                        console.log("Empty()")
                        let temp = {id: getID3(document.URL),mu:mu,name: document.title.replace(" - MangaDex",""),last: MINNUM,nextc: MAXNUM,nextl: null, time:timestamp}
                        function UpdateEmpty(arrayname,obj){
                            console.log("mu ue "+arrayname+": "+mu)
                            console.log("reference data:")
                            console.log(obj)
                            let dummy = SafeLoad(arrayname)
                            let index = FS(dummy,obj.id)
                            dummy[index].mu = mu
                            obj.mu = mu
                            if(!obj.time && dummy[index].time) obj.time = dummy[index].time
                            if(index >= 0) {
                                console.log(arrayname+" data:")
                                console.log(dummy[index])
                                if(dummy[index].last < 0 && dummy[index].nextl == null) dummy[index] = obj
                                //else it has previous data
                            }
                            else dummy.push(obj)
                            SafeSave(arrayname,dummy)
                            console.log("new data ("+arrayname+"):")
                            console.log(dummy[index])
                        }
                        if(fstatus == "Reading") {
                            UpdateEmpty("reading",temp)
                            UpdateEmpty("seriesdex",temp)
                            if(daIndex >= 0) CompareSD("reading",seriesdex[daIndex])
                        }
                        else if(fstatus == "On Hold") {
                            UpdateEmpty("onhold",temp)
                            if(daIndex >= 0) CompareSD("onhold",seriesdex[daIndex])
                        }
                        else if(fstatus == "Dropped") {
                            UpdateEmpty("dropped",temp)
                            if(daIndex >= 0) CompareSD("dropped",seriesdex[daIndex])
                        }
                    }

                    if(getCN("w-full").length){
                        for(let f of getCN("w-full")){
                            if(fstatus == "Completed" && f.innerText.includes("Final Chapter")){
                                let completed = SafeLoad("completed")
                                let temp = {id: getID3(document.URL),mu:mu,name: document.title.replace(" - MangaDex",""),last: GetNumero(f.innerText), time:timestamp}
                                let index = FS(completed,temp.id)
                                if(index >= 0) completed[index] = temp
                                else completed.push(temp)
                                SafeSave("completed",completed)
                                console.log("new data (completed):")
                                console.log(temp)
                                if(FS(seriesdex,temp.id) >= 0){
                                    seriesdex.splice(FS(seriesdex,temp.id),1)
                                    console.log("removed from seriesdex!")
                                    SafeSave("seriesdex",seriesdex)
                                }
                            }
                        }
                        Empty() //1.2
                    }
                    else if(toConsider.includes(fstatus)){//1.1.3.3
                        Empty() //1.2
                    }
                    LoadWBS() //1.2
                }
                else setTimeout(UpdatingSeriesData,500)
            }
            try{
                UpdatingSeriesData()
            }
            catch(e){
                console.log("catch UpdatingSeriesData")
                setTimeout(UpdatingSeriesData,1000)
            }
        }

        if(document.URL.includes("https://mangadex.org/chapter/")){//1.2
            try{
                if(!titlepage) titlepage = getTAG(getCN("menu flex-col")[0],"a")[0].href
                let current = GetNumero(getCN("placeholder-text")[1].innerText)
                let sid = getID3(titlepage)
                let chid = getID3(document.URL)
                let pseries = FS(seriesdex,sid)
                if(forbidden.includes(chid)){
                    console.log("FORBIDDEN!!")
                    window.location.href = titlepage
                }
                if(pseries >= 0 && current){//1.2.2
                    if(current > seriesdex[pseries].last){
                        console.log(`${getCN("ml-4")[1].innerText}'s previous last: ${seriesdex[pseries].last}`)
                        seriesdex[pseries].last = current
                        console.log(`${getCN("ml-4")[1].innerText}'s new last: ${seriesdex[pseries].last}`)
                        seriesdex[pseries] = DefaultNext(seriesdex[pseries])
                        console.log(seriesdex[pseries])
                        SafeSave("seriesdex",seriesdex)
                    }
                }
            }
            catch(e){//1.2.2
                console.log("External link?")
                for(let sd of seriesdex){
                    if(document.URL.includes(sd.nextl)){
                        let pseries = FS(seriesdex,sd.id)
                        sd.last = sd.nextc
                        sd = DefaultNext(sd)
                        console.log(`${document.title.split(" - ")[1]}'s new last: ${seriesdex[pseries].last}`)
                        SafeSave("seriesdex",seriesdex)
                        break
                    }
                }
            }

            // let nextlink = null
            // let menuclass = "menu flex flex-col gap-2 bg-background p-4"//"menu flex flex-col gap-2 bg-background p-4 open pinned"
            // if(getCN(menuclass)[0].children[4].children[2].href) nextlink = getCN(menuclass)[0].children[4].children[2].href
            // if(nextlink && forbidden.includes(getTID(nextlink))){//it's a blacklisted chapter
            //     if(getCN("md--pages")[0].firstChild.childElementCount == document.URL.split("/")[5]*1){//last page
            //         alert("Next chapter is blacklisted. Don't click it if you don't want to read it. Ctrl+M to go to title page.")
            //     }
            // }

        }

        if(document.URL.includes("https://mangadex.org/user/me")){//1.2
            function DisplayTabla(){
                if(getCN("select__tab-active")[0].innerText == "Info"){
                    let com = SafeLoad("completed")
                    let ptr = SafeLoad("planto")
                    let dro = SafeLoad("dropped")
                    let rea = SafeLoad("reading")
                    let onh = SafeLoad("onhold")
                    let daTable = '<tr><th>Name</th><th class="centered">MU Link</th><th class="centered">Status</th><th class="centered">Last Read</th><th class="centered">Next</th><th class="centered">Last Update</th></tr>'
                    function LlenarTabla(array,stat){
                        for(let a of array){
                            let mulink = ''
                            let mubody = '🚫'
                            if(a.mu){
                                mulink = ` href="https://www.mangaupdates.com/series.html?id=${a.mu}"`
                                mubody = '🔗'
                            }
                            let stamp = '⚠️'
                            if(a.time) stamp = (new Date(a.time)).toLocaleDateString()
                            let lastone = '🚫'
                            if(JSON.parse(a.last) != null && a.last > MINNUM) {
                                if(!a.lastv) lastone = a.last
                                else lastone = "v"+a.lastv+"c"+a.last
                            }
                            let nextone = '🚫'
                            let nextlink = ''
                            if(a.nextl){
                                nextone = a.nextc
                                if(a.nextv) nextone = "v"+a.nextv+"c"+a.nextc
                                nextlink = ` href="/chapter/${a.nextl}"`
                                if(a.nextl.includes(".")) nextlink = ` href="${a.nextl}"` //1.2.3
                            }
                            let bell = '🔕'
                            if(FS(seriesdex,a.id) >= 0) bell = '🔔 '
                            daTable+=`<tr><td><a class="levy" href="/title/${a.id}" title="${a.name.replaceAll('"','$').replaceAll("<",'\<').replaceAll(">",'\>')}">${bell+a.name}</a></td><td class="centered"><a${mulink}>${mubody}</a></td><td class="centered">${stat}</td><td class="centered"><div style="display: flex;justify-content: center;"><span>${lastone} </span><button onclick="NewLast3(event)">✍️</button></div></td><td class="centered"><a${nextlink}>${nextone}</a></td><td class="centered">${stamp}</td></tr>`
                        }
                    }
                    LlenarTabla(rea,"Reading")
                    LlenarTabla(onh,"On Hold")
                    LlenarTabla(dro,"Dropped")
                    LlenarTabla(ptr,"Plan to Read")
                    LlenarTabla(com,"Completed")
                    let divTabla = newInner("table","table",daTable)
                    divTabla.id = "divTabla"
                    divTabla.style.display = "grid"
                    if(!document.getElementById("divTabla")){
                        let target = null
                        if(getCN("px-6 page-container").length) target = getCN("px-6 page-container")[0].parentElement.parentElement
                        if(target) target.append(divTabla)
                        else setTimeout(target.append(divTabla),500)
                    }
                    else document.getElementById("divTabla").innerHTML = daTable
                }
            }
            DisplayTabla()
        }

        if(document.URL.includes("https://mangadex.org/group/")){
            blacklist = SafeLoad("blacklist")
            let gid = getID3(document.URL)
            let boton = getCN("rounded md-btn px-4")[0]
            let newboton = cloneDOM("button",boton)
            if(blacklist.findIndex(q => q[0] == 0 && q[1] == gid) < 0) {
                newboton.innerText = "Blacklist this"
                newboton.setAttribute("onclick","BLThis()")
            }
            else {
                newboton.innerText = "Remove from blacklist"
                newboton.setAttribute("onclick","unBLThis()")
            }
            boton.parentElement.append(newboton)
        }
    }
    else setTimeout(main,5000)
}

window.BLThis = function(){//1.2.2
    let gid = getID3(document.URL)
    blacklist = SafeLoad("blacklist")
    if(blacklist.findIndex(q => q[0] == 0 && q[1] == gid) < 0) blacklist.push([0,gid])
    SafeSave("blacklist",blacklist)
    alert(`${document.title.split(" - ")[0]} marked as globally blacklisted`)
    let boton = getCN("rounded md-btn px-4")[1]
    boton.innerText = "Remove from blacklist"
    boton.setAttribute("onclick","unBLThis()")
}

window.unBLThis = function(){//1.2.2
    let gid = getID3(document.URL)
    blacklist = SafeLoad("blacklist")
    let index = blacklist.findIndex(q => q[0] == 0 && q[1] == gid)
    if(index >= 0) blacklist.splice(index,1)
    SafeSave("blacklist",blacklist)
    alert(`${document.title.split(" - ")[0]} removed from globally blacklisted`)
    let boton = getCN("rounded md-btn px-4")[1]
    boton.innerText = "Blacklist this"
    boton.setAttribute("onclick","BLThis()")
}

document.addEventListener('keydown', function(event) {
    if(document.URL.includes("/chapter/") && event.ctrlKey && (event.key === 'm' || event.key === 'M')){
        window.location.href = titlepage
        // localStorage.setItem("reader.hidePagebar",0) //1.2.3
    }
});

//EXPORT FUNCTIONS
function exportToJsonFile(jsonData) {
    let dataStr = JSON.stringify(jsonData);
    let dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);

    let exportFileDefaultName = 'seriesdex.json';

    let linkElement = document.createElement('a');
    linkElement.setAttribute('href', dataUri);
    linkElement.setAttribute('download', exportFileDefaultName);
    linkElement.click();
}

function parseJSONToCSVStr(jsonData) {
    if(jsonData.length == 0) {
        return '';
    }

    let keys = Object.keys(jsonData[0]);

    let columnDelimiter = '\t';
    let lineDelimiter = '\n';

    let csvColumnHeader = keys.join(columnDelimiter);
    let csvStr = csvColumnHeader + lineDelimiter;

    jsonData.forEach(item => {
        keys.forEach((key, index) => {
            if( (index > 0) && (index < keys.length) ) {
                csvStr += columnDelimiter;
            }
            csvStr += item[key];
        });
        csvStr += lineDelimiter;
    });

    return encodeURIComponent(csvStr);;
}

function exportToCsvFile(jsonData) {
    let csvStr = parseJSONToCSVStr(jsonData);
    let dataUri = 'data:text/csv;charset=utf-8,'+ csvStr;

    let exportFileDefaultName = 'MangaDexFollowFeed.csv';

    let linkElement = document.createElement('a');
    linkElement.setAttribute('href', dataUri);
    linkElement.setAttribute('download', exportFileDefaultName);
    linkElement.click();
}

function PrepareData(lala){
    var temp = []
    let reading = SafeLoad("reading")
    let planto = SafeLoad("planto")
    let onhold = SafeLoad("onhold")
    let dropped = SafeLoad("dropped")
    let completed = SafeLoad("completed")

    function Processing(arrayy,naame){
        for(let a of arrayy){
            let last,daTime
            if(lala){
                //if(a.last*1 < 0 || JSON.parse(a.last) == null) last = "unregistered"
                if(a.last*1 < 0 || a.last == null) last = "unregistered"
                else last = a.last
                if(a.time) daTime = new Date(a.time).toLocaleString()
                else daTime = "unregistered"
            }
            else {
                last = a.last
                daTime = a.time
            }
            temp.push({id:a.id,mu:a.mu,name:a.name,state:naame,last:last, time:(new Date(a.time).toLocaleString())})
            if(temp.length == 0) temp = [{id:a.id,mu:a.mu,name:a.name,state:naame,last:last, time:(new Date(a.time).toLocaleString())}]
        }
    }

    if(reading.length+planto.length+onhold.length+dropped.length+completed.length){
        Processing(reading,"Reading")
        Processing(onhold,"On Hold")
        Processing(planto,"Plan to Read")
        Processing(dropped,"Dropped")
        Processing(completed,"Completed")
        return temp
    }
    else{
        alert("There's no data. Please press the FILL button to collect the data")
        return null
    }
}

window.DownloadCSV = function(){
    exportToCsvFile(PrepareData(true))
}

window.DownloadJSON = function(){
    exportToJsonFile(PrepareData(false))
}

// document.onscroll = function(){
//     var w = document.documentElement.clientHeight;
//     var over = document.documentElement.scrollTopMax;
//     if(document.documentElement.scrollTop < over) trigger = true
//     if(w < over && document.documentElement.scrollTop == over) {
//         if(trigger && !filling) setTimeout(main,500)
//         trigger = false
//     }
// }