From 20efcf404cf776be262662bc3a37dc5d9fece3a6 Mon Sep 17 00:00:00 2001
From: nyagami ' + chapterName + '
';
+ }
+ chapterText += pageText;
+ return [2 /*return*/];
+ }
+ });
+ }); };
+ loadPage = function (url) { return __awaiter(_this, void 0, void 0, function () {
+ var result, body, pageCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ pageCheerio = (0, cheerio_1.load)(body);
+ return [4 /*yield*/, addPage(pageCheerio)];
+ case 3:
+ _a.sent();
+ pageHasNextPage =
+ pageCheerio('#footlink a:last').text() === '下一页' ? true : false;
+ return [2 /*return*/, { pageCheerio: pageCheerio, pageHasNextPage: pageHasNextPage }];
+ }
+ });
+ }); };
+ url = chapterUrl;
+ _a.label = 1;
+ case 1: return [4 /*yield*/, loadPage(url)];
+ case 2:
+ page = _a.sent();
+ hasNextPage = page.pageHasNextPage;
+ if (hasNextPage === true) {
+ pageNumber++;
+ url = chapterUrl.replace(/\.html/gi, "_".concat(pageNumber) + '.html');
+ }
+ _a.label = 3;
+ case 3:
+ if (hasNextPage === true) return [3 /*break*/, 1];
+ _a.label = 4;
+ case 4: return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ Linovelib.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var searchUrl, Term, headers, NextPage, NoNextPage, DeadEnd, novels, addPage, loadPage, url, page;
+ var _this = this;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ searchUrl = "".concat(this.site, "/search/");
+ Term = encodeURI(searchTerm);
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ pageNo = 1;
+ novels = [];
+ addPage = function (pageCheerio, redirect) { return __awaiter(_this, void 0, void 0, function () {
+ var loadSearchResults, novelResults, novelName, novelCover, novelUrl;
+ var _this = this;
+ var _a;
+ return __generator(this, function (_b) {
+ loadSearchResults = function () {
+ pageCheerio('.book-ol .book-layout').each(function (i, el) {
+ var nUrl = pageCheerio(el).attr('href');
+ var novelName = pageCheerio(el).find('.book-title').text();
+ var novelCover = pageCheerio(el)
+ .find('img.book-cover')
+ .attr('data-src');
+ var novelUrl = _this.site + nUrl;
+ if (!nUrl)
+ return;
+ novels.push({
+ name: novelName,
+ url: novelUrl,
+ cover: novelCover,
+ });
+ });
+ };
+ novelResults = pageCheerio('.book-ol a.book-layout');
+ if (novelResults.length === 0) {
+ (0, showToast_1.showToast)('Bypass check by searching in Webview');
+ }
+ else {
+ loadSearchResults();
+ }
+ if (redirect.length) {
+ novels.length = 0;
+ novelName = pageCheerio('#bookDetailWrapper .book-title').text();
+ novelCover = pageCheerio('#bookDetailWrapper img.book-cover').attr('src');
+ novelUrl = this.site +
+ ((_a = pageCheerio('#btnReadBook').attr('href')) === null || _a === void 0 ? void 0 : _a.slice(0, -8)) +
+ '.html';
+ novels.push({
+ name: novelName,
+ url: novelUrl,
+ cover: novelCover,
+ });
+ }
+ return [2 /*return*/];
+ });
+ }); };
+ loadPage = function (url) { return __awaiter(_this, void 0, void 0, function () {
+ var result, body, pageCheerio, redirect;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ pageCheerio = (0, cheerio_1.load)(body);
+ redirect = pageCheerio('div.book-layout').text();
+ return [4 /*yield*/, addPage(pageCheerio, redirect)];
+ case 3:
+ _a.sent();
+ NextPage = pageCheerio('.next').attr('href');
+ if (!NextPage) {
+ NoNextPage === true;
+ }
+ else {
+ NoNextPage = NextPage === '#' ? true : false;
+ }
+ return [2 /*return*/, { pageCheerio: pageCheerio, NoNextPage: NoNextPage }];
+ }
+ });
+ }); };
+ url = "".concat(searchUrl).concat(Term, "_").concat(pageNo, ".html");
+ _a.label = 1;
+ case 1: return [4 /*yield*/, loadPage(url)];
+ case 2:
+ page = _a.sent();
+ DeadEnd = page.NoNextPage;
+ if (DeadEnd === false) {
+ pageNo++;
+ url = "".concat(searchUrl).concat(Term, "_").concat(pageNo, ".html");
+ }
+ _a.label = 3;
+ case 3:
+ if (DeadEnd === false) return [3 /*break*/, 1];
+ _a.label = 4;
+ case 4: return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ ;
+ Linovelib.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return Linovelib;
+}());
+exports.default = new Linovelib();
diff --git a/.js/plugins/english/BoxNovel[madara].js b/.js/plugins/english/BoxNovel[madara].js
new file mode 100644
index 0000000..f8b862d
--- /dev/null
+++ b/.js/plugins/english/BoxNovel[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "boxnovel", "sourceSite": "https://boxnovel.com/", "sourceName": "BoxNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shounen", "value": "shounen" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }], "inputType": "Picker" }], "options": { "path": { "genres": "manga-genre" }, "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/ClickNovel[madara].js b/.js/plugins/english/ClickNovel[madara].js
new file mode 100644
index 0000000..c766349
--- /dev/null
+++ b/.js/plugins/english/ClickNovel[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "clicknovel", "sourceSite": "https://clicknovel.net/", "sourceName": "ClickNovel", "filters": [], "options": { "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/CrateNovel[madara].js b/.js/plugins/english/CrateNovel[madara].js
new file mode 100644
index 0000000..c8c7bd7
--- /dev/null
+++ b/.js/plugins/english/CrateNovel[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "cratenovel", "sourceSite": "https://cratenovel.com/", "sourceName": "CrateNovel", "filters": [], "options": { "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/DaoNovel[madara].js b/.js/plugins/english/DaoNovel[madara].js
new file mode 100644
index 0000000..b6b9db3
--- /dev/null
+++ b/.js/plugins/english/DaoNovel[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "daonovel", "sourceSite": "https://daonovel.com/", "sourceName": "DaoNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "path": { "novels": "novels-list", "novel": "novels", "chapter": "novels" }, "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/FansTranslations[madara].js b/.js/plugins/english/FansTranslations[madara].js
new file mode 100644
index 0000000..8b57d94
--- /dev/null
+++ b/.js/plugins/english/FansTranslations[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "fanTLS", "sourceSite": "https://fanstranslations.com/", "sourceName": "Fans Translations", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/FirstKissNovel[madara].js b/.js/plugins/english/FirstKissNovel[madara].js
new file mode 100644
index 0000000..1329250
--- /dev/null
+++ b/.js/plugins/english/FirstKissNovel[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "1stkissnovel", "sourceSite": "https://1stkissnovel.org/", "sourceName": "FirstKissNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Anime", "value": "anime" }, { "label": "Apocalypse", "value": "apocalypse" }, { "label": "Boy's Love", "value": "boys-love" }, { "label": "Comedy", "value": "comedy" }, { "label": "Completed", "value": "completed" }, { "label": "Cooking", "value": "cooking" }, { "label": "Demons", "value": "demons" }, { "label": "Detective", "value": "detective" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Food", "value": "food" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Girls Love", "value": "girls-love" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Humor", "value": "humor" }, { "label": "Isekai", "value": "isekai" }, { "label": "Josei", "value": "josei" }, { "label": "Magic", "value": "magic" }, { "label": "Magical", "value": "magical" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Medical", "value": "medical" }, { "label": "Military", "value": "military" }, { "label": "Moder", "value": "moder" }, { "label": "Modern", "value": "modern" }, { "label": "Murim", "value": "murim" }, { "label": "Music", "value": "music" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reverse", "value": "reverse" }, { "label": "Reverse harem", "value": "reverse-harem" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Super power", "value": "super-power" }, { "label": "Superhero", "value": "superhero" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Thriller", "value": "thriller" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Vampire", "value": "vampire" }, { "label": "Webtoons", "value": "webtoons" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/FreeNovelMe[madara].js b/.js/plugins/english/FreeNovelMe[madara].js
new file mode 100644
index 0000000..d4ad448
--- /dev/null
+++ b/.js/plugins/english/FreeNovelMe[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "freenovel.me", "sourceSite": "https://freenovel.me/", "sourceName": "FreeNovelMe", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Drama", "value": "drama" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Historical", "value": "historical" }, { "label": "History", "value": "history" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Martial", "value": "martial" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Premium", "value": "premium" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reincarnation", "value": "reincarnation" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }], "inputType": "Picker" }], "options": { "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/Guavaread[madara].js b/.js/plugins/english/Guavaread[madara].js
new file mode 100644
index 0000000..81a00aa
--- /dev/null
+++ b/.js/plugins/english/Guavaread[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "guavaread", "sourceSite": "https://guavaread.com/", "sourceName": "Guavaread", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Complete", "value": "complete" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Drama", "value": "drama" }, { "label": "Dropped", "value": "dropped" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Mature", "value": "mature" }, { "label": "Mystery", "value": "mystery" }, { "label": "Original Story", "value": "original-story" }, { "label": "Pilot", "value": "pilot" }, { "label": "Psychological", "value": "psychological" }, { "label": "R-15", "value": "r-15" }, { "label": "R-19", "value": "r-19" }, { "label": "Reverse Harem", "value": "reverse-harem" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/LightNovelHeaven[madara].js b/.js/plugins/english/LightNovelHeaven[madara].js
new file mode 100644
index 0000000..75b392c
--- /dev/null
+++ b/.js/plugins/english/LightNovelHeaven[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "lnheaven", "sourceSite": "https://lightnovelheaven.com/", "sourceName": "LightNovelHeaven", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "path": { "novels": "series", "novel": "series", "chapter": "series" }, "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/LunarLetters[madara].js b/.js/plugins/english/LunarLetters[madara].js
new file mode 100644
index 0000000..9187e6c
--- /dev/null
+++ b/.js/plugins/english/LunarLetters[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "lunarletters", "sourceSite": "https://www.lunarletters.com/", "sourceName": "LunarLetters", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "path": { "novels": "series", "novel": "series", "chapter": "series" }, "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/MTLNovelClub[madara].js b/.js/plugins/english/MTLNovelClub[madara].js
new file mode 100644
index 0000000..e178575
--- /dev/null
+++ b/.js/plugins/english/MTLNovelClub[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "mtlnovel.club", "sourceSite": "https://mtlnovel.club/", "sourceName": "MTLNovel.Club", "filters": [], "options": { "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/MTLNovel[madara].js b/.js/plugins/english/MTLNovel[madara].js
new file mode 100644
index 0000000..fef3caa
--- /dev/null
+++ b/.js/plugins/english/MTLNovel[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "mtl-novel", "sourceSite": "https://mtl-novel.com/", "sourceName": "MTL-Novel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Chinese", "value": "chinese" }, { "label": "Comedy", "value": "comedy" }, { "label": "Conan", "value": "conan" }, { "label": "Drama", "value": "drama" }, { "label": "Erciyuan", "value": "erciyuan" }, { "label": "Fairy Tail", "value": "fairy-tail" }, { "label": "Faloo", "value": "faloo" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "FoodWars!", "value": "foodwars" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Hunter x Hunter", "value": "hunter-x-hunter" }, { "label": "Japanese", "value": "japanese" }, { "label": "Jojo", "value": "jojo" }, { "label": "Josei", "value": "josei" }, { "label": "Korean", "value": "korean" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Marvel", "value": "marvel" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Military", "value": "military" }, { "label": "Mystery", "value": "mystery" }, { "label": "Naruto", "value": "naruto" }, { "label": "One piece", "value": "one-piece" }, { "label": "Pokemon", "value": "pokemon" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sport", "value": "sport" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "System", "value": "system" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban", "value": "urban" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "path": { "genres": "manga-genre" }, "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/MostNovel[madara].js b/.js/plugins/english/MostNovel[madara].js
new file mode 100644
index 0000000..95263f5
--- /dev/null
+++ b/.js/plugins/english/MostNovel[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "mostnovel", "sourceSite": "https://mostnovel.com/", "sourceName": "MostNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "ACG", "value": "acg" }, { "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "AGA", "value": "aga" }, { "label": "Anime", "value": "anime" }, { "label": "Anime & Comics", "value": "anime-comics" }, { "label": "Bender", "value": "bender" }, { "label": "BL", "value": "bl" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Comic", "value": "comic" }, { "label": "Contemporary Romance", "value": "contemporary-romance" }, { "label": "Cooking", "value": "cooking" }, { "label": "Cultivation", "value": "cultivation" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Eastern Fantasy", "value": "eastern-fantasy" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Horror&Thriller", "value": "horrorthriller" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Magical Realism", "value": "magical-realism" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Modern", "value": "modern" }, { "label": "Movies", "value": "movies" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smart MC", "value": "smart-mc" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Video Games", "value": "video-games" }, { "label": "Webtoon", "value": "webtoon" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "path": { "novels": "manga", "novel": "manga", "chapter": "manga", "genres": "manga-genre" }, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/MysticalSeries[madara].js b/.js/plugins/english/MysticalSeries[madara].js
new file mode 100644
index 0000000..829e1fb
--- /dev/null
+++ b/.js/plugins/english/MysticalSeries[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "mysticalmerries", "sourceSite": "https://mysticalmerries.com/", "sourceName": "MysticalSeries", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adaptation", "value": "adaptation" }, { "label": "Adventure", "value": "adventure" }, { "label": "bilibili", "value": "bilibili" }, { "label": "Chinese Novel", "value": "chinese-novel" }, { "label": "Comedy", "value": "comedy" }, { "label": "Crossdressing", "value": "crossdressing" }, { "label": "Drama", "value": "drama" }, { "label": "Dropped", "value": "dropped" }, { "label": "Family", "value": "family" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Korean Novel", "value": "korean-novell" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Modern Romance", "value": "modern-romance" }, { "label": "Mystery", "value": "mystery" }, { "label": "Office Workers", "value": "office-workers" }, { "label": "One shot", "value": "one-shot" }, { "label": "Pilot Novel", "value": "pilot-novel" }, { "label": "R15", "value": "r15" }, { "label": "R19", "value": "r19" }, { "label": "Regression", "value": "regression" }, { "label": "Reincarnation", "value": "reincarnation" }, { "label": "Reverse Harem", "value": "reverse-harem" }, { "label": "Romance Fantasy", "value": "romance-fantasy" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Violence", "value": "violence" }], "inputType": "Picker" }], "options": { "path": { "novels": "series", "novel": "series", "chapter": "series", "genres": "genre" }, "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/NeoSekaiTranslations[madara].js b/.js/plugins/english/NeoSekaiTranslations[madara].js
new file mode 100644
index 0000000..2264b0f
--- /dev/null
+++ b/.js/plugins/english/NeoSekaiTranslations[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "neosekaiTLS", "sourceSite": "https://www.neosekaitranslations.com/", "sourceName": "NeoSekai Translations", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Drama", "value": "drama" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Harem", "value": "harem" }, { "label": "Horror", "value": "horror" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-Fi", "value": "sci-fi" }, { "label": "Slice of Life", "value": "slice-of-life" }], "inputType": "Picker" }], "options": { "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/NocturneTranslations[madara].js b/.js/plugins/english/NocturneTranslations[madara].js
new file mode 100644
index 0000000..b096667
--- /dev/null
+++ b/.js/plugins/english/NocturneTranslations[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "nocturneTLS", "sourceSite": "https://nocturnetls.net/", "sourceName": "Nocturne Translations", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Anime", "value": "anime" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Comic", "value": "comic" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Webtoon", "value": "webtoon" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "path": { "novels": "novels", "novel": "novels", "chapter": "novels", "genres": "manga-genre" }, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/NoobchanTranslation[madara].js b/.js/plugins/english/NoobchanTranslation[madara].js
new file mode 100644
index 0000000..d9aa474
--- /dev/null
+++ b/.js/plugins/english/NoobchanTranslation[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "noobchanTL", "sourceSite": "https://noobchan.xyz/", "sourceName": "Noobchan Translation", "filters": [], "options": { "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/NovelMultiverse[madara].js b/.js/plugins/english/NovelMultiverse[madara].js
new file mode 100644
index 0000000..545d558
--- /dev/null
+++ b/.js/plugins/english/NovelMultiverse[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "novelmultiverse", "sourceSite": "https://www.novelmultiverse.com/", "sourceName": "NovelMultiverse", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Anime", "value": "anime" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Comic", "value": "comic" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Original", "value": "original" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Translation", "value": "translation" }, { "label": "Webtoon", "value": "webtoon" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/NovelR18[madara].js b/.js/plugins/english/NovelR18[madara].js
new file mode 100644
index 0000000..b322c38
--- /dev/null
+++ b/.js/plugins/english/NovelR18[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "novelr18", "sourceSite": "https://novelr18.com/", "sourceName": "NovelR18", "filters": [{ "key": "sort", "label": "Sort by :", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest Update", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "Newly Added Novels", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "path": { "novels": "novel", "novel": "manga", "chapter": "manga" }, "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/NovelTranslate[madara].js b/.js/plugins/english/NovelTranslate[madara].js
new file mode 100644
index 0000000..3abed76
--- /dev/null
+++ b/.js/plugins/english/NovelTranslate[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "novelTL", "sourceSite": "https://noveltranslate.com/", "sourceName": "NovelTranslate", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Bleach", "value": "bleach" }, { "label": "Chinese", "value": "chinese" }, { "label": "Comedy", "value": "comedy" }, { "label": "Conan", "value": "conan" }, { "label": "cooking", "value": "cooking" }, { "label": "Dragon Ball", "value": "dragon-ball" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Erciyuan", "value": "erciyuan" }, { "label": "Fairy Tail", "value": "fairy-tail" }, { "label": "Faloo", "value": "faloo" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "FoodWars!", "value": "foodwars" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Hunter x Hunter", "value": "hunter-x-hunter" }, { "label": "Isekai", "value": "isekai" }, { "label": "Japanese", "value": "japanese" }, { "label": "Jojo", "value": "jojo" }, { "label": "Josei", "value": "josei" }, { "label": "Korean", "value": "korean" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Marvel", "value": "marvel" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Military", "value": "military" }, { "label": "Mystery", "value": "mystery" }, { "label": "Naruto", "value": "naruto" }, { "label": "One piece", "value": "one-piece" }, { "label": "Pokemon", "value": "pokemon" }, { "label": "Political", "value": "political" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sport", "value": "sport" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "System", "value": "system" }, { "label": "Toriko", "value": "toriko" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban", "value": "urban" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "path": { "novels": "all-novels", "novel": "manga", "chapter": "manga", "genres": "manga-genre" }, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/Novelroomnet[madara].js b/.js/plugins/english/Novelroomnet[madara].js
new file mode 100644
index 0000000..8b5455e
--- /dev/null
+++ b/.js/plugins/english/Novelroomnet[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "novelroom", "sourceSite": "https://novelroom.net/", "sourceName": "Novelroom.net", "filters": [], "options": { "path": { "novels": "manga", "novel": "manga", "chapter": "manga" }, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/Novelstic[madara].js b/.js/plugins/english/Novelstic[madara].js
new file mode 100644
index 0000000..2e9f9a5
--- /dev/null
+++ b/.js/plugins/english/Novelstic[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "novelstic", "sourceSite": "https://novelstic.com/", "sourceName": "Novelstic", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/OnlyMTL[madara].js b/.js/plugins/english/OnlyMTL[madara].js
new file mode 100644
index 0000000..eb7513f
--- /dev/null
+++ b/.js/plugins/english/OnlyMTL[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "onlymtl", "sourceSite": "https://www.onlymtl.com/", "sourceName": "OnlyMTL", "filters": [], "options": { "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/ReadWebNovels[madara].js b/.js/plugins/english/ReadWebNovels[madara].js
new file mode 100644
index 0000000..f93ae3f
--- /dev/null
+++ b/.js/plugins/english/ReadWebNovels[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "readwebnovels", "sourceSite": "https://readwebnovels.net/", "sourceName": "ReadWebNovels", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/SleepyTranslations[madara].js b/.js/plugins/english/SleepyTranslations[madara].js
new file mode 100644
index 0000000..0f60e4e
--- /dev/null
+++ b/.js/plugins/english/SleepyTranslations[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "sleeptTLS", "sourceSite": "https://sleepytranslations.com/", "sourceName": "SleepyTranslations", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "path": { "novels": "series", "novel": "series", "chapter": "series" }, "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/SonicMTL[madara].js b/.js/plugins/english/SonicMTL[madara].js
new file mode 100644
index 0000000..b975609
--- /dev/null
+++ b/.js/plugins/english/SonicMTL[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "sonicmtl", "sourceSite": "https://www.sonicmtl.com/", "sourceName": "SonicMTL", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/SugarBabies[madara].js b/.js/plugins/english/SugarBabies[madara].js
new file mode 100644
index 0000000..fa1a338
--- /dev/null
+++ b/.js/plugins/english/SugarBabies[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "sugarbbscan", "sourceSite": "https://sugarbbscan.com/", "sourceName": "Sugar Babies", "filters": [], "options": { "path": { "novels": "series", "novel": "series", "chapter": "series" }, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/SweetEscapeTranslations[madara].js b/.js/plugins/english/SweetEscapeTranslations[madara].js
new file mode 100644
index 0000000..917ffd3
--- /dev/null
+++ b/.js/plugins/english/SweetEscapeTranslations[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "sweetEscapeTL", "sourceSite": "https://sweetescapetranslations.com/", "sourceName": "Sweet Escape Translations", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Comedy", "value": "comedy" }, { "label": "Drama", "value": "drama" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Mature", "value": "mature" }, { "label": "Modern", "value": "modern" }, { "label": "Mystery", "value": "mystery" }, { "label": "R-15", "value": "r-15" }, { "label": "Romance", "value": "romance" }, { "label": "Slice of Life", "value": "slice-of-life" }], "inputType": "Picker" }], "options": { "path": { "novels": "manga", "novel": "manga", "chapter": "manga", "genres": "manga-genre" }, "useNewChapterEndpoint": false, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/WebNovelLover[madara].js b/.js/plugins/english/WebNovelLover[madara].js
new file mode 100644
index 0000000..44fffb0
--- /dev/null
+++ b/.js/plugins/english/WebNovelLover[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "webnovelover", "sourceSite": "https://www.webnovelover.com/", "sourceName": "WebNovelLover", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adapted into drama", "value": "adapted-into-drama" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Completed", "value": "completed" }, { "label": "Drama", "value": "drama" }, { "label": "English Novel", "value": "english-novel" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Indo Novel", "value": "indo-novel" }, { "label": "Josei", "value": "josei" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mystery", "value": "mystery" }, { "label": "Rebirth", "value": "rebirth" }, { "label": "Reincarnation", "value": "reincarnation" }, { "label": "Romance", "value": "romance" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shounen", "value": "shounen" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Spiritual", "value": "spiritual" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Transmigration", "value": "transmigration" }, { "label": "University", "value": "university" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Youth", "value": "youth" }], "inputType": "Picker" }], "options": { "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/WuxiaWorldSite[madara].js b/.js/plugins/english/WuxiaWorldSite[madara].js
new file mode 100644
index 0000000..db9b9bd
--- /dev/null
+++ b/.js/plugins/english/WuxiaWorldSite[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "wuxiaworld.site", "sourceSite": "https://wuxiaworld.site/", "sourceName": "WuxiaWorld.Site", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/ZetroTranslation[madara].js b/.js/plugins/english/ZetroTranslation[madara].js
new file mode 100644
index 0000000..aa2b9cf
--- /dev/null
+++ b/.js/plugins/english/ZetroTranslation[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "zetroTL", "sourceSite": "https://zetrotranslation.com/", "sourceName": "Zetro Translation", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Dark Elf", "value": "dark-elf" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Harem", "value": "harem" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "NTR", "value": "ntr" }, { "label": "Original Works", "value": "original-works" }, { "label": "Rom-Com", "value": "rom-com" }, { "label": "Romance", "value": "romance" }, { "label": "School", "value": "school" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Villain", "value": "villain" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "path": { "genres": "genre" }, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/ZinnNovel[madara].js b/.js/plugins/english/ZinnNovel[madara].js
new file mode 100644
index 0000000..9e42f1e
--- /dev/null
+++ b/.js/plugins/english/ZinnNovel[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "zinnovel", "sourceSite": "https://zinnovel.com/", "sourceName": "ZinnNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Anime", "value": "anime" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Comic", "value": "comic" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Lolicon", "value": "lolicon" }, { "label": "Magical Realism", "value": "magical-realism" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reincarnation", "value": "reincarnation" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Video Games", "value": "video-games" }, { "label": "Webtoon", "value": "webtoon" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "path": { "novels": "manga", "novel": "manga", "chapter": "manga", "genres": "manga-genre" }, "lang": "English" } });
+exports.default = plugin;
diff --git a/.js/plugins/english/bestlightnovel.js b/.js/plugins/english/bestlightnovel.js
new file mode 100644
index 0000000..25af43d
--- /dev/null
+++ b/.js/plugins/english/bestlightnovel.js
@@ -0,0 +1,231 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var fetch_1 = require("@libs/fetch");
+var novelStatus_1 = require("@libs/novelStatus");
+var BLN = /** @class */ (function () {
+ function BLN() {
+ this.id = "BLN.com";
+ this.name = "BestLightNovel";
+ this.icon = "src/en/bestlightnovel/icon.png";
+ this.site = "https://bestlightnovel.com/";
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ }
+ BLN.prototype.popularNovels = function (pageNo, options) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, result, _a, _b, body, loadedCheerio, novels;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ url = this.site + "novel_list?type=topview&category=all&state=all&page=1" + pageNo;
+ return [4 /*yield*/, fetch(url)];
+ case 1:
+ result = _c.sent();
+ if (!!result.ok) return [3 /*break*/, 3];
+ _b = (_a = console).error;
+ return [4 /*yield*/, result.text()];
+ case 2:
+ _b.apply(_a, [_c.sent()]);
+ // TODO: Cloudflare protection or other error
+ return [2 /*return*/, []];
+ case 3: return [4 /*yield*/, result.text()];
+ case 4:
+ body = _c.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novels = [];
+ loadedCheerio(".update_item.list_category").each(function () {
+ var novelName = loadedCheerio(this).find("h3 > a").text();
+ var novelCover = loadedCheerio(this).find("img").attr("src");
+ var novelUrl = loadedCheerio(this).find("h3 > a").attr("href");
+ if (!novelUrl) {
+ // TODO: Handle error
+ console.error("No novel url!");
+ return;
+ }
+ var novel = {
+ name: novelName,
+ url: novelUrl,
+ cover: novelCover,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ BLN.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a, _b, _c;
+ return __awaiter(this, void 0, void 0, function () {
+ var url, result, _d, _e, body, loadedCheerio, novel, status, novelChapters;
+ return __generator(this, function (_f) {
+ switch (_f.label) {
+ case 0:
+ url = novelUrl;
+ return [4 /*yield*/, fetch(url)];
+ case 1:
+ result = _f.sent();
+ if (!!result.ok) return [3 /*break*/, 3];
+ _e = (_d = console).error;
+ return [4 /*yield*/, result.text()];
+ case 2:
+ _e.apply(_d, [_f.sent()]);
+ // TODO: Cloudflare protection
+ return [2 /*return*/, { url: url, chapters: [] }];
+ case 3: return [4 /*yield*/, result.text()];
+ case 4:
+ body = _f.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novel = {
+ url: url,
+ name: "",
+ cover: "",
+ author: "",
+ status: novelStatus_1.NovelStatus.Unknown,
+ genres: "",
+ summary: "",
+ chapters: [],
+ };
+ novel.name = loadedCheerio(".truyen_info_right h1").text().trim();
+ novel.cover =
+ loadedCheerio(".info_image img").attr("src") || defaultCover_1.defaultCover;
+ novel.summary = (_a = loadedCheerio("#noidungm").text()) === null || _a === void 0 ? void 0 : _a.trim();
+ novel.author = (_b = loadedCheerio("#main_body > div.cotgiua > div.truyen_info_wrapper > div.truyen_info > div.entry-header > div.truyen_if_wrap > ul > li:nth-child(2) > a")
+ .text()) === null || _b === void 0 ? void 0 : _b.trim();
+ status = (_c = loadedCheerio("#main_body > div.cotgiua > div.truyen_info_wrapper > div.truyen_info > div.entry-header > div.truyen_if_wrap > ul > li:nth-child(4) > a")
+ .text()) === null || _c === void 0 ? void 0 : _c.trim();
+ novel.status =
+ status === "ONGOING"
+ ? novelStatus_1.NovelStatus.Ongoing
+ : status === "COMPLETED"
+ ? novelStatus_1.NovelStatus.Completed
+ : novelStatus_1.NovelStatus.Unknown;
+ novelChapters = [];
+ loadedCheerio(".chapter-list div.row").each(function () {
+ var chapterName = loadedCheerio(this).find("a").text().trim();
+ var releaseDate = loadedCheerio(this)
+ .find("span:nth-child(2)")
+ .text()
+ .trim();
+ var chapterUrl = loadedCheerio(this).find("a").attr("href");
+ if (!chapterUrl) {
+ // TODO: Handle error
+ console.error("No chapter url!");
+ return;
+ }
+ novelChapters.push({
+ name: chapterName,
+ releaseTime: releaseDate,
+ url: chapterUrl,
+ });
+ });
+ novel.chapters = novelChapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ BLN.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, result, body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ url = chapterUrl;
+ return [4 /*yield*/, fetch(url)];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio("#vung_doc").html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ BLN.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, result, body, loadedCheerio, novels;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ url = "".concat(this.site, "search_novels/").concat(searchTerm);
+ return [4 /*yield*/, fetch(url)];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novels = [];
+ loadedCheerio(".update_item.list_category").each(function () {
+ var novelName = loadedCheerio(this).find("h3 > a").text();
+ var novelCover = loadedCheerio(this).find("img").attr("src");
+ var novelUrl = loadedCheerio(this).find("h3 > a").attr("href");
+ if (!novelUrl) {
+ // TODO: Handle error
+ console.error("No novel url!");
+ return;
+ }
+ var novel = { name: novelName, cover: novelCover, url: novelUrl };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ BLN.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return BLN;
+}());
+exports.default = new BLN();
diff --git a/.js/plugins/english/nobleMTL.js b/.js/plugins/english/nobleMTL.js
new file mode 100644
index 0000000..db22d5b
--- /dev/null
+++ b/.js/plugins/english/nobleMTL.js
@@ -0,0 +1,377 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var cheerio_1 = require("cheerio");
+var fetch_1 = require("@libs/fetch");
+var filterInputs_1 = require("@libs/filterInputs");
+var NobleMTL = /** @class */ (function () {
+ function NobleMTL() {
+ this.id = "noblemtl";
+ this.name = "NobleMTL";
+ this.icon = "src/en/noblemtl/icon.png";
+ this.site = "https://noblemtl.com/";
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.filters = [
+ {
+ key: "order",
+ label: "Sort By",
+ values: [
+ { label: "Default", value: "" },
+ { label: "A-Z", value: "title" },
+ { label: "Z-A", value: "titlereverse" },
+ { label: "Latest Update", value: "update" },
+ { label: "Latest Added", value: "latest" },
+ { label: "Popular", value: "popular" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Picker,
+ },
+ {
+ key: "status",
+ label: "Status",
+ values: [
+ { label: "All", value: "" },
+ { label: "Ongoing", value: "ongoing" },
+ { label: "Hiatus", value: "hiatus" },
+ { label: "Completed", value: "completed" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Picker,
+ },
+ {
+ key: "type",
+ label: "Type",
+ values: [
+ { label: "Chinese novel", value: "chinese-novel" },
+ { label: "habyeol", value: "habyeol" },
+ { label: "korean novel", value: "korean-novel" },
+ { label: "Web Novel", value: "web-novel" },
+ { label: "삼심", value: "%ec%82%bc%ec%8b%ac" },
+ { label: "호곡", value: "%ed%98%b8%ea%b3%a1" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Checkbox,
+ },
+ {
+ key: "genres",
+ label: "Genres",
+ values: [
+ { label: "A.I", value: "a.i" },
+ { label: "Academy", value: "academy" },
+ { label: "Action", value: "action" },
+ { label: "Adult", value: "adult" },
+ { label: "Adventure", value: "adventure" },
+ { label: "Alternative History", value: "alternative-history" },
+ { label: "Another World", value: "another-world" },
+ { label: "Apocalypse", value: "apocalypse" },
+ { label: "Bromance", value: "bromance" },
+ { label: "Comedy", value: "comedy" },
+ { label: "Dark fantasy", value: "dark-fantasy" },
+ { label: "Demons", value: "demons" },
+ { label: "Drama", value: "drama" },
+ { label: "Dystopia", value: "dystopia" },
+ { label: "Ecchi", value: "ecchi" },
+ { label: "Entertainment", value: "entertainment" },
+ { label: "Exhaustion", value: "exhaustion" },
+ { label: "Fanfiction", value: "fanfiction" },
+ { label: "fantasy", value: "fantasy" },
+ { label: "finance", value: "finance" },
+ { label: "Full color", value: "full-color" },
+ { label: "Game", value: "game" },
+ { label: "Gender Bender", value: "gender-bender" },
+ { label: "Genius", value: "genius" },
+ { label: "Harem", value: "harem" },
+ { label: "Hero", value: "hero" },
+ { label: "Historical", value: "historical" },
+ { label: "Hunter", value: "hunter" },
+ { label: "korean novel", value: "korean-novel" },
+ { label: "Light Novel", value: "light-novel" },
+ {
+ label: "List Adventure Manga Genres",
+ value: "list-adventure-manga-genres",
+ },
+ { label: "Long Strip", value: "long-strip" },
+ { label: "Love comedy", value: "love-comedy" },
+ { label: "magic", value: "magic" },
+ { label: "Manhua", value: "manhua" },
+ { label: "Martial Arts", value: "martial-arts" },
+ { label: "Mature", value: "mature" },
+ { label: "Medieval", value: "medieval" },
+ { label: "Misunderstanding", value: "misunderstanding" },
+ { label: "Modern", value: "modern" },
+ { label: "modern fantasy", value: "modern-fantasy" },
+ { label: "music", value: "music" },
+ { label: "Mystery", value: "mystery" },
+ { label: "Necromancy", value: "necromancy" },
+ { label: "No Romance", value: "no-romance" },
+ { label: "NTL", value: "ntl" },
+ { label: "o", value: "o" },
+ { label: "Obsession", value: "obsession" },
+ { label: "Politics", value: "politics" },
+ { label: "Possession", value: "possession" },
+ { label: "Programming", value: "programming" },
+ { label: "Psychological", value: "psychological" },
+ { label: "Pure Love", value: "pure-love" },
+ { label: "Redemption", value: "redemption" },
+ { label: "Regression", value: "regression" },
+ { label: "Regret", value: "regret" },
+ { label: "Reincarnation", value: "reincarnation" },
+ { label: "Revenge", value: "revenge" },
+ { label: "Romance", value: "romance" },
+ { label: "Romance Fanrasy", value: "romance-fanrasy" },
+ { label: "Salvation", value: "salvation" },
+ { label: "School Life", value: "school-life" },
+ { label: "Sci-fi", value: "sci-fi" },
+ { label: "Science fiction", value: "science-fiction" },
+ { label: "Seinen", value: "seinen" },
+ { label: "Shounen", value: "shounen" },
+ { label: "Slice of Life", value: "slice-of-life" },
+ { label: "Soft yandere", value: "soft-yandere" },
+ { label: "Sports", value: "sports" },
+ { label: "Supernatural", value: "supernatural" },
+ { label: "Survival", value: "survival" },
+ { label: "system", value: "system" },
+ { label: "Time limit", value: "time-limit" },
+ { label: "Tragedy", value: "tragedy" },
+ { label: "Transmigration", value: "transmigration" },
+ { label: "TS", value: "ts" },
+ { label: "Tsundere", value: "tsundere" },
+ { label: "Unique", value: "unique" },
+ { label: "Wholesome", value: "wholesome" },
+ { label: "Wuxia", value: "wuxia" },
+ { label: "Xuanhuan", value: "xuanhuan" },
+ { label: "Yandere", value: "yandere" },
+ { label: "Yuri", value: "yuri" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Checkbox,
+ },
+ ];
+ }
+ NobleMTL.prototype.popularNovels = function (pageNo, _a) {
+ var filters = _a.filters;
+ return __awaiter(this, void 0, void 0, function () {
+ var link, headers, body, loadedCheerio, novels;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ link = "".concat(this.site, "series/?page=").concat(pageNo);
+ if (filters) {
+ if (Array.isArray(filters.genres) && filters.genres.length) {
+ link += filters.genres.map(function (i) { return "&genre[]=".concat(i); }).join("");
+ }
+ if (Array.isArray(filters.type) && filters.type.length)
+ link += filters.type.map(function (i) { return "&lang[]=".concat(i); }).join("");
+ }
+ link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters.status : "");
+ link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order : "popular");
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { headers: headers }).then(function (result) {
+ return result.text();
+ })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novels = [];
+ loadedCheerio("article.bs").each(function () {
+ var novelName = loadedCheerio(this).find(".ntitle").text().trim();
+ var image = loadedCheerio(this).find("img");
+ var novelCover = image.attr("data-src") || image.attr("src");
+ var novelUrl = loadedCheerio(this).find("a").attr("href");
+ if (!novelUrl)
+ return;
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ ;
+ NobleMTL.prototype.parseNovelAndChapters = function (novelUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, headers, result, body, loadedCheerio, novel, chapter;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ url = novelUrl;
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novel = {
+ url: url,
+ chapters: [],
+ };
+ novel.name = loadedCheerio(".entry-title").text();
+ novel.cover =
+ loadedCheerio("img.wp-post-image").attr("data-src") ||
+ loadedCheerio("img.wp-post-image").attr("src");
+ loadedCheerio("div.spe > span").each(function () {
+ var detailName = loadedCheerio(this).find("b").text().trim();
+ var detail = loadedCheerio(this).find('b').remove().end().text().trim();
+ switch (detailName) {
+ case "Author:":
+ novel.author = detail;
+ break;
+ case "Status:":
+ novel.status = detail;
+ break;
+ }
+ });
+ novel.genres = loadedCheerio(".genxed")
+ .text()
+ .trim()
+ .replace(/\s/g, ",");
+ loadedCheerio('div[itemprop="description"] h3,p.a,strong').remove();
+ novel.summary = loadedCheerio('div[itemprop="description"]')
+ .find("br")
+ .replaceWith("\n")
+ .end()
+ .text();
+ chapter = [];
+ loadedCheerio(".eplister")
+ .find("li")
+ .each(function () {
+ var chapterName = loadedCheerio(this).find(".epl-num").text() +
+ " - " +
+ loadedCheerio(this).find(".epl-title").text();
+ var releaseDate = loadedCheerio(this)
+ .find(".epl-date")
+ .text()
+ .trim();
+ var chapterUrl = loadedCheerio(this).find("a").attr("href");
+ if (!chapterUrl)
+ return;
+ chapter.push({
+ name: chapterName,
+ releaseTime: releaseDate,
+ url: chapterUrl,
+ });
+ });
+ novel.chapters = chapter.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ NobleMTL.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var headers, result, body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio(".epcontent").html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ NobleMTL.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, headers, result, body, loadedCheerio, novels;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ url = "".concat(this.site, "?s=").concat(searchTerm);
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novels = [];
+ loadedCheerio("article.bs").each(function () {
+ var novelName = loadedCheerio(this).find(".ntitle").text().trim();
+ var novelCover = loadedCheerio(this).find("img").attr("src");
+ var novelUrl = loadedCheerio(this).find("a").attr("href");
+ if (!novelUrl)
+ return;
+ novels.push({
+ name: novelName,
+ url: novelUrl,
+ cover: novelCover,
+ });
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ NobleMTL.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return NobleMTL;
+}());
+exports.default = new NobleMTL();
diff --git a/.js/plugins/english/pandaMTL.js b/.js/plugins/english/pandaMTL.js
new file mode 100644
index 0000000..50d8b18
--- /dev/null
+++ b/.js/plugins/english/pandaMTL.js
@@ -0,0 +1,304 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var cheerio_1 = require("cheerio");
+var fetch_1 = require("@libs/fetch");
+var filterInputs_1 = require("@libs/filterInputs");
+var PandaMTL = /** @class */ (function () {
+ function PandaMTL() {
+ this.id = "pandamtl";
+ this.name = "PandaMTL";
+ this.icon = "src/en/wordpress/icon.png";
+ this.site = "https://pandamtl.com/";
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.filters = [
+ {
+ key: "order",
+ label: "Sort By",
+ values: [
+ { label: "Default", value: "" },
+ { label: "A-Z", value: "title" },
+ { label: "Z-A", value: "titlereverse" },
+ { label: "Latest Update", value: "update" },
+ { label: "Latest Added", value: "latest" },
+ { label: "Popular", value: "popular" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Picker,
+ },
+ {
+ key: "status",
+ label: "Status",
+ values: [
+ { label: "All", value: "" },
+ { label: "Ongoing", value: "ongoing" },
+ { label: "Hiatus", value: "hiatus" },
+ { label: "Completed", value: "completed" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Picker,
+ },
+ {
+ key: "type",
+ label: "Type",
+ values: [
+ { label: "Light Novel (KR)", value: "light-novel-kr" },
+ { label: "Web Novel", value: "web-novel" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Checkbox,
+ },
+ {
+ key: "genres",
+ label: "Genres",
+ values: [
+ { label: "Action", value: "action" },
+ { label: "Adult", value: "adult" },
+ { label: "Adventure", value: "adventure" },
+ { label: "Comedy", value: "comedy" },
+ { label: "Ecchi", value: "ecchi" },
+ { label: "Fantasy", value: "fantasy" },
+ { label: "Harem", value: "harem" },
+ { label: "Josei", value: "josei" },
+ { label: "Martial Arts", value: "martial-arts" },
+ { label: "Mature", value: "mature" },
+ { label: "Romance", value: "romance" },
+ { label: "School Life", value: "school-life" },
+ { label: "Sci-fi", value: "sci-fi" },
+ { label: "Seinen", value: "seinen" },
+ { label: "Slice of Life", value: "slice-of-life" },
+ { label: "Smut", value: "smut" },
+ { label: "Sports", value: "sports" },
+ { label: "Supernatural", value: "supernatural" },
+ { label: "Tragedy", value: "tragedy" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Checkbox,
+ },
+ ];
+ }
+ PandaMTL.prototype.popularNovels = function (pageNo, _a) {
+ var filters = _a.filters;
+ return __awaiter(this, void 0, void 0, function () {
+ var link, headers, body, loadedCheerio, novels;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ link = "".concat(this.site, "series/?page=").concat(pageNo);
+ if (filters) {
+ if (Array.isArray(filters.genres) && filters.genres.length) {
+ link += filters.genres.map(function (i) { return "&genre[]=".concat(i); }).join("");
+ }
+ if (Array.isArray(filters.type) && filters.type.length)
+ link += filters.type.map(function (i) { return "&lang[]=".concat(i); }).join("");
+ }
+ link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters.status : "");
+ link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order : "popular");
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { headers: headers }).then(function (result) {
+ return result.text();
+ })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novels = [];
+ loadedCheerio("article.maindet").each(function () {
+ var novelName = loadedCheerio(this).find("h2").text();
+ var image = loadedCheerio(this).find("img");
+ var novelCover = image.attr("data-src") || image.attr("src");
+ var novelUrl = loadedCheerio(this).find("h2 a").attr("href");
+ if (!novelUrl)
+ return;
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ PandaMTL.prototype.parseNovelAndChapters = function (novelUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, headers, result, body, loadedCheerio, novel, chapter;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ url = novelUrl;
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novel = {
+ url: url,
+ chapters: [],
+ };
+ novel.name = loadedCheerio("h1.entry-title").text();
+ novel.cover =
+ loadedCheerio("img.wp-post-image").attr("data-src") ||
+ loadedCheerio("img.wp-post-image").attr("src");
+ loadedCheerio(".serl:nth-child(3) > span").each(function () {
+ var detailName = loadedCheerio(this).text().trim();
+ var detail = loadedCheerio(this).next().text().trim();
+ switch (detailName) {
+ case "Author":
+ novel.author = detail;
+ break;
+ }
+ });
+ novel.status = loadedCheerio(".sertostat > span").attr("class");
+ novel.genres = loadedCheerio(".sertogenre")
+ .children("a")
+ .map(function (i, el) { return loadedCheerio(el).text(); })
+ .toArray()
+ .join(",");
+ novel.summary = loadedCheerio(".sersys")
+ .find("br")
+ .replaceWith("\n")
+ .end()
+ .text();
+ chapter = [];
+ loadedCheerio(".eplister")
+ .find("li")
+ .each(function () {
+ var chapterName = loadedCheerio(this).find(".epl-num").text() +
+ " - " +
+ loadedCheerio(this).find(".epl-title").text();
+ var releaseDate = loadedCheerio(this)
+ .find(".epl-date")
+ .text()
+ .trim();
+ var chapterUrl = loadedCheerio(this).find("a").attr("href");
+ if (!chapterUrl)
+ return;
+ chapter.push({
+ name: chapterName,
+ releaseTime: releaseDate,
+ url: chapterUrl,
+ });
+ });
+ novel.chapters = chapter.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ PandaMTL.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var headers, result, body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio(".epcontent").html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ PandaMTL.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, headers, result, body, loadedCheerio, novels;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ url = "".concat(this.site, "?s=").concat(searchTerm);
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novels = [];
+ loadedCheerio("article.maindet").each(function () {
+ var novelName = loadedCheerio(this).find("h2").text();
+ var image = loadedCheerio(this).find("img");
+ var novelCover = image.attr("data-src") || image.attr("src");
+ var novelUrl = loadedCheerio(this).find("h2 a").attr("href");
+ if (!novelUrl)
+ return;
+ novels.push({
+ name: novelName,
+ url: novelUrl,
+ cover: novelCover,
+ });
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ PandaMTL.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return PandaMTL;
+}());
+exports.default = new PandaMTL();
diff --git a/.js/plugins/indonesian/MeioNovel[madara].js b/.js/plugins/indonesian/MeioNovel[madara].js
new file mode 100644
index 0000000..00bb961
--- /dev/null
+++ b/.js/plugins/indonesian/MeioNovel[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "meionovel", "sourceSite": "https://meionovel.id/", "sourceName": "MeioNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Cooking", "value": "cooking" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fanfiction", "value": "fanfiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Josei", "value": "josei" }, { "label": "Magic", "value": "magic" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reverse Harem", "value": "reverse-harem" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Virtual Reality", "value": "virtual-reality" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "Indonesian" } });
+exports.default = plugin;
diff --git a/.js/plugins/indonesian/MoreNovel[madara].js b/.js/plugins/indonesian/MoreNovel[madara].js
new file mode 100644
index 0000000..ce9c9ee
--- /dev/null
+++ b/.js/plugins/indonesian/MoreNovel[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "morenovel", "sourceSite": "https://morenovel.net/", "sourceName": "MoreNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "Indonesian" } });
+exports.default = plugin;
diff --git a/.js/plugins/indonesian/WBNovel[madara].js b/.js/plugins/indonesian/WBNovel[madara].js
new file mode 100644
index 0000000..405c815
--- /dev/null
+++ b/.js/plugins/indonesian/WBNovel[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "wbnovel", "sourceSite": "https://wbnovel.com/", "sourceName": "WBNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Alchemy", "value": "alchemy" }, { "label": "Comedy", "value": "comedy" }, { "label": "Crafting", "value": "crafting" }, { "label": "Cultivation", "value": "cultivation" }, { "label": "Drama", "value": "drama" }, { "label": "Dungeon Crawling", "value": "dungeon-crawling" }, { "label": "Eci", "value": "eci" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Game", "value": "game" }, { "label": "Harem", "value": "harem" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Kingdom Building", "value": "kingdom-building" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Modern Setting", "value": "modern-setting" }, { "label": "Mystery", "value": "mystery" }, { "label": "Pets", "value": "pets" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reincarnator", "value": "reincarnator" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shounen", "value": "shounen" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Transmigration", "value": "transmigration" }, { "label": "Virtual Reality", "value": "virtual-reality" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }], "inputType": "Picker" }], "options": { "lang": "Indonesian" } });
+exports.default = plugin;
diff --git a/.js/plugins/portuguese/lightnovelbrasil.js b/.js/plugins/portuguese/lightnovelbrasil.js
new file mode 100644
index 0000000..33c26e5
--- /dev/null
+++ b/.js/plugins/portuguese/lightnovelbrasil.js
@@ -0,0 +1,378 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var cheerio_1 = require("cheerio");
+var fetch_1 = require("@libs/fetch");
+var filterInputs_1 = require("@libs/filterInputs");
+var LightNovelBrasil = /** @class */ (function () {
+ function LightNovelBrasil() {
+ this.id = "lightnovelbrasil";
+ this.name = "Light Novel Brasil";
+ this.icon = "multisrc/wpmangastream/icons/lightnovelbrasil.png";
+ this.site = "https://lightnovelbrasil.com/";
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.filters = [
+ {
+ key: "order",
+ label: "Sort By",
+ values: [
+ { label: "Default", value: "" },
+ { label: "A-Z", value: "title" },
+ { label: "Z-A", value: "titlereverse" },
+ { label: "Latest Update", value: "update" },
+ { label: "Latest Added", value: "latest" },
+ { label: "Popular", value: "popular" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Picker,
+ },
+ {
+ key: "status",
+ label: "Status",
+ values: [
+ { label: "All", value: "" },
+ { label: "Ongoing", value: "ongoing" },
+ { label: "Hiatus", value: "hiatus" },
+ { label: "Completed", value: "completed" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Picker,
+ },
+ {
+ key: "type",
+ label: "Type",
+ values: [
+ { label: "Chinese novel", value: "chinese-novel" },
+ { label: "habyeol", value: "habyeol" },
+ { label: "korean novel", value: "korean-novel" },
+ { label: "Web Novel", value: "web-novel" },
+ { label: "삼심", value: "%ec%82%bc%ec%8b%ac" },
+ { label: "호곡", value: "%ed%98%b8%ea%b3%a1" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Checkbox,
+ },
+ {
+ key: "genres",
+ label: "Genres",
+ values: [
+ { label: "A.I", value: "a.i" },
+ { label: "Academy", value: "academy" },
+ { label: "Action", value: "action" },
+ { label: "Adult", value: "adult" },
+ { label: "Adventure", value: "adventure" },
+ { label: "Alternative History", value: "alternative-history" },
+ { label: "Another World", value: "another-world" },
+ { label: "Apocalypse", value: "apocalypse" },
+ { label: "Bromance", value: "bromance" },
+ { label: "Comedy", value: "comedy" },
+ { label: "Dark fantasy", value: "dark-fantasy" },
+ { label: "Demons", value: "demons" },
+ { label: "Drama", value: "drama" },
+ { label: "Dystopia", value: "dystopia" },
+ { label: "Ecchi", value: "ecchi" },
+ { label: "Entertainment", value: "entertainment" },
+ { label: "Exhaustion", value: "exhaustion" },
+ { label: "Fanfiction", value: "fanfiction" },
+ { label: "fantasy", value: "fantasy" },
+ { label: "finance", value: "finance" },
+ { label: "Full color", value: "full-color" },
+ { label: "Game", value: "game" },
+ { label: "Gender Bender", value: "gender-bender" },
+ { label: "Genius", value: "genius" },
+ { label: "Harem", value: "harem" },
+ { label: "Hero", value: "hero" },
+ { label: "Historical", value: "historical" },
+ { label: "Hunter", value: "hunter" },
+ { label: "korean novel", value: "korean-novel" },
+ { label: "Light Novel", value: "light-novel" },
+ {
+ label: "List Adventure Manga Genres",
+ value: "list-adventure-manga-genres",
+ },
+ { label: "Long Strip", value: "long-strip" },
+ { label: "Love comedy", value: "love-comedy" },
+ { label: "magic", value: "magic" },
+ { label: "Manhua", value: "manhua" },
+ { label: "Martial Arts", value: "martial-arts" },
+ { label: "Mature", value: "mature" },
+ { label: "Medieval", value: "medieval" },
+ { label: "Misunderstanding", value: "misunderstanding" },
+ { label: "Modern", value: "modern" },
+ { label: "modern fantasy", value: "modern-fantasy" },
+ { label: "music", value: "music" },
+ { label: "Mystery", value: "mystery" },
+ { label: "Necromancy", value: "necromancy" },
+ { label: "No Romance", value: "no-romance" },
+ { label: "NTL", value: "ntl" },
+ { label: "o", value: "o" },
+ { label: "Obsession", value: "obsession" },
+ { label: "Politics", value: "politics" },
+ { label: "Possession", value: "possession" },
+ { label: "Programming", value: "programming" },
+ { label: "Psychological", value: "psychological" },
+ { label: "Pure Love", value: "pure-love" },
+ { label: "Redemption", value: "redemption" },
+ { label: "Regression", value: "regression" },
+ { label: "Regret", value: "regret" },
+ { label: "Reincarnation", value: "reincarnation" },
+ { label: "Revenge", value: "revenge" },
+ { label: "Romance", value: "romance" },
+ { label: "Romance Fanrasy", value: "romance-fanrasy" },
+ { label: "Salvation", value: "salvation" },
+ { label: "School Life", value: "school-life" },
+ { label: "Sci-fi", value: "sci-fi" },
+ { label: "Science fiction", value: "science-fiction" },
+ { label: "Seinen", value: "seinen" },
+ { label: "Shounen", value: "shounen" },
+ { label: "Slice of Life", value: "slice-of-life" },
+ { label: "Soft yandere", value: "soft-yandere" },
+ { label: "Sports", value: "sports" },
+ { label: "Supernatural", value: "supernatural" },
+ { label: "Survival", value: "survival" },
+ { label: "system", value: "system" },
+ { label: "Time limit", value: "time-limit" },
+ { label: "Tragedy", value: "tragedy" },
+ { label: "Transmigration", value: "transmigration" },
+ { label: "TS", value: "ts" },
+ { label: "Tsundere", value: "tsundere" },
+ { label: "Unique", value: "unique" },
+ { label: "Wholesome", value: "wholesome" },
+ { label: "Wuxia", value: "wuxia" },
+ { label: "Xuanhuan", value: "xuanhuan" },
+ { label: "Yandere", value: "yandere" },
+ { label: "Yuri", value: "yuri" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Checkbox,
+ },
+ ];
+ }
+ LightNovelBrasil.prototype.popularNovels = function (pageNo, _a) {
+ var filters = _a.filters;
+ return __awaiter(this, void 0, void 0, function () {
+ var link, headers, body, loadedCheerio, novels;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ link = "".concat(this.site, "series/?page=").concat(pageNo);
+ if (filters) {
+ if (Array.isArray(filters.genres) && filters.genres.length) {
+ link += filters.genres.map(function (i) { return "&genre[]=".concat(i); }).join("");
+ }
+ if (Array.isArray(filters.type) && filters.type.length)
+ link += filters.type.map(function (i) { return "&lang[]=".concat(i); }).join("");
+ }
+ link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters.status : "");
+ link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order : "popular");
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { headers: headers }).then(function (result) {
+ return result.text();
+ })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novels = [];
+ loadedCheerio("article.bs").each(function () {
+ var novelName = loadedCheerio(this).find(".ntitle").text().trim();
+ var image = loadedCheerio(this).find("img");
+ var novelCover = image.attr("data-src") || image.attr("src");
+ var novelUrl = loadedCheerio(this).find("a").attr("href");
+ if (!novelUrl)
+ return;
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ ;
+ LightNovelBrasil.prototype.parseNovelAndChapters = function (novelUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, headers, result, body, loadedCheerio, novel, chapter;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ url = novelUrl;
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novel = {
+ url: url,
+ chapters: [],
+ };
+ novel.name = loadedCheerio(".entry-title").text();
+ novel.cover =
+ loadedCheerio("img.wp-post-image").attr("data-src") ||
+ loadedCheerio("img.wp-post-image").attr("src");
+ loadedCheerio("div.spe > span").each(function () {
+ var detailName = loadedCheerio(this).find("b").text().trim();
+ var detail = loadedCheerio(this).find('b').remove().end().text().trim();
+ switch (detailName) {
+ case "Autor:":
+ case "Author:":
+ novel.author = detail;
+ break;
+ case "Status:":
+ novel.status = detail;
+ break;
+ }
+ });
+ novel.genres = loadedCheerio(".genxed")
+ .text()
+ .trim()
+ .replace(/\s/g, ",");
+ loadedCheerio('div[itemprop="description"] h3,p.a,strong').remove();
+ novel.summary = loadedCheerio('div[itemprop="description"]')
+ .find("br")
+ .replaceWith("\n")
+ .end()
+ .text();
+ chapter = [];
+ loadedCheerio(".eplister")
+ .find("li")
+ .each(function () {
+ var chapterName = loadedCheerio(this).find(".epl-num").text() +
+ " - " +
+ loadedCheerio(this).find(".epl-title").text();
+ var releaseDate = loadedCheerio(this)
+ .find(".epl-date")
+ .text()
+ .trim();
+ var chapterUrl = loadedCheerio(this).find("a").attr("href");
+ if (!chapterUrl)
+ return;
+ chapter.push({
+ name: chapterName,
+ releaseTime: releaseDate,
+ url: chapterUrl,
+ });
+ });
+ novel.chapters = chapter.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ LightNovelBrasil.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var headers, result, body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio(".epcontent").html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ LightNovelBrasil.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, headers, result, body, loadedCheerio, novels;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ url = "".concat(this.site, "?s=").concat(searchTerm);
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novels = [];
+ loadedCheerio("article.bs").each(function () {
+ var novelName = loadedCheerio(this).find(".ntitle").text().trim();
+ var novelCover = loadedCheerio(this).find("img").attr("src");
+ var novelUrl = loadedCheerio(this).find("a").attr("href");
+ if (!novelUrl)
+ return;
+ novels.push({
+ name: novelName,
+ url: novelUrl,
+ cover: novelCover,
+ });
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ LightNovelBrasil.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return LightNovelBrasil;
+}());
+exports.default = new LightNovelBrasil();
diff --git a/.js/plugins/spanish/tunovelaligera.js b/.js/plugins/spanish/tunovelaligera.js
new file mode 100644
index 0000000..be932e5
--- /dev/null
+++ b/.js/plugins/spanish/tunovelaligera.js
@@ -0,0 +1,416 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var cheerio_1 = require("cheerio");
+var fetch_1 = require("@libs/fetch");
+var filterInputs_1 = require("@libs/filterInputs");
+var showToast_1 = require("@libs/showToast");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var TuNovelaLigera = /** @class */ (function () {
+ function TuNovelaLigera() {
+ this.id = "tunovelaligera";
+ this.name = "TuNovelaLigera";
+ this.icon = "src/es/tunovelaligera/icon.png";
+ this.site = "https://tunovelaligera.com/";
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.filters = [
+ {
+ key: "order",
+ label: "Ordenado por",
+ values: [
+ { label: "Lo mas reciente", value: "?m_orderby=latest" },
+ { label: "A-Z", value: "?m_orderby=alphabet" },
+ { label: "Clasificación", value: "?m_orderby=rating" },
+ { label: "Trending", value: "?m_orderby=trending" },
+ { label: "Mas visto", value: "?m_orderby=views" },
+ { label: "Nuevo", value: "?m_orderby=new-manga" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Picker,
+ },
+ {
+ key: "genres",
+ label: "Generos",
+ values: [
+ { label: "Acción", value: "accion" },
+ { label: "Adulto", value: "adulto" },
+ { label: "Artes Marciales", value: "artes-marciales" },
+ { label: "Aventura", value: "aventura" },
+ { label: "Ciencia Ficción", value: "ciencia-ficcion" },
+ { label: "Comedia", value: "comedia" },
+ { label: "Deportes", value: "deportes" },
+ { label: "Drama", value: "drama" },
+ { label: "Eastern Fantasy", value: "eastern-fantasy" },
+ { label: "Ecchi", value: "ecchi" },
+ { label: "FanFiction", value: "fan-fiction" },
+ { label: "Fantasía", value: "fantasia" },
+ { label: "Fantasía oriental", value: "fantasia-oriental" },
+ { label: "Ficción Romántica", value: "ficcion-romantica" },
+ { label: "Gender Bender", value: "gender-bender" },
+ { label: "Harem", value: "harem" },
+ { label: "Histórico", value: "historico" },
+ { label: "Horror", value: "horror" },
+ { label: "Josei", value: "josei" },
+ { label: "Maduro", value: "maduro" },
+ { label: "Mecha", value: "mecha" },
+ { label: "Misterio", value: "misterio" },
+ { label: "Novela China", value: "novela-china" },
+ { label: "Novela FanFiction", value: "novela-fanfiction" },
+ { label: "Novela Japonesa", value: "novela-japonesa" },
+ { label: "Novela Koreana", value: "novela-koreana" },
+ { label: "Novela ligera", value: "novela-ligera" },
+ { label: "Novela original", value: "novela-original" },
+ { label: "Novela Web", value: "web-novel" },
+ { label: "Psicológico", value: "psicologico" },
+ { label: "Realismo Mágico", value: "realismo-magico" },
+ { label: "Recuento de vida", value: "recuento-de-vida" },
+ { label: "Romance", value: "romance" },
+ { label: "Romance contemporáneo", value: "romance-contemporaneo" },
+ { label: "Romance Moderno", value: "romance-moderno" },
+ { label: "Seinen", value: "seinen" },
+ { label: "Shoujo", value: "shoujo" },
+ { label: "Shounen", value: "shounen" },
+ { label: "Sobrenatural", value: "sobrenatural" },
+ { label: "Tragedia", value: "tragedia" },
+ { label: "Vampiros", value: "vampiros" },
+ { label: "Vida Escolar", value: "vida-escolar" },
+ { label: "Western Fantasy", value: "western-fantasy" },
+ { label: "Wuxia", value: "wuxia" },
+ { label: "Xianxia", value: "xianxia" },
+ { label: "Xuanhuan", value: "xuanhuan" },
+ { label: "Yaoi", value: "yaoi" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Picker,
+ },
+ ];
+ }
+ TuNovelaLigera.prototype.popularNovels = function (pageNo, _a) {
+ var filters = _a.filters;
+ return __awaiter(this, void 0, void 0, function () {
+ var link, headers, result, body, loadedCheerio, novels;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ link = "".concat(this.site);
+ link += ((filters === null || filters === void 0 ? void 0 : filters.genres) ? "genero/" + filters.genres : "novelas");
+ link += "/page/".concat(pageNo);
+ link += ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order : "?m_orderby=rating");
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { headers: headers })];
+ case 1:
+ result = _b.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novels = [];
+ loadedCheerio(".page-item-detail").each(function (i, el) {
+ var novelName = loadedCheerio(el).find(".h5 > a").text();
+ var novelCover = loadedCheerio(el).find("img").attr("src");
+ var novelUrl = loadedCheerio(el).find(".h5 > a").attr("href");
+ if (!novelUrl)
+ return;
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ ;
+ TuNovelaLigera.prototype.parseNovelAndChapters = function (novelUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, headers, result, body, loadedCheerio, novel, novelCover, chapter, delay, lastPage, getChapters, getPageChapters, _a, _b;
+ var _this = this;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ url = novelUrl;
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })];
+ case 1:
+ result = _c.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _c.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novel = {
+ url: url,
+ chapters: [],
+ };
+ loadedCheerio(".manga-title-badges").remove();
+ novel.name = loadedCheerio(".post-title > h1").text().trim();
+ novelCover = loadedCheerio(".summary_image > a > img");
+ novel.cover =
+ novelCover.attr("data-src") ||
+ novelCover.attr("src") ||
+ novelCover.attr('data-cfsrc') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio(".post-content_item").each(function () {
+ var detailName = loadedCheerio(this)
+ .find(".summary-heading > h5")
+ .text()
+ .trim();
+ var detail = loadedCheerio(this)
+ .find(".summary-content")
+ .text()
+ .trim();
+ switch (detailName) {
+ case "Generos":
+ novel.genres = detail.replace(/, /g, ",");
+ break;
+ case "Autores":
+ novel.author = detail;
+ break;
+ case "Estado":
+ novel.status =
+ detail.includes("OnGoing") ||
+ detail.includes("Updating")
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ novel.summary = loadedCheerio("div.summary__content > p").text().trim();
+ chapter = [];
+ delay = function (ms) { return new Promise(function (res) { return setTimeout(res, ms); }); };
+ lastPage = 1;
+ lastPage = +loadedCheerio('.lcp_paginator li:last').prev().text();
+ getChapters = function () { return __awaiter(_this, void 0, void 0, function () {
+ var n, novelName, formData, result, text;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ n = url.split('/');
+ novelName = n[4];
+ (0, showToast_1.showToast)('Cargando desde Archivo...');
+ formData = new FormData();
+ formData.append("action", "madara_load_more");
+ formData.append("page", "0");
+ formData.append("template", "html/loop/content");
+ formData.append("vars[category_name]", novelName);
+ formData.append("vars[posts_per_page]", "10000");
+ return [4 /*yield*/, (0, fetch_1.fetchApi)("".concat(this.site, "wp-admin/admin-ajax.php"), {
+ method: "POST",
+ body: formData,
+ headers: headers
+ })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ text = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(text);
+ loadedCheerio('.heading').each(function (i, el) {
+ var chapterName = loadedCheerio(el)
+ .text()
+ .replace(/[\t\n]/g, '')
+ .trim();
+ var releaseDate = null;
+ var chapterUrl = loadedCheerio(el).find('a').attr('href') || "";
+ chapter.push({
+ name: chapterName,
+ url: chapterUrl,
+ releaseTime: releaseDate,
+ });
+ });
+ return [2 /*return*/, chapter.reverse()];
+ }
+ });
+ }); };
+ getPageChapters = function () { return __awaiter(_this, void 0, void 0, function () {
+ var _loop_1, i;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ _loop_1 = function (i) {
+ var chaptersUrl, result_1, chaptersHTML, chapterCheerio;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ chaptersUrl = "".concat(novelUrl, "?lcp_page0=").concat(i);
+ (0, showToast_1.showToast)("Cargando desde la p\u00E1gina ".concat(i, "/").concat(lastPage, "..."));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(chaptersUrl, { headers: headers })];
+ case 1:
+ result_1 = _b.sent();
+ return [4 /*yield*/, result_1.text()];
+ case 2:
+ chaptersHTML = _b.sent();
+ chapterCheerio = (0, cheerio_1.load)(chaptersHTML);
+ chapterCheerio('.lcp_catlist li').each(function (i, el) {
+ var chapterName = chapterCheerio(el)
+ .find('a')
+ .text()
+ .replace(/[\t\n]/g, '')
+ .trim();
+ var releaseDate = chapterCheerio(el)
+ .find('span')
+ .text()
+ .trim();
+ var chapterUrl = chapterCheerio(el).find('a').attr('href') || "";
+ chapter.push({
+ name: chapterName,
+ releaseTime: releaseDate,
+ url: chapterUrl,
+ });
+ });
+ return [4 /*yield*/, delay(1000)];
+ case 3:
+ _b.sent();
+ return [2 /*return*/];
+ }
+ });
+ };
+ i = 1;
+ _a.label = 1;
+ case 1:
+ if (!(i <= lastPage)) return [3 /*break*/, 4];
+ return [5 /*yield**/, _loop_1(i)];
+ case 2:
+ _a.sent();
+ _a.label = 3;
+ case 3:
+ i++;
+ return [3 /*break*/, 1];
+ case 4: return [2 /*return*/, chapter.reverse()];
+ }
+ });
+ }); };
+ _a = novel;
+ return [4 /*yield*/, getChapters()];
+ case 3:
+ _a.chapters = _c.sent();
+ if (!!novel.chapters.length) return [3 /*break*/, 6];
+ (0, showToast_1.showToast)('¡Archivo no encontrado!');
+ return [4 /*yield*/, delay(1000)];
+ case 4:
+ _c.sent();
+ _b = novel;
+ return [4 /*yield*/, getPageChapters()];
+ case 5:
+ _b.chapters = _c.sent();
+ _c.label = 6;
+ case 6: return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ TuNovelaLigera.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var headers, result, body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl)];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio("#hola_siguiente").next().find('div').remove();
+ chapterText = loadedCheerio("#hola_siguiente").next().html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ ;
+ TuNovelaLigera.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, result, body, loadedCheerio, novels;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ url = "".concat(this.site, "?s=").concat(searchTerm, "&post_type=wp-manga");
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url)];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novels = [];
+ loadedCheerio(".c-tabs-item__content").each(function (i, el) {
+ var novelName = loadedCheerio(el).find(".h4 > a").text();
+ var novelCover = loadedCheerio(el).find("img").attr("src");
+ var novelUrl = loadedCheerio(el).find(".h4 > a").attr("href");
+ if (!novelUrl)
+ return;
+ novels.push({
+ name: novelName,
+ url: novelUrl,
+ cover: novelCover,
+ });
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ ;
+ TuNovelaLigera.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return TuNovelaLigera;
+}());
+exports.default = new TuNovelaLigera();
diff --git a/.js/plugins/turkish/TurkceLightNovels[madara].js b/.js/plugins/turkish/TurkceLightNovels[madara].js
new file mode 100644
index 0000000..dc6ea8b
--- /dev/null
+++ b/.js/plugins/turkish/TurkceLightNovels[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "turkcelightnovels", "sourceSite": "https://turkcelightnovels.com/", "sourceName": "TurkceLightNovels", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "path": { "novels": "light-novel", "novel": "light-novel", "chapter": "light-novel" }, "lang": "Turkish" } });
+exports.default = plugin;
diff --git a/.js/plugins/turkish/WebNovelOku[madara].js b/.js/plugins/turkish/WebNovelOku[madara].js
new file mode 100644
index 0000000..122c9c0
--- /dev/null
+++ b/.js/plugins/turkish/WebNovelOku[madara].js
@@ -0,0 +1,269 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var fetch_1 = require("@libs/fetch");
+var cheerio_1 = require("cheerio");
+var defaultCover_1 = require("@libs/defaultCover");
+var novelStatus_1 = require("@libs/novelStatus");
+var parseMadaraDate_1 = require("@libs/parseMadaraDate");
+var dayjs_1 = __importDefault(require("dayjs"));
+var MadaraDefaultPath = {
+ novels: 'novel',
+ novel: 'novel',
+ chapter: 'novel'
+};
+var MadaraPlugin = /** @class */ (function () {
+ function MadaraPlugin(metadata) {
+ this.id = metadata.id;
+ this.name = metadata.sourceName + "[madara]";
+ var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase();
+ this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png");
+ this.site = metadata.sourceSite;
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.options = metadata.options;
+ this.filter = metadata.filters;
+ }
+ MadaraPlugin.prototype.popularNovels = function (pageNo, _a) {
+ var _b, _c, _d, _e, _f, _g;
+ var filters = _a.filters, showLatestNovels = _a.showLatestNovels;
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_h) {
+ switch (_h.label) {
+ case 0:
+ novels = [];
+ url = this.site;
+ if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) {
+ url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/';
+ }
+ else {
+ url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels;
+ }
+ url += '/page/' + pageNo + '/' +
+ '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating'));
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _h.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges').remove();
+ loadedCheerio('.page-item-detail').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this).find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ var _a;
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, body, loadedCheerio, html, novelId, formData, chapters;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.manga-title-badges, #manga-title span').remove();
+ novel.name =
+ loadedCheerio('.post-title h1').text().trim() ||
+ loadedCheerio('#manga-title h1').text();
+ novel.cover =
+ loadedCheerio('.summary_image > a > img').attr('data-lazy-src') ||
+ loadedCheerio('.summary_image > a > img').attr('data-src') ||
+ loadedCheerio('.summary_image > a > img').attr('src') ||
+ defaultCover_1.defaultCover;
+ loadedCheerio('.post-content_item, .post-content').each(function () {
+ var detailName = loadedCheerio(this).find('h5').text().trim();
+ var detail = loadedCheerio(this).find('.summary-content').text().trim();
+ switch (detailName) {
+ case 'Genre(s)':
+ case 'التصنيفات':
+ novel.genres = detail.replace(/[\\t\\n]/g, ',');
+ break;
+ case 'Author(s)':
+ case 'المؤلف':
+ case 'المؤلف (ين)':
+ novel.author = detail;
+ break;
+ case 'Status':
+ case 'الحالة':
+ novel.status =
+ detail.includes('OnGoing') || detail.includes('مستمرة')
+ ? novelStatus_1.NovelStatus.Ongoing
+ : novelStatus_1.NovelStatus.Completed;
+ break;
+ }
+ });
+ loadedCheerio('div.summary__content .code-block,script').remove();
+ novel.summary =
+ loadedCheerio('div.summary__content').text().trim() ||
+ loadedCheerio('#tab-manga-about').text().trim() ||
+ loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim();
+ if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3];
+ novelId = loadedCheerio('.rating-post-id').attr('value') ||
+ loadedCheerio('#manga-chapters-holder').attr('data-id') || '';
+ formData = new FormData();
+ formData.append("action", "manga_get_chapters");
+ formData.append("manga", novelId);
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(function (res) { return res.text(); })];
+ case 2:
+ html = _b.sent();
+ return [3 /*break*/, 5];
+ case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' })
+ .then(function (res) { return res.text(); })];
+ case 4:
+ html = _b.sent();
+ _b.label = 5;
+ case 5:
+ if (html !== '0') {
+ loadedCheerio = (0, cheerio_1.load)(html);
+ }
+ chapters = [];
+ loadedCheerio('.wp-manga-chapter').each(function () {
+ var chapterName = loadedCheerio(this).find('a').text().trim();
+ var releaseDate = null;
+ releaseDate = loadedCheerio(this)
+ .find('span.chapter-release-date')
+ .text()
+ .trim();
+ if (releaseDate) {
+ releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate);
+ }
+ else {
+ /**
+ * Insert current date
+ */
+ releaseDate = (0, dayjs_1.default)().format('LL');
+ }
+ var chapterUrl = loadedCheerio(this).find('a').attr('href') || '';
+ chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
+ });
+ novel.chapters = chapters.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio('.text-left').html() ||
+ loadedCheerio('.text-right').html() ||
+ loadedCheerio('.entry-content').html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novels, url, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novels = [];
+ url = this.site + "?s=" + searchTerm + "&post_type=wp-manga";
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })];
+ case 1:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ loadedCheerio('.c-tabs-item__content').each(function () {
+ var novelName = loadedCheerio(this).find('.post-title').text().trim();
+ var image = loadedCheerio(this).find('img');
+ var novelCover = image.attr('data-src') || image.attr('src');
+ var novelUrl = loadedCheerio(this)
+ .find('.post-title')
+ .find('a')
+ .attr('href') || '';
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ MadaraPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return MadaraPlugin;
+}());
+var plugin = new MadaraPlugin({ "id": "webnoveloku", "sourceSite": "https://www.webnoveloku.com/", "sourceName": "WebNovelOku ", "filters": [{ "key": "sort", "label": "Sırala", "values": [{ "label": "A-Z", "value": "alphabet" }, { "label": "En Son", "value": "latest" }, { "label": "Görüntülenme", "value": "views" }, { "label": "Popülarite", "value": "trending" }, { "label": "Reyting", "value": "rating" }, { "label": "Yeni", "value": "new-manga" }], "inputType": "Picker" }], "options": { "lang": "Turkish" } });
+exports.default = plugin;
diff --git a/.js/plugins/turkish/lshnovel.js b/.js/plugins/turkish/lshnovel.js
new file mode 100644
index 0000000..21807e0
--- /dev/null
+++ b/.js/plugins/turkish/lshnovel.js
@@ -0,0 +1,324 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var cheerio_1 = require("cheerio");
+var fetch_1 = require("@libs/fetch");
+var filterInputs_1 = require("@libs/filterInputs");
+var LSHNovel = /** @class */ (function () {
+ function LSHNovel() {
+ this.id = "lshnovel";
+ this.name = "Liebe Schnee Hiver Novel";
+ this.icon = "multisrc/wpmangastream/icons/lshnovel.png";
+ this.site = "https://lshnovel.com/";
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ this.filters = [
+ {
+ key: "order",
+ label: "Önerilen",
+ values: [
+ { label: "Varsayılan", value: "" },
+ { label: "A-Z", value: "title" },
+ { label: "Z-A", value: "titlereverse" },
+ { label: "Son Yüklemeler", value: "update" },
+ { label: "Son Eklenenler", value: "latest" },
+ { label: "Bestimiz", value: "popular" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Picker,
+ },
+ {
+ key: "status",
+ label: "Statü",
+ values: [
+ { label: "Tümü", value: "" },
+ { label: "Ongoing", value: "ongoing" },
+ { label: "Hiatus", value: "hiatus" },
+ { label: "Completed", value: "completed" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Picker,
+ },
+ {
+ key: "type",
+ label: "Tür",
+ values: [
+ { label: "Çeviri Novel", value: "ceviri-novel" },
+ { label: "Liz-Chan", value: "liz-chan" },
+ { label: "Manhwa", value: "manhwa" },
+ { label: "Orijinal Novel", value: "orijinal-novel" },
+ { label: "Web Novel", value: "web-novel" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Checkbox,
+ },
+ {
+ key: "genres",
+ label: "Kategori",
+ values: [
+ { label: "+18", value: "18" },
+ { label: "Action", value: "action" },
+ { label: "Adult", value: "adult" },
+ { label: "Aksiyon", value: "aksiyon" },
+ { label: "BL", value: "bl" },
+ { label: "Comedy", value: "comedy" },
+ { label: "Doğaüstü", value: "dogaustu" },
+ { label: "Dram", value: "dram" },
+ { label: "Drama", value: "drama" },
+ { label: "Ecchi", value: "ecchi" },
+ { label: "Fantastik", value: "fantastik" },
+ { label: "Fantasy", value: "fantasy" },
+ { label: "Gizem", value: "gizem" },
+ { label: "Harem", value: "harem" },
+ { label: "Historical", value: "historical" },
+ { label: "Josei", value: "josei" },
+ { label: "Macera", value: "macera" },
+ { label: "Manhwa", value: "manhwa" },
+ { label: "Martial Arts", value: "martial-arts" },
+ { label: "Mature", value: "mature" },
+ { label: "Novel", value: "novel" },
+ { label: "Okul", value: "okul" },
+ { label: "Psikolojik", value: "psikolojik" },
+ { label: "Psychological", value: "psychological" },
+ { label: "Reverse Harem", value: "reverse-harem" },
+ { label: "Romance", value: "romance" },
+ { label: "Romantik", value: "romantik" },
+ { label: "Shoujo", value: "shoujo" },
+ { label: "Slice Of Life", value: "slice-of-life" },
+ { label: "Smut", value: "smut" },
+ { label: "Supernatural", value: "supernatural" },
+ { label: "Tarihi", value: "tarihi" },
+ { label: "Tragedy", value: "tragedy" },
+ { label: "Yaoi", value: "yaoi" },
+ ],
+ inputType: filterInputs_1.FilterInputs.Checkbox,
+ },
+ ];
+ }
+ LSHNovel.prototype.popularNovels = function (pageNo, _a) {
+ var filters = _a.filters;
+ return __awaiter(this, void 0, void 0, function () {
+ var link, headers, body, loadedCheerio, novels;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ link = "".concat(this.site, "series/?page=").concat(pageNo);
+ if (filters) {
+ if (Array.isArray(filters.genres) && filters.genres.length) {
+ link += filters.genres.map(function (i) { return "&genre[]=".concat(i); }).join("");
+ }
+ if (Array.isArray(filters.type) && filters.type.length)
+ link += filters.type.map(function (i) { return "&lang[]=".concat(i); }).join("");
+ }
+ link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters.status : "");
+ link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order : "popular");
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { headers: headers }).then(function (result) {
+ return result.text();
+ })];
+ case 1:
+ body = _b.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novels = [];
+ loadedCheerio("article.bs").each(function () {
+ var novelName = loadedCheerio(this).find(".ntitle").text().trim();
+ var image = loadedCheerio(this).find("img");
+ var novelCover = image.attr("data-src") || image.attr("src");
+ var novelUrl = loadedCheerio(this).find("a").attr("href");
+ if (!novelUrl)
+ return;
+ var novel = {
+ name: novelName,
+ cover: novelCover,
+ url: novelUrl,
+ };
+ novels.push(novel);
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ ;
+ LSHNovel.prototype.parseNovelAndChapters = function (novelUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, headers, result, body, loadedCheerio, novel, chapter;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ url = novelUrl;
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novel = {
+ url: url,
+ chapters: [],
+ };
+ novel.name = loadedCheerio(".entry-title").text();
+ novel.cover =
+ loadedCheerio("img.wp-post-image").attr("data-src") ||
+ loadedCheerio("img.wp-post-image").attr("src");
+ loadedCheerio("div.spe > span").each(function () {
+ var detailName = loadedCheerio(this).find("b").text().trim();
+ var detail = loadedCheerio(this).find('b').remove().end().text().trim();
+ switch (detailName) {
+ case "Yazar:":
+ novel.author = detail;
+ break;
+ case "Seviye:":
+ novel.status = detail;
+ break;
+ }
+ });
+ novel.genres = loadedCheerio(".genxed")
+ .text()
+ .trim()
+ .replace(/\s/g, ",");
+ loadedCheerio('div[itemprop="description"] h3,p.a,strong').remove();
+ novel.summary = loadedCheerio('div[itemprop="description"]')
+ .find("br")
+ .replaceWith("\n")
+ .end()
+ .text();
+ chapter = [];
+ loadedCheerio(".eplister")
+ .find("li")
+ .each(function () {
+ var chapterName = loadedCheerio(this).find(".epl-num").text() +
+ " - " +
+ loadedCheerio(this).find(".epl-title").text();
+ var releaseDate = loadedCheerio(this)
+ .find(".epl-date")
+ .text()
+ .trim();
+ var chapterUrl = loadedCheerio(this).find("a").attr("href");
+ if (!chapterUrl)
+ return;
+ chapter.push({
+ name: chapterName,
+ releaseTime: releaseDate,
+ url: chapterUrl,
+ });
+ });
+ novel.chapters = chapter.reverse();
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ LSHNovel.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var headers, result, body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio(".epcontent").html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ LSHNovel.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, headers, result, body, loadedCheerio, novels;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ url = "".concat(this.site, "?s=").concat(searchTerm);
+ headers = new Headers();
+ if (this.cookieString) {
+ headers.append("cookie", this.cookieString);
+ }
+ return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novels = [];
+ loadedCheerio("article.bs").each(function () {
+ var novelName = loadedCheerio(this).find(".ntitle").text().trim();
+ var novelCover = loadedCheerio(this).find("img").attr("src");
+ var novelUrl = loadedCheerio(this).find("a").attr("href");
+ if (!novelUrl)
+ return;
+ novels.push({
+ name: novelName,
+ url: novelUrl,
+ cover: novelCover,
+ });
+ });
+ return [2 /*return*/, novels];
+ }
+ });
+ });
+ };
+ LSHNovel.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return LSHNovel;
+}());
+exports.default = new LSHNovel();
diff --git a/.js/plugins/vietnamese/LNHako.js b/.js/plugins/vietnamese/LNHako.js
new file mode 100644
index 0000000..2133d02
--- /dev/null
+++ b/.js/plugins/vietnamese/LNHako.js
@@ -0,0 +1,219 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var cheerio_1 = require("cheerio");
+var fetch_1 = require("@libs/fetch");
+var isAbsoluteUrl_1 = require("@libs/isAbsoluteUrl");
+var HakoPlugin = /** @class */ (function () {
+ function HakoPlugin() {
+ this.id = "ln.hako";
+ this.name = "Hako";
+ this.icon = "src/vi/hakolightnovel/icon.png";
+ this.site = "https://ln.hako.vn";
+ this.version = "1.0.0";
+ this.userAgent = "";
+ this.cookieString = "";
+ }
+ HakoPlugin.prototype.parseNovels = function (loadedCheerio) {
+ var _this = this;
+ var novels = [];
+ loadedCheerio(".row > .thumb-item-flow").each(function (index, ele) {
+ var url = loadedCheerio(ele)
+ .find("div.thumb_attr.series-title > a")
+ .attr("href");
+ if (url && !(0, isAbsoluteUrl_1.isUrlAbsolute)(url)) {
+ url = _this.site + url;
+ }
+ if (url) {
+ var name_1 = loadedCheerio(ele)
+ .find(".series-title")
+ .text()
+ .trim();
+ var cover = loadedCheerio(ele)
+ .find(".img-in-ratio")
+ .attr("data-bg");
+ if (cover && !(0, isAbsoluteUrl_1.isUrlAbsolute)(cover)) {
+ cover = _this.site + cover;
+ }
+ var novel = { name: name_1, url: url, cover: cover };
+ novels.push(novel);
+ }
+ });
+ return novels;
+ };
+ HakoPlugin.prototype.popularNovels = function (pageNo, options) {
+ return __awaiter(this, void 0, void 0, function () {
+ var link, result, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ link = this.site + "/danh-sach?truyendich=1&sapxep=topthang&page=" + pageNo;
+ return [4 /*yield*/, fetch(link)];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ return [2 /*return*/, this.parseNovels(loadedCheerio)];
+ }
+ });
+ });
+ };
+ HakoPlugin.prototype.parseNovelAndChapters = function (novelUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var novel, result, body, loadedCheerio, background, novelCover, chapters;
+ var _this = this;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ novel = {
+ url: novelUrl,
+ };
+ return [4 /*yield*/, fetch(novelUrl)];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ novel.name = loadedCheerio(".series-name").text();
+ background = loadedCheerio(".series-cover > .a6-ratio > div").attr("style") || "";
+ novelCover = background.substring(background.indexOf("http"), background.length - 2);
+ novel.cover = novelCover
+ ? (0, isAbsoluteUrl_1.isUrlAbsolute)(novelCover)
+ ? novelCover
+ : this.site + novelCover
+ : "";
+ novel.summary = loadedCheerio(".summary-content").text().trim();
+ novel.author = loadedCheerio("#mainpart > div:nth-child(2) > div > div:nth-child(1) > section > main > div.top-part > div > div.col-12.col-md-9 > div.series-information > div:nth-child(2) > span.info-value > a")
+ .text()
+ .trim();
+ novel.genres = loadedCheerio(".series-gernes")
+ .text()
+ .trim()
+ .replace(/ +/g, " ")
+ .split("\n")
+ .filter(function (e) { return e.trim(); })
+ .join(", ");
+ novel.status = loadedCheerio("#mainpart > div:nth-child(2) > div > div:nth-child(1) > section > main > div.top-part > div > div.col-12.col-md-9 > div.series-information > div:nth-child(4) > span.info-value > a")
+ .text()
+ .trim();
+ chapters = [];
+ loadedCheerio(".list-chapters li").each(function (index, ele) {
+ var chapterUrl = loadedCheerio(ele).find("a").attr("href");
+ if (chapterUrl && !(0, isAbsoluteUrl_1.isUrlAbsolute)(chapterUrl)) {
+ chapterUrl = _this.site + chapterUrl;
+ }
+ if (chapterUrl) {
+ var chapterName = loadedCheerio(ele)
+ .find(".chapter-name")
+ .text()
+ .trim();
+ var releaseTime = loadedCheerio(ele)
+ .find(".chapter-time")
+ .text();
+ var chapter = {
+ name: chapterName,
+ releaseTime: releaseTime,
+ url: chapterUrl,
+ };
+ chapters.push(chapter);
+ }
+ });
+ novel.chapters = chapters;
+ return [2 /*return*/, novel];
+ }
+ });
+ });
+ };
+ HakoPlugin.prototype.parseChapter = function (chapterUrl) {
+ return __awaiter(this, void 0, void 0, function () {
+ var result, body, loadedCheerio, chapterText;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, fetch(chapterUrl)];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ chapterText = loadedCheerio("#chapter-content").html() || "";
+ return [2 /*return*/, chapterText];
+ }
+ });
+ });
+ };
+ HakoPlugin.prototype.searchNovels = function (searchTerm, pageNo) {
+ return __awaiter(this, void 0, void 0, function () {
+ var url, result, body, loadedCheerio;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ url = this.site + "/tim-kiem?keywords=" + searchTerm;
+ return [4 /*yield*/, fetch(url)];
+ case 1:
+ result = _a.sent();
+ return [4 /*yield*/, result.text()];
+ case 2:
+ body = _a.sent();
+ loadedCheerio = (0, cheerio_1.load)(body);
+ return [2 /*return*/, this.parseNovels(loadedCheerio)];
+ }
+ });
+ });
+ };
+ HakoPlugin.prototype.fetchImage = function (url) {
+ return __awaiter(this, void 0, void 0, function () {
+ var headers;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ headers = {
+ Referer: "https://ln.hako.vn",
+ };
+ return [4 /*yield*/, (0, fetch_1.fetchFile)(url, { headers: headers })];
+ case 1: return [2 /*return*/, _a.sent()];
+ }
+ });
+ });
+ };
+ return HakoPlugin;
+}());
+exports.default = new HakoPlugin();
diff --git a/README.md b/README.md
index c070119..5a73cd8 100644
--- a/README.md
+++ b/README.md
@@ -11,16 +11,15 @@
qM
zjGg&oh}$YeS2VLdV_8M>==3$|M4ACH!yT$3ChrL~yLR{s%ePKFd7N|NKPUfAbea)1
z@APb$B;NiPubj1i+qwJLoariWWS9^kx7So|BGP+z@*lSUqv*nx@9KOXPjd0-Pv5Sg
z^S{6T8osks*TmxPnaY~qN;|&3`^%dLr(V0pv&s7YpwqhxiNEO)DL)>x{YC3+r}f$P
z2USI0yNDghg!cN|`zn7tX!O(HZht0NSxu}7WK4XI<1~ZNnZY@5h}iNE=5p>u+v %v^Fvdv&B;6JDDJ(cvwOns+q*aZd+ASZVY6G*S{{zOb@I`1&req0U-5lS;d!0V
zZ$s~IZr+@{S)7rW`PKo)19uMW-v6&2>#>iGjTSndD!sC QSF>`QO&IM$eLLhk<~K+Gtwigt>L*+7Oi<
zp1wZ)JJw&%Ejnj?&ba2Ab92wdoHIL@bK&ikmMiD2jJlBTX?dZYdtYB
{DfGz@;1P>^W!IJ^;BZIs=a|nHqb7kNm
zouTvwwU7HU3}y0`@}bWNxbHa4R|PphO`5-q&*00z1Bw7?CVv@^$wPoX0$AK7TsChB
zmjz%0&w{>_fa}Bt9)U&jOE_%KViFwALYV3KfH`aqdlpb@pq2m&fH}YvU=y&AL`^&gZ%aBkjyf*ZTtk1iVn`
zixh7XsvPSo(xDwHxxt1A0B~TSY=gfn8E!+dzsiCFs*E%|q>(~q3(8VK8Z%_jKn~6y
zeR&OlC`f>ZFQ@_7@Bug$hpDBe%`!Bd%(~QH%Q|