f95zone watched filter

f95zone filter only the watched threads.

// ==UserScript==
// @name        f95zone watched filter
// @namespace   f95zone watched filter
// @description f95zone filter only the watched threads.
// @author       C. Gauthier
// @license     MIT
// @icon        https://www.google.com/s2/favicons?domain=f95zone.to
// @match       https://f95zone.to/sam/latest_alpha/
// @version     1.0.0
// @require     https://cdn.jsdelivr.net/combine/npm/@violentmonkey/dom@2,npm/@violentmonkey/ui@0.7
// @require     https://cdn.jsdelivr.net/npm/@violentmonkey/dom@2/dist/solid.js
// @require     https://cdn.jsdelivr.net/npm/lodash@4/lodash.min.js
// @require     https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js
// @grant       GM_addStyle
// @grant       GM_getValue
// @grant       GM_setValue
// ==/UserScript==

(function (web, lodash, solidJs) {
    'use strict';
    $(function(b) {
        var css_248z$1 = ".customTags{border-radius:2px;box-shadow:0 0 0 0 transparent,0 1px 1px 0 rgba(0,0,0,.15),0 1px 2px 0 rgba(0,0,0,.15);display:inline-block;font-size:.8em;line-height:1.8em;margin:4px 4px 0 0;padding:0 6px;text-shadow:1px 1px 2px rgba(0,0,0,.75)}.selected-tags-wrap span:hover{background-color:#ba4545}.selected-tags-wrap span{background-color:#181a1d;border-radius:3px;cursor:pointer;display:inline-block;font-size:.9em;line-height:24px;margin:4px 4px 0 0;padding:0 7px;transition:.2s}.input-tag{left:0;opacity:1;position:relative;width:127px}.border-gradient{border:3px solid;border-image-slice:1}.flxgrow{flex-grow:1}.solid-select-multi-value{background-color:#181a1d;border-radius:3px;display:inline-block;font-size:.9em;gap:5px;line-height:24px;margin:4px 4px 0 0;padding:0 7px;transition:.2s}.solid-select-multi-value-remove{background-color:#ba4545;background-color:#953737;border:none;border-radius:2px;cursor:pointer}.solid-select-list{background:#181a1b;z-index:2}.select-likes.select-likes{border:1px solid grey;margin-bottom:5px;padding:5px}";

        var css_248z = ".solid-select-container[data-disabled=true]{pointer-events:none}.solid-select-container{position:relative}.solid-select-control[data-disabled=true]{--tw-bg-opacity:1;--tw-border-opacity:1;background-color:rgba(243,244,246,var(--tw-bg-opacity));border-color:rgba(209,213,219,var(--tw-border-opacity))}.solid-select-control{--tw-border-opacity:1;border-color:rgba(229,231,235,var(--tw-border-opacity));border-radius:.25rem;border-width:1px;display:-ms-grid;display:grid;grid-template-columns:repeat(1,minmax(0,1fr));line-height:1.5;padding:.25rem .5rem}.solid-select-control[data-multiple=true][data-has-value=true]{-webkit-box-align:stretch;-ms-flex-align:stretch;grid-gap:.25rem;-webkit-align-items:stretch;align-items:stretch;display:-webkit-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-wrap:wrap;gap:.25rem}.solid-select-control:focus-within{--tw-outline-opacity:1;outline-color:rgba(209,213,219,var(--tw-outline-opacity))}.solid-select-placeholder{--tw-text-opacity:1;color:rgba(156,163,175,var(--tw-text-opacity))}.solid-select-placeholder,.solid-select-single-value{grid-column-start:1;grid-row-start:1}.solid-select-multi-value{--tw-bg-opacity:1;-webkit-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center;background-color:rgba(243,244,246,var(--tw-bg-opacity));border-radius:.25rem;display:-webkit-box;display:-ms-flexbox;display:-webkit-flex;display:flex;font-size:85%;line-height:1;line-height:inherit;padding-left:4px;padding-right:4px}.solid-select-multi-value-remove{padding-left:.25rem;padding-right:.25rem}.solid-select-multi-value-remove:hover{text-shadow:1px 1px 3px rgba(0,0,0,.29),2px 4px 7px rgba(73,64,125,.35)}.solid-select-input{-webkit-box-flex:1;background-color:initial;border-width:0;caret-color:transparent;-ms-flex:1 1 0%;-webkit-flex:1 1 0%;flex:1 1 0%;font:inherit;grid-column-start:1;grid-row-start:1;margin:0;outline:2px solid transparent;outline-offset:2px;padding:0}.solid-select-input:read-only{cursor:default}.solid-select-input[data-is-active=true],.solid-select-input[data-multiple=true]{caret-color:currentColor}.solid-select-list{--tw-shadow:0 10px 15px -3px rgb(0 0 0/0.1),0 4px 6px -4px rgb(0 0 0/0.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);background-color:inherit;border-radius:.125rem;-webkit-box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);margin-top:.25rem;max-height:50vh;min-width:100%;overflow-y:auto;padding:.5rem;position:absolute;white-space:nowrap;z-index:1}.solid-select-option:hover{--tw-bg-opacity:1;background-color:rgba(229,231,235,var(--tw-bg-opacity))}.solid-select-option[data-focused=true]{--tw-bg-opacity:1;background-color:rgba(243,244,246,var(--tw-bg-opacity))}.solid-select-option>mark{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgba(unset,var(--tw-bg-opacity));color:rgba(unset,var(--tw-text-opacity));-webkit-text-decoration-line:underline;text-decoration-line:underline}.solid-select-option{cursor:default;padding:.5rem 1rem;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.solid-select-option[data-disabled=true]{--tw-text-opacity:1;color:rgba(156,163,175,var(--tw-text-opacity));pointer-events:none}.solid-select-list-placeholder{cursor:default;padding:.5rem 1rem;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}";
        var SelectCss = css_248z;


        var thread_data = GM_getValue('thread_data', []);
        var test = [];


        console.log(GM_getValue("thread_data", []));
        //GM_setValue("thread_data", []);


        // ==/ajaxSetup==
        b.ajaxSetup({
            method: "GET",
            cache: !1,
            dataType: "json",
            timeout: 1E4
        });

        //var redirectXHR = GM_getValue('watchedFilter', false);

        // Save the original send method
        const originalSend = XMLHttpRequest.prototype.send;

        // Override the send method
        XMLHttpRequest.prototype.send = function(body) {
            // Store the reference to the current XHR object
            const xhr = this;
            //console.log('ready to intercept request to:', xhr.responseURL);

            // Attach an event listener to capture the response
            xhr.addEventListener('readystatechange', function() {
                if (xhr.readyState === XMLHttpRequest.DONE && xhr.responseURL.includes('latest_data.php?cmd=list') && GM_getValue('watchedFilter', false)) {

                    // Here you can modify the response before it's processed by the application
                    const filtered = filterThreadData(xhr.responseURL);
                    const threads = filtered[0];
                    const searchParams = new URLSearchParams(xhr.responseURL); const page = Number(searchParams.get("page"));
                    const pTotal = filtered[1];
                    const count = filtered[2];
                    let customData = JSON.stringify({ "status": "ok", "msg": { "data": threads, "pagination": { "page": page, "total": pTotal }, "count": count }}); // Your custom JSON data

                    // Override the responseText property to return your custom data
                    Object.defineProperty(xhr, 'responseText', { value: customData });
                }
            });

            // Call the original send method to continue with the request
            originalSend.apply(this, arguments);
        };

        function sortArrayByKey(arr, key, ascending = false) {
            return arr.sort((a, b) => {
                if (typeof a[key] === 'string') {
                    return ascending ? a[key].localeCompare(b[key]) : b[key].localeCompare(a[key]);
                } else {
                    return ascending ? a[key] - b[key] : b[key] - a[key];
                }
            });
        }

        function calculateWeightedRating(threads, m = 3.5, C = 100000) {
            // C is the minimum number of views required to be considered
            // m is the average rating across all threads

            m = threads.reduce((accumulator, currentValue) => accumulator + currentValue.rating, 0,)/threads.length;

            return threads.map(thread => {
                const { rating, views } = thread;

                // Calculate the weighted rating using the Bayesian formula
                const weightedRating = (views*rating + m*C) / (views+C)
                //console.log(thread.title, "weightedRating :", weightedRating);

                return {
                    ...thread,
                    weightedRating: weightedRating.toFixed(2) // round to 2 decimal places
                };
            });
        }

        function filterThreadData(url){
            var tmp_thread_data = GM_getValue('thread_data', []);
            //var tmp_thread_data = thread_data.map((x) => x);
            const searchParams = new URLSearchParams(url);

            //sort
            if(searchParams.has("sort")){
                let key = searchParams.get("sort"); let ascending = key == "title";
                switch(searchParams.get("sort")) {
                    case "date":
                        break;
                    case "rating":
                        tmp_thread_data = calculateWeightedRating(tmp_thread_data);
                        console.log(thread_data);
                        console.log(tmp_thread_data[0].title, "date :", tmp_thread_data[0].date, "weightedRating :", tmp_thread_data[0].weightedRating);
                        sortArrayByKey(tmp_thread_data, "weightedRating", ascending);
                        break;
                    default:
                        sortArrayByKey(tmp_thread_data, key, ascending);
                }
                /*let key = searchParams.get("sort"); var ascending = key == "title";
                sortArrayByKey(tmp_thread_data, key, ascending);*/
            }

            //date
            if(searchParams.has("date")){
                let key = Number(searchParams.get("date"));
                //console.log("data :", tmp_thread_data);
                tmp_thread_data = tmp_thread_data.filter(thread => {
                    const timeDifference = new Date() - new Date(thread.date);
                    const daysDifference = timeDifference / (1000 * 60 * 60 * 24);
                    return daysDifference < key
                });
                //tmp_thread_data = tmp_thread_data.filter(thread => thread.date.includes(key));
            }

            //tags (and/or)
            if(searchParams.has("tags[]")){
                let key = searchParams.getAll("tags[]").map(Number);
                tmp_thread_data = tmp_thread_data.filter(thread => {
                    if(searchParams.has("tagtype")){
                        // Return true if at least one of the tags in key is found in the thread's tags array
                        return key.some(tag => thread.tags.includes(tag));
                    }else{
                        // Check if every tag in keys is present in item.tags
                        return key.every(tag => thread.tags.includes(tag));
                    }
                });
            }

            //notags
            if(searchParams.has("notags[]")){
                let key = searchParams.getAll("notags[]").map(Number);
                tmp_thread_data = tmp_thread_data.filter(thread => {
                    // Return true if none of thetags in key are found in the thread's tags array
                    return !key.some(tag => thread.tags.includes(tag));
                });
            }

            //prefixes
            if(searchParams.has("prefixes[]")){
                let key = searchParams.getAll("prefixes[]").map(Number);
                tmp_thread_data = tmp_thread_data.filter(thread => {
                    // Return true if all of the prefixes in key are found in the thread's prefixes array
                    return key.every(tag => thread.prefixes.includes(tag));
                });
            }

            //noprefixes
            if(searchParams.has("noprefixes[]")){
                let key = searchParams.getAll("noprefixes[]").map(Number);
                tmp_thread_data = tmp_thread_data.filter(thread => {
                    // Return true if none of the prefixes in key are found in the thread's prefixes array
                    return !key.some(tag => thread.prefixes.includes(tag));
                });
            }

            //search
            if(searchParams.has("search")){
                let key = searchParams.get("search").toLowerCase();
                tmp_thread_data = tmp_thread_data.filter(thread => thread.title.toLowerCase().includes(key));
            }

            //creator
            if(searchParams.has("creator")){
                let key = searchParams.get("creator").toLowerCase();
                tmp_thread_data = tmp_thread_data.filter(thread => thread.creator.toLowerCase().includes(key));
            }

            //page and rows
            let page = [];
            let rows = 30; if(searchParams.has("rows")){rows = Number(searchParams.get("rows"));}
            if(searchParams.has("page")){
                let key = Number(searchParams.get("page"));
                for(let id = rows*(key-1); id < Math.min(rows*key, tmp_thread_data.length); id++){
                    page.push(tmp_thread_data[id]);
                }
            }

            //Date() to String ( Date() => "x mins / hrs / days / weeks / months / years" )
            //console.log(page);
            page.forEach(thread => {
                let d = timeSince(Date.parse(thread.date));
                thread.date = String(d[0]) + " "+ d[1];
            });


            return [page, Math.ceil(tmp_thread_data.length/rows), tmp_thread_data.length];
        }



        function subtractTime(date, input) {
            const [amount, unit] = (() => {
                const parts = input.split(' ');
                if (parts.length === 2) {
                    return [parseInt(parts[0]), parts[1]];
                } else if (input.toLowerCase() === "yesterday") {
                    return [1, "days"];
                } else {
                    return [null, null];
                }
            })();

            if (amount === null || unit === null) {
                return date;
            }

            const newDate = new Date(date);

            switch (unit) {
                case 'min':
                case 'mins':
                    newDate.setMinutes(newDate.getMinutes() - amount);
                    break;
                case 'hr':
                case 'hrs':
                    newDate.setHours(newDate.getHours() - amount);
                    break;
                case 'days':
                    newDate.setDate(newDate.getDate() - amount);
                    break;
                case 'week':
                case 'weeks':
                    newDate.setDate(newDate.getDate() - (amount * 7));
                    break;
                case 'month':
                case 'months':
                    newDate.setMonth(newDate.getMonth() - amount);
                    break;
                case 'year':
                case 'years':
                    newDate.setFullYear(newDate.getFullYear() - amount);
                    break;
                default:
                    throw new Error('Invalid time unit');
            }

            return newDate;
        }

        function timeSince(date) {
            const now = new Date();
            const diffInMs = now - date;

            const minutes = Math.floor(diffInMs / (1000 * 60));
            const hours = Math.floor(diffInMs / (1000 * 60 * 60));
            const days = Math.floor(diffInMs / (1000 * 60 * 60 * 24));
            const weeks = Math.floor(days / 7);
            const months = Math.floor(days / 30);
            const years = Math.floor(days / 365);

            if (minutes < 1) {
                return [0, "min"];
            } else if (minutes === 1) {
                return [1, "min"];
            } else if (minutes < 60) {
                return [minutes, "mins"];
            } else if (hours === 1) {
                return [1, "hr"];
            } else if (hours < 24) {
                return [hours, "hrs"];
            } else if (days === 1) {
                return ["", "yesterday"];
            } else if (days < 7) {
                return [days, "days"];
            } else if (weeks === 1) {
                return [1, "week"];
            } else if (weeks < 4) {
                return [weeks, "weeks"];
            } else if (months === 1) {
                return [1, "month"];
            } else if (months < 12) {
                return [months, "months"];
            } else if (years === 1) {
                return [1, "year"];
            } else {
                return [years, "years"];
            }
        }

        function splitString(input) {
            const parts = input.split(' ');

            if (parts.length === 2) {
                if(parts[1] == "hours"){return [parts[0], "hrs"];}
                return [parts[0], parts[1]];
            } else {
                return ["", parts[0]];
            }
        }

        function uniqByKeepFirst(data, key) {
            const seen = new Set();
            return data.filter(obj => {
                const keyValue = obj[key];
                if (seen.has(keyValue)) {
                    return false;
                } else {
                    seen.add(keyValue);
                    return true;
                }
            });
        }



        const prefixes = {"23":{"id":23,"name":"SiteRip","class":"label--lightGreen"},"19":{"id":19,"name":"Collection","class":"label--gray"},"13":{"id":13,"name":"VN","class":"label--red"},"14":{"id":14,"name":"Others","class":"label--lightGreen"},"5":{"id":5,"name":"RAGS","class":"label--orange"},"2":{"id":2,"name":"RPGM","class":"label--blue"},"47":{"id":47,"name":"WebGL","class":"pre-webgl"},"3":{"id":3,"name":"Unity","class":"pre-unity"},"4":{"id":4,"name":"HTML","class":"label--olive"},"1":{"id":1,"name":"QSP","class":"label--red"},"6":{"id":6,"name":"Java","class":"pre-java"},"7":{"id":7,"name":"Ren\u0026#039;Py","class":"pre-renpy"},"31":{"id":31,"name":"UnrealEngine","class":"label--royalBlue"},"30":{"id":30,"name":"WolfRPG","class":"label--green"},"8":{"id":8,"name":"Flash","class":"label--gray"},"12":{"id":12,"name":"ADRIFT","class":"label--blue"},"17":{"id":17,"name":"Tads","class":"label--blue"},"18":{"id":18,"name":"Completed","class":"label--blue"},"20":{"id":20,"name":"Onhold","class":"label--skyBlue"},"22":{"id":22,"name":"Abandoned","class":"label--orange"}};



        function MarkFilter() {
            const isChecked = GM_getValue('watchedFilter', false);

            //console.log(isChecked, typeof isChecked);
            /*for (let i = 0; i < element.length; i++) {
                if (isChecked) {
                    element[i].setAttribute('isOriginal', 'true');
                }else{
                    if(element[i].getAttribute('isOriginal') === 'false'){
                        element[i].remove();
                        //i--;
                    }else{
                        element[i].setAttribute('isOriginal', 'false');
                    }
                }
            }
            if(isChecked){AlternateFilter(); } */
        }


        /*
        function AlternateFilter(){
            const element = document.querySelectorAll('.resource-tile');
            const data = GM_getValue("thread_data",[]);
            const parent = document.querySelector('.grid-selected');

            for(var i = 0; i < Math.max(data.length, 300); i++){
                const e = data[i];
                if(e.watched == true){
                    const newDiv = document.createElement("div");

                    var views = e.views;
                    if (999 < e.views && e.views <= 999999) {views = String(Math.floor(e.views/1000)); if(views.length==1){views+="."+String(Math.floor(e.views/100)-Number(views)*10);} views+="K";}
                    else if (e.views > 999999) {views = String(Math.floor(e.views/1000000)); if(views.length==1){views+="."+String(Math.floor(e.views/100000)-Number(views)*10);} views+="M";}

                    var ratingStars = Math.floor(e.rating/5*100); //the % of the 5 rating stars of the thread needing to be filled

                    var tags = e.tags[0]; for(var j0 = 1; j0 < e.tags.length; j0++){tags += "," + e.tags[j0];} //the list of tags of the thread

                    var images = e.screens[0]; for(var j1 = 1; j1 < e.screens.length; j1++){images += "," + e.screens[j1];} //the urls of preview pictures of the thread

                    var eDate = Date.parse(e.date); //the aproximate date since creation of the thread
                    var date_type = timeSince(eDate)[1];
                    var date = String(timeSince(eDate)[0]);


                    var p = e.prefixes;
                    var prefixes_left = ''; var prefixes_right = '';
                    p.forEach((id) => {
                        var temp = '<div class="'+prefixes[id]["class"]+'">'+prefixes[id]["name"]+'</div>';
                        if(id == 18 || id == 20 || id == 22){
                            prefixes_right += temp;
                        }else{
                            prefixes_left += temp;
                            }
                    });


                    // Set the class attribute
                    newDiv.className = 'resource-tile resource-tile_update border-gradient';

                    // Set the style attribute (even if it's empty here)
                    newDiv.style.cssText = '';

                    // Set the custom data attributes
                    newDiv.setAttribute('data-thread-id', e.thread_id);
                    newDiv.setAttribute('data-tags', tags);
                    newDiv.setAttribute('data-images', images);

                    // Set the other attributes
                    newDiv.setAttribute('isdisplay', e.watched);
                    newDiv.setAttribute('isignore', e.ignored);
                    newDiv.setAttribute('isOriginal', 'false');

                    newDiv.innerHTML = '<a href="https://f95zone.to/threads/'+e.thread_id+'/" class="resource-tile_link" rel="noopener" target="_blank" title=""><div class="resource-tile_thumb-wrap"><div class="resource-tile_thumb" style="background-image:url('+e.cover+')"></div></div><div class="resource-tile_body" style="position: relative; top: auto; width: 100%; left: auto; height: auto;"><div class="resource-tile_label-wrap"><div class="resource-tile_label-wrap_left">'+prefixes_left+'</div><div class="resource-tile_label-wrap_right">'+prefixes_right+'<div class="resource-tile_label-version">'+e.version+'</div></div></div><div class="resource-tile_info"><header class="resource-tile_info-header"><div class="header_title-wrap"><h2 class="resource-tile_info-header_title" style="text-overflow: ellipsis; text-indent: 0px; transition: text-indent 0.2s linear;">'+e.title+'</h2></div><div class="header_title-ver">'+e.version+'</div><div class="resource-tile_dev fas fa-user">'+e.creator+'</div></header><div class="resource-tile_info-meta"><div class="resource-tile_info-meta_time"><span class="tile-date_'+date_type+'">'+date+'</span></div><div class="resource-tile_info-meta_likes">'+e.likes+'</div><div class="resource-tile_info-meta_views">'+views+'</div><div class="resource-tile_info-meta_rating">'+e.rating+'</div><div class="resource-tile_rating"><span style="width:'+ratingStars+'%"></span></div></div></div></div></a>'
                    parent.appendChild(newDiv);
                }

            };
        }
        */

        async function getPagesData(){


            function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
            var page_number = GM_getValue('pages_to_filter', 1);
            console.log("data is loading, pages searched : " + page_number);
            //page_number = document.querySelector("#sub-nav_inner > div.sub-nav_paging > div").lastChild.getAttribute("data-page");// need to find something else to not use the "item per page" slider
            //page_number = 1;

            // Create the overlay div
            var overlay = document.createElement('div');

            // Apply styles to the overlay div
            overlay.style.position = 'fixed'; overlay.style.top = '0';overlay.style.left = '0'; overlay.style.width = '100%'; overlay.style.height = '100%'; overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; //style
            overlay.style.zIndex = '9999'; // ensure it's on top of all other elements

            // Create the message element
            var message = document.createElement('div');
            message.innerText = 'Please wait, loading...'; // Your custom message
            message.style.color = 'white';message.style.fontSize = '24px';message.style.fontFamily = 'Arial, sans-serif';message.style.textAlign = 'center';message.style.padding = '20px';message.style.backgroundColor = 'rgba(0, 0, 0, 0.75)';message.style.borderRadius = '10px';

            // Append the message to the overlay
            overlay.appendChild(message);

            // Add the overlay to the document body
            document.body.appendChild(overlay);

            for (let i = 1; i <= page_number; i++) {
                console.log("page "+i+" ...");
                await b.ajax({
                    url: "latest_data.php?cmd=list&cat=games&page="+i+"&sort=date&rows=90&_=1710376207895", //only works if the "item per page" slider is on 90
                    success: function(f) {
                        f.msg.data.forEach(function(l) {if(l.watched){

                            var newDate = subtractTime(new Date(), l.date); // change the l.date string as a Date object aproximating the creation date instead of a string of the time since creation
                            l.date = String(newDate);

                            test.push(l);
                        }});
                    }
                });
            }

            if (overlay) {
                overlay.parentNode.removeChild(overlay);
            }
            var concat = test.concat(thread_data);
            thread_data = uniqByKeepFirst(concat, "thread_id");
            GM_setValue("thread_data", thread_data);
            await sleep(500);
            console.log("your watched threads data :", GM_getValue("thread_data", "data not found"));

        }

        function init() {
            const element = document.querySelectorAll('.resource-tile');
            const elementLength = element.length;
            if (element[0]) {
                for (let i = 0; i < 3; i++) {
                    MarkFilter();
                    const filtered = _.filter(document.querySelectorAll('.resource-tile'), e => {
                        return e.getAttribute('isDisplay') === 'true';
                    });
                    console.debug('Filtered', filtered);
                    if (filtered.length < elementLength) {
                        break;
                    }
                }
            } else {
                setTimeout(init, 100);
            }
        }

        const _tmpl$$7 = /*#__PURE__*/web.template(`<div class=filter-block><div class=filter-block_button-wrap><span class="filter-block_title flxgrow">Filter watched threads:</span><input type=checkbox id=filter-mark>`);
        function FilterMark() {
            const onChange = event => {
                GM_setValue('watchedFilter', event.target.checked);
                //window.location.reload();
                MarkFilter();
            };
            return (() => {
                const _el$ = _tmpl$$7(),
                      _el$2 = _el$.firstChild,
                      _el$3 = _el$2.firstChild,
                      _el$4 = _el$3.nextSibling;
                _el$2.style.setProperty("display", "flex");
                _el$4.addEventListener("change", onChange);
                web.effect(() => _el$4.checked = GM_getValue('watchedFilter', false));
                return _el$;
            })();
        }

        const _tmpl$$8 = /*#__PURE__*/web.template(`<div class=filter-block><div class=filter-block_button-wrap><span class="filter-block_title flxgrow">Thread scrapper:</span><input type="number" id="pages-to-filter" name="quantity" min="1" max="300"><input type=button id=get-pages value="get data">`);
        function GetPagesDataButton() {
            const onPages = event => {
                GM_setValue('pages_to_filter', event.target.value);
            };
            return (() => {
                const _el$ = _tmpl$$8(),
                      _el$2 = _el$.firstChild,
                      _el$3 = _el$2.firstChild,
                      _el$4 = _el$3.nextSibling,
                      _el$5 = _el$4.nextSibling;
                _el$2.style.setProperty("display", "flex");
                _el$4.addEventListener("change", onPages);
                _el$5.addEventListener("click", getPagesData);
                web.effect(() => _el$4.value = GM_getValue('pages_to_filter', 1));
                return _el$;
            })();
        }

        const _tmpl$ = /*#__PURE__*/web.template(`<style>`);
        function mainFilter() {
            solidJs.createEffect(() => {
                init();

                // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                // @ts-ignore
                window.history.onpushstate = function () {
                    setTimeout(init, 200);
                };
                (function (history) {
                    const pushState = history.pushState;
                    history.pushState = function (state) {
                        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                        // @ts-ignore
                        if (typeof history.onpushstate === 'function') {
                            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                            // @ts-ignore
                            history.onpushstate({
                                state
                            });
                        }
                        return pushState.apply(history, arguments);
                    };
                })(window.history);
            }, [window.history]);
            return [web.createComponent(FilterMark, {}), web.createComponent(GetPagesDataButton, {}), (() => {
                const _el$ = _tmpl$();
                web.insert(_el$, SelectCss);
                return _el$;
            })(), (() => {
                const _el$2 = _tmpl$();
                web.insert(_el$2, css_248z$1);
                return _el$2;
            })()];
        }

        web.render(mainFilter, document.querySelector('.content-block_filter'));
    });

})(VM.solid.web, _, VM.solid);