Greasy Fork

ニコニコ静画、簡単NGスクリプト

申し訳ないが見たくないイラストはNG

当前为 2020-10-25 提交的版本,查看 最新版本

// ==UserScript==
// @name         ニコニコ静画、簡単NGスクリプト
// @namespace    http://tampermonkey.net/
// @version      1.072
// @description  申し訳ないが見たくないイラストはNG
// @author       cbxm
// @match        https://seiga.nicovideo.jp/tag/*
// @match        https://seiga.nicovideo.jp/seiga/*
// @grant        GM.xmlHttpRequest
// @grant        GM.getValue
// @grant        GM.setValue
// @run-at document-start
// ==/UserScript==
(async () => {
    "use strict";
    ;
    ;
    class Util {
        //xmlString=未探査部分
        static XmlToObj(xmlString) {
            const F = (xmlString, obj) => {
                //タグを抜き出す
                let tagMatchs = null;
                while (true) {
                    tagMatchs = xmlString.match(/<([^>]+)>/);
                    //タグがないということはそれが値になる
                    if (tagMatchs == null) {
                        return xmlString;
                    }
                    if (tagMatchs[1][tagMatchs[1].length - 1] == "/") {
                        xmlString = xmlString.replace(/<[^>]+>([^]*)/, "$1");
                    }
                    else {
                        break;
                    }
                }
                const tag = tagMatchs[1];
                //タグの内側とその先を抜き出す
                const matchChildlen = [];
                while (true) {
                    const matchs = xmlString.match(new RegExp(`^[^<]*<${tag}>([^]+?)<\/${tag}>([^]*)`));
                    if (matchs == null) {
                        break;
                    }
                    matchChildlen.push(matchs[1]);
                    xmlString = matchs[2];
                }
                //タグあったのにマッチしなかったおかしい
                if (matchChildlen.length == 0) {
                    return obj;
                }
                //そのタグが一つしかないとき、オブジェクトになる
                if (matchChildlen.length == 1) {
                    //子を探す
                    obj[tag] = F(matchChildlen[0], {});
                }
                //そのタグが複数あるとき、配列になる
                if (matchChildlen.length > 1) {
                    obj = [];
                    for (let i = 0; i < matchChildlen.length; i++) {
                        //子を探す
                        obj[i] = F(matchChildlen[i], {});
                    }
                }
                //兄弟を探す
                F(xmlString, obj);
                return obj;
            };
            //初期化で<xml>を取り除く
            xmlString = xmlString.replace(/\s*<[^>]+>([^]+)/, "$1");
            return F(xmlString, {});
        }
        static HtmlToDocument(str) {
            const parser = new DOMParser();
            return parser.parseFromString(str, "text/html");
        }
        static HtmlToChildNodes(str) {
            return this.HtmlToDocument(str).body.childNodes;
        }
        static Wait(ms) {
            return new Promise(r => setTimeout(r, ms));
        }
        static async Download(url, name) {
            const link = document.createElement("a");
            document.body.appendChild(link);
            link.download = name;
            link.href = url;
            link.click();
            //すぐに消すと反応しないとか
            await this.Wait(100);
            document.body.removeChild(link);
        }
    }
    ;
    class Fetcher {
        static GMFetchText(url) {
            return new Promise(r => {
                GM.xmlHttpRequest({
                    url: url,
                    method: "GET",
                    onload: (response) => {
                        r(response.responseText);
                    }
                });
            });
        }
        static async FetchIllustDatas(ids) {
            if (ids.length == 0) {
                return { illusts: [], userIds: [] };
            }
            const url = `http:\/\/seiga.nicovideo.jp/api/illust/info?id_list=${ids.join()}`;
            const res = await this.GMFetchText(url);
            const obj = Util.XmlToObj(res);
            const list = Array.isArray(obj.response.image_list) ? obj.response.image_list : [obj.response.image_list.image];
            const illusts = [];
            for (let i = 0; i < list.length; i++) {
                illusts[i] = {
                    id: list[i].id,
                    created: new Date(list[i].created)
                };
            }
            return {
                illusts: illusts,
                userIds: list.map(l => l.user_id)
            };
        }
        static async FetchUserName(userId) {
            const url = "http://seiga.nicovideo.jp/api/user/info?id=" + userId;
            const json = Util.XmlToObj(await this.GMFetchText(url));
            return json.response.user.nickname;
        }
        static async FetchUserId(illustId) {
            const url = "https://seiga.nicovideo.jp/api/illust/info?id=im" + illustId;
            const resultText = await this.GMFetchText(url);
            const json = Util.XmlToObj(resultText);
            return json.response.image.user_id;
        }
    }
    ;
    class Storage {
        constructor(storageName) {
            this.storageName = "";
            this.storageName = storageName;
        }
        async GetStorageData(defaultValue = null) {
            const text = await GM.getValue(this.storageName, null);
            return text != null ? JSON.parse(decodeURIComponent(text)) : defaultValue;
        }
        async SetStorageData(data) {
            await GM.setValue(this.storageName, encodeURIComponent(JSON.stringify(data)));
        }
    }
    ;
    class Observer {
        static Wait(predicate, parent = document, option = null) {
            return new Promise(r => {
                if (option == null) {
                    option = {
                        childList: true,
                        subtree: true
                    };
                }
                const mutationObserver = new MutationObserver((mrs) => {
                    if (predicate(mrs)) {
                        mutationObserver.disconnect();
                        r(mrs);
                        return;
                    }
                });
                mutationObserver.observe(parent, option);
            });
        }
        ;
        static WaitAddedNode(predicate, parent, option = null) {
            return new Promise(r => {
                if (option == null) {
                    option = {
                        childList: true,
                        subtree: true
                    };
                }
                const mutationObserver = new MutationObserver((mrs) => {
                    //console.log(document.head.innerHTML);
                    //console.log(document.body.innerHTML);
                    for (let node of mrs) {
                        node.addedNodes.forEach(added => {
                            //console.log(added);
                            if (predicate(added)) {
                                mutationObserver.disconnect();
                                r(added);
                                return;
                            }
                        });
                    }
                });
                mutationObserver.observe(parent, option);
            });
        }
        ;
        static async DefinitelyGetElementById(id, parent = document, option = null) {
            const e = document.getElementById(id);
            if (e != null) {
                return e;
            }
            return this.WaitAddedNode(e => e.id != null && e.id == id, parent, option);
        }
        //getElementsByClassNameをつかうけど単体なので注意
        static async DefinitelyGetElementByClassName(className, parent = document, option = null) {
            const e = document.getElementsByClassName(className)[0];
            if (e != null) {
                return e;
            }
            return this.WaitAddedNode(e => e.className != null && e.className == className, parent, option);
        }
        //getElementsByTagNameをつかうけど単体なので注意
        static async DefinitelyGetElementByTagName(tagName, parent = document, option = null) {
            tagName = tagName.toUpperCase();
            const e = document.getElementsByTagName(tagName)[0];
            if (e != null) {
                return e;
            }
            return this.WaitAddedNode(e => e.tagName != null && e.tagName == tagName, parent, option);
        }
    }
    ;
    //暫定OK、暫定荒らし、確定OK、確定荒らし
    //type Status = "OK" | "NG" | "LOK" | "LNG"
    let PageType;
    (function (PageType) {
        PageType[PageType["None"] = -1] = "None";
        PageType[PageType["TAG_SEARCH"] = 0] = "TAG_SEARCH";
        PageType[PageType["ILLUST"] = 1] = "ILLUST";
        PageType[PageType["MAX"] = 2] = "MAX";
    })(PageType || (PageType = {}));
    ;
    ;
    const pageInfos = [
        {
            regex: /https:\/\/seiga.nicovideo.jp\/tag\/.*/,
            name: "タグ検索",
        },
        {
            regex: /https:\/\/seiga.nicovideo.jp\/seiga\/.*/,
            name: "イラストページ",
        }
    ];
    let Status;
    (function (Status) {
        Status[Status["NONE"] = 0] = "NONE";
        Status[Status["OK"] = 1] = "OK";
        Status[Status["NG"] = 2] = "NG";
        Status[Status["WHITE"] = 3] = "WHITE";
        Status[Status["BLACK"] = 4] = "BLACK";
        Status[Status["MAX"] = 5] = "MAX";
    })(Status || (Status = {}));
    let IllustSize;
    (function (IllustSize) {
        IllustSize[IllustSize["NOMAL"] = 0] = "NOMAL";
        IllustSize[IllustSize["CUTOUT"] = 1] = "CUTOUT";
    })(IllustSize || (IllustSize = {}));
    ;
    class Main {
        constructor() {
            this.cache = [];
            this.illustInfos = [];
            this.selectedList = [];
            this.cacheStorage = new Storage("NICONICO_RENTO_ARASI_NG_DATA_CACHE");
            this.optionStorage = new Storage("NICONICO_RENTO_ARASI_NG_OPTION_CACHE");
            this.imgIntersectionObserver = new IntersectionObserver(entries => {
                for (let e of entries) {
                    if (e.intersectionRatio > 0) {
                        const img = e.target;
                        if (img.src != null && img.dataset != null && img.dataset.src != null) {
                            img.src = img.dataset.src;
                        }
                        this.imgIntersectionObserver.unobserve(img);
                    }
                }
            });
        }
        async GetStorageData() {
            this.cache = (await this.cacheStorage.GetStorageData([]));
            //console.log(this.cache);
            const defaultOption = {
                usePages: [true, false],
                judge: {
                    isJudge: false,
                    time: 1 * 60 * 60 * 1000,
                    postCount: 3
                },
                okCacheMax: 1000 //どのくらいがいいのかわからない
            };
            this.option = await this.optionStorage.GetStorageData(defaultOption);
            if (this.option.usePages == undefined) {
                this.option.usePages = defaultOption.usePages;
            }
            for (let i = 0; i < PageType.MAX; i++) {
                if (this.option.usePages[i] == undefined) {
                    this.option.usePages[i] = defaultOption.usePages[i];
                }
            }
            if (this.option.judge == undefined) {
                this.option.judge = defaultOption.judge;
            }
            if (this.option.judge.time == undefined) {
                this.option.judge.time = defaultOption.judge.time;
            }
            if (this.option.judge.postCount == undefined) {
                this.option.judge.postCount = defaultOption.judge.postCount;
            }
            if (this.option.judge.isJudge == undefined) {
                this.option.judge.isJudge = defaultOption.judge.isJudge;
            }
            if (this.option.okCacheMax == undefined) {
                this.option.okCacheMax = defaultOption.okCacheMax;
            }
            //console.log(this.option);
        }
        GetInfo(illustId) {
            for (let c of this.cache) {
                for (let illust of c.illusts) {
                    if (illust.id == illustId) {
                        return { user: c, illust: illust };
                    }
                }
            }
            return undefined;
        }
        CheckArasi(user) {
            if (user.illusts.length == 0 || user.status == Status.BLACK || user.status == Status.WHITE || user.status == Status.NG) {
                return;
            }
            for (let illust of user.illusts) {
                if (typeof illust.created == "string") {
                    illust.created = new Date(illust.created);
                }
            }
            //新しい順
            const sorted = user.illusts.sort((a, b) => b.created.getTime() - a.created.getTime());
            for (let i = 0; i < sorted.length; i++) {
                const currentDate = sorted[i].created;
                let j = i + 1;
                let postCount = 1;
                while (true) {
                    if (j >= sorted.length || currentDate.getTime() - sorted[j].created.getTime() > this.option.judge.time) {
                        break;
                    }
                    j++;
                    postCount++;
                }
                if (postCount >= this.option.judge.postCount) {
                    user.status = Status.NG;
                    return;
                }
            }
        }
        ;
        GetIllustIds(itemListElement) {
            var _a;
            const illustIdElements = itemListElement.getElementsByTagName("a");
            const illustIds = [];
            for (let i = 0; i < illustIdElements.length; i++) {
                if (illustIdElements[i].parentElement != null && ((_a = illustIdElements[i].parentElement) === null || _a === void 0 ? void 0 : _a.classList.contains("list_more_link"))) {
                    continue;
                }
                const idMatchs = illustIdElements[i].href.match(/im(\d+)/);
                if (idMatchs == null) {
                    continue;
                }
                const id = idMatchs[1];
                illustIds.push(id);
            }
            return illustIds;
        }
        DrawList() {
            const list = this.optionDialog.getElementsByClassName("scrollUL")[0];
            const onlyCurrentPageCheckbox = this.optionDialog.getElementsByClassName("onlyCurrentPageCheckbox")[0];
            const listStatusSelect = this.optionDialog.getElementsByClassName("listStatusSelect")[0];
            if (list == undefined || onlyCurrentPageCheckbox == undefined || listStatusSelect == undefined) {
                return;
            }
            const status = listStatusSelect.value == "ALL" ? "" : Status[listStatusSelect.value];
            list.innerHTML = "";
            for (let user of this.cache) {
                if (status != "" && user.status != status) {
                    continue;
                }
                const info = this.illustInfos.find(info => info.user.userId == user.userId);
                let sampleIllustId = info != undefined ? info.illustId : undefined;
                if (onlyCurrentPageCheckbox.checked && sampleIllustId == undefined) {
                    continue;
                }
                if (sampleIllustId == undefined) {
                    sampleIllustId = user.illusts[0].id;
                }
                const div = document.createElement("div");
                div.style.height = "70px";
                div.style.display = "flex";
                div.style.flexDirection = "column";
                div.className = "userInfoItem";
                list.appendChild(div);
                div.addEventListener("mouseup", e => this.ClickList(div));
                {
                    const nameIdDiv = document.createElement("div");
                    nameIdDiv.style.top = "relative";
                    nameIdDiv.style.position = "4px";
                    div.appendChild(nameIdDiv);
                    {
                        const nameSpan = document.createElement("span");
                        nameSpan.className = "userName";
                        nameSpan.textContent = info == undefined ? "" : info.name;
                        nameSpan.style.fontSize = "130%";
                        nameSpan.style.color = "black";
                        nameSpan.style.width = "66px";
                        nameSpan.style.height = "24px";
                        nameSpan.style.padding = "3px";
                        nameIdDiv.appendChild(nameSpan);
                        const idSpan = document.createElement("span");
                        idSpan.className = "userId";
                        idSpan.textContent = user.userId;
                        idSpan.style.fontSize = "130%";
                        idSpan.style.color = "black";
                        idSpan.style.width = "66px";
                        idSpan.style.padding = "3px";
                        nameIdDiv.appendChild(idSpan);
                    }
                    const userAndSampleImgDiv = document.createElement("div");
                    div.appendChild(userAndSampleImgDiv);
                    {
                        const aUser = document.createElement("a");
                        aUser.href = `https:\/\/seiga.nicovideo.jp/user/illust/${user.userId}`;
                        userAndSampleImgDiv.appendChild(aUser);
                        {
                            const imgUser = document.createElement("img");
                            imgUser.dataset.src = `https:\/\/secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/${Math.floor(parseInt(user.userId) / 10000)}/${user.userId}.jpg`;
                            imgUser.style.height = "40px";
                            imgUser.style.position = "relative";
                            imgUser.style.padding = "0 20px 0 10px";
                            imgUser.style.top = "-5px";
                            this.imgIntersectionObserver.observe(imgUser);
                            aUser.appendChild(imgUser);
                            imgUser.addEventListener("error", () => {
                                imgUser.src = "https:\/\/secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/defaults/blank.jpg";
                            });
                        }
                        const aSample = document.createElement("a");
                        aSample.href = `https:/\/seiga.nicovideo.jp/seiga/im${sampleIllustId}`;
                        userAndSampleImgDiv.appendChild(aSample);
                        {
                            const imgSample = document.createElement("img");
                            imgSample.dataset.src = `https:\/\/lohas.nicoseiga.jp\/\/thumb/${sampleIllustId}c`;
                            imgSample.style.height = "30px";
                            this.imgIntersectionObserver.observe(imgSample);
                            imgSample.style.position = "relative";
                            imgSample.style.top = "-5px";
                            aSample.appendChild(imgSample);
                            const bigSample = document.createElement("img");
                            bigSample.dataset.src = `https:\/\/lohas.nicoseiga.jp\/\/thumb/${sampleIllustId}c`;
                            bigSample.style.height = "100px";
                            this.imgIntersectionObserver.observe(bigSample);
                            bigSample.style.pointerEvents = "none";
                            bigSample.style.position = "absolute";
                            bigSample.style.zIndex = "110";
                            imgSample.addEventListener("mouseover", () => {
                                const clientRect = imgSample.getBoundingClientRect();
                                const x = window.pageXOffset + clientRect.left + imgSample.width / 2 - 50;
                                const y = window.pageYOffset + clientRect.top + imgSample.height / 2 - 50;
                                bigSample.style.top = y + "px";
                                bigSample.style.left = x + "px";
                                document.body.appendChild(bigSample);
                            });
                            imgSample.addEventListener("mouseleave", () => {
                                bigSample.remove();
                            });
                        }
                    }
                }
            }
        }
        ClickList(target) {
            if (target != null) {
                if (this.selectedList.includes(target)) {
                    target.style.backgroundColor = "";
                    this.selectedList = this.selectedList.filter(s => s != target);
                }
                else {
                    target.style.backgroundColor = "rgba(0, 140, 255, 0.5)";
                    this.selectedList.push(target);
                }
            }
        }
        async SetOptionButton() {
            const parent = await Observer.DefinitelyGetElementByClassName("sg_pankuzu");
            if (document.getElementById("optionSpan") != null) {
                return;
            }
            const optionSpan = document.createElement("span");
            optionSpan.id = "optionSpan";
            optionSpan.style.margin = "0 10px";
            parent.appendChild(optionSpan);
            {
                const optionButton = document.createElement("input");
                optionButton.type = "button";
                optionButton.value = "簡単NGスクリプト";
                optionButton.style.backgroundColor = "yellow";
                optionButton.style.padding = "1px 10px";
                optionButton.style.fontSize = "110%";
                optionButton.style.cssText += "color: black !important;";
                optionButton.addEventListener("click", () => {
                    if (this.optionDialog.parentElement == null) {
                        optionSpan.appendChild(this.optionDialog);
                        return;
                    }
                    this.optionDialog.style.display = (this.optionDialog.style.display == "none") ? "block" : "none";
                });
                optionSpan.appendChild(optionButton);
                this.optionDialog = document.createElement("div");
                this.optionDialog.style.backgroundColor = "white";
                this.optionDialog.style.position = "absolute";
                this.optionDialog.style.padding = "5px";
                this.optionDialog.style.marginLeft = "10px";
                this.optionDialog.style.zIndex = "100";
                this.optionDialog.style.border = "2px solid";
                {
                    const list1 = document.createElement("div");
                    list1.style.display = "flex";
                    list1.style.paddingTop = "5px";
                    list1.style.paddingBottom = "10px";
                    this.optionDialog.appendChild(list1);
                    {
                        const listStatusSelect = document.createElement("select");
                        listStatusSelect.className = "listStatusSelect";
                        listStatusSelect.style.margin = "5px";
                        list1.appendChild(listStatusSelect);
                        for (let i = 1; i <= Status.MAX; i++) {
                            const option = document.createElement("option");
                            const text = i == Status.MAX ? "ALL" : Status[i];
                            option.value = text;
                            option.textContent = text;
                            listStatusSelect.appendChild(option);
                        }
                        listStatusSelect.addEventListener("change", () => {
                            while (this.selectedList.length != 0) {
                                const element = this.selectedList.pop();
                                if (element != undefined) {
                                    element.style.backgroundColor = "";
                                }
                            }
                            this.DrawList();
                        });
                        const onlyCurrentPageLabel = document.createElement("label");
                        onlyCurrentPageLabel.style.color = "black";
                        onlyCurrentPageLabel.style.padding = "3px";
                        onlyCurrentPageLabel.style.display = "flex";
                        list1.appendChild(onlyCurrentPageLabel);
                        {
                            const onlyCurrentPageCheckbox = document.createElement("input");
                            onlyCurrentPageCheckbox.type = "checkbox";
                            onlyCurrentPageCheckbox.className = "onlyCurrentPageCheckbox";
                            onlyCurrentPageCheckbox.checked = true;
                            onlyCurrentPageCheckbox.style.padding = "3px";
                            onlyCurrentPageCheckbox.style.margin = "10px";
                            onlyCurrentPageCheckbox.style.marginRight = "3px";
                            onlyCurrentPageCheckbox.style.marginLeft = "0px";
                            onlyCurrentPageLabel.appendChild(onlyCurrentPageCheckbox);
                            onlyCurrentPageCheckbox.addEventListener("change", () => this.DrawList());
                            const onlyCurrentPageText = document.createElement("div");
                            onlyCurrentPageText.textContent = "このページだけ";
                            onlyCurrentPageText.style.color = "black";
                            onlyCurrentPageLabel.appendChild(onlyCurrentPageText);
                        }
                        const allSelect = document.createElement("input");
                        allSelect.type = "button";
                        allSelect.value = "全選択";
                        allSelect.style.color = "black";
                        allSelect.style.fontSize = "120%";
                        allSelect.style.padding = "0 5px";
                        allSelect.style.margin = "3px";
                        list1.appendChild(allSelect);
                        allSelect.addEventListener("click", () => {
                            const infos = Array.from(document.getElementsByClassName("userInfoItem"));
                            for (let info of infos) {
                                this.ClickList(info);
                            }
                        });
                        const detailButton = document.createElement("input");
                        detailButton.type = "button";
                        detailButton.value = "設定";
                        detailButton.style.color = "black";
                        detailButton.style.fontSize = "120%";
                        detailButton.style.margin = "3px";
                        detailButton.style.marginLeft = "45px";
                        detailButton.style.padding = "0 10px";
                        list1.appendChild(detailButton);
                        detailButton.addEventListener("click", () => detailDialog.style.display = (detailDialog.style.display == "none") ? "block" : "none");
                        const detailDialog = document.createElement("div");
                        detailDialog.style.backgroundColor = "white";
                        detailDialog.style.display = "none";
                        detailDialog.style.position = "absolute";
                        detailDialog.style.padding = "0 10px";
                        detailDialog.style.zIndex = "100";
                        detailDialog.style.border = "2px solid";
                        detailDialog.style.left = "360px";
                        detailDialog.style.top = "10px";
                        list1.appendChild(detailDialog);
                        const useSettingH3 = document.createElement("h1");
                        useSettingH3.textContent = "使うところ";
                        useSettingH3.style.fontSize = "140%";
                        useSettingH3.style.marginTop = "10px";
                        useSettingH3.style.color = "black";
                        detailDialog.appendChild(useSettingH3);
                        const setUseListDiv = document.createElement("div");
                        setUseListDiv.style.marginBottom = "10px";
                        detailDialog.appendChild(setUseListDiv);
                        {
                            for (let i = 0; i < PageType.MAX; i++) {
                                const setUseLabel = document.createElement("label");
                                setUseLabel.style.padding = "3px";
                                setUseLabel.style.display = "flex";
                                setUseListDiv.appendChild(setUseLabel);
                                {
                                    const setUsePageCheckbox = document.createElement("input");
                                    setUsePageCheckbox.type = "checkbox";
                                    setUsePageCheckbox.checked = this.option.usePages[i];
                                    setUsePageCheckbox.style.padding = "3px";
                                    setUsePageCheckbox.style.margin = "10px";
                                    setUsePageCheckbox.style.marginRight = "3px";
                                    setUseLabel.appendChild(setUsePageCheckbox);
                                    setUsePageCheckbox.addEventListener("change", async () => {
                                        this.option.usePages[i] = setUsePageCheckbox.checked;
                                        await this.optionStorage.SetStorageData(this.option);
                                    });
                                    const setUsePageText = document.createElement("div");
                                    setUsePageText.textContent = pageInfos[i].name;
                                    setUsePageText.style.padding = "3px";
                                    setUsePageText.style.fontSize = "120%";
                                    setUsePageText.style.color = "black";
                                    setUseLabel.appendChild(setUsePageText);
                                }
                            }
                        }
                        const otherSettingH3 = document.createElement("h1");
                        otherSettingH3.textContent = "その他";
                        otherSettingH3.style.fontSize = "140%";
                        otherSettingH3.style.marginTop = "10px";
                        otherSettingH3.style.color = "black";
                        detailDialog.appendChild(otherSettingH3);
                        const judgeRigorCover = document.createElement("div");
                        const setIsJudgeDiv = document.createElement("div");
                        setIsJudgeDiv.style.padding = "5px";
                        setIsJudgeDiv.style.paddingBottom = "0";
                        setIsJudgeDiv.style.display = "flex";
                        detailDialog.appendChild(setIsJudgeDiv);
                        {
                            const isJudgeCheckbox = document.createElement("input");
                            isJudgeCheckbox.type = "checkbox";
                            isJudgeCheckbox.id = "isJudgeCheckbox";
                            isJudgeCheckbox.checked = this.option.judge.isJudge;
                            isJudgeCheckbox.style.padding = "3px";
                            isJudgeCheckbox.style.margin = "10px";
                            isJudgeCheckbox.style.marginRight = "3px";
                            setIsJudgeDiv.appendChild(isJudgeCheckbox);
                            isJudgeCheckbox.addEventListener("change", async () => {
                                this.option.judge.isJudge = isJudgeCheckbox.checked;
                                if (this.option.judge.isJudge) {
                                    judgeRigorCover.style.visibility = "hidden";
                                }
                                else {
                                    judgeRigorCover.style.visibility = "visible";
                                }
                                await this.optionStorage.SetStorageData(this.option);
                            });
                            const isJudgeLabel = document.createElement("label");
                            isJudgeLabel.htmlFor = "isJudgeCheckbox";
                            isJudgeLabel.textContent = "連投自動NG";
                            isJudgeLabel.style.color = "black";
                            isJudgeLabel.style.padding = "3px";
                            isJudgeLabel.style.fontSize = "120%";
                            setIsJudgeDiv.appendChild(isJudgeLabel);
                        }
                        const setJudgeRigorFlex = document.createElement("div");
                        setJudgeRigorFlex.style.padding = "0px 10px 5px 10px";
                        setJudgeRigorFlex.style.position = "relative";
                        detailDialog.appendChild(setJudgeRigorFlex);
                        {
                            const setJudgeTime = document.createElement("input");
                            setJudgeTime.type = "time";
                            setJudgeTime.style.height = "20px";
                            setJudgeTime.style.fontSize = "120%";
                            const hour = ('00' + Math.floor(this.option.judge.time / 60 / 1000 / 60).toString()).slice(-2);
                            const minutes = ('00' + (this.option.judge.time / 60 / 1000 % 60).toString()).slice(-2);
                            setJudgeTime.value = `${hour}:${minutes}`;
                            setJudgeTime.addEventListener("change", async () => {
                                const [h, m] = setJudgeTime.value.split(":").map(s => parseInt(s));
                                const ms = ((h * 60) + m) * 60 * 1000;
                                if (ms >= 1) {
                                    this.option.judge.time = ms;
                                    await this.optionStorage.SetStorageData(this.option);
                                }
                                else {
                                    const hour = ('00' + Math.floor(this.option.judge.time / 60 / 1000 / 60).toString()).slice(-2);
                                    const minutes = ('00' + (this.option.judge.time / 60 / 1000 % 60).toString()).slice(-2);
                                    setJudgeTime.value = `${hour}:${minutes}`;
                                }
                            });
                            setJudgeRigorFlex.appendChild(setJudgeTime);
                            const setJudgeText1 = document.createElement("span");
                            setJudgeText1.textContent = "以内に";
                            setJudgeText1.style.color = "black";
                            setJudgeText1.style.fontSize = "15px";
                            setJudgeRigorFlex.appendChild(setJudgeText1);
                            const setJudgePostCount = document.createElement("input");
                            setJudgePostCount.type = "number";
                            setJudgePostCount.value = this.option.judge.postCount.toString();
                            setJudgePostCount.style.width = "40px";
                            setJudgePostCount.min = "2";
                            setJudgePostCount.style.height = "20px";
                            setJudgePostCount.style.fontSize = "120%";
                            setJudgePostCount.addEventListener("change", async () => {
                                const num = parseInt(setJudgePostCount.value);
                                if (num >= 2) {
                                    this.option.judge.postCount = num;
                                    await this.optionStorage.SetStorageData(this.option);
                                }
                                else {
                                    this.option.judge.postCount = 2;
                                    setJudgePostCount.value = this.option.judge.postCount.toString();
                                }
                            });
                            setJudgeRigorFlex.appendChild(setJudgePostCount);
                            const setJudgeText2 = document.createElement("span");
                            setJudgeText2.textContent = "回投稿で仮荒らし認定";
                            setJudgeText2.style.color = "black";
                            setJudgeText2.style.fontSize = "15px";
                            setJudgeRigorFlex.appendChild(setJudgeText2);
                            judgeRigorCover.style.backgroundColor = "gray";
                            judgeRigorCover.style.width = "310px";
                            judgeRigorCover.style.height = "30px";
                            judgeRigorCover.style.zIndex = "1000";
                            judgeRigorCover.style.opacity = "0.5";
                            judgeRigorCover.style.position = "absolute";
                            judgeRigorCover.style.top = "0";
                            setJudgeRigorFlex.appendChild(judgeRigorCover);
                            if (this.option.judge.isJudge) {
                                judgeRigorCover.style.visibility = "hidden";
                            }
                            else {
                                judgeRigorCover.style.visibility = "visible";
                            }
                        }
                        const categoryBlock = document.createElement("div");
                        categoryBlock.style.margin = "10px 0";
                        detailDialog.appendChild(categoryBlock);
                        const setOKCacheMaxFlex = document.createElement("div");
                        setOKCacheMaxFlex.style.padding = "5px";
                        detailDialog.appendChild(setOKCacheMaxFlex);
                        {
                            const setOKCacheMaxText1 = document.createElement("span");
                            setOKCacheMaxText1.textContent = "OKユーザーのキャッシュ最大数:";
                            setOKCacheMaxText1.style.color = "black";
                            setOKCacheMaxText1.style.fontSize = "15px";
                            setOKCacheMaxFlex.appendChild(setOKCacheMaxText1);
                            const setOKCacheMax = document.createElement("input");
                            setOKCacheMax.type = "number";
                            setOKCacheMax.value = this.option.okCacheMax.toString();
                            setOKCacheMax.style.width = "80px";
                            setOKCacheMax.min = "100";
                            setOKCacheMax.style.height = "20px";
                            setOKCacheMax.style.fontSize = "120%";
                            setOKCacheMax.addEventListener("change", async () => {
                                const num = parseInt(setOKCacheMax.value);
                                if (num >= 100) {
                                    this.option.okCacheMax = num;
                                    await this.optionStorage.SetStorageData(this.option);
                                }
                                else {
                                    this.option.okCacheMax = 100;
                                    setOKCacheMax.value = this.option.okCacheMax.toString();
                                }
                            });
                            setOKCacheMaxFlex.appendChild(setOKCacheMax);
                        }
                    }
                    const list2 = document.createElement("div");
                    list2.style.position = "relative";
                    list2.style.display = "flex";
                    this.optionDialog.appendChild(list2);
                    {
                        const userInfoList = document.createElement("ul");
                        userInfoList.className = "scrollUL";
                        userInfoList.style.overflowY = "scroll";
                        userInfoList.style.overflowX = "hidden";
                        userInfoList.style.height = "380px";
                        userInfoList.style.width = "250px";
                        list2.appendChild(userInfoList);
                        const buttonList = document.createElement("ul");
                        buttonList.style.width = "90px";
                        list2.appendChild(buttonList);
                        {
                            const moveButtonList = document.createElement("div");
                            moveButtonList.style.marginTop = "20px";
                            moveButtonList.style.marginBottom = "10px";
                            buttonList.appendChild(moveButtonList);
                            {
                                for (let i = 1; i < Status.MAX; i++) {
                                    const div = document.createElement("div");
                                    moveButtonList.appendChild(div);
                                    {
                                        const toButton = document.createElement("input");
                                        toButton.type = "button";
                                        toButton.style.padding = "3px";
                                        toButton.style.fontSize = "130%";
                                        toButton.style.margin = "3px";
                                        toButton.value = "→ " + Status[i];
                                        toButton.name = Status[i];
                                        div.appendChild(toButton);
                                        toButton.addEventListener("click", async () => {
                                            while (this.selectedList.length != 0) {
                                                const element = this.selectedList.pop();
                                                if (element == undefined) {
                                                    continue;
                                                }
                                                element.style.backgroundColor = "";
                                                const userId = element.getElementsByClassName("userId")[0].textContent;
                                                const user = this.cache.find(c => c.userId == userId);
                                                if (user != undefined) {
                                                    user.status = Status[toButton.name];
                                                }
                                            }
                                            for (let info of this.illustInfos) {
                                                this.UpdateIllust(info);
                                                this.DrawBlackWhiteButton(info);
                                            }
                                            this.DrawList();
                                            await this.cacheStorage.SetStorageData(this.cache);
                                        });
                                    }
                                }
                            }
                            const DeleteSelectedUser = () => {
                                while (this.selectedList.length != 0) {
                                    const element = this.selectedList.pop();
                                    if (element == undefined) {
                                        continue;
                                    }
                                    const userId = element.getElementsByClassName("userId")[0].textContent;
                                    this.cache = this.cache.filter(c => c.userId != userId);
                                    const infos = this.illustInfos.filter(c => c.user.userId == userId);
                                    for (let info of infos) {
                                        info.user.status = Status.WHITE;
                                        this.UpdateIllust(info);
                                        this.DrawBlackWhiteButton(info);
                                    }
                                    this.illustInfos = this.illustInfos.filter(c => c.user.userId != userId);
                                }
                            };
                            const div = document.createElement("div");
                            buttonList.appendChild(div);
                            {
                                const selectedCacheClearButton = document.createElement("input");
                                selectedCacheClearButton.type = "button";
                                selectedCacheClearButton.style.padding = "3px";
                                selectedCacheClearButton.style.fontSize = "120%";
                                selectedCacheClearButton.style.margin = "3px";
                                selectedCacheClearButton.style.marginTop = "5px";
                                selectedCacheClearButton.style.backgroundColor = "yellow";
                                selectedCacheClearButton.style.cssText += "color: black !important";
                                selectedCacheClearButton.value = "→DELETE";
                                div.appendChild(selectedCacheClearButton);
                                selectedCacheClearButton.addEventListener("click", async () => {
                                    if (!window.confirm("選択したアイテムのキャッシュクリアしていいですか?\nホワイト・ブラックリストも削除されます。")) {
                                        return;
                                    }
                                    DeleteSelectedUser();
                                    this.DrawList();
                                    await this.cacheStorage.SetStorageData(this.cache);
                                });
                            }
                            const div2 = document.createElement("div");
                            buttonList.appendChild(div2);
                            {
                                const allCacheClearButton = document.createElement("input");
                                allCacheClearButton.type = "button";
                                allCacheClearButton.style.padding = "3px";
                                allCacheClearButton.style.fontSize = "120%";
                                allCacheClearButton.style.margin = "3px";
                                allCacheClearButton.style.backgroundColor = "red";
                                allCacheClearButton.value = "ALL\nDELETE";
                                div2.appendChild(allCacheClearButton);
                                allCacheClearButton.addEventListener("click", async () => {
                                    if (!window.confirm("全キャッシュクリアしていいですか?\nホワイト・ブラックリストも削除されます。")) {
                                        return;
                                    }
                                    for (let info of this.illustInfos) {
                                        info.user.status = Status.WHITE;
                                        this.UpdateIllust(info);
                                        this.DrawBlackWhiteButton(info);
                                    }
                                    this.illustInfos = [];
                                    this.cache = [];
                                    this.DrawList();
                                    await this.cacheStorage.SetStorageData(this.cache);
                                });
                            }
                            const div3 = document.createElement("div");
                            buttonList.appendChild(div3);
                            {
                                const reStartButton = document.createElement("input");
                                reStartButton.type = "button";
                                reStartButton.style.padding = "3px";
                                reStartButton.style.fontSize = "120%";
                                reStartButton.style.margin = "3px";
                                reStartButton.style.marginTop = "10px";
                                reStartButton.style.backgroundColor = "green";
                                reStartButton.style.cssText += "color: white !important";
                                reStartButton.value = "RE START";
                                div3.appendChild(reStartButton);
                                reStartButton.addEventListener("click", async () => {
                                    await this.Run();
                                });
                            }
                            const div4 = document.createElement("div");
                            div4.style.marginTop = "10px";
                            div4.style.marginBottom = "10px";
                            buttonList.appendChild(div4);
                            {
                                const importDiv = document.createElement("div");
                                importDiv.style.position = "relative";
                                div4.appendChild(importDiv);
                                {
                                    const importButton = document.createElement("input");
                                    importButton.type = "button";
                                    importButton.style.padding = "3px";
                                    importButton.style.fontSize = "120%";
                                    importButton.style.margin = "3px";
                                    importButton.style.marginTop = "10px";
                                    importButton.value = "← IMPORT";
                                    importDiv.appendChild(importButton);
                                    const importFile = document.createElement("input");
                                    importFile.type = "file";
                                    importFile.style.position = "absolute";
                                    importFile.style.opacity = "0";
                                    importFile.style.width = "80px";
                                    importFile.style.top = "8px";
                                    importFile.style.left = "0";
                                    importFile.accept = "text/plain";
                                    importFile.style.padding = "0";
                                    importDiv.appendChild(importFile);
                                    importFile.addEventListener("change", async (e) => {
                                        if (e.target == null) {
                                            return;
                                        }
                                        const files = e.target.files;
                                        if (files == null) {
                                            return;
                                        }
                                        const file = files[0];
                                        if (file.type != "text/plain") {
                                            alert("テキストファイルを入れてください。");
                                            return;
                                        }
                                        if (!window.confirm("インポートしていいですか?\nインポートする前に、今選択しているユーザーは削除されます。")) {
                                            return;
                                        }
                                        DeleteSelectedUser();
                                        this.DrawList();
                                        const reader = new FileReader();
                                        reader.readAsText(file);
                                        reader.onload = async () => {
                                            if (typeof reader.result != "string") {
                                                return;
                                            }
                                            const importUsers = JSON.parse(reader.result);
                                            for (let imUser of importUsers) {
                                                for (let illust of imUser.illusts) {
                                                    illust.created = new Date(illust.created);
                                                }
                                            }
                                            for (let imUser of importUsers) {
                                                const cachedUser = this.cache.find(c => c.userId == imUser.userId);
                                                if (cachedUser == undefined) {
                                                    this.cache.push(imUser);
                                                }
                                                else {
                                                    cachedUser.status = imUser.status;
                                                    for (let illust of cachedUser.illusts) {
                                                        if (cachedUser.illusts.some(c => c.id == illust.id)) {
                                                            continue;
                                                        }
                                                        cachedUser.illusts.push(illust);
                                                    }
                                                }
                                            }
                                            await this.cacheStorage.SetStorageData(this.cache);
                                            this.Run();
                                        };
                                    });
                                }
                                const exportEiv = document.createElement("div");
                                div4.appendChild(exportEiv);
                                {
                                    const reStartButton = document.createElement("input");
                                    reStartButton.type = "button";
                                    reStartButton.style.padding = "3px";
                                    reStartButton.style.fontSize = "120%";
                                    reStartButton.style.margin = "3px";
                                    reStartButton.style.marginTop = "5px";
                                    reStartButton.value = "→ EXPORT";
                                    exportEiv.appendChild(reStartButton);
                                    reStartButton.addEventListener("click", async () => {
                                        const selectedUsers = [];
                                        for (let element of this.selectedList) {
                                            if (element == undefined) {
                                                continue;
                                            }
                                            const userId = element.getElementsByClassName("userId")[0].textContent;
                                            const user = this.cache.find(c => c.userId == userId);
                                            if (user != undefined) {
                                                selectedUsers.push(user);
                                            }
                                        }
                                        if (selectedUsers.length == 0) {
                                            alert("出力するユーザーを選択してください");
                                            return;
                                        }
                                        const listStatusSelect = document.getElementById("listStatusSelect");
                                        const status = listStatusSelect.value;
                                        const blob = new Blob([JSON.stringify(selectedUsers)], { type: "text/plain" });
                                        const dlUrl = URL.createObjectURL(blob);
                                        await Util.Download(dlUrl, `niconicoNG_${status}.txt`);
                                    });
                                }
                            }
                        }
                    }
                }
            }
        }
        UpdateIllust(info) {
            if (info.user.status == Status.OK || info.user.status == Status.WHITE) {
                info.element.getElementsByTagName("img")[0].style.filter = "brightness(1)";
                if (info.element.parentElement == null) {
                    info.parent.appendChild(info.element);
                }
            }
            if (info.user.status == Status.NG) {
                info.element.getElementsByTagName("img")[0].style.filter = "brightness(0.3)";
                info.parent.appendChild(info.element);
            }
            if (info.user.status == Status.BLACK) {
                info.element.remove();
            }
        }
        AddUserLink(illustInfo) {
            if (illustInfo.element.getElementsByClassName("userLink").length > 0) {
                return;
            }
            const userElement = illustInfo.element.getElementsByClassName("user")[0];
            const userA = document.createElement("a");
            userA.className = "userLink";
            userA.href = "https://seiga.nicovideo.jp/user/illust/" + illustInfo.user.userId;
            userA.style.left = "0";
            userA.style.zIndex = "10";
            userA.style.right = "10px";
            userA.style.position = "absolute";
            userA.style.border = "0";
            userA.style.opacity = "0";
            userA.addEventListener("mouseover", () => {
                userA.style.border = "solid 1px silver";
                userA.style.opacity = "0.3";
            });
            userA.addEventListener("mouseleave", () => {
                userA.style.border = "0";
                userA.style.opacity = "0";
            });
            if (illustInfo.size == IllustSize.NOMAL) {
                userA.style.height = "10px";
                userA.style.top = "34px";
                userA.style.backgroundColor = "silver";
            }
            if (illustInfo.size == IllustSize.CUTOUT) {
                userA.style.height = "20px";
                userA.style.top = "20px";
                userA.style.backgroundColor = "black";
            }
            userElement.style.position = "relative";
            userElement.style.zIndex = "20";
            userElement.style.pointerEvents = "none";
            userElement.insertAdjacentElement("beforebegin", userA);
        }
        DrawBlackWhiteButton(illustInfo) {
            if (illustInfo.user.status == Status.BLACK || illustInfo.user.status == Status.WHITE) {
                if (illustInfo.user.status == Status.WHITE) {
                    const list = Array.from(illustInfo.element.getElementsByClassName("toListButton"));
                    for (let l of list) {
                        l.remove();
                    }
                }
                return;
            }
            if (illustInfo.element.getElementsByClassName("toListButton").length > 0) {
                return;
            }
            const whiteButton = document.createElement("input");
            const blackButton = document.createElement("input");
            whiteButton.style.position = "relative";
            whiteButton.style.zIndex = "20";
            whiteButton.style.visibility = "hidden";
            if (illustInfo.size == IllustSize.NOMAL) {
                whiteButton.style.left = "117px";
                whiteButton.style.top = "-30px";
                whiteButton.style.width = "40px";
                whiteButton.style.height = "25px";
            }
            if (illustInfo.size == IllustSize.CUTOUT) {
                whiteButton.style.left = "54px";
                whiteButton.style.top = "-19px";
                whiteButton.style.width = "30px";
                whiteButton.style.height = "19px";
            }
            //上記のスタイルを両方に適用
            blackButton.style.cssText = whiteButton.style.cssText;
            whiteButton.type = "button";
            blackButton.type = "button";
            whiteButton.className = "toListButton";
            blackButton.className = "toListButton";
            whiteButton.name = "white";
            blackButton.name = "black";
            whiteButton.style.cssText += `background-color : white !important;`;
            blackButton.style.cssText += `background-color : black !important;`;
            whiteButton.addEventListener("contextmenu", async (e) => {
                e.preventDefault();
                illustInfo.user.status = Status.OK;
                for (let info of this.illustInfos) {
                    this.UpdateIllust(info);
                }
                this.DrawList();
                await this.cacheStorage.SetStorageData(this.cache);
            });
            whiteButton.addEventListener("click", async () => {
                illustInfo.user.status = Status.WHITE;
                for (let info of this.illustInfos) {
                    this.UpdateIllust(info);
                    if (info.user.userId != illustInfo.user.userId) {
                        continue;
                    }
                    const buttons = info.element.getElementsByClassName("toListButton");
                    while (buttons.length != 0) {
                        buttons[0].remove();
                    }
                }
                this.DrawList();
                await this.cacheStorage.SetStorageData(this.cache);
            });
            blackButton.addEventListener("contextmenu", async (e) => {
                e.preventDefault();
                illustInfo.user.status = Status.NG;
                for (let info of this.illustInfos) {
                    this.UpdateIllust(info);
                }
                this.DrawList();
                await this.cacheStorage.SetStorageData(this.cache);
            });
            blackButton.addEventListener("click", async () => {
                illustInfo.user.status = Status.BLACK;
                for (let info of this.illustInfos) {
                    this.UpdateIllust(info);
                }
                this.DrawList();
                await this.cacheStorage.SetStorageData(this.cache);
            });
            if (illustInfo.size == IllustSize.NOMAL) {
                const infoElement = illustInfo.element.getElementsByClassName("illust_count")[0];
                blackButton.addEventListener("mouseover", () => {
                    infoElement.style.opacity = "1";
                });
                blackButton.addEventListener("mouseleave", () => {
                    infoElement.style.opacity = "";
                });
                whiteButton.addEventListener("mouseover", () => {
                    infoElement.style.opacity = "1";
                });
                whiteButton.addEventListener("mouseleave", () => {
                    infoElement.style.opacity = "";
                });
            }
            if (illustInfo.size == IllustSize.CUTOUT) {
                const infoElement = illustInfo.element.getElementsByClassName("illust_info")[0];
                blackButton.addEventListener("mouseover", () => {
                    infoElement.style.bottom = "0px";
                });
                blackButton.addEventListener("mouseleave", () => {
                    infoElement.style.bottom = "";
                });
                whiteButton.addEventListener("mouseover", () => {
                    infoElement.style.bottom = "0px";
                });
                whiteButton.addEventListener("mouseleave", () => {
                    infoElement.style.bottom = "";
                });
            }
            illustInfo.element.addEventListener("mouseover", () => {
                blackButton.style.visibility = "visible";
                whiteButton.style.visibility = "visible";
            });
            illustInfo.element.addEventListener("mouseleave", () => {
                blackButton.style.visibility = "hidden";
                whiteButton.style.visibility = "hidden";
            });
            illustInfo.element.appendChild(whiteButton);
            illustInfo.element.appendChild(blackButton);
        }
        async AddInfos(illustListElement) {
            var _a;
            illustListElement.style.visibility = "hidden";
            for (let moreLink of Array.from(illustListElement.getElementsByClassName("list_more_link"))) {
                if (moreLink.parentElement == null) {
                    continue;
                }
                moreLink.parentElement.insertAdjacentElement("afterend", moreLink);
            }
            const illustElements = Array.from(illustListElement.getElementsByClassName("list_item"));
            const illustCutoutElements = Array.from(illustListElement.getElementsByClassName("list_item_cutout"));
            illustElements.push(...illustCutoutElements);
            const illustIds = this.GetIllustIds(illustListElement);
            const names = Array.from(illustListElement.getElementsByClassName("user"));
            //console.log(illustIds);
            //console.log(illustElements);
            //console.log(names);
            //キャッシュからの情報と合わせて追加(もうこれ分かんねぇこともある)
            for (let i = 0; i < illustIds.length; i++) {
                if (this.illustInfos.some(info => info.illustId == illustIds[i] && info.element == illustElements[i])) {
                    continue;
                }
                const info = this.GetInfo(illustIds[i]);
                let size = IllustSize.NOMAL;
                if (illustElements[i].classList.contains("list_item_cutout")) {
                    size = IllustSize.CUTOUT;
                }
                this.illustInfos.push({
                    name: (_a = names[i].textContent) !== null && _a !== void 0 ? _a : "",
                    illustId: illustIds[i],
                    illust: info == undefined ? { created: "", id: "" } : info.illust,
                    user: info == undefined ? { illusts: [], status: Status.NONE, userId: "" } : info.user,
                    element: illustElements[i],
                    parent: illustListElement,
                    size: size
                });
            }
        }
        SetCurrentPage(url) {
            for (let i = 0; i < pageInfos.length; i++) {
                if (pageInfos[i].regex.test(url)) {
                    this.currentPage = i;
                    return this.option.usePages[i];
                }
            }
            this.currentPage = PageType.None;
            return false;
        }
        //メインクラス、メイン関数の肥大化もう始まってる!
        async Run(illustListElements) {
            await Observer.DefinitelyGetElementByClassName("illust_list");
            await Observer.DefinitelyGetElementById("footer");
            illustListElements = illustListElements !== null && illustListElements !== void 0 ? illustListElements : Array.from(document.getElementsByClassName("item_list"));
            for (let illustListElement of illustListElements) {
                await this.AddInfos(illustListElement);
            }
            //console.log("infos", this.illustInfos, this.illustInfos.length);
            //これもう分かんねぇやつら
            const unkownInfos = this.illustInfos.filter(info => info.user.userId == "");
            //console.log("unkownInfos", unkownInfos);
            //この戻り値なんかダサい・・・ダサくない?
            const result = await Fetcher.FetchIllustDatas(unkownInfos.map(info => info.illustId));
            //これもう分かんねぇやつらとキャッシュまで!?の情報更新
            for (let i = 0; i < unkownInfos.length; i++) {
                unkownInfos[i].illust = result.illusts[i];
                let cachedUser = this.cache.find((c) => c.userId == result.userIds[i]);
                if (cachedUser == undefined) {
                    unkownInfos[i].user.userId = result.userIds[i];
                    unkownInfos[i].user.status = Status.OK;
                    this.cache.push(unkownInfos[i].user);
                }
                else {
                    //キャッシュ使ったら後ろにしとく
                    this.cache = this.cache.filter(c => c.userId != (cachedUser === null || cachedUser === void 0 ? void 0 : cachedUser.userId));
                    this.cache.push(cachedUser);
                    unkownInfos[i].user = cachedUser;
                }
                unkownInfos[i].user.illusts.push(result.illusts[i]);
            }
            //増えすぎたキャッシュ削除
            if (this.cache.length > 0) {
                let okCount = 0;
                for (let c of this.cache) {
                    if (c.status == Status.OK) {
                        okCount++;
                    }
                }
                while (okCount > this.option.okCacheMax) {
                    //OK以外消さない
                    if (this.cache[0].status != Status.OK) {
                        const c = this.cache.shift();
                        this.cache.push(c);
                        continue;
                    }
                    //今使ってたら消さない
                    if (this.illustInfos.some(info => info.user.userId == this.cache[0].userId)) {
                        break;
                    }
                    this.cache.shift();
                    okCount--;
                }
            }
            //console.log(result);
            //ブラック,ホワイトリストにないイラストエレメントにボタン追加
            for (let illustInfo of this.illustInfos) {
                this.DrawBlackWhiteButton(illustInfo);
                this.AddUserLink(illustInfo);
            }
            if (this.option.judge.isJudge) {
                //情報取ってきた投稿者の荒らし判定更新 ↓これは重複排除
                for (let c of [...new Set(unkownInfos.map(u => u.user))]) {
                    this.CheckArasi(c);
                }
            }
            await this.cacheStorage.SetStorageData(this.cache);
            for (let info of this.illustInfos) {
                this.UpdateIllust(info);
            }
            for (let illustListElement of illustListElements) {
                illustListElement.style.visibility = "visible";
            }
            await this.SetOptionButton();
            this.DrawList();
        }
    }
    ;
    const main = new Main();
    await main.GetStorageData();
    await main.SetOptionButton();
    const isUseNG = main.SetCurrentPage(location.href);
    if (!isUseNG) {
        return;
    }
    await main.Run();
    const illustList = await Observer.DefinitelyGetElementByClassName("illust_list");
    const mutationObserver = new MutationObserver(async (mrs) => {
        for (let mr of mrs) {
            for (let i = 0; i < mr.addedNodes.length; i++) {
                const element = mr.addedNodes[i];
                if (element.classList != null && element.classList.contains("item_list")) {
                    await main.Run([element]);
                }
            }
        }
    });
    mutationObserver.observe(illustList, {
        childList: true,
        subtree: true
    });
})();