Furaffinity-Request-Helper

Helper Library to simplify requests to Furaffinity

Tính đến 18-11-2024. Xem phiên bản mới nhất.

Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta // @require https://update.greatest.deepsurf.us/scripts/483952/1486330/Furaffinity-Request-Helper.js

// ==UserScript==
// @name        Furaffinity-Request-Helper
// @namespace   Violentmonkey Scripts
// @grant       none
// @version     1.1.0
// @author      Midori Dragon
// @description Helper Library to simplify requests to Furaffinity
// @icon        https://www.furaffinity.net/themes/beta/img/banners/fa_logo.png?v2
// @license     MIT
// ==/UserScript==
// jshint esversion: 8
(() => {
    "use strict";
    class Semaphore {
        constructor(maxConcurrency) {
            this.maxConcurrency = maxConcurrency, this.currentConcurrency = 0, this.waitingQueue = [];
        }
        acquire() {
            return new Promise(((resolve, _) => {
                this.currentConcurrency < this.maxConcurrency ? (this.currentConcurrency++, resolve()) : this.waitingQueue.push(resolve);
            }));
        }
        release() {
            if (this.waitingQueue.length > 0) {
                this.waitingQueue.shift()();
            } else this.currentConcurrency--;
        }
    }
    class PercentHelper {
        constructor() {
            throw new Error("The PercentHelper class is static and cannot be instantiated.");
        }
        static percentAll={};
        static setPercentValue(id, value) {
            return !!(id && value && PercentHelper.percentAll.hasOwnProperty(id)) && (PercentHelper.percentAll[id] = value, 
            !0);
        }
        static getPercentValue(id, decimalPlaces = 2) {
            if (!id) return -1;
            const percent = PercentHelper.percentAll[id];
            return percent ? parseFloat(percent.toFixed(decimalPlaces)) : -1;
        }
        static createPercentValue(uniqueId) {
            return uniqueId || (uniqueId = Date.now() + Math.random()), PercentHelper.percentAll[uniqueId] = 0, 
            uniqueId;
        }
        static deletePercentValue(id) {
            PercentHelper.percentAll.hasOwnProperty(id) && delete PercentHelper.percentAll[id];
        }
    }
    class WaitAndCallAction {
        constructor(action, usePercent, delay) {
            this.action = action, this.delay = delay, this.intervalId, this.usePercent = usePercent, 
            this._running = !1;
        }
        start() {
            if (this.action && this.delay && !1 === this._running) return this._running = !0, 
            this.usePercent && PercentHelper.createPercentValue(this.intervalId.toString()), 
            this.intervalId = setInterval((() => {
                this.usePercent ? this.action(PercentHelper.getPercentValue(this.intervalId.toString())) : this.action();
            }), this.delay), this.intervalId;
        }
        stop() {
            this._running && (this._running = !1, clearInterval(this.intervalId), this.usePercent && PercentHelper.deletePercentValue(this.intervalId.toString()));
        }
        static async callFunctionAsync(functionToCall, params, action, delay, usePercent) {
            const waitAndCallAction = new WaitAndCallAction(action, usePercent, delay), percentId = waitAndCallAction.start();
            usePercent && params.push(percentId);
            const result = await functionToCall(...params);
            return waitAndCallAction.stop(), result;
        }
        static callFunction(functionToCall, params, action, delay, usePercent) {
            const waitAndCallAction = new WaitAndCallAction(action, usePercent, delay), percentId = waitAndCallAction.start();
            usePercent && params.push(percentId);
            const result = functionToCall(...params);
            return waitAndCallAction.stop(), result;
        }
    }
    class Logger {
        constructor() {
            throw new Error("The Logger class is static and cannot be instantiated.");
        }
        static logMessage(message) {
            FuraffinityRequests.logLevel >= 3 && console.log(message);
        }
        static logWarning(message) {
            FuraffinityRequests.logLevel >= 2 && console.warn(message);
        }
        static logError(message) {
            FuraffinityRequests.logLevel >= 1 && console.error(message);
        }
        static setLogLevel(level) {
            FuraffinityRequests.logLevel = level;
        }
    }
    class IdArray {
        constructor() {
            throw new Error("The IdArray class is static and cannot be instantiated.");
        }
        static getTillId(collection, toId) {
            const result = [];
            for (const elem of Array.from(collection)) if (result.push(elem), elem.id.toString().replace("sid-", "") == toId) break;
            return result;
        }
        static getSinceId(collection, fromId) {
            const array = Array.from(collection);
            array.reverse();
            const result = [];
            for (const elem of array) if (result.push(elem), elem.id.toString().replace("sid-", "") == fromId) break;
            return result.reverse(), result;
        }
        static getBetweenIds(collection, fromId, toId) {
            const array = Array.from(collection);
            let startIndex = -1, endIndex = -1;
            for (let i = 0; i < array.length && (array[i].id.toString().replace("sid-", "") == fromId && (startIndex = i), 
            array[i].id.toString().replace("sid-", "") == toId && (endIndex = i), -1 == startIndex || -1 == endIndex); i++) ;
            if (-1 == startIndex && -1 == endIndex) return array;
            -1 == startIndex && (startIndex = 0), -1 == endIndex && (endIndex = array.length - 1);
            const result = [];
            for (let i = startIndex; i <= endIndex; i++) result.push(array[i]);
            return result;
        }
        static containsId(collection, id) {
            for (const elem of Array.from(collection)) if (elem.id.toString().replace("sid-", "") == id) return !0;
            return !1;
        }
    }
    class Scraps {
        constructor(semaphore) {
            this.semaphore = semaphore;
        }
        static get hardLink() {
            return FuraffinityRequests.getUrl() + "/scraps/";
        }
        async getFiguresBetweenIds(username, fromId, toId, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, toId, null, "scraps", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, fromId, null, "scraps", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, fromId, toId, null, null, "scraps", this.semaphore ], action, delay, !0);
        }
        async getFiguresBetweenIdsBetweenPages(username, fromId, toId, fromPageNumber, toPageNumber, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, toId, fromPageNumber, "scraps", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, fromId, toPageNumber, "scraps", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, fromId, toId, fromPageNumber, toPageNumber, "scraps", this.semaphore ], action, delay, !0);
        }
        async getFiguresBetweenPages(username, fromPageNumber, toPageNumber, action, delay = 100) {
            return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillPage, [ username, toPageNumber, "scraps", this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSincePage, [ username, fromPageNumber, "scraps", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenPages, [ username, fromPageNumber, toPageNumber, "scraps", this.semaphore ], action, delay, !0);
        }
        async getFigures(username, pageNumber, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFigures, [ username, null, pageNumber, "scraps", this.semaphore ], action, delay);
        }
        async getPage(username, pageNumber, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(Page.getGalleryPage, [ username, null, pageNumber, "scraps", this.semaphore ], action, delay);
        }
    }
    class Favorites {
        constructor(semaphore) {
            this.semaphore = semaphore;
        }
        static get hardLink() {
            return FuraffinityRequests.getUrl() + "/favorites/";
        }
        async getFiguresBetweenIds(username, fromId, toId, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, toId, null, "favorites", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, fromId, null, "favorites", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, fromId, toId, null, null, "favorites", this.semaphore ], action, delay, !0);
        }
        async getFiguresBetweenIdsBetweenPages(username, fromId, toId, fromPageNumber, toPageNumber, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, toId, fromPageNumber, "favorites", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, fromId, toPageNumber, "favorites", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, fromId, toId, fromPageNumber, toPageNumber, "favorites", this.semaphore ], action, delay, !0);
        }
        async getFiguresBetweenPages(username, fromPageNumber, toPageNumber, action, delay = 100) {
            return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillPage, [ username, toPageNumber, "favorites", this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSincePage, [ username, fromPageNumber, "favorites", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenPages, [ username, fromPageNumber, toPageNumber, "favorites", this.semaphore ], action, delay, !0);
        }
        async getFigures(username, pageNumber, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFigures, [ username, null, pageNumber, "favorites", this.semaphore ], action, delay);
        }
        async getPage(username, pageNumber, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(Page.getGalleryPage, [ username, null, pageNumber, "favorites", this.semaphore ], action, delay);
        }
    }
    class Journals {
        constructor(semaphore) {
            this.semaphore = semaphore;
        }
        static get hardLink() {
            return FuraffinityRequests.getUrl() + "/journals/";
        }
        async getFiguresBetweenIds(username, fromId, toId, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsTillId, [ username, toId, null, this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsSinceId, [ username, fromId, null, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsBetweenIds, [ username, fromId, toId, null, null, this.semaphore ], action, delay);
        }
        async getFiguresBetweenIdsBetweenPages(username, fromId, toId, fromPageNumber, toPageNumber, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsTillId, [ username, toId, fromPageNumber, this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsSinceId, [ username, fromId, toPageNumber, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsBetweenIds, [ username, fromId, toId, fromPageNumber, toPageNumber, this.semaphore ], action, delay);
        }
        async getSectionsBetweenPages(username, fromPageNumber, toPageNumber, action, delay = 100) {
            return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsTillPage, [ username, toPageNumber, this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsSincePage, [ username, fromPageNumber, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsBetweenPages, [ username, fromPageNumber, toPageNumber, this.semaphore ], action, delay, !0);
        }
        async getSections(username, pageNumber, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSections, [ username, pageNumber, this.semaphore ], action, delay);
        }
        async getPage(username, pageNumber, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(Page.getJournalsPage, [ username, pageNumber, this.semaphore ], action, delay);
        }
    }
    class Search {
        constructor(semaphore) {
            this.semaphore = semaphore;
        }
        static get hardLink() {
            return FuraffinityRequests.getUrl() + "/search/";
        }
        get newSearchOptions() {
            return new SearchOptions;
        }
        get SearchOptions() {
            return SearchOptions;
        }
        async getFiguresBetweenIds(fromId, toId, searchOptions, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresTillId, [ toId, null, searchOptions, this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresSinceId, [ fromId, null, searchOptions, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresBetweenIds, [ fromId, toId, null, null, searchOptions, this.semaphore ], action, delay, !0);
        }
        async getFiguresBetweenIdsBetweenPages(fromId, toId, fromPageNumber, toPageNumber, searchOptions, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresTillId, [ toId, fromPageNumber, searchOptions, this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresSinceId, [ fromId, toPageNumber, searchOptions, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresBetweenIds, [ fromId, toId, fromPageNumber, toPageNumber, searchOptions, this.semaphore ], action, delay, !0);
        }
        async getFiguresBetweenPages(fromPageNumber, toPageNumber, searchOptions, action, delay = 100) {
            return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresTillPage, [ toPageNumber, searchOptions, this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresSincePage, [ fromPageNumber, searchOptions, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresBetweenPages, [ fromPageNumber, toPageNumber, searchOptions, this.semaphore ], action, delay, !0);
        }
        async getFigures(pageNumber, searchOptions, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFigures, [ pageNumber, searchOptions, this.semaphore ], action, delay);
        }
        async getPage(pageNumber, searchOptions, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(Page.getSearchPage, [ pageNumber, searchOptions, this.semaphore ], action, delay);
        }
    }
    class SearchOptions {
        constructor() {
            this.input = "", this.orderBy = SearchOptions.orderBy.relevancy, this.orderDirection = SearchOptions.orderDirection.descending, 
            this.range = SearchOptions.range.alltime, this.rangeFrom = null, this.rangeTo = null, 
            this.ratingGeneral = !0, this.ratingMature = !0, this.ratingAdult = !0, this.typeArt = !0, 
            this.typeMusic = !0, this.typeFlash = !0, this.typeStory = !0, this.typePhotos = !0, 
            this.typePoetry = !0, this.matching = SearchOptions.matching.all;
        }
        static get orderBy() {
            return {
                relevancy: "relevancy",
                date: "date",
                popularity: "popularity"
            };
        }
        static get orderDirection() {
            return {
                ascending: "asc",
                descending: "desc"
            };
        }
        static get range() {
            return {
                "1day": "1day",
                "3days": "3days",
                "7days": "7days",
                "30days": "30days",
                "90days": "90days",
                "1year": "1year",
                "3years": "3years",
                "5years": "5years",
                alltime: "all",
                manual: "manual"
            };
        }
        static get matching() {
            return {
                all: "all",
                any: "any",
                extended: "extended"
            };
        }
    }
    class SearchRequests {
        constructor(semaphore) {
            this.semaphore = semaphore, this.Browse = new Browse(this.semaphore), this.Search = new Search(this.semaphore);
        }
        static async getBrowseFiguresTillId(toId, fromPage, browseOptions, semaphore) {
            if (!toId) return Logger.logError("No toId given"), null;
            let allFigures = [], running = !0, i = 1;
            for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
                const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
                let currFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), null == currFigureId ? running = !1 : IdArray.containsId(figures, toId) ? (allFigures.push(IdArray.getTillId(figures, toId)), 
                running = !1) : (allFigures.push(figures), i++);
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getBrowseFiguresSinceId(fromId, toPage, browseOptions, semaphore) {
            if (!fromId) return Logger.logError("No fromId given"), null;
            let lastFigureId, running = !0, i = 1;
            for (;running; ) {
                if (toPage && toPage >= 1 && i == toPage) {
                    running = !1;
                    break;
                }
                const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
                let currFigureId = lastFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId || IdArray.containsId(figures, fromId) ? running = !1 : i++;
            }
            let allFigures = [];
            for (lastFigureId = null, running = !0; running; ) {
                const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
                let currFigureId = lastFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId ? running = !1 : (allFigures.push(IdArray.getSinceId(figures, fromId)), 
                i++);
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getBrowseFiguresBetweenIds(fromId, toId, fromPage, toPage, browseOptions, semaphore, percentId) {
            if (!fromId) return Logger.logError("No fromId given"), null;
            if (!toId) return Logger.logError("No toId given"), null;
            let lastFigureId;
            (!fromPage || fromPage <= 0 || !toPage || toPage <= 1) && (Logger.logWarning("No fromPage or toPage given. Percentages can not be calculated."), 
            percentId = null);
            let running = !0, i = 1;
            for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
                const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
                let currFigureId = lastFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId || IdArray.containsId(figures, fromId) ? running = !1 : i++;
            }
            let allFigures = [];
            for (lastFigureId = null, running = !0; running; ) {
                if (toPage && toPage >= 1 && i == toPage) {
                    running = !1;
                    break;
                }
                const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
                let currFigureId = lastFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId ? running = !1 : IdArray.containsId(figures, toId) ? (allFigures.push(IdArray.getBetweenIds(figures, fromId, toId)), 
                running = !1) : (allFigures.push(figures), i++);
            }
            if (percentId) {
                const progress = 1 / toPage * 100;
                PercentHelper.setPercentValue(percentId, progress);
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getBrowseFiguresTillPage(toPageNumber, browseOptions, semaphore, percentId) {
            if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
            if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"), 
            null;
            let allFigures = [], completedPages = 0;
            for (let i = 1; i <= toPageNumber; i++) {
                const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
                if (figures && 0 !== figures.length && allFigures.push(figures), completedPages++, 
                percentId) {
                    const progress = completedPages / toPageNumber * 100;
                    PercentHelper.setPercentValue(percentId, progress);
                }
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getBrowseFiguresSincePage(fromPageNumber, browseOptions, semaphore) {
            if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
            if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"), 
            null;
            let allFigures = [], running = !0, i = fromPageNumber;
            for (;running; ) {
                const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
                let currFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), null == currFigureId ? running = !1 : (allFigures.push(figures), 
                i++);
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getBrowseFiguresBetweenPages(fromPageNumber, toPageNumber, browseOptions, semaphore, percentId) {
            if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
            if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"), 
            null;
            if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
            if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"), 
            null;
            let allFigures = [];
            const direction = fromPageNumber < toPageNumber ? 1 : -1, totalPages = Math.abs(toPageNumber - fromPageNumber) + 1;
            let completedPages = 0;
            for (let i = fromPageNumber; i <= toPageNumber; i += direction) {
                const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
                if (figures && 0 !== figures.length && allFigures.push(figures), completedPages++, 
                percentId) {
                    const progress = completedPages / totalPages * 100;
                    PercentHelper.setPercentValue(percentId, progress);
                }
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getBrowseFigures(pageNumber, browseOptions, semaphore) {
            const galleryDoc = await Page.getBrowsePage(pageNumber, browseOptions, semaphore);
            if (!galleryDoc || !(galleryDoc instanceof Document) || galleryDoc.getElementById("no-images")) return Logger.logMessage(`No images found at browse on page "${pageNumber}".`), 
            null;
            const figures = galleryDoc.getElementsByTagName("figure");
            return figures && 0 !== figures.length ? figures : (Logger.logMessage(`No figures found at browse on page "${pageNumber}".`), 
            null);
        }
        static async getSearchFiguresTillId(toId, fromPage, searchOptions, semaphore) {
            if (!toId) return Logger.logError("No toId given"), null;
            let allFigures = [], running = !0, i = 1;
            for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
                const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
                let currFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), null == currFigureId ? running = !1 : IdArray.containsId(figures, toId) ? (allFigures.push(IdArray.getTillId(figures, toId)), 
                running = !1) : (allFigures.push(figures), i++);
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getSearchFiguresSinceId(fromId, toPage, searchOptions, semaphore) {
            if (!fromId) return Logger.logError("No fromId given"), null;
            let lastFigureId, running = !0, i = 1;
            for (;running; ) {
                if (toPage && toPage >= 1 && i == toPage) {
                    running = !1;
                    break;
                }
                const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
                let currFigureId = lastFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId || IdArray.containsId(figures, fromId) ? running = !1 : i++;
            }
            let allFigures = [];
            for (lastFigureId = null, running = !0; running; ) {
                const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
                let currFigureId = lastFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId ? running = !1 : (allFigures.push(IdArray.getSinceId(figures, fromId)), 
                i++);
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getSearchFiguresBetweenIds(fromId, toId, fromPage, toPage, searchOptions, semaphore, percentId) {
            if (!fromId) return Logger.logError("No fromId given"), null;
            if (!toId) return Logger.logError("No toId given"), null;
            let lastFigureId;
            (!fromPage || fromPage <= 0 || !toPage || toPage <= 1) && (Logger.logWarning("No fromPage or toPage given. Percentages can not be calculated."), 
            percentId = null);
            let running = !0, i = 1;
            for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
                const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
                let currFigureId = lastFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId || IdArray.containsId(figures, fromId) ? running = !1 : i++;
            }
            let allFigures = [];
            for (lastFigureId = null, running = !0; running; ) {
                if (toPage && toPage >= 1 && i == toPage) {
                    running = !1;
                    break;
                }
                const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
                let currFigureId = lastFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId ? running = !1 : IdArray.containsId(figures, toId) ? (allFigures.push(IdArray.getBetweenIds(figures, fromId, toId)), 
                running = !1) : (allFigures.push(figures), i++);
            }
            if (percentId) {
                const progress = 1 / toPage * 100;
                PercentHelper.setPercentValue(percentId, progress);
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getSearchFiguresTillPage(toPageNumber, searchOptions, semaphore, percentId) {
            if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
            if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"), 
            null;
            let allFigures = [], completedPages = 0;
            for (let i = 1; i <= toPageNumber; i++) {
                const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
                if (figures && 0 !== figures.length && allFigures.push(figures), completedPages++, 
                percentId) {
                    const progress = completedPages / toPageNumber * 100;
                    PercentHelper.setPercentValue(percentId, progress);
                }
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getSearchFiguresSincePage(fromPageNumber, searchOptions, semaphore) {
            if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
            if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"), 
            null;
            let allFigures = [], running = !0, i = fromPageNumber;
            for (;running; ) {
                const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
                let currFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), null == currFigureId ? running = !1 : (allFigures.push(figures), 
                i++);
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getSearchFiguresBetweenPages(fromPageNumber, toPageNumber, searchOptions, semaphore, percentId) {
            if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
            if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"), 
            null;
            if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
            if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"), 
            null;
            let allFigures = [];
            const direction = fromPageNumber < toPageNumber ? 1 : -1, totalPages = Math.abs(toPageNumber - fromPageNumber) + 1;
            let completedPages = 0;
            for (let i = fromPageNumber; i <= toPageNumber; i += direction) {
                const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
                if (figures && 0 !== figures.length && allFigures.push(figures), completedPages++, 
                percentId) {
                    const progress = completedPages / totalPages * 100;
                    PercentHelper.setPercentValue(percentId, progress);
                }
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getSearchFigures(pageNumber, searchOptions, semaphore) {
            const galleryDoc = await Page.getSearchPage(pageNumber, searchOptions, semaphore);
            if (!galleryDoc || !(galleryDoc instanceof Document) || galleryDoc.getElementById("no-images")) return Logger.logMessage(`No images found at search on page "${pageNumber}".`), 
            null;
            const figures = galleryDoc.getElementsByTagName("figure");
            return figures && 0 !== figures.length ? figures : (Logger.logMessage(`No figures found at search on page "${pageNumber}".`), 
            null);
        }
    }
    class Browse {
        constructor(semaphore) {
            this.semaphore = semaphore;
        }
        static get hardLink() {
            return FuraffinityRequests.getUrl() + "/browse/";
        }
        get newBrowseOptions() {
            return new BrowseOptions;
        }
        get BrowseOptions() {
            return BrowseOptions;
        }
        async getFiguresBetweenIds(fromId, toId, browseOptions, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresTillId, [ toId, null, browseOptions, this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresSinceId, [ fromId, null, browseOptions, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresBetweenIds, [ fromId, toId, null, null, browseOptions, this.semaphore ], action, delay, !0);
        }
        async getFiguresBetweenIdsBetweenPages(fromId, toId, fromPageNumber, toPageNumber, browseOptions, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresTillId, [ toId, fromPageNumber, browseOptions, this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresSinceId, [ fromId, toPageNumber, browseOptions, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresBetweenIds, [ fromId, toId, fromPageNumber, toPageNumber, browseOptions, this.semaphore ], action, delay, !0);
        }
        async getFiguresBetweenPages(fromPageNumber, toPageNumber, browseOptions, action, delay = 100) {
            return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresTillPage, [ toPageNumber, browseOptions, this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresSincePage, [ fromPageNumber, browseOptions, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresBetweenPages, [ fromPageNumber, toPageNumber, browseOptions, this.semaphore ], action, delay, !0);
        }
        async getFigures(pageNumber, browseOptions, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFigures, [ pageNumber, browseOptions, this.semaphore ], action, delay);
        }
        async getPage(pageNumber, browseOptions, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(Page.getBrowsePage, [ pageNumber, browseOptions, this.semaphore ], action, delay);
        }
    }
    class BrowseOptions {
        constructor() {
            this.category = BrowseOptions.category.all, this.type = BrowseOptions.type.all, 
            this.species = BrowseOptions.species.any, this.gender = BrowseOptions.gender.any, 
            this.results = BrowseOptions.results[72], this.ratingGeneral = !0, this.ratingMature = !0, 
            this.ratingAdult = !0;
        }
        static get category() {
            return {
                all: 1,
                "artwork-digital": 2,
                "artwork-traditional": 3,
                "cel-shading": 4,
                crafting: 5,
                designs: 6,
                flash: 7,
                fursuiting: 8,
                icons: 9,
                mosaics: 10,
                photography: 11,
                "food-recipes": 32,
                sculpting: 12,
                story: 13,
                poetry: 14,
                prose: 15,
                music: 16,
                podcasts: 17,
                skins: 18,
                handhelds: 19,
                resources: 20,
                adoptables: 21,
                auctions: 22,
                contests: 23,
                "current-events": 24,
                desktops: 25,
                stockart: 26,
                screenshots: 27,
                scraps: 28,
                wallpaper: 29,
                "ych-sale": 30,
                other: 31
            };
        }
        static get type() {
            return {
                all: 1,
                abstract: 2,
                "animal-related-non-anthro": 3,
                anime: 4,
                comics: 5,
                doodle: 6,
                fanart: 7,
                fantasy: 8,
                human: 9,
                portraits: 10,
                scenery: 11,
                "still-life": 12,
                tutorials: 13,
                miscellaneous: 14,
                "baby-fur": 101,
                bondage: 102,
                digimon: 103,
                "fat-furs": 104,
                "fetish-other": 105,
                fursuit: 106,
                gore: 119,
                hyper: 107,
                hypnosis: 121,
                inflation: 108,
                micro: 109,
                muscle: 110,
                "my-little-pony": 111,
                paw: 112,
                pokemon: 113,
                pregnancy: 114,
                sonic: 115,
                transformation: 116,
                "tf-tg": 120,
                vore: 117,
                "water-sports": 118,
                "general-furry-art": 100,
                techno: 201,
                trance: 202,
                house: 203,
                "90s": 204,
                "80s": 205,
                "70s": 206,
                "60s": 207,
                "pre-60s": 208,
                classical: 209,
                "game-music": 210,
                rock: 211,
                pop: 212,
                rap: 213,
                industrial: 214,
                "other-music": 200
            };
        }
        static get species() {
            return {
                any: 1,
                "airborne-vehicle": 10001,
                alien: 5001,
                amphibian: 1e3,
                aquatic: 2e3,
                avian: 3e3,
                bear: 6002,
                bovine: 6007,
                canine: 6017,
                cervine: 6018,
                dog: 6010,
                dragon: 4e3,
                equine: 10009,
                exotic: 5e3,
                feline: 6030,
                fox: 6075,
                slime: 10007,
                "hybrid-species": 10002,
                inanimate: 10006,
                insect: 8003,
                "land-vehicle": 10003,
                mammal: 6e3,
                marsupial: 6042,
                mustelid: 6051,
                plant: 10008,
                primate: 6058,
                reptilian: 7e3,
                robot: 10004,
                rodent: 6067,
                "sea-vehicle": 10005,
                taur: 5025,
                vulpine: 6015,
                "original-species": 11014,
                character: 11015,
                aeromorph: 11001,
                "angel-dragon": 11002,
                avali: 11012,
                chakat: 5003,
                citra: 5005,
                crux: 5006,
                dracat: 5009,
                dutch: 11003,
                felkin: 11011,
                ferrin: 11004,
                jogauni: 11005,
                langurhali: 5014,
                nevrean: 11006,
                protogen: 11007,
                rexouium: 11016,
                sergal: 5021,
                synx: 11010,
                wickerbeast: 11013,
                yinglet: 11009,
                zorgoia: 11008,
                angel: 12001,
                centaur: 12002,
                cerberus: 12003,
                "shape-shifter": 12038,
                chimera: 12004,
                chupacabra: 12005,
                cockatrice: 12006,
                daemon: 5007,
                demon: 12007,
                "displacer-beast": 12008,
                dragonborn: 12009,
                drow: 12010,
                dwarf: 12011,
                "eastern-dragon": 4001,
                elf: 5011,
                gargoyle: 5012,
                goblin: 12012,
                golem: 12013,
                gryphon: 3007,
                harpy: 12014,
                hellhound: 12015,
                hippogriff: 12016,
                hobbit: 12017,
                hydra: 4002,
                imp: 12018,
                incubus: 12019,
                jackalope: 12020,
                kirin: 12021,
                kitsune: 12022,
                kobold: 12023,
                lamia: 12024,
                manticore: 12025,
                minotaur: 12026,
                naga: 5016,
                nephilim: 12027,
                orc: 5018,
                pegasus: 12028,
                peryton: 12029,
                phoenix: 3010,
                sasquatch: 12030,
                satyr: 5020,
                sphinx: 12031,
                succubus: 12032,
                tiefling: 12033,
                troll: 12034,
                unicorn: 5023,
                "water-dragon": 12035,
                werewolf: 12036,
                "western-dragon": 4004,
                wyvern: 4005,
                yokai: 12037,
                alicorn: 13001,
                argonian: 5002,
                asari: 13002,
                bangaa: 13003,
                "bubble-dragon": 13004,
                burmecian: 13005,
                charr: 13006,
                chiss: 13007,
                chocobo: 5004,
                deathclaw: 13008,
                digimon: 5008,
                draenei: 5010,
                drell: 13009,
                elcor: 13010,
                ewok: 13011,
                hanar: 13012,
                hrothgar: 13013,
                iksar: 5013,
                kaiju: 5015,
                kelpie: 13041,
                kemonomimi: 13014,
                khajiit: 13015,
                koopa: 13016,
                krogan: 13017,
                lombax: 13018,
                mimiga: 13019,
                mobian: 13020,
                moogle: 5017,
                neopet: 13021,
                "nu-mou": 13022,
                pokemon: 5019,
                "pony-mlp": 13023,
                protoss: 13024,
                quarian: 13025,
                ronso: 13026,
                salarian: 13027,
                sangheili: 13028,
                tauntaun: 13029,
                tauren: 13030,
                trandoshan: 13031,
                transformer: 13032,
                turian: 13033,
                twilek: 13034,
                viera: 13035,
                wookiee: 13036,
                xenomorph: 5024,
                yautja: 13037,
                yordle: 13038,
                yoshi: 13039,
                zerg: 13040,
                aardvark: 14001,
                aardwolf: 14002,
                "african-wild-dog": 14003,
                akita: 14004,
                albatross: 14005,
                crocodile: 7001,
                alpaca: 14006,
                anaconda: 14007,
                anteater: 14008,
                antelope: 6004,
                arachnid: 8e3,
                "arctic-fox": 14009,
                armadillo: 14010,
                axolotl: 14011,
                baboon: 14012,
                badger: 6045,
                bat: 6001,
                beaver: 6064,
                bee: 14013,
                binturong: 14014,
                bison: 14015,
                "blue-jay": 14016,
                "border-collie": 14017,
                "brown-bear": 14018,
                buffalo: 14019,
                "buffalo-bison": 14020,
                "bull-terrier": 14021,
                butterfly: 14022,
                caiman: 14023,
                camel: 6074,
                capybara: 14024,
                caribou: 14025,
                caterpillar: 14026,
                cephalopod: 2001,
                chameleon: 14027,
                cheetah: 6021,
                chicken: 14028,
                chimpanzee: 14029,
                chinchilla: 14030,
                chipmunk: 14031,
                civet: 14032,
                "clouded-leopard": 14033,
                coatimundi: 14034,
                cockatiel: 14035,
                corgi: 14036,
                corvid: 3001,
                cougar: 6022,
                cow: 6003,
                coyote: 6008,
                crab: 14037,
                crane: 14038,
                crayfish: 14039,
                crow: 3002,
                crustacean: 14040,
                dalmatian: 14041,
                deer: 14042,
                dhole: 14043,
                dingo: 6011,
                dinosaur: 8001,
                doberman: 6009,
                dolphin: 2002,
                donkey: 6019,
                duck: 3003,
                eagle: 3004,
                eel: 14044,
                elephant: 14045,
                falcon: 3005,
                fennec: 6072,
                ferret: 6046,
                finch: 14046,
                fish: 2005,
                flamingo: 14047,
                fossa: 14048,
                frog: 1001,
                gazelle: 6005,
                gecko: 7003,
                genet: 14049,
                "german-shepherd": 6012,
                gibbon: 14050,
                giraffe: 6031,
                goat: 6006,
                goose: 3006,
                gorilla: 6054,
                "gray-fox": 14051,
                "great-dane": 14052,
                "grizzly-bear": 14053,
                "guinea-pig": 14054,
                hamster: 14055,
                hawk: 3008,
                hedgehog: 6032,
                heron: 14056,
                hippopotamus: 6033,
                honeybee: 14057,
                horse: 6034,
                housecat: 6020,
                human: 6055,
                humanoid: 14058,
                hummingbird: 14059,
                husky: 6014,
                hyena: 6035,
                iguana: 7004,
                impala: 14060,
                jackal: 6013,
                jaguar: 6023,
                kangaroo: 6038,
                "kangaroo-mouse": 14061,
                "kangaroo-rat": 14062,
                kinkajou: 14063,
                "kit-fox": 14064,
                koala: 6039,
                "kodiak-bear": 14065,
                "komodo-dragon": 14066,
                labrador: 14067,
                lemur: 6056,
                leopard: 6024,
                liger: 14068,
                linsang: 14069,
                lion: 6025,
                lizard: 7005,
                llama: 6036,
                lobster: 14070,
                "longhair-cat": 14071,
                lynx: 6026,
                magpie: 14072,
                "maine-coon": 14073,
                malamute: 14074,
                "mammal-feline": 14075,
                "mammal-herd": 14076,
                "mammal-marsupial": 14077,
                "mammal-mustelid": 14078,
                "mammal-other predator": 14079,
                "mammal-prey": 14080,
                "mammal-primate": 14081,
                "mammal-rodent": 14082,
                manatee: 14083,
                mandrill: 14084,
                "maned-wolf": 14085,
                mantid: 8004,
                marmoset: 14086,
                marten: 14087,
                meerkat: 6043,
                mink: 6048,
                mole: 14088,
                mongoose: 6044,
                "monitor-lizard": 14089,
                monkey: 6057,
                moose: 14090,
                moth: 14091,
                mouse: 6065,
                "musk-deer": 14092,
                "musk-ox": 14093,
                newt: 1002,
                ocelot: 6027,
                octopus: 14094,
                okapi: 14095,
                olingo: 14096,
                opossum: 6037,
                orangutan: 14097,
                orca: 14098,
                oryx: 14099,
                ostrich: 14100,
                otter: 6047,
                owl: 3009,
                panda: 6052,
                pangolin: 14101,
                panther: 6028,
                parakeet: 14102,
                parrot: 14103,
                peacock: 14104,
                penguin: 14105,
                "persian-cat": 14106,
                pig: 6053,
                pigeon: 14107,
                pika: 14108,
                "pine-marten": 14109,
                platypus: 14110,
                "polar-bear": 14111,
                pony: 6073,
                poodle: 14112,
                porcupine: 14113,
                porpoise: 2004,
                procyonid: 14114,
                puffin: 14115,
                quoll: 6040,
                rabbit: 6059,
                raccoon: 6060,
                rat: 6061,
                ray: 14116,
                "red-fox": 14117,
                "red-panda": 6062,
                reindeer: 14118,
                reptillian: 14119,
                rhinoceros: 6063,
                robin: 14120,
                rottweiler: 14121,
                sabercats: 14122,
                sabertooth: 14123,
                salamander: 1003,
                scorpion: 8005,
                seagull: 14124,
                seahorse: 14125,
                seal: 6068,
                "secretary-bird": 14126,
                "serpent-dragon": 4003,
                serval: 14127,
                shark: 2006,
                sheep: 14128,
                "shiba-inu": 14129,
                "shorthair-cat": 14130,
                shrew: 14131,
                siamese: 14132,
                sifaka: 14133,
                "silver-fox": 14134,
                skunk: 6069,
                sloth: 14135,
                snail: 14136,
                "snake-serpent": 7006,
                "snow-leopard": 14137,
                sparrow: 14138,
                squid: 14139,
                squirrel: 6070,
                stoat: 14140,
                stork: 14141,
                "sugar-glider": 14142,
                "sun-bear": 14143,
                swan: 3011,
                "swift-fox": 14144,
                tanuki: 5022,
                tapir: 14145,
                "tasmanian-devil": 14146,
                thylacine: 14147,
                tiger: 6029,
                toucan: 14148,
                turtle: 7007,
                vulture: 14149,
                wallaby: 6041,
                walrus: 14150,
                wasp: 14151,
                weasel: 6049,
                whale: 2003,
                wolf: 6016,
                wolverine: 6050,
                zebra: 6071
            };
        }
        static get gender() {
            return {
                any: 0,
                male: 2,
                female: 3,
                herm: 4,
                intersex: 11,
                "trans-male": 8,
                "trans-female": 9,
                "non-binary": 10,
                multiple: 6,
                other: 7,
                "not-specified": 7
            };
        }
        static get results() {
            return {
                24: 24,
                48: 48,
                72: 72,
                96: 96,
                128: 128
            };
        }
    }
    class Page {
        static async getGalleryPage(username, folderId, pageNumber, galleryType, semaphore) {
            if ("journals" == galleryType) return await Page.getJournalsPage(username, pageNumber, semaphore);
            if ("browse" == galleryType) return await Page.getBrowsePage(pageNumber, null, semaphore);
            if (!username) return Logger.logError("No username given"), null;
            if (!pageNumber) return Logger.logError("No page number given"), null;
            let url;
            switch (pageNumber <= 0 && (Logger.logWarning("Page number is less 1. Using default 1 instead."), 
            pageNumber = 1), galleryType || (Logger.logWarning("No gallery type given. Using default 'Gallery' instead."), 
            galleryType = "gallery"), username.endsWith("/") || (username += "/"), galleryType) {
              case "gallery":
                url = Gallery.hardLink + username;
                break;

              case "scraps":
                url = Scraps.hardLink + username;
                break;

              case "favorites":
                url = Favorites.hardLink + username;
            }
            return folderId && (url += "folder/" + folderId + "/"), url ? await FuraffinityRequests.getHTML(url + pageNumber, semaphore) : null;
        }
        static async getJournalsPage(username, pageNumber, semaphore) {
            if (!username) return Logger.logError("No username given"), null;
            if (!pageNumber) return Logger.logError("No page number given"), null;
            if (pageNumber <= 0) return Logger.logError("Page number must be greater than 0"), 
            null;
            username.endsWith("/") || (username += "/");
            const url = Journals.hardLink + username;
            return url ? await FuraffinityRequests.getHTML(url + pageNumber, semaphore) : null;
        }
        static async getBrowsePage(pageNumber, browseOptions, semaphore) {
            if (!pageNumber) return Logger.logError("No page number given"), null;
            if (pageNumber <= 0) return Logger.logError("Page number must be greater than 0"), 
            null;
            browseOptions || (browseOptions = new BrowseOptions);
            const payload = {
                cat: browseOptions.category,
                atype: browseOptions.type,
                species: browseOptions.species,
                gender: browseOptions.gender,
                perpage: browseOptions.results,
                page: pageNumber,
                rating_general: browseOptions.ratingGeneral ? "on" : "off",
                rating_mature: browseOptions.ratingMature ? "on" : "off",
                rating_adult: browseOptions.ratingAdult ? "on" : "off"
            };
            for (const key in payload) null != payload[key] && null != payload[key] && 0 != payload[key] && "off" != payload[key] || delete payload[key];
            const payloadArray = Object.entries(payload), url = Browse.hardLink;
            return url ? await FuraffinityRequests.postHTML(url, payloadArray, semaphore) : null;
        }
        static async getSearchPage(pageNumber, searchOptions, semaphore) {
            if (!pageNumber) return Logger.logError("No page number given"), null;
            if (pageNumber <= 0) return Logger.logError("Page number must be greater than 0"), 
            null;
            searchOptions || (searchOptions = new SearchOptions);
            const payload = {
                page: pageNumber,
                q: searchOptions.input,
                "order-by": searchOptions.orderBy,
                "order-direction": searchOptions.orderDirection,
                range: searchOptions.range,
                range_from: "",
                range_to: "",
                "rating-general": searchOptions.ratingGeneral ? 1 : 0,
                "rating-mature": searchOptions.ratingMature ? 1 : 0,
                "rating-adult": searchOptions.ratingAdult ? 1 : 0,
                "type-art": searchOptions.typeArt ? 1 : 0,
                "type-music": searchOptions.typeMusic ? 1 : 0,
                "type-flash": searchOptions.typeFlash ? 1 : 0,
                "type-story": searchOptions.typeStory ? 1 : 0,
                "type-photos": searchOptions.typePhotos ? 1 : 0,
                "type-poetry": searchOptions.typePoetry ? 1 : 0,
                mode: searchOptions.matching
            };
            for (const key in payload) null != payload[key] && null != payload[key] && 0 != payload[key] && "off" != payload[key] || delete payload[key];
            if (searchOptions.rangeFrom instanceof Date && searchOptions.rangeFrom) {
                const formattedDate = `${searchOptions.rangeFrom.getFullYear()}-${(searchOptions.rangeFrom.getMonth() + 1).toString().padStart(2, "0")}-${searchOptions.rangeFrom.getDate().toString().padStart(2, "0")}`;
                payload.range_from = formattedDate;
            } else "string" == typeof searchOptions.rangeFrom && searchOptions.rangeFrom && (payload.range_from = searchOptions.rangeFrom);
            if (searchOptions.rangeTo instanceof Date && searchOptions.rangeTo) {
                const formattedDate = `${searchOptions.rangeTo.getFullYear()}-${(searchOptions.rangeTo.getMonth() + 1).toString().padStart(2, "0")}-${searchOptions.rangeTo.getDate().toString().padStart(2, "0")}`;
                payload.range_to = formattedDate;
            } else "string" == typeof searchOptions.rangeTo && searchOptions.rangeTo && (payload.range_to = searchOptions.rangeTo);
            const payloadArray = Object.entries(payload), url = Search.hardLink;
            return url ? await FuraffinityRequests.postHTML(url, payloadArray, semaphore) : null;
        }
    }
    class Gallery {
        constructor(semaphore) {
            this.semaphore = semaphore;
        }
        static get hardLink() {
            return FuraffinityRequests.getUrl() + "/gallery/";
        }
        async getFiguresBetweenIds(username, fromId, toId, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, null, toId, null, "gallery", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, null, fromId, null, "gallery", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, null, fromId, toId, null, null, "gallery", this.semaphore ], action, delay, !0);
        }
        async getFiguresInFolderBetweenIds(username, folderId, fromId, toId, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, folderId, toId, null, "gallery", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, folderId, fromId, null, "gallery", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, folderId, fromId, toId, null, null, "gallery", this.semaphore ], action, delay, !0);
        }
        async getFiguresBetweenIdsBetweenPages(username, fromId, toId, fromPageNumber, toPageNumber, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, null, toId, fromPageNumber, "gallery", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, null, fromId, toPageNumber, "gallery", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, null, fromId, toId, fromPageNumber, toPageNumber, "gallery", this.semaphore ], action, delay, !0);
        }
        async getFiguresInFolderBetweenIdsBetweenPages(username, folderId, fromId, toId, fromPageNumber, toPageNumber, action, delay = 100) {
            return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, folderId, toId, fromPageNumber, "gallery", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, folderId, fromId, toPageNumber, "gallery", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, folderId, fromId, toId, fromPageNumber, toPageNumber, "gallery", this.semaphore ], action, delay, !0);
        }
        async getFiguresBetweenPages(username, fromPageNumber, toPageNumber, action, delay = 100) {
            return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillPage, [ username, null, toPageNumber, "gallery", this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSincePage, [ username, null, fromPageNumber, "gallery", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenPages, [ username, null, fromPageNumber, toPageNumber, "gallery", this.semaphore ], action, delay, !0);
        }
        async getFiguresInFolderBetweenPages(username, folderId, fromPageNumber, toPageNumber, action, delay = 100) {
            return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillPage, [ username, folderId, toPageNumber, "gallery", this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSincePage, [ username, folderId, fromPageNumber, "gallery", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenPages, [ username, folderId, fromPageNumber, toPageNumber, "gallery", this.semaphore ], action, delay, !0);
        }
        async getFigures(username, pageNumber, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFigures, [ username, null, pageNumber, "gallery", this.semaphore ], action, delay);
        }
        async getFiguresInFolder(username, folderId, pageNumber, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFigures, [ username, folderId, pageNumber, "gallery", this.semaphore ], action, delay);
        }
        async getPage(username, pageNumber, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(Page.getGalleryPage, [ username, null, pageNumber, "gallery", this.semaphore ], action, delay);
        }
        async getPageInFolder(username, folderId, pageNumber, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(Page.getGalleryPage, [ username, folderId, pageNumber, "gallery", this.semaphore ], action, delay);
        }
    }
    class GalleryRequests {
        constructor(semaphore) {
            this.semaphore = semaphore, this.Gallery = new Gallery(semaphore), this.Scraps = new Scraps(semaphore), 
            this.Favorites = new Favorites(semaphore), this.Journals = new Journals(semaphore);
        }
        static async getGalleryFiguresTillId(username, folderId, toId, fromPage, galleryType, semaphore) {
            if (!toId) return Logger.logError("No toId given"), null;
            let allFigures = [], running = !0, i = 1;
            for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
                const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
                let currFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), null == currFigureId ? running = !1 : IdArray.containsId(figures, toId) ? (allFigures.push(IdArray.getTillId(figures, toId)), 
                running = !1) : (allFigures.push(figures), i++);
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getGalleryFiguresSinceId(username, folderId, fromId, toPage, galleryType, semaphore) {
            if (!fromId) return Logger.logError("No fromId given"), null;
            let lastFigureId, running = !0, i = 1;
            for (;running; ) {
                if (toPage && toPage >= 1 && i == toPage) {
                    running = !1;
                    break;
                }
                const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
                let currFigureId = lastFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId || IdArray.containsId(figures, fromId) ? running = !1 : i++;
            }
            let allFigures = [];
            for (lastFigureId = null, running = !0; running; ) {
                const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
                let currFigureId = lastFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId ? running = !1 : (allFigures.push(IdArray.getSinceId(figures, fromId)), 
                i++);
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getGalleryFiguresBetweenIds(username, folderId, fromId, toId, fromPage, toPage, galleryType, semaphore, percentId) {
            if (!fromId) return Logger.logError("No fromId given"), null;
            if (!toId) return Logger.logError("No toId given"), null;
            let lastFigureId;
            (!fromPage || fromPage <= 0 || !toPage || toPage <= 1) && (Logger.logWarning("No fromPage or toPage given. Percentages can not be calculated."), 
            percentId = null);
            let running = !0, i = 1;
            for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
                const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
                let currFigureId = lastFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId || IdArray.containsId(figures, fromId) ? running = !1 : i++;
            }
            let allFigures = [];
            for (lastFigureId = null, running = !0; running; ) {
                if (toPage && toPage >= 1 && i == toPage) {
                    running = !1;
                    break;
                }
                const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
                let currFigureId = lastFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId ? running = !1 : IdArray.containsId(figures, toId) ? (allFigures.push(IdArray.getBetweenIds(figures, fromId, toId)), 
                running = !1) : (allFigures.push(figures), i++);
            }
            if (percentId) {
                const progress = 1 / toPage * 100;
                PercentHelper.setPercentValue(percentId, progress);
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getGalleryFiguresTillPage(username, folderId, toPageNumber, galleryType, semaphore, percentId) {
            if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
            if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"), 
            null;
            let allFigures = [], completedPages = 0;
            for (let i = 1; i <= toPageNumber; i++) {
                const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
                if (figures && 0 !== figures.length && allFigures.push(figures), completedPages++, 
                percentId) {
                    const progress = completedPages / toPageNumber * 100;
                    PercentHelper.setPercentValue(percentId, progress);
                }
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getGalleryFiguresSincePage(username, folderId, fromPageNumber, galleryType, semaphore) {
            if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
            if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"), 
            null;
            let allFigures = [], running = !0, i = fromPageNumber;
            for (;running; ) {
                const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
                let currFigureId;
                figures && 0 !== figures.length && (currFigureId = figures[0].id), null == currFigureId ? running = !1 : (allFigures.push(figures), 
                i++);
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getGalleryFiguresBetweenPages(username, folderId, fromPageNumber, toPageNumber, galleryType, semaphore, percentId) {
            if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
            if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"), 
            null;
            if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
            if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"), 
            null;
            let allFigures = [];
            const direction = fromPageNumber < toPageNumber ? 1 : -1, totalPages = Math.abs(toPageNumber - fromPageNumber) + 1;
            let completedPages = 0;
            for (let i = fromPageNumber; i <= toPageNumber; i += direction) {
                const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
                if (figures && 0 !== figures.length && allFigures.push(figures), completedPages++, 
                percentId) {
                    const progress = completedPages / totalPages * 100;
                    PercentHelper.setPercentValue(percentId, progress);
                }
            }
            return 0 === allFigures.length ? null : allFigures;
        }
        static async getGalleryFigures(username, folderId, pageNumber, galleryType, semaphore) {
            const galleryDoc = await Page.getGalleryPage(username, folderId, pageNumber, galleryType, semaphore);
            if (!galleryDoc || !(galleryDoc instanceof Document) || galleryDoc.getElementById("no-images")) return Logger.logMessage(`No images found at ${galleryType} of "${username}" on page "${pageNumber}".`), 
            null;
            const figures = galleryDoc.getElementsByTagName("figure");
            return figures && 0 !== figures.length ? figures : (Logger.logMessage(`No figures found at ${galleryType} of "${username}" on page "${pageNumber}".`), 
            null);
        }
        static async getJournalsSectionsTillId(username, toId, fromPage, semaphore) {
            if (toId) return Logger.logError("No toId given"), null;
            let allSections = [], running = !0, i = 1;
            for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
                const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
                let currSectionId;
                sections && 0 !== sections.length && (currSectionId = sections[0].id), null == currSectionId ? running = !1 : IdArray.containsId(sections, toId) ? (allSections.push(IdArray.getTillId(sections, toId)), 
                running = !1) : (allSections.push(sections), i++);
            }
            return 0 === allSections.length ? null : allSections;
        }
        static async getJournalsSectionsSinceId(username, fromId, toPage, semaphore) {
            if (!fromId) return Logger.logError("No fromId given"), null;
            let lastSectionId, running = !0, i = 1;
            for (;running; ) {
                if (toPage && toPage >= 1 && i == toPage) {
                    running = !1;
                    break;
                }
                const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
                let currSectionId = lastSectionId;
                sections && 0 !== sections.length && (currSectionId = sections[0].id), currSectionId == lastSectionId || IdArray.containsId(sections, fromId) ? running = !1 : i++;
            }
            let allSections = [];
            for (lastSectionId = null, running = !0; running; ) {
                const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
                let currSectionId = lastSectionId;
                sections && 0 !== sections.length && (currSectionId = sections[0].id), currSectionId == lastSectionId ? running = !1 : (allSections.push(IdArray.getSinceId(sections, fromId)), 
                i++);
            }
            return 0 === allSections.length ? null : allSections;
        }
        static async getJournalsSectionsBetweenIds(username, fromId, toId, fromPage, toPage, semaphore, percentId) {
            if (!fromId) return Logger.logError("No fromId given"), null;
            if (!toId) return Logger.logError("No toId given"), null;
            let lastSectionId;
            (!fromPage || fromPage <= 0 || !toPage || toPage <= 1) && (Logger.logWarning("No fromPage or toPage given. Percentages can not be calculated."), 
            percentId = null);
            let running = !0, i = 1;
            for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
                const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
                let currSectionId = lastSectionId;
                sections && 0 !== sections.length && (currSectionId = sections[0].id), currSectionId == lastSectionId || IdArray.containsId(sections, fromId) ? running = !1 : i++;
            }
            let allSections = [];
            lastSectionId = null, running = !0;
            for (;running; ) {
                if (toPage && toPage >= 1 && i == toPage) {
                    running = !1;
                    break;
                }
                const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
                let currFigureId = lastSectionId;
                sections && 0 !== sections.length && (currFigureId = sections[0].id), currFigureId == lastSectionId ? running = !1 : IdArray.containsId(sections, toId) ? (allSections.push(IdArray.getBetweenIds(sections, fromId, toId)), 
                running = !1) : (allSections.push(sections), i++);
            }
            if (percentId) {
                const progress = 1 / toPage * 100;
                PercentHelper.setPercentValue(percentId, progress);
            }
            return 0 === allSections.length ? null : allSections;
        }
        static async getJournalsSectionsTillPage(username, toPageNumber, semaphore, percentId) {
            if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
            if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"), 
            null;
            let allSections = [], completedPages = 0;
            for (let i = 1; i <= toPageNumber; i++) {
                const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
                if (sections && 0 !== sections.length && allSections.push(sections), completedPages++, 
                percentId) {
                    const progress = completedPages / toPageNumber * 100;
                    PercentHelper.setPercentValue(percentId, progress);
                }
            }
            return 0 === allSections.length ? null : allSections;
        }
        static async getJournalsSectionsSincePage(username, fromPageNumber, semaphore) {
            if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
            if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"), 
            null;
            let allSections = [], running = !0, i = fromPageNumber;
            for (;running; ) {
                const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
                if (sections && 0 !== sections.length) {
                    null == sections[0].id ? running = !1 : (allSections.push(sections), i++);
                }
            }
            return 0 === allSections.length ? null : allSections;
        }
        static async getJournalsSectionsBetweenPages(username, fromPageNumber, toPageNumber, semaphore, percentId) {
            if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
            if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"), 
            null;
            if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
            if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"), 
            null;
            let allSections = [], direction = fromPageNumber < toPageNumber ? 1 : -1;
            const totalPages = Math.abs(toPageNumber - fromPageNumber) + 1;
            let completedPages = 0;
            for (let i = fromPageNumber; i <= toPageNumber; i += direction) {
                const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
                sections && allSections.push(sections), completedPages++;
                const progress = completedPages / totalPages * 100;
                PercentHelper.setPercentValue(percentId, progress);
            }
            return 0 === allSections.length ? null : allSections;
        }
        static async getJournalsSections(username, pageNumber, semaphore) {
            const galleryDoc = await Page.getJournalsPage(username, pageNumber, semaphore);
            if (!galleryDoc) return Logger.logMessage(`No journals found at "${username}" on page "${pageNumber}".`), 
            null;
            const columnPage = galleryDoc.getElementById("columnpage");
            if (!columnPage) return Logger.logMessage(`No column page found at "${username}" on page "${pageNumber}".`), 
            null;
            const sections = columnPage.getElementsByTagName("section");
            return sections && 0 !== sections.length ? sections : (Logger.logMessage(`No journals found at "${username}" on page "${pageNumber}".`), 
            null);
        }
    }
    class UserRequests {
        constructor(semaphore) {
            this.semaphore = semaphore, this.GalleryRequests = new GalleryRequests(semaphore), 
            this.SearchRequests = new SearchRequests(semaphore);
        }
        static get hardLinks() {
            return {
                user: FuraffinityRequests.getUrl() + "/user/",
                watch: FuraffinityRequests.getUrl() + "/watch/",
                unwatch: FuraffinityRequests.getUrl() + "/unwatch/",
                block: FuraffinityRequests.getUrl() + "/block/",
                unblock: FuraffinityRequests.getUrl() + "/unblock/"
            };
        }
        async getUserPage(username, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getUserPageLocal, [ username, this.semaphore ], action, delay);
        }
        async watchUser(username, watchKey, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(watchUserLocal, [ username, watchKey, this.semaphore ], action, delay);
        }
        async unwatchUser(username, unwatchKey, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(unwatchUserLocal, [ username, unwatchKey, this.semaphore ], action, delay);
        }
        async blockUser(username, blockKey, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(blockUserLocal, [ username, blockKey, this.semaphore ], action, delay);
        }
        async unblockUser(username, unblockKey, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(unblockUserLocal, [ username, unblockKey, this.semaphore ], action, delay);
        }
    }
    async function getUserPageLocal(username, semaphore) {
        if (!username) return Logger.logWarning("No username given"), null;
        UserRequests.hardLinks.user.endsWith("/") || (UserRequests.hardLinks.user += "/");
        const url = UserRequests.hardLinks.user + username;
        return url ? await FuraffinityRequests.getHTML(url, semaphore) : null;
    }
    async function watchUserLocal(username, watchKey, semaphore) {
        if (!username) return Logger.logWarning("No username given"), null;
        if (!watchKey) return Logger.logWarning("No watch key given"), null;
        UserRequests.hardLinks.watch.endsWith("/") || (UserRequests.hardLinks.watch += "/");
        const url = UserRequests.hardLinks.watch + username + "?key=" + watchKey;
        return !!url && !!await FuraffinityRequests.getHTML(url, semaphore);
    }
    async function unwatchUserLocal(username, unwatchKey, semaphore) {
        if (!username) return Logger.logWarning("No username given"), null;
        if (!unwatchKey) return Logger.logWarning("No unwatch key given"), null;
        UserRequests.hardLinks.unwatch.endsWith("/") || (UserRequests.hardLinks.unwatch += "/");
        const url = UserRequests.hardLinks.unwatch + username + "?key=" + unwatchKey;
        return !!url && !!await FuraffinityRequests.getHTML(url, semaphore);
    }
    async function blockUserLocal(username, blockKey, semaphore) {
        if (!username) return Logger.logWarning("No username given"), null;
        if (!blockKey) return Logger.logWarning("No block key given"), null;
        UserRequests.hardLinks.block.endsWith("/") || (UserRequests.hardLinks.block += "/");
        const url = UserRequests.hardLinks.block + username + "?key=" + blockKey;
        return !!url && !!await FuraffinityRequests.getHTML(url, semaphore);
    }
    async function unblockUserLocal(username, unblockKey, semaphore) {
        if (!username) return Logger.logWarning("No username given"), null;
        if (!unblockKey) return Logger.logWarning("No unblock key given"), null;
        UserRequests.hardLinks.unblock.endsWith("/") || (UserRequests.hardLinks.unblock += "/");
        const url = UserRequests.hardLinks.unblock + username + "?key=" + unblockKey;
        return !!url && !!await FuraffinityRequests.getHTML(url, semaphore);
    }
    class NewSubmissions {
        constructor(semaphore) {
            this.semaphore = semaphore;
        }
        static get hardLink() {
            return FuraffinityRequests.getUrl() + "/msg/submissions/";
        }
        async getSubmissionsPage(firstSubmissionId, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getSubmissionsPageLocal, [ firstSubmissionId, this.semaphore ], action, delay);
        }
        async removeSubmissions(submissionIds, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(removeSubmissionsLocal, [ submissionIds, this.semaphore ], action, delay);
        }
        async nukeSubmissions(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(nukeSubmissionsLocal, [ this.semaphore ], action, delay);
        }
    }
    async function getSubmissionsPageLocal(firstSubmissionId, semaphore) {
        return firstSubmissionId ? await FuraffinityRequests.getHTML(`${NewSubmissions.hardLink}new~${firstSubmissionId}@72/`, semaphore) : await FuraffinityRequests.getHTML(`${NewSubmissions.hardLink}new@72/`, semaphore);
    }
    async function removeSubmissionsLocal(submissionIds, semaphore) {
        if (!submissionIds || 0 == submissionIds.length) return void Logger.logWarning("No submission ids to remove");
        const payload = [];
        for (const submissionId of submissionIds) payload.push({
            key: "submissions[]",
            value: submissionId
        });
        return payload.push({
            key: "messagecenter-action",
            value: Message.hardActions.remove
        }), await FuraffinityRequests.postHTML(`${NewSubmissions.hardLink}new@72/`, payload, semaphore);
    }
    async function nukeSubmissionsLocal(semaphore) {
        const payload = [];
        return payload.push({
            key: "messagecenter-action",
            value: Message.hardActions.nuke
        }), await FuraffinityRequests.postHTML(`${NewSubmissions.hardLink}new@72/`, payload, semaphore);
    }
    class Message {
        constructor(semaphore) {
            this.semaphore = semaphore, this.NewSubmissions = new NewSubmissions(semaphore);
        }
        static hardActions={
            remove: "remove_checked",
            nuke: "nuke_notifications"
        };
    }
    class AccountInformation {
        constructor(semaphore) {
            this.semaphore = semaphore;
        }
        static get hardLinks() {
            return {
                settings: FuraffinityRequests.getUrl() + "/controls/settings/",
                siteSettings: FuraffinityRequests.getUrl() + "/controls/site-settings/",
                userSettings: FuraffinityRequests.getUrl() + "/controls/user-settings/"
            };
        }
        async getSettingsPage(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getSettingsPageLocal, [ this.semaphore ], action, delay);
        }
        async getSiteSettingsPage(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getSiteSettingsPageLocal, [ this.semaphore ], action, delay);
        }
        async getUserSettingsPage(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getUserSettingsPageLocal, [ this.semaphore ], action, delay);
        }
    }
    async function getSettingsPageLocal(semaphore) {
        return AccountInformation.hardLinks.settings.endsWith("/") || (AccountInformation.hardLinks.settings += "/"), 
        await FuraffinityRequests.getHTML(AccountInformation.hardLinks.settings, semaphore);
    }
    async function getSiteSettingsPageLocal(semaphore) {
        return AccountInformation.hardLinks.siteSettings.endsWith("/") || (AccountInformation.hardLinks.siteSettings += "/"), 
        await FuraffinityRequests.getHTML(AccountInformation.hardLinks.siteSettings, semaphore);
    }
    async function getUserSettingsPageLocal(semaphore) {
        return AccountInformation.hardLinks.userSettings.endsWith("/") || (AccountInformation.hardLinks.userSettings += "/"), 
        await FuraffinityRequests.getHTML(AccountInformation.hardLinks.userSettings, semaphore);
    }
    class UserProfile {
        constructor(semaphore) {
            this.semaphore = semaphore;
        }
        static get hardLinks() {
            return {
                profile: FuraffinityRequests.getUrl() + "/controls/profile/",
                profilebanner: FuraffinityRequests.getUrl() + "/controls/profilebanner/",
                contacts: FuraffinityRequests.getUrl() + "/controls/contacts/",
                avatar: FuraffinityRequests.getUrl() + "/controls/avatar/"
            };
        }
        async getProfilePage(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getProfilePageLocal, [ this.semaphore ], action, delay);
        }
        async getProfilebannerPage(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getProfilebannerPageLocal, [ this.semaphore ], action, delay);
        }
        async getContactsPage(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getContactsPageLocal, [ this.semaphore ], action, delay);
        }
        async getAvatarPage(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getAvatarPageLocal, [ this.semaphore ], action, delay);
        }
    }
    async function getProfilePageLocal(semaphore) {
        return UserProfile.hardLinks.profile.endsWith("/") || (UserProfile.hardLinks.profile += "/"), 
        await FuraffinityRequests.getHTML(UserProfile.hardLinks.profile, semaphore);
    }
    async function getProfilebannerPageLocal(semaphore) {
        return UserProfile.hardLinks.profilebanner.endsWith("/") || (UserProfile.hardLinks.profilebanner += "/"), 
        await FuraffinityRequests.getHTML(UserProfile.hardLinks.profilebanner, semaphore);
    }
    async function getContactsPageLocal(semaphore) {
        return UserProfile.hardLinks.contacts.endsWith("/") || (UserProfile.hardLinks.contacts += "/"), 
        await FuraffinityRequests.getHTML(UserProfile.hardLinks.contacts, semaphore);
    }
    async function getAvatarPageLocal(semaphore) {
        return UserProfile.hardLinks.avatar.endsWith("/") || (UserProfile.hardLinks.avatar += "/"), 
        await FuraffinityRequests.getHTML(UserProfile.hardLinks.avatar, semaphore);
    }
    class ManageContent {
        constructor(semaphore) {
            this.semaphore = semaphore;
        }
        static get hardLinks() {
            return {
                submissions: FuraffinityRequests.getUrl() + "/controls/submissions/",
                folders: FuraffinityRequests.getUrl() + "/controls/folders/submissions/",
                journals: FuraffinityRequests.getUrl() + "/controls/journal/",
                favorites: FuraffinityRequests.getUrl() + "/controls/favorites/",
                buddylist: FuraffinityRequests.getUrl() + "/controls/buddylist/",
                shouts: FuraffinityRequests.getUrl() + "/controls/shouts/",
                badges: FuraffinityRequests.getUrl() + "/controls/badges/"
            };
        }
        async getFoldersPages(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getContentFoldersLocal, [ this.semaphore ], action, delay);
        }
        async getAllWatchesPages(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getContentAllWatchesPagesLocal, [ this.semaphore ], action, delay);
        }
        async getWatchesPage(pageNumber, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getWatchesPageLocal, [ pageNumber, this.semaphore ], action, delay);
        }
    }
    async function getContentFoldersLocal(semaphore) {
        return ManageContent.hardLinks.folders.endsWith("/") || (ManageContent.hardLinks.folders += "/"), 
        await FuraffinityRequests.getHTML(ManageContent.hardLinks.folders, semaphore);
    }
    async function getContentAllWatchesPagesLocal(semaphore) {
        ManageContent.hardLinks.buddylist.endsWith("/") || (ManageContent.hardLinks.buddylist += "/");
        let usersDoc = await FuraffinityRequests.getHTML(ManageContent.hardLinks.buddylist + "x", semaphore);
        const pages = usersDoc.getElementById("columnpage").querySelector('div[class="section-body"').querySelectorAll(":scope > a");
        let userPageDocs = [];
        for (let i = 1; i <= pages.length; i++) usersDoc = await getWatchesPageLocal(i, semaphore), 
        usersDoc && userPageDocs.push(usersDoc);
        return 0 == userPageDocs.length ? null : userPageDocs;
    }
    async function getWatchesPageLocal(pageNumber, semaphore) {
        return pageNumber ? (pageNumber <= 0 && (Logger.logWarning("Page number is less 1. Using default 1 instead."), 
        pageNumber = 1), ManageContent.hardLinks.buddylist.endsWith("/") || (ManageContent.hardLinks.buddylist += "/"), 
        await FuraffinityRequests.getHTML(ManageContent.hardLinks.buddylist + pageNumber, semaphore)) : (Logger.logError("No page number given"), 
        null);
    }
    class Security {
        constructor(semaphore) {
            this.semaphore = semaphore;
        }
        static get hardLinks() {
            return {
                sessions: FuraffinityRequests.getUrl() + "/controls/sessions/logins/",
                logs: FuraffinityRequests.getUrl() + "/controls/logs/",
                labels: FuraffinityRequests.getUrl() + "/controls/labels/"
            };
        }
        async getSessionsPage(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getSecuritySessionsPageLocal, [ this.semaphore ], action, delay);
        }
        async getLogsPage(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getSecurityLogsPageLocal, [ this.semaphore ], action, delay);
        }
        async getLabelsPage(action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getSecurityLabelsPageLocal, [ this.semaphore ], action, delay);
        }
    }
    async function getSecuritySessionsPageLocal(semaphore) {
        return Security.hardLinks.sessions.endsWith("/") || (Security.hardLinks.sessions += "/"), 
        await FuraffinityRequests.getHTML(Security.hardLinks.sessions, semaphore);
    }
    async function getSecurityLogsPageLocal(semaphore) {
        return Security.hardLinks.logs.endsWith("/") || (Security.hardLinks.logs += "/"), 
        await FuraffinityRequests.getHTML(Security.hardLinks.logs, semaphore);
    }
    async function getSecurityLabelsPageLocal(semaphore) {
        return Security.hardLinks.labels.endsWith("/") || (Security.hardLinks.labels += "/"), 
        await FuraffinityRequests.getHTML(Security.hardLinks.labels, semaphore);
    }
    class PersonalUserRequests {
        constructor(semaphore) {
            this.semaphore = semaphore, this.MessageRequests = new Message(semaphore), this.AccountInformation = new AccountInformation(semaphore), 
            this.UserProfile = new UserProfile(semaphore), this.ManageContent = new ManageContent(semaphore), 
            this.Security = new Security(semaphore);
        }
    }
    class SubmissionRequests {
        constructor(semaphore) {
            this.semaphore = semaphore;
        }
        static get hardLinks() {
            return {
                view: FuraffinityRequests.getUrl() + "/view/",
                fav: FuraffinityRequests.getUrl() + "/fav/",
                unfav: FuraffinityRequests.getUrl() + "/unfav/",
                journal: FuraffinityRequests.getUrl() + "/journal/"
            };
        }
        async getSubmissionPage(submissionId, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getSubmissionPageLocal, [ submissionId, this.semaphore ], action, delay);
        }
        async favSubmission(submissionId, favKey, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(favSubmissionLocal, [ submissionId, favKey, this.semaphore ], action, delay);
        }
        async unfavSubmission(submissionId, unfavKey, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(unfavSubmissionLocal, [ submissionId, unfavKey, this.semaphore ], action, delay);
        }
        async getJournalPage(journalId, action, delay = 100) {
            return await WaitAndCallAction.callFunctionAsync(getJournalPageLocal, [ journalId, this.semaphore ], action, delay);
        }
    }
    async function getSubmissionPageLocal(submissionId, semaphore) {
        if (!submissionId) return Logger.logError("No submissionId given"), null;
        SubmissionRequests.hardLinks.view.endsWith("/") || (SubmissionRequests.hardLinks.view += "/");
        const url = SubmissionRequests.hardLinks.view + submissionId;
        return url ? await FuraffinityRequests.getHTML(url, semaphore) : null;
    }
    async function favSubmissionLocal(submissionId, favKey, semaphore) {
        if (!submissionId) return void Logger.logError("No submissionId given");
        if (!favKey) return void Logger.logError("No favKey given");
        SubmissionRequests.hardLinks.fav.endsWith("/") || (SubmissionRequests.hardLinks.fav += "/");
        const url = SubmissionRequests.hardLinks.fav + submissionId + "?key=" + favKey;
        if (url) {
            const resultDoc = await FuraffinityRequests.getHTML(url, semaphore);
            try {
                const standardpage = resultDoc.getElementById("standardpage");
                if (standardpage) {
                    const blocked = standardpage.querySelector('div[class="redirect-message"]');
                    if (blocked && blocked.textContent.includes("blocked")) return;
                }
                return getFavKeyLocal(resultDoc);
            } catch {}
        }
    }
    async function unfavSubmissionLocal(submissionId, unfavKey, semaphore) {
        if (!submissionId) return void Logger.logError("No submissionId given");
        if (!unfavKey) return void Logger.logError("No unfavKey given");
        SubmissionRequests.hardLinks.unfav.endsWith("/") || (SubmissionRequests.hardLinks.unfav += "/");
        const url = SubmissionRequests.hardLinks.unfav + submissionId + "?key=" + unfavKey;
        if (url) {
            const resultDoc = await FuraffinityRequests.getHTML(url, semaphore);
            if (resultDoc) {
                return getFavKeyLocal(resultDoc);
            }
        }
    }
    async function getJournalPageLocal(journalId, semaphore) {
        if (!journalId) return Logger.logError("No journalId given"), null;
        SubmissionRequests.hardLinks.journal.endsWith("/") || (SubmissionRequests.hardLinks.journal += "/");
        const url = SubmissionRequests.hardLinks.journal + journalId;
        return url ? await FuraffinityRequests.getHTML(url, semaphore) : null;
    }
    function getFavKeyLocal(doc) {
        const buttons = doc.getElementById("columnpage").querySelector('div[class*="favorite-nav"').querySelectorAll('a[class*="button"][href]');
        let favButton;
        for (const button of Array.from(buttons)) button.textContent.toLowerCase().includes("fav") && (favButton = button);
        if (favButton) {
            return favButton.getAttribute("href").split("?key=")[1];
        }
    }
    class FuraffinityRequests {
        constructor(maxAmountRequests = 2) {
            this._semaphore = new Semaphore(maxAmountRequests), this.UserRequests = new UserRequests(this._semaphore), 
            this.PersonalUserRequests = new PersonalUserRequests(this._semaphore), this.SubmissionRequests = new SubmissionRequests(this._semaphore);
        }
        set maxAmountRequests(value) {
            this._semaphore.maxConcurrency != value && (this._semaphore.maxConcurrency = value);
        }
        get maxAmountRequests() {
            return this._semaphore.maxConcurrency;
        }
        static set useHttps(value) {
            FuraffinityRequests._useHttps != value && (FuraffinityRequests._useHttps = value, 
            FuraffinityRequests._httpsString = value ? "https://" : "http://");
        }
        static get useHttps() {
            return FuraffinityRequests._useHttps;
        }
        static logLevel=1;
        static domain="www.furaffinity.net";
        static _httpsString="https://";
        static _useHttps=!0;
        static getUrl() {
            return FuraffinityRequests._httpsString + FuraffinityRequests.domain;
        }
        static async getHTML(url, semaphore, action, delay = 100) {
            const waitAndCallAction = new WaitAndCallAction(action, null, delay);
            waitAndCallAction.start();
            const html = await async function(url, semaphore) {
                Logger.logMessage(`Requesting '${url}'`);
                const semaphoreActive = semaphore && semaphore.maxConcurrency > 0;
                semaphoreActive && await semaphore.acquire();
                try {
                    const response = await fetch(url), html = await response.text(), parser = new DOMParser;
                    return parser.parseFromString(html, "text/html");
                } catch (error) {
                    Logger.logError(error);
                } finally {
                    semaphoreActive && semaphore.release();
                }
            }(url, semaphore);
            return waitAndCallAction.stop(), html;
        }
        static async postHTML(url, payload, semaphore, action, delay = 100) {
            const waitAndCallAction = new WaitAndCallAction(action, null, delay);
            waitAndCallAction.start();
            const html = await async function(url, payload, semaphore) {
                const semaphoreActive = semaphore && semaphore.maxConcurrency > 0;
                semaphoreActive && await semaphore.acquire();
                try {
                    const response = await fetch(url, {
                        method: "POST",
                        body: new URLSearchParams(payload).toString(),
                        headers: {
                            "Content-Type": "application/x-www-form-urlencoded"
                        }
                    });
                    if (!response.ok) return void Logger.logError(`HTTP error! Status: ${response.status}`);
                    const responseData = await response.text();
                    try {
                        const parser = new DOMParser;
                        return parser.parseFromString(responseData, "text/html");
                    } catch {
                        return responseData;
                    }
                } catch (error) {
                    Logger.logError(error);
                } finally {
                    semaphoreActive && semaphore.release();
                }
            }(url, payload, semaphore);
            return waitAndCallAction.stop(), html;
        }
    }
    Object.defineProperty(window, "FARequestHelper", {
        get: () => FuraffinityRequests
    });
})();