您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Helper Library to simplify requests to Furaffinity
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/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 }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址