From 2830ae68ddb878187a4dc0c4832e9e759736e433 Mon Sep 17 00:00:00 2001 From: nyagami Date: Sun, 21 Jan 2024 21:21:35 +0700 Subject: [PATCH] Almost english sources (#709) * fix: LightNovelPub * fix: novelpub -> lightnovelworld * still broken, wuxiaworld keep html in js variables * fix: NovelsOnline * fix: novelhole -> novelhall * fix: novelfull * fix: mtl reader * refactor: mtlnovel * temporary fix: lightnovelupdates * still cant work * cant work * cant parseNovel and chapters: Wuxiaworld --- .dist/nyagami/plugins.json | 472 ++++++++++------- .dist/nyagami/plugins.min.json | 2 +- .js/plugins/english/NovelFullMe.js | 2 +- .js/plugins/english/NovelOnline.js | 161 ++++++ .js/plugins/english/lightnovelpub.js | 219 ++++++++ .js/plugins/english/lightnovelupdates.js | 200 +++++++ .js/plugins/english/lightnovelworld.js | 219 ++++++++ .js/plugins/english/mtlnovel.js | 208 ++++++++ .js/plugins/english/mtlreader.js | 177 +++++++ .js/plugins/english/novelfull.js | 227 ++++++++ .js/plugins/english/novelhall.js | 183 +++++++ .js/plugins/english/novelupdates.js | 467 +++++++++++++++++ .js/plugins/english/wuxiaworld.js | 192 +++++++ icons/src/en/lightnovelworld/icon.png | Bin 0 -> 5380 bytes icons/src/en/mtlnovel/icon.png | Bin 0 -> 3746 bytes .../src/en/{novelhold => novelhall}/icon.png | Bin icons/src/en/novelpub/icon.png | Bin 2827 -> 0 bytes icons/src/en/novelupdates/icon.png | Bin 0 -> 4124 bytes icons/src/en/wuxiaworld/icon.png | Bin 0 -> 1660 bytes plugins/english/NovelFullMe.ts | 2 +- plugins/english/NovelOnline.broken.ts | 111 ---- plugins/english/NovelOnline.ts | 115 ++++ plugins/english/lightnovelpub.broken.ts | 213 -------- plugins/english/lightnovelpub.ts | 173 ++++++ ...updates.broken.ts => lightnovelupdates.ts} | 76 ++- plugins/english/lightnovelworld.ts | 173 ++++++ plugins/english/mtlnovel.broken.ts | 180 ------- plugins/english/mtlnovel.ts | 155 ++++++ plugins/english/mtlreader.broken.ts | 133 ----- plugins/english/mtlreader.ts | 126 +++++ plugins/english/novelfull.broken.ts | 172 ------ plugins/english/novelfull.ts | 168 ++++++ plugins/english/novelhall.ts | 138 +++++ plugins/english/novelhold.broken.ts | 148 ------ plugins/english/novelpub.broken.ts | 189 ------- plugins/english/novelupdates.broken.ts | 492 ------------------ plugins/english/novelupdates.ts | 463 ++++++++++++++++ plugins/english/wuxiaworld.broken.ts | 146 ------ plugins/english/wuxiaworld.ts | 145 ++++++ 39 files changed, 4227 insertions(+), 2020 deletions(-) create mode 100644 .js/plugins/english/NovelOnline.js create mode 100644 .js/plugins/english/lightnovelpub.js create mode 100644 .js/plugins/english/lightnovelupdates.js create mode 100644 .js/plugins/english/lightnovelworld.js create mode 100644 .js/plugins/english/mtlnovel.js create mode 100644 .js/plugins/english/mtlreader.js create mode 100644 .js/plugins/english/novelfull.js create mode 100644 .js/plugins/english/novelhall.js create mode 100644 .js/plugins/english/novelupdates.js create mode 100644 .js/plugins/english/wuxiaworld.js create mode 100644 icons/src/en/lightnovelworld/icon.png create mode 100644 icons/src/en/mtlnovel/icon.png rename icons/src/en/{novelhold => novelhall}/icon.png (100%) delete mode 100644 icons/src/en/novelpub/icon.png create mode 100644 icons/src/en/novelupdates/icon.png create mode 100644 icons/src/en/wuxiaworld/icon.png delete mode 100644 plugins/english/NovelOnline.broken.ts create mode 100644 plugins/english/NovelOnline.ts delete mode 100644 plugins/english/lightnovelpub.broken.ts create mode 100644 plugins/english/lightnovelpub.ts rename plugins/english/{lightnovelupdates.broken.ts => lightnovelupdates.ts} (68%) create mode 100644 plugins/english/lightnovelworld.ts delete mode 100644 plugins/english/mtlnovel.broken.ts create mode 100644 plugins/english/mtlnovel.ts delete mode 100644 plugins/english/mtlreader.broken.ts create mode 100644 plugins/english/mtlreader.ts delete mode 100644 plugins/english/novelfull.broken.ts create mode 100644 plugins/english/novelfull.ts create mode 100644 plugins/english/novelhall.ts delete mode 100644 plugins/english/novelhold.broken.ts delete mode 100644 plugins/english/novelpub.broken.ts delete mode 100644 plugins/english/novelupdates.broken.ts create mode 100644 plugins/english/novelupdates.ts delete mode 100644 plugins/english/wuxiaworld.broken.ts create mode 100644 plugins/english/wuxiaworld.ts diff --git a/.dist/nyagami/plugins.json b/.dist/nyagami/plugins.json index 9b7e8e7..e6c8500 100644 --- a/.dist/nyagami/plugins.json +++ b/.dist/nyagami/plugins.json @@ -6,8 +6,8 @@ "site": "https://ar-mtl.club/", "lang": "العربية", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/ArMTL[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/armtl.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/ArMTL[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/armtl.png" }, { "id": "arnovel", @@ -15,8 +15,8 @@ "site": "https://arnovel.me/", "lang": "العربية", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/ArNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/arnovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/ArNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/arnovel.png" }, { "id": "hizomanga", @@ -24,8 +24,8 @@ "site": "https://hizomanga.com/", "lang": "العربية", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/HizoManga[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/hizomanga.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/HizoManga[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/hizomanga.png" }, { "id": "kol-novel", @@ -33,8 +33,8 @@ "site": "https://kolnovel.com/", "lang": "العربية", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/KolNovel[wpmangastream].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/kol-novel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/KolNovel[wpmangastream].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/wpmangastream/icons/kol-novel.png" }, { "id": "kolnovel", @@ -42,8 +42,8 @@ "site": "https://kolnovel.lol/", "lang": "العربية", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/kolnovel.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/kolnovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/kolnovel.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/wpmangastream/icons/kolnovel.png" }, { "id": "novel4up", @@ -51,8 +51,8 @@ "site": "https://novel4up.com/", "lang": "العربية", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/Novel4Up[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/novel4up.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/Novel4Up[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/novel4up.png" }, { "id": "riwyat", @@ -60,8 +60,8 @@ "site": "https://riwyat.com/", "lang": "العربية", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/Riwyat[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/riwyat.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/Riwyat[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/riwyat.png" }, { "id": "teamxnovel", @@ -69,8 +69,8 @@ "site": "https://teamxnovel.com/", "lang": "العربية", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/TeamXNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/teamxnovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/TeamXNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/teamxnovel.png" } ], "中文, 汉语, 漢語": [ @@ -80,8 +80,8 @@ "site": "https://w.linovelib.com", "lang": "中文, 汉语, 漢語", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/chinese/linovelib.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/cn/linovelib/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/chinese/linovelib.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/cn/linovelib/icon.png" } ], "English": [ @@ -91,8 +91,8 @@ "site": "https://1stkissnovel.org/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/FirstKissNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/firstkissnovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/FirstKissNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/firstkissnovel.png" }, { "id": "anf.net", @@ -100,8 +100,8 @@ "site": "https://allnovelfull.net", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/allnovelfull.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/allnovelfull/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/allnovelfull.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/allnovelfull/icon.png" }, { "id": "BLN.com", @@ -109,8 +109,8 @@ "site": "https://bestlightnovel.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/bestlightnovel.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/bestlightnovel/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/bestlightnovel.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/bestlightnovel/icon.png" }, { "id": "boxnovel", @@ -118,8 +118,8 @@ "site": "https://boxnovel.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/BoxNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/boxnovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/BoxNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/boxnovel.png" }, { "id": "clicknovel", @@ -127,8 +127,8 @@ "site": "https://clicknovel.net/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/ClickNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/clicknovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/ClickNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/clicknovel.png" }, { "id": "comrademao", @@ -136,8 +136,8 @@ "site": "https://comrademao.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/comrademao.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/comrademao/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/comrademao.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/comrademao/icon.png" }, { "id": "cratenovel", @@ -145,8 +145,8 @@ "site": "https://cratenovel.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/CrateNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/cratenovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/CrateNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/cratenovel.png" }, { "id": "daonovel", @@ -154,8 +154,8 @@ "site": "https://daonovel.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/DaoNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/daonovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/DaoNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/daonovel.png" }, { "id": "DDL.com", @@ -163,8 +163,8 @@ "site": "https://www.divinedaolibrary.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/divinedaolibrary.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/divinedaolibrary/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/divinedaolibrary.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/divinedaolibrary/icon.png" }, { "id": "earlynovel", @@ -172,8 +172,8 @@ "site": "https://earlynovel.net/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/earlynovel.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/latestnovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/earlynovel.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/latestnovel.png" }, { "id": "fanTLS", @@ -181,8 +181,8 @@ "site": "https://fanstranslations.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/FansTranslations[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/fanstranslations.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/FansTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/fanstranslations.png" }, { "id": "foxaholic", @@ -190,8 +190,8 @@ "site": "https://www.foxaholic.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/foxaholic.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/foxaholic/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/foxaholic.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/foxaholic/icon.png" }, { "id": "freenovel.me", @@ -199,8 +199,8 @@ "site": "https://freenovel.me/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/FreeNovelMe[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/freenovelme.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/FreeNovelMe[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/freenovelme.png" }, { "id": "FWN.com", @@ -208,8 +208,8 @@ "site": "https://freewebnovel.com", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/freewebnovel.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/freewebnovel/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/freewebnovel.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/freewebnovel/icon.png" }, { "id": "guavaread", @@ -217,8 +217,35 @@ "site": "https://guavaread.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Guavaread[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/guavaread.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/Guavaread[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/guavaread.png" + }, + { + "id": "lightnovelpub", + "name": "LightNovelPub", + "site": "https://www.lightnovelpub.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/lightnovelpub.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/lightnovelpub/icon.png" + }, + { + "id": "LightNovelUpdates", + "name": "Light Novel Updates", + "site": "https://www.lightnovelupdates.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/lightnovelupdates.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/lightnovelupdates/icon.png" + }, + { + "id": "lightnovelworld", + "name": "LightNovelWorld", + "site": "https://www.webnovelworld.org/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/lightnovelworld.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/lightnovelworld/icon.png" }, { "id": "lnheaven", @@ -226,8 +253,8 @@ "site": "https://lightnovelheaven.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/LightNovelHeaven[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/lightnovelheaven.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/LightNovelHeaven[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/lightnovelheaven.png" }, { "id": "Ltnovel.com", @@ -235,8 +262,8 @@ "site": "https://www.ltnovel.com", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Ltnovel[readwn].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/readwn/icons/ltnovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/Ltnovel[readwn].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/readwn/icons/ltnovel.png" }, { "id": "lunarletters", @@ -244,8 +271,8 @@ "site": "https://www.lunarletters.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/LunarLetters[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/lunarletters.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/LunarLetters[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/lunarletters.png" }, { "id": "mostnovel", @@ -253,8 +280,8 @@ "site": "https://mostnovel.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/MostNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/mostnovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/MostNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/mostnovel.png" }, { "id": "mtl-novel", @@ -262,8 +289,17 @@ "site": "https://mtl-novel.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/MTLNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/mtl-novel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/MTLNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/mtl-novel.png" + }, + { + "id": "mtlnovel", + "name": "MTL Novel", + "site": "https://www.mtlnovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/mtlnovel.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/mtlnovel/icon.png" }, { "id": "mtlnovel.club", @@ -271,8 +307,17 @@ "site": "https://mtlnovel.club/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/MTLNovelClub[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/mtlnovel.club.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/MTLNovelClub[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/mtlnovel.club.png" + }, + { + "id": "mtlreader", + "name": "MTL Reader", + "site": "https://mtlreader.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/mtlreader.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/mtlreader/icon.png" }, { "id": "mysticalmerries", @@ -280,8 +325,8 @@ "site": "https://mysticalmerries.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/MysticalSeries[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/mysticalseries.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/MysticalSeries[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/mysticalseries.png" }, { "id": "neosekaiTLS", @@ -289,17 +334,17 @@ "site": "https://www.neosekaitranslations.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NeoSekaiTranslations[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/neosekaitranslations.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NeoSekaiTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/neosekaitranslations.png" }, { "id": "NF.me", - "name": "NovelFull", + "name": "NovelFullMe", "site": "https://novelfull.me/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NovelFullMe.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/novelfullme/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NovelFullMe.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/novelfullme/icon.png" }, { "id": "nitromanga", @@ -307,8 +352,17 @@ "site": "https://nitromanga.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/nitromanga.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/nitromanga/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/nitromanga.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/nitromanga/icon.png" + }, + { + "id": "NO.net", + "name": "novelsOnline", + "site": "https://novelsonline.net", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NovelOnline.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/coverNotAvailable.jpg" }, { "id": "noblemtl", @@ -316,8 +370,8 @@ "site": "https://noblemtl.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/nobleMTL.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/noblemtl/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/nobleMTL.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/noblemtl/icon.png" }, { "id": "nocturneTLS", @@ -325,8 +379,8 @@ "site": "https://nocturnetls.net/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NocturneTranslations[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/nocturnetranslations.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NocturneTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/nocturnetranslations.png" }, { "id": "noobchanTL", @@ -334,8 +388,8 @@ "site": "https://noobchan.xyz/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NoobchanTranslation[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/noobchantranslation.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NoobchanTranslation[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/noobchantranslation.png" }, { "id": "novelbin", @@ -343,8 +397,26 @@ "site": "https://novelmax.net/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/novelbin.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/novelbin/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/novelbin.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/novelbin/icon.png" + }, + { + "id": "novelfull", + "name": "NovelFull", + "site": "https://novelfull.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/novelfull.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/novelfull/icon.png" + }, + { + "id": "novelhold", + "name": "Novel Hall", + "site": "https://novelhall.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/novelhall.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/novelhall/icon.png" }, { "id": "novelmultiverse", @@ -352,8 +424,8 @@ "site": "https://www.novelmultiverse.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NovelMultiverse[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/novelmultiverse.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NovelMultiverse[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/novelmultiverse.png" }, { "id": "novelr18", @@ -361,8 +433,8 @@ "site": "https://novelr18.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NovelR18[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/novelr18.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NovelR18[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/novelr18.png" }, { "id": "novelroom", @@ -370,8 +442,8 @@ "site": "https://novelroom.net/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Novelroomnet[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/novelroom.net.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/Novelroomnet[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/novelroom.net.png" }, { "id": "novelstic", @@ -379,8 +451,8 @@ "site": "https://novelstic.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Novelstic[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/novelstic.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/Novelstic[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/novelstic.png" }, { "id": "novelTL", @@ -388,8 +460,17 @@ "site": "https://noveltranslate.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NovelTranslate[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/noveltranslate.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NovelTranslate[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/noveltranslate.png" + }, + { + "id": "novelupdates", + "name": "Novel Updates", + "site": "https://www.novelupdates.com/", + "lang": "English", + "version": "0.5.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/novelupdates.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/novelupdates/icon.png" }, { "id": "onlymtl", @@ -397,8 +478,8 @@ "site": "https://www.onlymtl.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/OnlyMTL[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/onlymtl.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/OnlyMTL[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/onlymtl.png" }, { "id": "pandamtl", @@ -406,8 +487,8 @@ "site": "https://pandamtl.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/pandaMTL.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/wordpress/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/pandaMTL.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/wordpress/icon.png" }, { "id": "readwebnovels", @@ -415,8 +496,8 @@ "site": "https://readwebnovels.net/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/ReadWebNovels[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/readwebnovels.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/ReadWebNovels[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/readwebnovels.png" }, { "id": "sleeptTLS", @@ -424,8 +505,8 @@ "site": "https://sleepytranslations.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/SleepyTranslations[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/sleepytranslations.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/SleepyTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/sleepytranslations.png" }, { "id": "sonicmtl", @@ -433,8 +514,8 @@ "site": "https://www.sonicmtl.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/SonicMTL[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/sonicmtl.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/SonicMTL[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/sonicmtl.png" }, { "id": "sugarbbscan", @@ -442,8 +523,8 @@ "site": "https://sugarbbscan.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/SugarBabies[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/sugarbabies.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/SugarBabies[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/sugarbabies.png" }, { "id": "sweetEscapeTL", @@ -451,8 +532,8 @@ "site": "https://sweetescapetranslations.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/SweetEscapeTranslations[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/sweetescapetranslations.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/SweetEscapeTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/sweetescapetranslations.png" }, { "id": "webnovelover", @@ -460,8 +541,8 @@ "site": "https://www.webnovelover.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/WebNovelLover[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/webnovellover.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/WebNovelLover[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/webnovellover.png" }, { "id": "wuxiacity", @@ -469,8 +550,8 @@ "site": "https://www.wuxiacity.com", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Wuxiacity[readwn].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/readwn/icons/wuxiacity.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/Wuxiacity[readwn].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/readwn/icons/wuxiacity.png" }, { "id": "wuxiap", @@ -478,8 +559,17 @@ "site": "https://www.wuxiap.com", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Wuxiap[readwn].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/readwn/icons/wuxiap.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/Wuxiap[readwn].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/readwn/icons/wuxiap.png" + }, + { + "id": "wuxiaworld", + "name": "Wuxia World", + "site": "https://www.wuxiaworld.com/", + "lang": "English", + "version": "0.5.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/wuxiaworld.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/wuxiaworld/icon.png" }, { "id": "wuxiaworld.site", @@ -487,8 +577,8 @@ "site": "https://wuxiaworld.site/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/WuxiaWorldSite[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/wuxiaworld.site.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/WuxiaWorldSite[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/wuxiaworld.site.png" }, { "id": "zetroTL", @@ -496,8 +586,8 @@ "site": "https://zetrotranslation.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/ZetroTranslation[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/zetrotranslation.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/ZetroTranslation[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/zetrotranslation.png" }, { "id": "zinnovel", @@ -505,8 +595,8 @@ "site": "https://zinnovel.com/", "lang": "English", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/ZinnNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/zinnnovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/ZinnNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/zinnnovel.png" } ], "français, française": [ @@ -516,8 +606,8 @@ "site": "https://chireads.com", "lang": "français, française", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/french/chireads.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/fr/chireads/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/french/chireads.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/fr/chireads/icon.png" }, { "id": "lightnovelfr", @@ -525,8 +615,8 @@ "site": "https://lightnovelfr.com/", "lang": "français, française", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/french/LighNovelFR[wpmangastream].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/lightnovelfr.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/french/LighNovelFR[wpmangastream].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/wpmangastream/icons/lightnovelfr.png" }, { "id": "NDG.com", @@ -534,8 +624,8 @@ "site": "https://noveldeglace.com/", "lang": "français, française", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/french/noveldeglace.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/fr/noveldeglace/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/french/noveldeglace.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/fr/noveldeglace/icon.png" } ], "Bahasa Indonesia": [ @@ -545,8 +635,8 @@ "site": "https://indowebnovel.id/id/", "lang": "Bahasa Indonesia", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/indonesian/indowebnovel.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/id/indowebnovel/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/indonesian/indowebnovel.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/id/indowebnovel/icon.png" }, { "id": "meionovel", @@ -554,8 +644,8 @@ "site": "https://meionovel.id/", "lang": "Bahasa Indonesia", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/indonesian/MeioNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/meionovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/indonesian/MeioNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/meionovel.png" }, { "id": "morenovel", @@ -563,8 +653,8 @@ "site": "https://morenovel.net/", "lang": "Bahasa Indonesia", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/indonesian/MoreNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/morenovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/indonesian/MoreNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/morenovel.png" }, { "id": "novelringan.com", @@ -572,8 +662,8 @@ "site": "https://novelringan.com/", "lang": "Bahasa Indonesia", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/indonesian/novelringan.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/id/novelringan/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/indonesian/novelringan.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/id/novelringan/icon.png" }, { "id": "sakura.id", @@ -581,8 +671,8 @@ "site": "https://sakuranovel.id/", "lang": "Bahasa Indonesia", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/indonesian/sakuranovel.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/id/sakuranovel/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/indonesian/sakuranovel.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/id/sakuranovel/icon.png" }, { "id": "wbnovel", @@ -590,8 +680,8 @@ "site": "https://wbnovel.com/", "lang": "Bahasa Indonesia", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/indonesian/WBNovel[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/wbnovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/indonesian/WBNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/wbnovel.png" } ], "日本語": [ @@ -601,8 +691,8 @@ "site": "https://yomou.syosetu.com/", "lang": "日本語", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/japanese/Syosetu.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/jp/syosetu/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/japanese/Syosetu.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/jp/syosetu/icon.png" } ], "한국어, 조선말": [ @@ -612,8 +702,8 @@ "site": "https://agit501.xyz/", "lang": "한국어, 조선말", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/korean/Agitoon.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/kr/agitoon/agit.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/korean/Agitoon.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/kr/agitoon/agit.png" } ], "Português": [ @@ -623,8 +713,8 @@ "site": "https://lightnovelbrasil.com/", "lang": "Português", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/portuguese/lightnovelbrasil.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/lightnovelbrasil.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/portuguese/lightnovelbrasil.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/wpmangastream/icons/lightnovelbrasil.png" } ], "русский язык": [ @@ -634,8 +724,8 @@ "site": "https://author.today", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/authortoday.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/authortoday/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/authortoday.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/authortoday/icon.png" }, { "id": "bookhamster", @@ -643,8 +733,8 @@ "site": "https://bookhamster.ru", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/Bookhamster[ifreedom].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/ifreedom/icons/bookhamster.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/Bookhamster[ifreedom].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/ifreedom/icons/bookhamster.png" }, { "id": "bookriver", @@ -652,8 +742,8 @@ "site": "https://bookriver.ru", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/bookriver.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/bookriver/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/bookriver.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/bookriver/icon.png" }, { "id": "erolate", @@ -661,8 +751,8 @@ "site": "https://erolate.com", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/Erolate[rulate].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/rulate/icons/erolate.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/Erolate[rulate].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/rulate/icons/erolate.png" }, { "id": "ficbook", @@ -670,8 +760,8 @@ "site": "https://ficbook.net", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ficbook.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ficbook/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/ficbook.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/ficbook/icon.png" }, { "id": "freedlit.space", @@ -679,8 +769,8 @@ "site": "https://freedlit.space", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/LitSpace.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/freedlit/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/LitSpace.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/freedlit/icon.png" }, { "id": "ifreedom", @@ -688,8 +778,8 @@ "site": "https://ifreedom.su", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/СвободныйМирРанобэ[ifreedom].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/ifreedom/icons/ifreedom.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/СвободныйМирРанобэ[ifreedom].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/ifreedom/icons/ifreedom.png" }, { "id": "jaomix.ru", @@ -697,8 +787,8 @@ "site": "https://jaomix.ru", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/jaomix.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/jaomix/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/jaomix.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/jaomix/icon.png" }, { "id": "ReN", @@ -706,8 +796,8 @@ "site": "https://renovels.org", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/renovels.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/renovels/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/renovels.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/renovels/icon.png" }, { "id": "RLIB", @@ -715,8 +805,8 @@ "site": "https://ranobelib.me", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ranobelib.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ranobelib/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/ranobelib.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/ranobelib/icon.png" }, { "id": "RNBH.org", @@ -724,8 +814,8 @@ "site": "https://ranobehub.org/", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ranobehub.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ranobehub/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/ranobehub.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/ranobehub/icon.png" }, { "id": "RNRF", @@ -733,8 +823,8 @@ "site": "https://ранобэ.рф", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ranoberf.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ranoberf/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/ranoberf.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/ranoberf/icon.png" }, { "id": "TL", @@ -742,8 +832,8 @@ "site": "https://novel.tl", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/novelTL.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/noveltl/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/novelTL.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/noveltl/icon.png" }, { "id": "tl.rulate", @@ -751,8 +841,8 @@ "site": "https://tl.rulate.ru", "lang": "русский язык", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/Rulate[rulate].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/rulate/icons/rulate.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/Rulate[rulate].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/rulate/icons/rulate.png" } ], "español, castellano": [ @@ -762,8 +852,8 @@ "site": "http://www.reinowuxia.com/", "lang": "español, castellano", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/novelawuxia.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/novelawuxia/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/novelawuxia.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/novelawuxia/icon.png" }, { "id": "HasuTL", @@ -771,8 +861,8 @@ "site": "https://hasutl.wordpress.com/", "lang": "español, castellano", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/hasutl.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/hasutl/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/hasutl.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/hasutl/icon.png" }, { "id": "ligera.com", @@ -780,8 +870,8 @@ "site": "https://novelasligera.com/", "lang": "español, castellano", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/novelasligera.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/novelasligera/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/novelasligera.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/novelasligera/icon.png" }, { "id": "oasisTL.wp", @@ -789,8 +879,8 @@ "site": "https://oasistranslations.wordpress.com/", "lang": "español, castellano", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/oasistranslations.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/oasistranslations/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/oasistranslations.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/oasistranslations/icon.png" }, { "id": "skynovels.net", @@ -798,8 +888,8 @@ "site": "https://www.skynovels.net/", "lang": "español, castellano", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/skynovels.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/skynovels/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/skynovels.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/skynovels/icon.png" }, { "id": "tunovelaligera", @@ -807,8 +897,8 @@ "site": "https://tunovelaligera.com/", "lang": "español, castellano", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/tunovelaligera.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/tunovelaligera/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/tunovelaligera.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/tunovelaligera/icon.png" }, { "id": "yuukitls.com", @@ -816,8 +906,8 @@ "site": "https://yuukitls.com/", "lang": "español, castellano", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/yukitls.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/yuukitls/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/yukitls.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/yuukitls/icon.png" } ], "Türkçe": [ @@ -827,8 +917,8 @@ "site": "https://www.epiknovel.com/", "lang": "Türkçe", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/turkish/epiknovel.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/tr/epiknovel/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/turkish/epiknovel.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/tr/epiknovel/icon.png" }, { "id": "lshnovel", @@ -836,8 +926,8 @@ "site": "https://lshnovel.com/", "lang": "Türkçe", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/turkish/lshnovel.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/lshnovel.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/turkish/lshnovel.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/wpmangastream/icons/lshnovel.png" }, { "id": "turkcelightnovels", @@ -845,8 +935,8 @@ "site": "https://turkcelightnovels.com/", "lang": "Türkçe", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/turkish/TurkceLightNovels[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/turkcelightnovels.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/turkish/TurkceLightNovels[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/turkcelightnovels.png" }, { "id": "webnoveloku", @@ -854,8 +944,8 @@ "site": "https://www.webnoveloku.com/", "lang": "Türkçe", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/turkish/WebNovelOku[madara].js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/webnoveloku.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/turkish/WebNovelOku[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/webnoveloku.png" } ], "Україна": [ @@ -865,8 +955,8 @@ "site": "https://smakolykytl.site/", "lang": "Україна", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/ukraine/smakolykytl.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ua/smakolykytl/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/ukraine/smakolykytl.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ua/smakolykytl/icon.png" } ], "Tiếng Việt": [ @@ -876,8 +966,8 @@ "site": "https://ln.hako.vn", "lang": "Tiếng Việt", "version": "1.0.0", - "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/vietnamese/LNHako.js", - "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/vi/hakolightnovel/icon.png" + "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/vietnamese/LNHako.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/vi/hakolightnovel/icon.png" } ] } \ No newline at end of file diff --git a/.dist/nyagami/plugins.min.json b/.dist/nyagami/plugins.min.json index 72ef5db..7b0379e 100644 --- a/.dist/nyagami/plugins.min.json +++ b/.dist/nyagami/plugins.min.json @@ -1 +1 @@ -{"العربية":[{"id":"ar-mtl","name":"ArMTL[madara]","site":"https://ar-mtl.club/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/ArMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/armtl.png"},{"id":"arnovel","name":"ArNovel[madara]","site":"https://arnovel.me/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/ArNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/arnovel.png"},{"id":"hizomanga","name":"HizoManga[madara]","site":"https://hizomanga.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/HizoManga[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/hizomanga.png"},{"id":"kol-novel","name":"Kol Novel[wpmangastream]","site":"https://kolnovel.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/KolNovel[wpmangastream].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/kol-novel.png"},{"id":"kolnovel","name":"KolNovel","site":"https://kolnovel.lol/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/kolnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/kolnovel.png"},{"id":"novel4up","name":"Novel4Up[madara]","site":"https://novel4up.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/Novel4Up[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/novel4up.png"},{"id":"riwyat","name":"Riwyat[madara]","site":"https://riwyat.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/Riwyat[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/riwyat.png"},{"id":"teamxnovel","name":"TeamXNovel[madara]","site":"https://teamxnovel.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/TeamXNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/teamxnovel.png"}],"中文, 汉语, 漢語":[{"id":"linovelib","name":"Linovelib","site":"https://w.linovelib.com","lang":"中文, 汉语, 漢語","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/chinese/linovelib.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/cn/linovelib/icon.png"}],"English":[{"id":"1stkissnovel","name":"FirstKissNovel[madara]","site":"https://1stkissnovel.org/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/FirstKissNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/firstkissnovel.png"},{"id":"anf.net","name":"AllNovelFull","site":"https://allnovelfull.net","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/allnovelfull.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/allnovelfull/icon.png"},{"id":"BLN.com","name":"BestLightNovel","site":"https://bestlightnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/bestlightnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/bestlightnovel/icon.png"},{"id":"boxnovel","name":"BoxNovel[madara]","site":"https://boxnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/BoxNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/boxnovel.png"},{"id":"clicknovel","name":"ClickNovel[madara]","site":"https://clicknovel.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/ClickNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/clicknovel.png"},{"id":"comrademao","name":"Comrade Mao","site":"https://comrademao.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/comrademao.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/comrademao/icon.png"},{"id":"cratenovel","name":"CrateNovel[madara]","site":"https://cratenovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/CrateNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/cratenovel.png"},{"id":"daonovel","name":"DaoNovel[madara]","site":"https://daonovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/DaoNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/daonovel.png"},{"id":"DDL.com","name":"Divine Dao Library","site":"https://www.divinedaolibrary.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/divinedaolibrary.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/divinedaolibrary/icon.png"},{"id":"earlynovel","name":"Early Novel","site":"https://earlynovel.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/earlynovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/latestnovel.png"},{"id":"fanTLS","name":"Fans Translations[madara]","site":"https://fanstranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/FansTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/fanstranslations.png"},{"id":"foxaholic","name":"Foxaholic","site":"https://www.foxaholic.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/foxaholic.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/foxaholic/icon.png"},{"id":"freenovel.me","name":"FreeNovelMe[madara]","site":"https://freenovel.me/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/FreeNovelMe[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/freenovelme.png"},{"id":"FWN.com","name":"Web NOVEL","site":"https://freewebnovel.com","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/freewebnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/freewebnovel/icon.png"},{"id":"guavaread","name":"Guavaread[madara]","site":"https://guavaread.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Guavaread[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/guavaread.png"},{"id":"lnheaven","name":"LightNovelHeaven[madara]","site":"https://lightnovelheaven.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/LightNovelHeaven[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/lightnovelheaven.png"},{"id":"Ltnovel.com","name":"Ltnovel[readwn]","site":"https://www.ltnovel.com","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Ltnovel[readwn].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/readwn/icons/ltnovel.png"},{"id":"lunarletters","name":"LunarLetters[madara]","site":"https://www.lunarletters.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/LunarLetters[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/lunarletters.png"},{"id":"mostnovel","name":"MostNovel[madara]","site":"https://mostnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/MostNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/mostnovel.png"},{"id":"mtl-novel","name":"MTL-Novel[madara]","site":"https://mtl-novel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/MTLNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/mtl-novel.png"},{"id":"mtlnovel.club","name":"MTLNovel.Club[madara]","site":"https://mtlnovel.club/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/MTLNovelClub[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/mtlnovel.club.png"},{"id":"mysticalmerries","name":"MysticalSeries[madara]","site":"https://mysticalmerries.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/MysticalSeries[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/mysticalseries.png"},{"id":"neosekaiTLS","name":"NeoSekai Translations[madara]","site":"https://www.neosekaitranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NeoSekaiTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/neosekaitranslations.png"},{"id":"NF.me","name":"NovelFull","site":"https://novelfull.me/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NovelFullMe.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/novelfullme/icon.png"},{"id":"nitromanga","name":"Nitro Manga","site":"https://nitromanga.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/nitromanga.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/nitromanga/icon.png"},{"id":"noblemtl","name":"NobleMTL","site":"https://noblemtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/nobleMTL.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/noblemtl/icon.png"},{"id":"nocturneTLS","name":"Nocturne Translations[madara]","site":"https://nocturnetls.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NocturneTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/nocturnetranslations.png"},{"id":"noobchanTL","name":"Noobchan Translation[madara]","site":"https://noobchan.xyz/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NoobchanTranslation[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/noobchantranslation.png"},{"id":"novelbin","name":"Novel Bin","site":"https://novelmax.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/novelbin.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/novelbin/icon.png"},{"id":"novelmultiverse","name":"NovelMultiverse[madara]","site":"https://www.novelmultiverse.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NovelMultiverse[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/novelmultiverse.png"},{"id":"novelr18","name":"NovelR18[madara]","site":"https://novelr18.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NovelR18[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/novelr18.png"},{"id":"novelroom","name":"Novelroom.net[madara]","site":"https://novelroom.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Novelroomnet[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/novelroom.net.png"},{"id":"novelstic","name":"Novelstic[madara]","site":"https://novelstic.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Novelstic[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/novelstic.png"},{"id":"novelTL","name":"NovelTranslate[madara]","site":"https://noveltranslate.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/NovelTranslate[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/noveltranslate.png"},{"id":"onlymtl","name":"OnlyMTL[madara]","site":"https://www.onlymtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/OnlyMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/onlymtl.png"},{"id":"pandamtl","name":"PandaMTL","site":"https://pandamtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/pandaMTL.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/wordpress/icon.png"},{"id":"readwebnovels","name":"ReadWebNovels[madara]","site":"https://readwebnovels.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/ReadWebNovels[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/readwebnovels.png"},{"id":"sleeptTLS","name":"SleepyTranslations[madara]","site":"https://sleepytranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/SleepyTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/sleepytranslations.png"},{"id":"sonicmtl","name":"SonicMTL[madara]","site":"https://www.sonicmtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/SonicMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/sonicmtl.png"},{"id":"sugarbbscan","name":"Sugar Babies[madara]","site":"https://sugarbbscan.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/SugarBabies[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/sugarbabies.png"},{"id":"sweetEscapeTL","name":"Sweet Escape Translations[madara]","site":"https://sweetescapetranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/SweetEscapeTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/sweetescapetranslations.png"},{"id":"webnovelover","name":"WebNovelLover[madara]","site":"https://www.webnovelover.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/WebNovelLover[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/webnovellover.png"},{"id":"wuxiacity","name":"Wuxiacity[readwn]","site":"https://www.wuxiacity.com","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Wuxiacity[readwn].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/readwn/icons/wuxiacity.png"},{"id":"wuxiap","name":"Wuxiap[readwn]","site":"https://www.wuxiap.com","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Wuxiap[readwn].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/readwn/icons/wuxiap.png"},{"id":"wuxiaworld.site","name":"WuxiaWorld.Site[madara]","site":"https://wuxiaworld.site/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/WuxiaWorldSite[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/wuxiaworld.site.png"},{"id":"zetroTL","name":"Zetro Translation[madara]","site":"https://zetrotranslation.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/ZetroTranslation[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/zetrotranslation.png"},{"id":"zinnovel","name":"ZinnNovel[madara]","site":"https://zinnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/ZinnNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/zinnnovel.png"}],"français, française":[{"id":"chireads.com","name":"Chireads","site":"https://chireads.com","lang":"français, française","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/french/chireads.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/fr/chireads/icon.png"},{"id":"lightnovelfr","name":"Ligh Novel FR[wpmangastream]","site":"https://lightnovelfr.com/","lang":"français, française","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/french/LighNovelFR[wpmangastream].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/lightnovelfr.png"},{"id":"NDG.com","name":"NovelDeGlace","site":"https://noveldeglace.com/","lang":"français, française","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/french/noveldeglace.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/fr/noveldeglace/icon.png"}],"Bahasa Indonesia":[{"id":"IDWN.id","name":"IndoWebNovel","site":"https://indowebnovel.id/id/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/indonesian/indowebnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/id/indowebnovel/icon.png"},{"id":"meionovel","name":"MeioNovel[madara]","site":"https://meionovel.id/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/indonesian/MeioNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/meionovel.png"},{"id":"morenovel","name":"MoreNovel[madara]","site":"https://morenovel.net/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/indonesian/MoreNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/morenovel.png"},{"id":"novelringan.com","name":"NovelRingan","site":"https://novelringan.com/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/indonesian/novelringan.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/id/novelringan/icon.png"},{"id":"sakura.id","name":"SakuraNovel","site":"https://sakuranovel.id/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/indonesian/sakuranovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/id/sakuranovel/icon.png"},{"id":"wbnovel","name":"WBNovel[madara]","site":"https://wbnovel.com/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/indonesian/WBNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/wbnovel.png"}],"日本語":[{"id":"yomou.syosetu","name":"Syosetu","site":"https://yomou.syosetu.com/","lang":"日本語","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/japanese/Syosetu.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/jp/syosetu/icon.png"}],"한국어, 조선말":[{"id":"agit.xyz","name":"Agitoon","site":"https://agit501.xyz/","lang":"한국어, 조선말","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/korean/Agitoon.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/kr/agitoon/agit.png"}],"Português":[{"id":"lightnovelbrasil","name":"Light Novel Brasil","site":"https://lightnovelbrasil.com/","lang":"Português","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/portuguese/lightnovelbrasil.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/lightnovelbrasil.png"}],"русский язык":[{"id":"AT","name":"Автор Тудей","site":"https://author.today","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/authortoday.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/authortoday/icon.png"},{"id":"bookhamster","name":"Bookhamster[ifreedom]","site":"https://bookhamster.ru","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/Bookhamster[ifreedom].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/ifreedom/icons/bookhamster.png"},{"id":"bookriver","name":"Bookriver","site":"https://bookriver.ru","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/bookriver.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/bookriver/icon.png"},{"id":"erolate","name":"Erolate[rulate]","site":"https://erolate.com","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/Erolate[rulate].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/rulate/icons/erolate.png"},{"id":"ficbook","name":"ficbook","site":"https://ficbook.net","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ficbook.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ficbook/icon.png"},{"id":"freedlit.space","name":"LitSpace","site":"https://freedlit.space","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/LitSpace.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/freedlit/icon.png"},{"id":"ifreedom","name":"Свободный Мир Ранобэ[ifreedom]","site":"https://ifreedom.su","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/СвободныйМирРанобэ[ifreedom].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/ifreedom/icons/ifreedom.png"},{"id":"jaomix.ru","name":"Jaomix","site":"https://jaomix.ru","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/jaomix.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/jaomix/icon.png"},{"id":"ReN","name":"Renovels","site":"https://renovels.org","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/renovels.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/renovels/icon.png"},{"id":"RLIB","name":"RanobeLib","site":"https://ranobelib.me","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ranobelib.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ranobelib/icon.png"},{"id":"RNBH.org","name":"RanobeHub","site":"https://ranobehub.org/","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ranobehub.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ranobehub/icon.png"},{"id":"RNRF","name":"РанобэРФ","site":"https://ранобэ.рф","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ranoberf.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ranoberf/icon.png"},{"id":"TL","name":"NovelTL","site":"https://novel.tl","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/novelTL.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/noveltl/icon.png"},{"id":"tl.rulate","name":"Rulate[rulate]","site":"https://tl.rulate.ru","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/Rulate[rulate].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/rulate/icons/rulate.png"}],"español, castellano":[{"id":"awuxia.com","name":"ReinoWuxia","site":"http://www.reinowuxia.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/novelawuxia.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/novelawuxia/icon.png"},{"id":"HasuTL","name":"Hasu Translations","site":"https://hasutl.wordpress.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/hasutl.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/hasutl/icon.png"},{"id":"ligera.com","name":"Novelas Ligera","site":"https://novelasligera.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/novelasligera.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/novelasligera/icon.png"},{"id":"oasisTL.wp","name":"Oasis Translations","site":"https://oasistranslations.wordpress.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/oasistranslations.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/oasistranslations/icon.png"},{"id":"skynovels.net","name":"SkyNovels","site":"https://www.skynovels.net/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/skynovels.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/skynovels/icon.png"},{"id":"tunovelaligera","name":"TuNovelaLigera","site":"https://tunovelaligera.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/tunovelaligera.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/tunovelaligera/icon.png"},{"id":"yuukitls.com","name":"Yuuki Tls","site":"https://yuukitls.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/spanish/yukitls.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/es/yuukitls/icon.png"}],"Türkçe":[{"id":"epiknovel.com","name":"EpikNovel","site":"https://www.epiknovel.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/turkish/epiknovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/tr/epiknovel/icon.png"},{"id":"lshnovel","name":"Liebe Schnee Hiver Novel","site":"https://lshnovel.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/turkish/lshnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/lshnovel.png"},{"id":"turkcelightnovels","name":"TurkceLightNovels[madara]","site":"https://turkcelightnovels.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/turkish/TurkceLightNovels[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/turkcelightnovels.png"},{"id":"webnoveloku","name":"WebNovelOku [madara]","site":"https://www.webnoveloku.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/turkish/WebNovelOku[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/webnoveloku.png"}],"Україна":[{"id":"smakolykytl","name":"Смаколики","site":"https://smakolykytl.site/","lang":"Україна","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/ukraine/smakolykytl.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ua/smakolykytl/icon.png"}],"Tiếng Việt":[{"id":"ln.hako","name":"Hako","site":"https://ln.hako.vn","lang":"Tiếng Việt","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/vietnamese/LNHako.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/vi/hakolightnovel/icon.png"}]} \ No newline at end of file +{"العربية":[{"id":"ar-mtl","name":"ArMTL[madara]","site":"https://ar-mtl.club/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/ArMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/armtl.png"},{"id":"arnovel","name":"ArNovel[madara]","site":"https://arnovel.me/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/ArNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/arnovel.png"},{"id":"hizomanga","name":"HizoManga[madara]","site":"https://hizomanga.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/HizoManga[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/hizomanga.png"},{"id":"kol-novel","name":"Kol Novel[wpmangastream]","site":"https://kolnovel.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/KolNovel[wpmangastream].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/wpmangastream/icons/kol-novel.png"},{"id":"kolnovel","name":"KolNovel","site":"https://kolnovel.lol/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/kolnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/wpmangastream/icons/kolnovel.png"},{"id":"novel4up","name":"Novel4Up[madara]","site":"https://novel4up.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/Novel4Up[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/novel4up.png"},{"id":"riwyat","name":"Riwyat[madara]","site":"https://riwyat.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/Riwyat[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/riwyat.png"},{"id":"teamxnovel","name":"TeamXNovel[madara]","site":"https://teamxnovel.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/arabic/TeamXNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/teamxnovel.png"}],"中文, 汉语, 漢語":[{"id":"linovelib","name":"Linovelib","site":"https://w.linovelib.com","lang":"中文, 汉语, 漢語","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/chinese/linovelib.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/cn/linovelib/icon.png"}],"English":[{"id":"1stkissnovel","name":"FirstKissNovel[madara]","site":"https://1stkissnovel.org/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/FirstKissNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/firstkissnovel.png"},{"id":"anf.net","name":"AllNovelFull","site":"https://allnovelfull.net","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/allnovelfull.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/allnovelfull/icon.png"},{"id":"BLN.com","name":"BestLightNovel","site":"https://bestlightnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/bestlightnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/bestlightnovel/icon.png"},{"id":"boxnovel","name":"BoxNovel[madara]","site":"https://boxnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/BoxNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/boxnovel.png"},{"id":"clicknovel","name":"ClickNovel[madara]","site":"https://clicknovel.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/ClickNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/clicknovel.png"},{"id":"comrademao","name":"Comrade Mao","site":"https://comrademao.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/comrademao.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/comrademao/icon.png"},{"id":"cratenovel","name":"CrateNovel[madara]","site":"https://cratenovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/CrateNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/cratenovel.png"},{"id":"daonovel","name":"DaoNovel[madara]","site":"https://daonovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/DaoNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/daonovel.png"},{"id":"DDL.com","name":"Divine Dao Library","site":"https://www.divinedaolibrary.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/divinedaolibrary.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/divinedaolibrary/icon.png"},{"id":"earlynovel","name":"Early Novel","site":"https://earlynovel.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/earlynovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/latestnovel.png"},{"id":"fanTLS","name":"Fans Translations[madara]","site":"https://fanstranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/FansTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/fanstranslations.png"},{"id":"foxaholic","name":"Foxaholic","site":"https://www.foxaholic.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/foxaholic.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/foxaholic/icon.png"},{"id":"freenovel.me","name":"FreeNovelMe[madara]","site":"https://freenovel.me/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/FreeNovelMe[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/freenovelme.png"},{"id":"FWN.com","name":"Web NOVEL","site":"https://freewebnovel.com","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/freewebnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/freewebnovel/icon.png"},{"id":"guavaread","name":"Guavaread[madara]","site":"https://guavaread.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/Guavaread[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/guavaread.png"},{"id":"lightnovelpub","name":"LightNovelPub","site":"https://www.lightnovelpub.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/lightnovelpub.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/lightnovelpub/icon.png"},{"id":"LightNovelUpdates","name":"Light Novel Updates","site":"https://www.lightnovelupdates.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/lightnovelupdates.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/lightnovelupdates/icon.png"},{"id":"lightnovelworld","name":"LightNovelWorld","site":"https://www.webnovelworld.org/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/lightnovelworld.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/lightnovelworld/icon.png"},{"id":"lnheaven","name":"LightNovelHeaven[madara]","site":"https://lightnovelheaven.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/LightNovelHeaven[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/lightnovelheaven.png"},{"id":"Ltnovel.com","name":"Ltnovel[readwn]","site":"https://www.ltnovel.com","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/Ltnovel[readwn].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/readwn/icons/ltnovel.png"},{"id":"lunarletters","name":"LunarLetters[madara]","site":"https://www.lunarletters.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/LunarLetters[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/lunarletters.png"},{"id":"mostnovel","name":"MostNovel[madara]","site":"https://mostnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/MostNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/mostnovel.png"},{"id":"mtl-novel","name":"MTL-Novel[madara]","site":"https://mtl-novel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/MTLNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/mtl-novel.png"},{"id":"mtlnovel","name":"MTL Novel","site":"https://www.mtlnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/mtlnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/mtlnovel/icon.png"},{"id":"mtlnovel.club","name":"MTLNovel.Club[madara]","site":"https://mtlnovel.club/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/MTLNovelClub[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/mtlnovel.club.png"},{"id":"mtlreader","name":"MTL Reader","site":"https://mtlreader.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/mtlreader.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/mtlreader/icon.png"},{"id":"mysticalmerries","name":"MysticalSeries[madara]","site":"https://mysticalmerries.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/MysticalSeries[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/mysticalseries.png"},{"id":"neosekaiTLS","name":"NeoSekai Translations[madara]","site":"https://www.neosekaitranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NeoSekaiTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/neosekaitranslations.png"},{"id":"NF.me","name":"NovelFullMe","site":"https://novelfull.me/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NovelFullMe.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/novelfullme/icon.png"},{"id":"nitromanga","name":"Nitro Manga","site":"https://nitromanga.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/nitromanga.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/nitromanga/icon.png"},{"id":"NO.net","name":"novelsOnline","site":"https://novelsonline.net","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NovelOnline.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/coverNotAvailable.jpg"},{"id":"noblemtl","name":"NobleMTL","site":"https://noblemtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/nobleMTL.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/noblemtl/icon.png"},{"id":"nocturneTLS","name":"Nocturne Translations[madara]","site":"https://nocturnetls.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NocturneTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/nocturnetranslations.png"},{"id":"noobchanTL","name":"Noobchan Translation[madara]","site":"https://noobchan.xyz/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NoobchanTranslation[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/noobchantranslation.png"},{"id":"novelbin","name":"Novel Bin","site":"https://novelmax.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/novelbin.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/novelbin/icon.png"},{"id":"novelfull","name":"NovelFull","site":"https://novelfull.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/novelfull.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/novelfull/icon.png"},{"id":"novelhold","name":"Novel Hall","site":"https://novelhall.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/novelhall.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/novelhall/icon.png"},{"id":"novelmultiverse","name":"NovelMultiverse[madara]","site":"https://www.novelmultiverse.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NovelMultiverse[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/novelmultiverse.png"},{"id":"novelr18","name":"NovelR18[madara]","site":"https://novelr18.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NovelR18[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/novelr18.png"},{"id":"novelroom","name":"Novelroom.net[madara]","site":"https://novelroom.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/Novelroomnet[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/novelroom.net.png"},{"id":"novelstic","name":"Novelstic[madara]","site":"https://novelstic.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/Novelstic[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/novelstic.png"},{"id":"novelTL","name":"NovelTranslate[madara]","site":"https://noveltranslate.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/NovelTranslate[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/noveltranslate.png"},{"id":"novelupdates","name":"Novel Updates","site":"https://www.novelupdates.com/","lang":"English","version":"0.5.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/novelupdates.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/novelupdates/icon.png"},{"id":"onlymtl","name":"OnlyMTL[madara]","site":"https://www.onlymtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/OnlyMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/onlymtl.png"},{"id":"pandamtl","name":"PandaMTL","site":"https://pandamtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/pandaMTL.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/wordpress/icon.png"},{"id":"readwebnovels","name":"ReadWebNovels[madara]","site":"https://readwebnovels.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/ReadWebNovels[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/readwebnovels.png"},{"id":"sleeptTLS","name":"SleepyTranslations[madara]","site":"https://sleepytranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/SleepyTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/sleepytranslations.png"},{"id":"sonicmtl","name":"SonicMTL[madara]","site":"https://www.sonicmtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/SonicMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/sonicmtl.png"},{"id":"sugarbbscan","name":"Sugar Babies[madara]","site":"https://sugarbbscan.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/SugarBabies[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/sugarbabies.png"},{"id":"sweetEscapeTL","name":"Sweet Escape Translations[madara]","site":"https://sweetescapetranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/SweetEscapeTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/sweetescapetranslations.png"},{"id":"webnovelover","name":"WebNovelLover[madara]","site":"https://www.webnovelover.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/WebNovelLover[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/webnovellover.png"},{"id":"wuxiacity","name":"Wuxiacity[readwn]","site":"https://www.wuxiacity.com","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/Wuxiacity[readwn].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/readwn/icons/wuxiacity.png"},{"id":"wuxiap","name":"Wuxiap[readwn]","site":"https://www.wuxiap.com","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/Wuxiap[readwn].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/readwn/icons/wuxiap.png"},{"id":"wuxiaworld","name":"Wuxia World","site":"https://www.wuxiaworld.com/","lang":"English","version":"0.5.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/wuxiaworld.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/en/wuxiaworld/icon.png"},{"id":"wuxiaworld.site","name":"WuxiaWorld.Site[madara]","site":"https://wuxiaworld.site/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/WuxiaWorldSite[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/wuxiaworld.site.png"},{"id":"zetroTL","name":"Zetro Translation[madara]","site":"https://zetrotranslation.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/ZetroTranslation[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/zetrotranslation.png"},{"id":"zinnovel","name":"ZinnNovel[madara]","site":"https://zinnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/english/ZinnNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/zinnnovel.png"}],"français, française":[{"id":"chireads.com","name":"Chireads","site":"https://chireads.com","lang":"français, française","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/french/chireads.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/fr/chireads/icon.png"},{"id":"lightnovelfr","name":"Ligh Novel FR[wpmangastream]","site":"https://lightnovelfr.com/","lang":"français, française","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/french/LighNovelFR[wpmangastream].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/wpmangastream/icons/lightnovelfr.png"},{"id":"NDG.com","name":"NovelDeGlace","site":"https://noveldeglace.com/","lang":"français, française","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/french/noveldeglace.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/fr/noveldeglace/icon.png"}],"Bahasa Indonesia":[{"id":"IDWN.id","name":"IndoWebNovel","site":"https://indowebnovel.id/id/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/indonesian/indowebnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/id/indowebnovel/icon.png"},{"id":"meionovel","name":"MeioNovel[madara]","site":"https://meionovel.id/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/indonesian/MeioNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/meionovel.png"},{"id":"morenovel","name":"MoreNovel[madara]","site":"https://morenovel.net/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/indonesian/MoreNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/morenovel.png"},{"id":"novelringan.com","name":"NovelRingan","site":"https://novelringan.com/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/indonesian/novelringan.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/id/novelringan/icon.png"},{"id":"sakura.id","name":"SakuraNovel","site":"https://sakuranovel.id/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/indonesian/sakuranovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/id/sakuranovel/icon.png"},{"id":"wbnovel","name":"WBNovel[madara]","site":"https://wbnovel.com/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/indonesian/WBNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/wbnovel.png"}],"日本語":[{"id":"yomou.syosetu","name":"Syosetu","site":"https://yomou.syosetu.com/","lang":"日本語","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/japanese/Syosetu.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/jp/syosetu/icon.png"}],"한국어, 조선말":[{"id":"agit.xyz","name":"Agitoon","site":"https://agit501.xyz/","lang":"한국어, 조선말","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/korean/Agitoon.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/kr/agitoon/agit.png"}],"Português":[{"id":"lightnovelbrasil","name":"Light Novel Brasil","site":"https://lightnovelbrasil.com/","lang":"Português","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/portuguese/lightnovelbrasil.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/wpmangastream/icons/lightnovelbrasil.png"}],"русский язык":[{"id":"AT","name":"Автор Тудей","site":"https://author.today","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/authortoday.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/authortoday/icon.png"},{"id":"bookhamster","name":"Bookhamster[ifreedom]","site":"https://bookhamster.ru","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/Bookhamster[ifreedom].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/ifreedom/icons/bookhamster.png"},{"id":"bookriver","name":"Bookriver","site":"https://bookriver.ru","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/bookriver.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/bookriver/icon.png"},{"id":"erolate","name":"Erolate[rulate]","site":"https://erolate.com","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/Erolate[rulate].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/rulate/icons/erolate.png"},{"id":"ficbook","name":"ficbook","site":"https://ficbook.net","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/ficbook.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/ficbook/icon.png"},{"id":"freedlit.space","name":"LitSpace","site":"https://freedlit.space","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/LitSpace.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/freedlit/icon.png"},{"id":"ifreedom","name":"Свободный Мир Ранобэ[ifreedom]","site":"https://ifreedom.su","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/СвободныйМирРанобэ[ifreedom].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/ifreedom/icons/ifreedom.png"},{"id":"jaomix.ru","name":"Jaomix","site":"https://jaomix.ru","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/jaomix.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/jaomix/icon.png"},{"id":"ReN","name":"Renovels","site":"https://renovels.org","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/renovels.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/renovels/icon.png"},{"id":"RLIB","name":"RanobeLib","site":"https://ranobelib.me","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/ranobelib.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/ranobelib/icon.png"},{"id":"RNBH.org","name":"RanobeHub","site":"https://ranobehub.org/","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/ranobehub.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/ranobehub/icon.png"},{"id":"RNRF","name":"РанобэРФ","site":"https://ранобэ.рф","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/ranoberf.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/ranoberf/icon.png"},{"id":"TL","name":"NovelTL","site":"https://novel.tl","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/novelTL.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ru/noveltl/icon.png"},{"id":"tl.rulate","name":"Rulate[rulate]","site":"https://tl.rulate.ru","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/russian/Rulate[rulate].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/rulate/icons/rulate.png"}],"español, castellano":[{"id":"awuxia.com","name":"ReinoWuxia","site":"http://www.reinowuxia.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/novelawuxia.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/novelawuxia/icon.png"},{"id":"HasuTL","name":"Hasu Translations","site":"https://hasutl.wordpress.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/hasutl.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/hasutl/icon.png"},{"id":"ligera.com","name":"Novelas Ligera","site":"https://novelasligera.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/novelasligera.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/novelasligera/icon.png"},{"id":"oasisTL.wp","name":"Oasis Translations","site":"https://oasistranslations.wordpress.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/oasistranslations.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/oasistranslations/icon.png"},{"id":"skynovels.net","name":"SkyNovels","site":"https://www.skynovels.net/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/skynovels.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/skynovels/icon.png"},{"id":"tunovelaligera","name":"TuNovelaLigera","site":"https://tunovelaligera.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/tunovelaligera.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/tunovelaligera/icon.png"},{"id":"yuukitls.com","name":"Yuuki Tls","site":"https://yuukitls.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/spanish/yukitls.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/es/yuukitls/icon.png"}],"Türkçe":[{"id":"epiknovel.com","name":"EpikNovel","site":"https://www.epiknovel.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/turkish/epiknovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/tr/epiknovel/icon.png"},{"id":"lshnovel","name":"Liebe Schnee Hiver Novel","site":"https://lshnovel.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/turkish/lshnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/wpmangastream/icons/lshnovel.png"},{"id":"turkcelightnovels","name":"TurkceLightNovels[madara]","site":"https://turkcelightnovels.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/turkish/TurkceLightNovels[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/turkcelightnovels.png"},{"id":"webnoveloku","name":"WebNovelOku [madara]","site":"https://www.webnoveloku.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/turkish/WebNovelOku[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/multisrc/madara/icons/webnoveloku.png"}],"Україна":[{"id":"smakolykytl","name":"Смаколики","site":"https://smakolykytl.site/","lang":"Україна","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/ukraine/smakolykytl.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/ua/smakolykytl/icon.png"}],"Tiếng Việt":[{"id":"ln.hako","name":"Hako","site":"https://ln.hako.vn","lang":"Tiếng Việt","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/.js/plugins/vietnamese/LNHako.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-en/icons/src/vi/hakolightnovel/icon.png"}]} \ No newline at end of file diff --git a/.js/plugins/english/NovelFullMe.js b/.js/plugins/english/NovelFullMe.js index fdf6b40..eb49d9d 100644 --- a/.js/plugins/english/NovelFullMe.js +++ b/.js/plugins/english/NovelFullMe.js @@ -41,7 +41,7 @@ var fetch_1 = require("@libs/fetch"); var NovelFull = /** @class */ (function () { function NovelFull() { this.id = "NF.me"; - this.name = "NovelFull"; + this.name = "NovelFullMe"; this.site = "https://novelfull.me/"; this.version = "1.0.0"; this.icon = "src/en/novelfullme/icon.png"; diff --git a/.js/plugins/english/NovelOnline.js b/.js/plugins/english/NovelOnline.js new file mode 100644 index 0000000..edb8506 --- /dev/null +++ b/.js/plugins/english/NovelOnline.js @@ -0,0 +1,161 @@ +"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 NovelsOnline = /** @class */ (function () { + function NovelsOnline() { + this.id = "NO.net"; + this.name = "novelsOnline"; + this.site = "https://novelsonline.net"; + this.icon = "src/coverNotAvailable.jpg"; + this.version = "1.0.0"; + } + NovelsOnline.prototype.popularNovels = function (pageNo, options) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, []]; /** TO DO */ + }); + }); + }; + NovelsOnline.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + var novel, result, $; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novel = { + url: novelUrl, + chapters: [], + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + result = _a.sent(); + $ = (0, cheerio_1.load)(result); + novel.name = $("h1").text(); + novel.cover = $(".novel-cover").find("a > img").attr("src"); + novel.author = $("div.novel-details > div:nth-child(5) > div.novel-detail-body") + .find("li") + .map(function (_, el) { return $(el).text(); }) + .get() + .join(", "); + novel.genres = $("div.novel-details > div:nth-child(2) > div.novel-detail-body") + .find("li") + .map(function (_, el) { return $(el).text(); }) + .get() + .join(","); + novel.summary = $("div.novel-right > div > div:nth-child(1) > div.novel-detail-body").text(); + novel.chapters = $("ul.chapter-chs > li > a") + .map(function (_, el) { + var chapterUrl = $(el).attr("href"); + var chapterName = $(el).text(); + return { + name: chapterName, + releaseTime: "", + url: chapterUrl, + }; + }) + .get(); + return [2 /*return*/, novel]; + } + }); + }); + }; + NovelsOnline.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var result, 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: + result = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(result); + chapterText = loadedCheerio("#contentall").html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + NovelsOnline.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var result, $, headers; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)("https://novelsonline.net/sResults.php", { + headers: { + Accept: "*/*", + "Accept-Language": "pl,en-US;q=0.7,en;q=0.3", + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + }, + method: "POST", + body: "q=" + encodeURIComponent(searchTerm), + }).then(function (res) { return res.text(); })]; + case 1: + result = _a.sent(); + $ = (0, cheerio_1.load)(result); + headers = $("li"); + return [2 /*return*/, headers + .map(function (i, h) { + var novelName = $(h).text(); + var novelUrl = $(h).find("a").attr("href"); + var novelCover = $(h).find("img").attr("src"); + if (!novelUrl) { + return null; + } + return { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + }) + .get() + .filter(function (sr) { return sr !== null; })]; + } + }); + }); + }; + NovelsOnline.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, (0, fetch_1.fetchFile)(url)]; + }); + }); + }; + return NovelsOnline; +}()); +exports.default = new NovelsOnline(); diff --git a/.js/plugins/english/lightnovelpub.js b/.js/plugins/english/lightnovelpub.js new file mode 100644 index 0000000..8831c9b --- /dev/null +++ b/.js/plugins/english/lightnovelpub.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 LightNovelPub = /** @class */ (function () { + function LightNovelPub() { + this.id = "lightnovelpub"; + this.name = "LightNovelPub"; + this.version = "1.0.0"; + this.icon = "src/en/lightnovelpub/icon.png"; + this.site = "https://www.lightnovelpub.com/"; + this.baseUrl = this.site; + this.headers = { + Accept: "application/json", + "Content-Type": "application/json", + }; + } + LightNovelPub.prototype.popularNovels = function (pageNo, options) { + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novels; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.baseUrl, "browse/all/popular/all/").concat(pageNo); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio(".novel-item.ads").remove(); + loadedCheerio(".novel-item").each(function (idx, ele) { + var _a; + var novelName = loadedCheerio(ele) + .find(".novel-title") + .text() + .trim(); + var novelCover = loadedCheerio(ele).find("img").attr("data-src"); + var novelUrl = _this.baseUrl + + ((_a = loadedCheerio(ele) + .find(".novel-title > a") + .attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + LightNovelPub.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novel, delay, chapterListUrl, chapterListBody, loadedChapterList, lastNumber, lastChapterUrl, chapterUrlPrefix, chapters, i; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + url = novelUrl; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio("h1.novel-title").text().trim(); + novel.cover = loadedCheerio("figure.cover > img").attr("data-src"); + novel.genres = ""; + loadedCheerio(".categories > ul > li > a").each(function () { + novel.genres += loadedCheerio(this).text() + ","; + }); + novel.genres = novel.genres.slice(0, -1); + loadedCheerio("div.header-stats > span").each(function () { + if (loadedCheerio(this).find("small").text() === "Status") { + novel.status = loadedCheerio(this).find("strong").text(); + } + }); + novel.author = loadedCheerio(".author > a > span").text(); + novel.summary = loadedCheerio(".summary > .content").text().trim(); + delay = function (ms) { return new Promise(function (res) { return setTimeout(res, ms); }); }; + return [4 /*yield*/, delay(1000)]; + case 2: + _b.sent(); + chapterListUrl = novelUrl + '/chapters?chorder=desc'; + return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterListUrl).then(function (r) { return r.text(); })]; + case 3: + chapterListBody = _b.sent(); + loadedChapterList = (0, cheerio_1.load)(chapterListBody); + lastNumber = parseInt((_a = loadedChapterList('ul.chapter-list > li:nth-child(1)').attr('data-chapterno')) !== null && _a !== void 0 ? _a : '0'); + lastChapterUrl = loadedChapterList('ul.chapter-list > li:nth-child(1) > a').attr('href'); + if (lastChapterUrl) { + chapterUrlPrefix = this.baseUrl + lastChapterUrl.split('/').slice(1, -1).join('/'); + chapters = []; + for (i = 1; i <= lastNumber; i++) { + chapters.push({ + chapterNumber: i, + name: 'Chapter ' + i, + url: chapterUrlPrefix + '/chapter-' + i, + }); + } + novel.chapters = chapters; + } + return [2 /*return*/, novel]; + } + }); + }); + }; + LightNovelPub.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 (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio("#chapter-container").html() || ''; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + LightNovelPub.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, link, response, token, verifytoken, formData, body, loadedCheerio, novels, results; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.baseUrl, "lnsearchlive"); + link = "".concat(this.baseUrl, "search"); + return [4 /*yield*/, (0, fetch_1.fetchApi)(link).then(function (r) { return r.text(); })]; + case 1: + response = _a.sent(); + token = (0, cheerio_1.load)(response); + verifytoken = token("#novelSearchForm > input").attr("value"); + formData = new FormData(); + formData.append("inputContent", searchTerm); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { + method: "POST", + headers: { LNRequestVerifyToken: verifytoken }, + body: formData, + }).then(function (r) { return r.text(); })]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + results = JSON.parse(loadedCheerio("body").text()); + loadedCheerio = (0, cheerio_1.load)(results.resultview); + loadedCheerio(".novel-item").each(function (idx, ele) { + var _a; + var novelName = loadedCheerio(ele) + .find("h4.novel-title") + .text() + .trim(); + var novelCover = loadedCheerio(ele).find("img").attr("src"); + var novelUrl = _this.baseUrl + ((_a = loadedCheerio(ele).find("a").attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + LightNovelPub.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, (0, fetch_1.fetchFile)(url, { headers: this.headers })]; + }); + }); + }; + return LightNovelPub; +}()); +exports.default = new LightNovelPub(); diff --git a/.js/plugins/english/lightnovelupdates.js b/.js/plugins/english/lightnovelupdates.js new file mode 100644 index 0000000..4d17f1c --- /dev/null +++ b/.js/plugins/english/lightnovelupdates.js @@ -0,0 +1,200 @@ +"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 LightNovelUpdates = /** @class */ (function () { + function LightNovelUpdates() { + this.id = "LightNovelUpdates"; + this.name = "Light Novel Updates"; + this.version = "1.0.0"; + this.icon = "src/en/lightnovelupdates/icon.png"; + this.site = "https://www.lightnovelupdates.com/"; + this.baseUrl = this.site; + } + LightNovelUpdates.prototype.popularNovels = function (pageNo, options) { + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.baseUrl, "novel/page/").concat(pageNo, "/?m_orderby=rating"); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio(".page-item-detail").each(function () { + var novelName = loadedCheerio(this).find(".h5 > a").text(); + var novelCover = loadedCheerio(this).find("img").attr("src"); + var novelUrl = loadedCheerio(this).find(".h5 > a").attr("href"); + if (!novelUrl) + return; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + LightNovelUpdates.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novel, chapter, novelId, formData, data, text; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = novelUrl; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio(".post-title > h1").text().trim(); + novel.cover = + loadedCheerio(".summary_image > a > img").attr("src") || undefined; + 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 "Genre(s)": + novel.genres = detail.trim().replace(/[\t\n]/g, ","); + break; + case "Author(s)": + novel.author = detail.trim(); + break; + case "Status": + novel.status = detail.replace(/G/g, "g"); + break; + } + }); + novel.summary = loadedCheerio("div.summary__content").text(); + chapter = []; + novelId = loadedCheerio(".rating-post-id").attr("value"); + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)("https://www.lightnovelupdates.com/wp-admin/admin-ajax.php", { + method: "POST", + body: formData, + })]; + case 2: + data = _a.sent(); + return [4 /*yield*/, data.text()]; + case 3: + text = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(text); + loadedCheerio(".wp-manga-chapter").each(function () { + var chapterName = loadedCheerio(this).find("a").text().trim(); + var releaseDate = loadedCheerio(this).find("span").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]; + } + }); + }); + }; + LightNovelUpdates.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var chapterText; + return __generator(this, function (_a) { + chapterText = 'unable to load'; + return [2 /*return*/, chapterText]; + }); + }); + }; + LightNovelUpdates.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.baseUrl, "?s=").concat(searchTerm, "&post_type=wp-manga&m_orderby=rating"); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio(".c-tabs-item__content").each(function () { + var novelName = loadedCheerio(this).find(".h4 > a").text(); + var novelCover = loadedCheerio(this).find("img").attr("src"); + var novelUrl = loadedCheerio(this).find(".h4 > a").attr("href"); + if (!novelUrl) + return; + novels.push({ + url: novelUrl, + name: novelName, + cover: novelCover, + }); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + LightNovelUpdates.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, (0, fetch_1.fetchFile)(url)]; + }); + }); + }; + return LightNovelUpdates; +}()); +exports.default = new LightNovelUpdates(); diff --git a/.js/plugins/english/lightnovelworld.js b/.js/plugins/english/lightnovelworld.js new file mode 100644 index 0000000..9b405f7 --- /dev/null +++ b/.js/plugins/english/lightnovelworld.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 LightNovelWorld = /** @class */ (function () { + function LightNovelWorld() { + this.id = "lightnovelworld"; + this.name = "LightNovelWorld"; + this.site = "https://www.webnovelworld.org/"; + this.version = "1.0.0"; + this.icon = "src/en/lightnovelworld/icon.png"; + this.baseUrl = this.site; + this.headers = { + Accept: "application/json", + "Content-Type": "application/json", + }; + } + LightNovelWorld.prototype.popularNovels = function (pageNo, options) { + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novels; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.baseUrl, "browse/all/popular/all/").concat(pageNo); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio(".novel-item.ads").remove(); + loadedCheerio(".novel-item").each(function (idx, ele) { + var _a; + var novelName = loadedCheerio(ele) + .find(".novel-title") + .text() + .trim(); + var novelCover = loadedCheerio(ele).find("img").attr("data-src"); + var novelUrl = _this.baseUrl + + ((_a = loadedCheerio(ele) + .find(".novel-title > a") + .attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + LightNovelWorld.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novel, delay, chapterListUrl, chapterListBody, loadedChapterList, lastNumber, lastChapterUrl, chapterUrlPrefix, chapters, i; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + url = novelUrl; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio("h1.novel-title").text().trim(); + novel.cover = loadedCheerio("figure.cover > img").attr("data-src"); + novel.genres = ""; + loadedCheerio(".categories > ul > li > a").each(function () { + novel.genres += loadedCheerio(this).text() + ","; + }); + novel.genres = novel.genres.slice(0, -1); + loadedCheerio("div.header-stats > span").each(function () { + if (loadedCheerio(this).find("small").text() === "Status") { + novel.status = loadedCheerio(this).find("strong").text(); + } + }); + novel.author = loadedCheerio(".author > a > span").text(); + novel.summary = loadedCheerio(".summary > .content").text().trim(); + delay = function (ms) { return new Promise(function (res) { return setTimeout(res, ms); }); }; + return [4 /*yield*/, delay(1000)]; + case 2: + _b.sent(); + chapterListUrl = novelUrl + '/chapters?chorder=desc'; + return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterListUrl).then(function (r) { return r.text(); })]; + case 3: + chapterListBody = _b.sent(); + loadedChapterList = (0, cheerio_1.load)(chapterListBody); + lastNumber = parseInt((_a = loadedChapterList('ul.chapter-list > li:nth-child(1)').attr('data-chapterno')) !== null && _a !== void 0 ? _a : '0'); + lastChapterUrl = loadedChapterList('ul.chapter-list > li:nth-child(1) > a').attr('href'); + if (lastChapterUrl) { + chapterUrlPrefix = this.baseUrl + lastChapterUrl.split('/').slice(1, -1).join('/'); + chapters = []; + for (i = 1; i <= lastNumber; i++) { + chapters.push({ + chapterNumber: i, + name: 'Chapter ' + i, + url: chapterUrlPrefix + '/chapter-' + i, + }); + } + novel.chapters = chapters; + } + return [2 /*return*/, novel]; + } + }); + }); + }; + LightNovelWorld.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 (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio("#chapter-container").html() || ''; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + LightNovelWorld.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, link, response, token, verifytoken, formData, body, loadedCheerio, novels, results; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.baseUrl, "lnsearchlive"); + link = "".concat(this.baseUrl, "search"); + return [4 /*yield*/, (0, fetch_1.fetchApi)(link).then(function (r) { return r.text(); })]; + case 1: + response = _a.sent(); + token = (0, cheerio_1.load)(response); + verifytoken = token("#novelSearchForm > input").attr("value"); + formData = new FormData(); + formData.append("inputContent", searchTerm); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { + method: "POST", + headers: { LNRequestVerifyToken: verifytoken }, + body: formData, + }).then(function (r) { return r.text(); })]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + results = JSON.parse(loadedCheerio("body").text()); + loadedCheerio = (0, cheerio_1.load)(results.resultview); + loadedCheerio(".novel-item").each(function (idx, ele) { + var _a; + var novelName = loadedCheerio(ele) + .find("h4.novel-title") + .text() + .trim(); + var novelCover = loadedCheerio(ele).find("img").attr("src"); + var novelUrl = _this.baseUrl + ((_a = loadedCheerio(ele).find("a").attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + LightNovelWorld.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, (0, fetch_1.fetchFile)(url, { headers: this.headers })]; + }); + }); + }; + return LightNovelWorld; +}()); +exports.default = new LightNovelWorld(); diff --git a/.js/plugins/english/mtlnovel.js b/.js/plugins/english/mtlnovel.js new file mode 100644 index 0000000..61cc344 --- /dev/null +++ b/.js/plugins/english/mtlnovel.js @@ -0,0 +1,208 @@ +"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 MTLNovel = /** @class */ (function () { + function MTLNovel() { + this.id = "mtlnovel"; + this.name = "MTL Novel"; + this.version = "1.0.0"; + this.icon = "src/en/mtlnovel/icon.png"; + this.site = "https://www.mtlnovel.com/"; + this.baseUrl = this.site; + } + MTLNovel.prototype.popularNovels = function (pageNo, options) { + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.baseUrl, "alltime-rank/page/").concat(pageNo); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (result) { return result.text(); })]; + case 1: + body = _a.sent(); + console.log(body); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("div.box.wide").each(function () { + var novelName = loadedCheerio(this) + .find("a.list-title") + .text() + .slice(4); + var novelCover = loadedCheerio(this).find("amp-img").attr("src"); + var novelUrl = loadedCheerio(this).find("a.list-title").attr("href"); + if (!novelUrl) + return; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MTLNovel.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + function getChapters() { + return __awaiter(this, void 0, void 0, function () { + var listResult, listBody, chapter; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, fetch(chapterListUrl)]; + case 1: + listResult = _a.sent(); + return [4 /*yield*/, listResult.text()]; + case 2: + listBody = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(listBody); + chapter = []; + loadedCheerio("div.ch-list") + .find("a.ch-link") + .each(function () { + var chapterName = loadedCheerio(this) + .text() + .replace("~ ", ""); + var releaseDate = null; + var chapterUrl = loadedCheerio(this).attr("href"); + if (chapterUrl) { + chapter.push({ + url: chapterUrl, + name: chapterName, + releaseTime: releaseDate, + }); + } + }); + return [2 /*return*/, chapter.reverse()]; + } + }); + }); + } + var url, headers, body, loadedCheerio, novel, chapterListUrl, _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + url = novelUrl; + headers = { + Referer: "".concat(this.baseUrl, "alltime-rank/"), + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { + method: "GET", + headers: headers, + }).then(function (result) { return result.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio("h1.entry-title").text(); + novel.cover = loadedCheerio(".nov-head > amp-img").attr("src"); + novel.summary = loadedCheerio("div.desc > h2").next().text().trim(); + novel.author = loadedCheerio("#author").text(); + novel.status = loadedCheerio("#status").text(); + novel.genres = loadedCheerio("#genre").text().replace(/\s+/g, ""); + chapterListUrl = url + "chapter-list/"; + _a = novel; + return [4 /*yield*/, getChapters()]; + case 2: + _a.chapters = _b.sent(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MTLNovel.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 (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio("div.par").html() || ''; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MTLNovel.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var searchUrl, res, result, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + searchUrl = this.baseUrl + + "wp-admin/admin-ajax.php?action=autosuggest&q=" + + searchTerm + + "&__amp_source_origin=https%3A%2F%2Fwww.mtlnovel.com"; + return [4 /*yield*/, fetch(searchUrl)]; + case 1: + res = _a.sent(); + return [4 /*yield*/, res.json()]; + case 2: + result = _a.sent(); + novels = []; + result.items[0].results.map(function (item) { + var novelName = item.title.replace(/<\/?strong>/g, ""); + var novelCover = item.thumbnail; + var novelUrl = item.permalink.replace("https://www.mtlnovel.com/", ""); + var novel = { name: novelName, cover: novelCover, url: novelUrl }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MTLNovel.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, (0, fetch_1.fetchFile)(url)]; + }); + }); + }; + return MTLNovel; +}()); +exports.default = new MTLNovel(); diff --git a/.js/plugins/english/mtlreader.js b/.js/plugins/english/mtlreader.js new file mode 100644 index 0000000..69e656f --- /dev/null +++ b/.js/plugins/english/mtlreader.js @@ -0,0 +1,177 @@ +"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 MTLReader = /** @class */ (function () { + function MTLReader() { + this.id = "mtlreader"; + this.name = "MTL Reader"; + this.version = "1.0.0"; + this.icon = "src/en/mtlreader/icon.png"; + this.site = "https://mtlreader.com/"; + this.baseUrl = this.site; + } + MTLReader.prototype.popularNovels = function (pageNo, options) { + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.baseUrl, "novels?page=").concat(pageNo); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio(".col-md-4.col-sm-4").each(function () { + var novelName = loadedCheerio(this).find("h5").text(); + var novelCover = loadedCheerio(this).find("img").attr("src"); + var novelUrl = loadedCheerio(this).find("h5 > a").attr("href"); + if (!novelUrl) + return; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MTLReader.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novel, chapter; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = novelUrl; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio(".agent-title").text().trim(); + novel.cover = loadedCheerio(".agent-p-img > img").attr("src"); + novel.summary = loadedCheerio("#editdescription").text().trim(); + novel.author = loadedCheerio("i.fa-user") + .parent() + .text() + .replace("Author: ", "") + .trim(); + chapter = []; + loadedCheerio("tr.spaceUnder").each(function () { + var chapterName = loadedCheerio(this).find("a").text().trim(); + var releaseDate = null; + var chapterUrl = loadedCheerio(this).find("a").attr("href"); + if (!chapterUrl) + return; + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + novel.chapters = chapter; + return [2 /*return*/, novel]; + } + }); + }); + }; + MTLReader.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 (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio(".container ins,script,p.mtlreader").remove(); + chapterText = loadedCheerio(".container").html() || ''; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MTLReader.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.baseUrl, "search?input=").concat(searchTerm); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio(".col-md-4.col-sm-4").each(function () { + var novelName = loadedCheerio(this).find("h5").text(); + var novelCover = loadedCheerio(this).find("img").attr("src"); + var novelUrl = loadedCheerio(this).find("h5 > a").attr("href"); + if (!novelUrl) + return; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MTLReader.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, (0, fetch_1.fetchFile)(url)]; + }); + }); + }; + return MTLReader; +}()); +exports.default = new MTLReader(); diff --git a/.js/plugins/english/novelfull.js b/.js/plugins/english/novelfull.js new file mode 100644 index 0000000..8efc789 --- /dev/null +++ b/.js/plugins/english/novelfull.js @@ -0,0 +1,227 @@ +"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 NovelFull = /** @class */ (function () { + function NovelFull() { + this.id = "novelfull"; + this.name = "NovelFull"; + this.version = "1.0.0"; + this.icon = "src/en/novelfull/icon.png"; + this.site = "https://novelfull.com/"; + this.baseUrl = this.site; + } + NovelFull.prototype.popularNovels = function (pageNo, options) { + return __awaiter(this, void 0, void 0, function () { + var url, result, body, loadedCheerio, novels; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.baseUrl, "most-popular?page=").concat(pageNo); + 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(".col-truyen-main .list-truyen .row").each(function (idx, ele) { + var _a, _b; + var novelName = loadedCheerio(ele) + .find("h3.truyen-title > a") + .text(); + var novelCover = _this.baseUrl + ((_a = loadedCheerio(ele).find("img").attr("src")) === null || _a === void 0 ? void 0 : _a.slice(1)); + var novelUrl = _this.baseUrl + + ((_b = loadedCheerio(ele) + .find("h3.truyen-title > a") + .attr("href")) === null || _b === void 0 ? void 0 : _b.slice(1)); + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + NovelFull.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + function getChapters(id, baseUrl) { + return __awaiter(this, void 0, void 0, function () { + var chapterListUrl, data, chapterlist, chapter; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + chapterListUrl = baseUrl + "ajax/chapter-option?novelId=" + id; + return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterListUrl)]; + case 1: + data = _a.sent(); + return [4 /*yield*/, data.text()]; + case 2: + chapterlist = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(chapterlist); + chapter = []; + loadedCheerio("select > option").each(function () { + var _a; + var chapterName = loadedCheerio(this).text(); + var releaseDate = null; + var chapterUrl = baseUrl + ((_a = loadedCheerio(this).attr("value")) === null || _a === void 0 ? void 0 : _a.slice(1)); + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + return [2 /*return*/, chapter]; + } + }); + }); + } + var url, result, body, loadedCheerio, novel, novelId, _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + url = novelUrl; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url)]; + case 1: + result = _b.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio("div.book > img").attr("alt"); + novel.cover = this.baseUrl + loadedCheerio("div.book > img").attr("src"); + novel.summary = loadedCheerio("div.desc-text").text().trim(); + novel.author = loadedCheerio('h3:contains("Author")') + .parent() + .contents() + .text() + .replace("Author:", ""); + novel.genres = loadedCheerio('h3:contains("Genre")') + .siblings() + .map(function (i, el) { return loadedCheerio(el).text(); }) + .toArray() + .join(","); + novel.status = loadedCheerio('h3:contains("Status")').next().text(); + novelId = loadedCheerio("#rating").attr("data-novel-id"); + _a = novel; + return [4 /*yield*/, getChapters(novelId, this.baseUrl)]; + case 3: + _a.chapters = _b.sent(); + return [2 /*return*/, novel]; + } + }); + }); + }; + NovelFull.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*/, (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("#chapter-content div.ads").remove(); + chapterText = loadedCheerio("#chapter-content").html() || ''; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + NovelFull.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var searchUrl, result, body, loadedCheerio, novels; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + searchUrl = "".concat(this.baseUrl, "search?keyword=").concat(searchTerm); + return [4 /*yield*/, (0, fetch_1.fetchApi)(searchUrl)]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio(".col-truyen-main .list-truyen .row").each(function (idx, ele) { + var _a, _b; + var novelName = loadedCheerio(ele) + .find("h3.truyen-title > a") + .text(); + var novelCover = _this.baseUrl + ((_a = loadedCheerio(ele).find("img").attr("src")) === null || _a === void 0 ? void 0 : _a.slice(1)); + var novelUrl = _this.baseUrl + + ((_b = loadedCheerio(ele) + .find("h3.truyen-title > a") + .attr("href")) === null || _b === void 0 ? void 0 : _b.slice(1)); + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + NovelFull.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, (0, fetch_1.fetchFile)(url)]; + }); + }); + }; + return NovelFull; +}()); +exports.default = new NovelFull(); diff --git a/.js/plugins/english/novelhall.js b/.js/plugins/english/novelhall.js new file mode 100644 index 0000000..f90d559 --- /dev/null +++ b/.js/plugins/english/novelhall.js @@ -0,0 +1,183 @@ +"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 NovelHall = /** @class */ (function () { + function NovelHall() { + this.id = "novelhold"; + this.name = "Novel Hall"; + this.version = "1.0.0"; + this.icon = "src/en/novelhall/icon.png"; + this.site = "https://novelhall.com/"; + this.baseUrl = this.site; + } + NovelHall.prototype.popularNovels = function (pageNo, options) { + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novels; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.baseUrl, "all2022-").concat(pageNo, ".html"); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("li.btm").each(function (idx, ele) { + var novelName = loadedCheerio(ele).text().trim(); + var novelUrl = _this.baseUrl + loadedCheerio(ele).find("a").attr("href"); + var novel = { + name: novelName, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + NovelHall.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novel, chapter; + var _this = this; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + url = novelUrl; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio(".booknav2 > h1").text(); + novel.cover = loadedCheerio('meta[property="og:image"]').attr("content"); + novel.summary = loadedCheerio(".navtxt").text().trim(); + novel.author = loadedCheerio('p:contains("Author")') + .text() + .replace("Author:", "") + .trim(); + novel.status = loadedCheerio('p:contains("Status")') + .text() + .replace("Status:", "") + .replace("Active", "Ongoing") + .trim(); + novel.genres = (_a = loadedCheerio('p:contains("Genre")') + .text()) === null || _a === void 0 ? void 0 : _a.replace("Genre:", "").trim(); + chapter = []; + loadedCheerio("#morelist ul > li").each(function (idx, ele) { + var chapterName = loadedCheerio(ele).find("a").text().trim(); + var releaseDate = null; + var chapterUrl = _this.baseUrl + loadedCheerio(ele).find("a").attr("href"); + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + novel.chapters = chapter; + return [2 /*return*/, novel]; + } + }); + }); + }; + NovelHall.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 (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio(".content").html() || ''; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + NovelHall.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, body, loadedCheerio, novels; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.baseUrl, "index.php?s=so&module=book&keyword=").concat(searchTerm); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (r) { return r.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("#article_list_content > li").each(function (idx, ele) { + var _a; + var novelName = loadedCheerio(ele) + .find("h3") + .text() + .replace(/\t+/g, "") + .replace(/\n/g, " "); + var novelCover = loadedCheerio(ele).find("img").attr("data-src"); + var novelUrl = _this.baseUrl + ((_a = loadedCheerio(ele).find("a").attr("href")) === null || _a === void 0 ? void 0 : _a.slice(1)); + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + NovelHall.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, (0, fetch_1.fetchFile)(url)]; + }); + }); + }; + return NovelHall; +}()); +exports.default = new NovelHall(); diff --git a/.js/plugins/english/novelupdates.js b/.js/plugins/english/novelupdates.js new file mode 100644 index 0000000..f102ff2 --- /dev/null +++ b/.js/plugins/english/novelupdates.js @@ -0,0 +1,467 @@ +"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 NovelUpdates = /** @class */ (function () { + function NovelUpdates() { + this.id = "novelupdates"; + this.name = "Novel Updates"; + this.version = "0.5.0"; + this.icon = "src/en/novelupdates/icon.png"; + this.site = "https://www.novelupdates.com/"; + this.baseUrl = this.site; + this.filters = { + sort: { + label: "Sort Results By", + type: filterInputs_1.FilterTypes.Picker, + options: [ + { label: "Last Updated", value: "sdate" }, + { label: "Rating", value: "srate" }, + { label: "Rank", value: "srank" }, + { label: "Reviews", value: "sreview" }, + { label: "Chapters", value: "srel" }, + { label: "Title", value: "abc" }, + { label: "Readers", value: "sread" }, + { label: "Frequency", value: "sfrel" }, + ], + value: "sdate", + }, + order: { + label: "Order", + type: filterInputs_1.FilterTypes.Picker, + options: [ + { label: "Descending", value: "desc" }, + { label: "Ascending", value: "asc" }, + ], + value: "asc" + }, + storyStatus: { + label: "Story Status (Translation)", + type: filterInputs_1.FilterTypes.Picker, + options: [ + { label: "All", value: "" }, + { label: "Completed", value: "2" }, + { label: "Ongoing", value: "3" }, + { label: "Hiatus", value: "4" }, + ], + value: "" + }, + language: { + label: "Language", + options: [ + { label: "Chinese", value: "495" }, + { label: "Filipino", value: "9181" }, + { label: "Indonesian", value: "9179" }, + { label: "Japanese", value: "496" }, + { label: "Khmer", value: "18657" }, + { label: "Korean", value: "497" }, + { label: "Malaysian", value: "9183" }, + { label: "Thai", value: "9954" }, + { label: "Vietnamese", value: "9177" }, + ], + type: filterInputs_1.FilterTypes.Picker, + value: "" + }, + novelType: { + label: "Novel Type", + type: filterInputs_1.FilterTypes.CheckboxGroup, + value: [], + options: [ + { label: "Light Novel", value: "2443" }, + { label: "Published Novel", value: "26874" }, + { label: "Web Novel", value: "2444" }, + ] + }, + genres: { + label: "Genres", + type: filterInputs_1.FilterTypes.CheckboxGroup, + value: [], + options: [ + { label: "Action", value: "8" }, + { label: "Adult", value: "280" }, + { label: "Adventure", value: "13" }, + { label: "Comedy", value: "17" }, + { label: "Drama", value: "9" }, + { label: "Ecchi", value: "292" }, + { label: "Fantasy", value: "5" }, + { label: "Gender Bender", value: "168" }, + { label: "Harem", value: "3" }, + { label: "Historical", value: "330" }, + { label: "Horror", value: "343" }, + { label: "Josei", value: "324" }, + { label: "Martial Arts", value: "14" }, + { label: "Mature", value: "4" }, + { label: "Mecha", value: "10" }, + { label: "Mystery", value: "245" }, + { label: "Psychoical", value: "486" }, + { label: "Romance", value: "15" }, + { label: "School Life", value: "6" }, + { label: "Sci-fi", value: "11" }, + { label: "Seinen", value: "18" }, + { label: "Shoujo", value: "157" }, + { label: "Shoujo Ai", value: "851" }, + { label: "Shounen", value: "12" }, + { label: "Shounen Ai", value: "1692" }, + { label: "Slice of Life", value: "7" }, + { label: "Smut", value: "281" }, + { label: "Sports", value: "1357" }, + { label: "Supernatural", value: "16" }, + { label: "Tragedy", value: "132" }, + { label: "Wuxia", value: "479" }, + { label: "Xianxia", value: "480" }, + { label: "Xuanhuan", value: "3954" }, + { label: "Yaoi", value: "560" }, + { label: "Yuri", value: "922" }, + ] + } + }; + } + NovelUpdates.prototype.getPopularNovelsUrl = function (page, _a) { + var _b, _c, _d; + var showLatestNovels = _a.showLatestNovels, filters = _a.filters; + var url = "".concat(this.baseUrl).concat(filters + ? "series-finder" + : showLatestNovels + ? "latest-series" + : "series-ranking", "/"); + if (!filters) { + url += "?rank=week"; + } + else { + url += "?sf=1"; + } + if (filters) { + if (Array.isArray(filters.novelType) && ((_b = filters.novelType) === null || _b === void 0 ? void 0 : _b.length)) { + url += "&nt=" + (filters === null || filters === void 0 ? void 0 : filters.novelType.join(",")); + } + if (Array.isArray(filters.genres) && ((_c = filters.genres) === null || _c === void 0 ? void 0 : _c.length)) { + url += "&gi=" + (filters === null || filters === void 0 ? void 0 : filters.genres.join(",")) + "&mgi=and"; + } + if (Array.isArray(filters.language) && ((_d = filters.language) === null || _d === void 0 ? void 0 : _d.length)) { + url += "&org=" + (filters === null || filters === void 0 ? void 0 : filters.language.join(",")); + } + if (filters.storyStatus) { + url += "&ss=" + (filters === null || filters === void 0 ? void 0 : filters.storyStatus); + } + } + if (!(filters === null || filters === void 0 ? void 0 : filters.sort)) { + url += "&sort=" + "sdate"; + } + else { + url += "&sort=" + (filters === null || filters === void 0 ? void 0 : filters.sort); + } + if (!(filters === null || filters === void 0 ? void 0 : filters.order)) { + url += "&order=" + "desc"; + } + else { + url += "&order=" + (filters === null || filters === void 0 ? void 0 : filters.order); + } + return url; + }; + NovelUpdates.prototype.popularNovels = function (pageNo, _a) { + var showLatestNovels = _a.showLatestNovels, filters = _a.filters; + return __awaiter(this, void 0, void 0, function () { + var url, result, body, loadedCheerio, novels; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + url = this.getPopularNovelsUrl(pageNo, { showLatestNovels: showLatestNovels, filters: filters }); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url)]; + case 1: + result = _b.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("div.search_main_box_nu").each(function (idx, ele) { + var novelCover = loadedCheerio(ele).find("img").attr("src"); + var novelName = loadedCheerio(ele).find(".search_title > a").text(); + var novelUrl = loadedCheerio(ele) + .find(".search_title > a") + .attr("href"); + if (!novelUrl) + return; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + NovelUpdates.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + var url, result, body, loadedCheerio, novel, type, summary, chapter, novelId, formData, link, text; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = novelUrl; + 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); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio(".seriestitlenu").text(); + novel.cover = loadedCheerio(".seriesimg > img").attr("src"); + novel.author = loadedCheerio("#showauthors").text().trim(); + novel.genres = loadedCheerio("#seriesgenre") + .children("a") + .map(function (i, el) { return loadedCheerio(el).text(); }) + .toArray() + .join(","); + novel.status = loadedCheerio("#editstatus").text().includes("Ongoing") + ? "Ongoing" + : "Completed"; + type = loadedCheerio("#showtype").text().trim(); + summary = loadedCheerio("#editdescription").text().trim(); + novel.summary = summary + "\n\nType: ".concat(type); + chapter = []; + novelId = loadedCheerio("input#mypostid").attr("value"); + formData = new FormData(); + formData.append("action", "nd_getchapters"); + formData.append("mygrr", "0"); + formData.append("mypostid", novelId); + link = "https://www.novelupdates.com/wp-admin/admin-ajax.php"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { + method: "POST", + body: formData, + }).then(function (data) { return data.text(); })]; + case 3: + text = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(text); + loadedCheerio("li.sp_li_chp").each(function () { + var chapterName = loadedCheerio(this).text().trim(); + var releaseDate = null; + var chapterUrl = "https:" + + loadedCheerio(this).find("a").first().next().attr("href"); + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + novel.chapters = chapter.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + NovelUpdates.prototype.getLocation = function (href) { + var match = href.match(/^(https?:)\/\/(([^:/?#]*)(?::([0-9]+))?)([/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); + return match && "".concat(match[1], "//").concat(match[3]); + }; + NovelUpdates.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var chapterText, result, body, loadedCheerio, isWuxiaWorld, isBlogspot, isTumblr, isWattpad, isLightNovelsTls, isiNovelTranslation, isTravisTranslation, isWordPressStr, isWordPress, isRainOfSnow, isWebNovel, isHostedNovel, isScribbleHub, bloatClasses, tags; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + chapterText = ""; + 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); + isWuxiaWorld = chapterUrl.toLowerCase().includes("wuxiaworld"); + isBlogspot = chapterUrl.toLowerCase().includes("blogspot"); + isTumblr = chapterUrl.toLowerCase().includes("tumblr"); + isWattpad = chapterUrl.toLowerCase().includes("wattpad"); + isLightNovelsTls = chapterUrl + .toLowerCase() + .includes("lightnovelstranslations"); + isiNovelTranslation = chapterUrl + .toLowerCase() + .includes("inoveltranslation"); + isTravisTranslation = chapterUrl + .toLowerCase() + .includes("travistranslations"); + isWordPressStr = loadedCheerio('meta[name="generator"]').attr("content") || + loadedCheerio("footer").text(); + isWordPress = false; + if (isWordPressStr) { + isWordPress = + isWordPressStr.toLowerCase().includes("wordpress") || + isWordPressStr.includes("Site Kit by Google") || + loadedCheerio(".powered-by") + .text() + .toLowerCase() + .includes("wordpress"); + } + isRainOfSnow = chapterUrl.toLowerCase().includes("rainofsnow"); + isWebNovel = chapterUrl.toLowerCase().includes("webnovel"); + isHostedNovel = chapterUrl.toLowerCase().includes("hostednovel"); + isScribbleHub = chapterUrl.toLowerCase().includes("scribblehub"); + if (isWuxiaWorld) { + chapterText = loadedCheerio("#chapter-content").html(); + } + else if (isRainOfSnow) { + chapterText = loadedCheerio("div.content").html(); + } + else if (isTumblr) { + chapterText = loadedCheerio(".post").html(); + } + else if (isBlogspot) { + loadedCheerio(".post-share-buttons").remove(); + chapterText = loadedCheerio(".entry-content").html(); + } + else if (isHostedNovel) { + chapterText = loadedCheerio(".chapter").html(); + } + else if (isScribbleHub) { + chapterText = loadedCheerio("div.chp_raw").html(); + } + else if (isWattpad) { + chapterText = loadedCheerio(".container pre").html(); + } + else if (isTravisTranslation) { + chapterText = loadedCheerio(".reader-content").html(); + } + else if (isLightNovelsTls) { + chapterText = loadedCheerio(".text_story").html(); + } + else if (isiNovelTranslation) { + chapterText = loadedCheerio(".chakra-skeleton").html(); + } + else if (isWordPress) { + bloatClasses = [ + ".c-ads", + "#madara-comments", + "#comments", + ".content-comments", + ".sharedaddy", + ".wp-dark-mode-switcher", + ".wp-next-post-navi", + ".wp-block-buttons", + ".wp-block-columns", + ".post-cats", + ".sidebar", + ".author-avatar", + ".ezoic-ad", + ]; + bloatClasses.map(function (tag) { return loadedCheerio(tag).remove(); }); + chapterText = + loadedCheerio(".entry-content").html() || + loadedCheerio(".single_post").html() || + loadedCheerio(".post-entry").html() || + loadedCheerio(".main-content").html() || + loadedCheerio("article.post").html() || + loadedCheerio(".content").html() || + loadedCheerio("#content").html() || + loadedCheerio(".page-body").html() || + loadedCheerio(".td-page-content").html(); + } + else if (isWebNovel) { + chapterText = loadedCheerio(".cha-words").html(); + if (!chapterText) { + chapterText = loadedCheerio("._content").html(); + } + } + else { + tags = ["nav", "header", "footer", ".hidden"]; + tags.map(function (tag) { return loadedCheerio(tag).remove(); }); + chapterText = loadedCheerio("body").html(); + } + if (chapterText) { + /** + * Convert relative urls to absolute + */ + chapterText = chapterText.replace(/href="\//g, "href=\"".concat(this.getLocation(chapterUrl), "/")); + } + return [2 /*return*/, chapterText]; + } + }); + }); + }; + NovelUpdates.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 = "https://www.novelupdates.com/?s=" + + searchTerm + + "&post_type=seriesplans"; + 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("div.search_main_box_nu").each(function () { + var _a; + var novelCover = loadedCheerio(this).find("img").attr("src"); + var novelName = loadedCheerio(this).find(".search_title > a").text(); + var novelUrl = (_a = loadedCheerio(this) + .find(".search_title > a") + .attr("href")) === null || _a === void 0 ? void 0 : _a.split("/")[4]; + if (!novelUrl) + return; + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + NovelUpdates.prototype.fetchImage = function (url) { + return (0, fetch_1.fetchFile)(url); + }; + return NovelUpdates; +}()); +exports.default = new NovelUpdates(); diff --git a/.js/plugins/english/wuxiaworld.js b/.js/plugins/english/wuxiaworld.js new file mode 100644 index 0000000..cc99c5f --- /dev/null +++ b/.js/plugins/english/wuxiaworld.js @@ -0,0 +1,192 @@ +"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 WuxiaWorld = /** @class */ (function () { + function WuxiaWorld() { + this.id = "wuxiaworld"; + this.name = "Wuxia World"; + this.icon = "src/en/wuxiaworld/icon.png"; + this.site = "https://www.wuxiaworld.com/"; + this.version = "0.5.0"; + this.baseUrl = this.site; + } + WuxiaWorld.prototype.popularNovels = function (pageNo, options) { + return __awaiter(this, void 0, void 0, function () { + var link, result, data, novels; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + link = "".concat(this.baseUrl, "api/novels"); + return [4 /*yield*/, fetch(link)]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.json()]; + case 2: + data = _a.sent(); + novels = []; + data.items.map(function (novel) { + var name = novel.name; + var cover = novel.coverUrl; + var url = _this.baseUrl + "novel/" + novel.slug + "/"; + novels.push({ + name: name, + cover: cover, + url: url, + }); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + WuxiaWorld.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + var url, result, body, loadedCheerio, novel, genres, chapter; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = novelUrl; + 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); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio("h1.line-clamp-2").text(); + novel.cover = loadedCheerio("img.absolute").attr("src"); + novel.summary = loadedCheerio("div.flex-col:nth-child(4) > div > div > span > span") + .text() + .trim(); + novel.author = loadedCheerio("div.MuiGrid-container > div > div > div") + .filter(function () { + return loadedCheerio(this).text().trim() === "Author:"; + }) + .next() + .text(); + genres = []; + loadedCheerio("a.MuiLink-underlineNone").each(function () { + genres.push(loadedCheerio(this).find("div > div").text()); + }); + novel.genres = genres.join(","); + novel.status = loadedCheerio("div.font-set-b10") + .text(); + chapter = []; + loadedCheerio("div.border-b.border-gray-line-base").each(function (idx, ele) { + var _a; + var name = loadedCheerio(ele) + .find("a > div > div > div > span") + .text(); + var releaseTime = loadedCheerio(ele) + .find("a > div > div > div > div > span") + .text(); + var url = (_a = loadedCheerio(ele).find("a").attr("href")) === null || _a === void 0 ? void 0 : _a.slice(1); + url = "".concat(_this.baseUrl).concat(url); + chapter.push({ name: name, releaseTime: releaseTime, url: url }); + }); + novel.chapters = chapter; + return [2 /*return*/, novel]; + } + }); + }); + }; + WuxiaWorld.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*/, (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(".chapter-nav").remove(); + loadedCheerio("#chapter-content > script").remove(); + chapterText = loadedCheerio("#chapter-content").html() || ''; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + WuxiaWorld.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var searchUrl, url, result, data, novels; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + searchUrl = "https://www.wuxiaworld.com/api/novels/search?query="; + url = "".concat(searchUrl).concat(searchTerm); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url)]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.json()]; + case 2: + data = _a.sent(); + novels = []; + data.items.map(function (novel) { + var name = novel.name; + var cover = novel.coverUrl; + var url = _this.baseUrl + "novel/" + novel.slug + "/"; + novels.push({ + name: name, + url: url, + cover: cover, + }); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + WuxiaWorld.prototype.fetchImage = function (url) { + return (0, fetch_1.fetchFile)(url); + }; + return WuxiaWorld; +}()); +exports.default = new WuxiaWorld(); diff --git a/icons/src/en/lightnovelworld/icon.png b/icons/src/en/lightnovelworld/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a6507a3edbdcd39ca1bfc669dc39ec10043739fd GIT binary patch literal 5380 zcmWkyby!p1AEs2q`btS7N-3d~0@5j6V{D8X-HoJ-MncKaB8@Z~4ixDc2%{O@(gl?mVu)+v5kyo}*8@3!Brb^UQqnTZ zt7{$IXmw*d;w}n>T3Y$LzkfhX6&ja{!C=!DR6t|^8Eaq=-koK(bLmIj7MyjRtF9Y3>+RF65C}ojU-g`;Bffh z;NZ#0X;V{EW@hH!zki7WaU~tFOEA%Gr1z58I5adgGczM5uOXueg1CpOf$dD4eCtst zhZv&!0aV8yjO|V~LHVq@<=E;Y2G7pHJrA(Z;SYbMGiK zuSjikR}=RzMSXM0_XdXce!7+(#9#nhUjH_@H@mvI4Yjs|Hw=C73$V3!DD9lI`dkwlJ>ePE)zY&E55`BsR{nIJ|8DL` zL=IH`T4`=L4NC1b4?(zi2aGK2dU_63A%4J%reQJ3nnuvJj&ARem;?M_aRv_R=oxQ! zWM|_vFuu&q!(;3BDT9j>N_+=my!EvWNd8@G9&2i7X{w)RNGqLmsjI7=@2e=O?#XYd zDkvSOwcR4sCy8k0f`ug<04$0JFGULY{tPRGff)9FLZpzd#4|VC8G^& zc}0CPh1n(9p2oiLK=IdU7xwC|Z}83A;*_4XAcdU`aJn9p;dSFJu_J%Xt&Ty5i!3}y(!q9KRMolcm3xy=4eg)E&a26ykIBxL9 zrfRTq47eT_5vEXD$-@dNdr>xbsqSK0qNOK81599C+u2xc`?KU>U=Z<;|4nlTWghV6 znvoeum7bpTVJdfRV@LW;YE8`|1q6s)7L7ViE)HHmx4*}*v{NPugpa7$1x<_fKLRZj zM*Hg=edtjas*@2~0V(kgeCzABM6g85vtj~R&(p~Hg7B5#l+I8wk3UigYboL3otINm zv~2N@wfC@M%jCTtFjuHR5SYOjt-?Zg*u0+rDN`6C*s1 z4X_r*WHoff6_i9LJ$dzwMNqfFQ4k3H7uIikcEwCom`SwlGCypy(p-chdt@9%xEzBR(1*;E~$_L|?p zCLkaR0O1~FqjQoeFQ}?^KpV$ZMo81HbuYK=)rVZrqIl+B@EO2UfQg~hQE<|5tzbAU zo)i<1`^tMT%N{EIMgU5V<6l5nMW?em&D2oxS;Bs7By;LaU9IgceI$iCd)%}msR$5< zv?d@VF*l);tuu@xq<;wAZkt*OFN&k@$WlC>-6<0o5L6Xs|{N*lEZwY6`h$O!*Y0zEIt@QZbKkn>zY_W%rXVw_S&2EcM-Sz zsjLu?N~s0z25_V+;zR{H82h94#EqwNYv-+HrBB6U4FAOYN<%@g!9b-04E=+S&eB%7 zxx2QKrfWP2_h_^N4n5jO6)Tq?GeCnb_l0iCQ?SKNxgeJ3|s z#%PJ1u<%Kbo`Hgt{(je5d`_+HzrSr#T#`9ZEsZ$~uSIDSEK@EGJ!|ofj4e1c=}q;6 zJLnF)J0?tML;$-YV1TJ?>*ehib;~Abv)qc?xxF(v5Ca8iz!*tF3HGqAaiu9GHzjON zI7Dhol#Y&t0M;FT=hh*@;k8bofDTW&V~=&!mTMba69ntr?^O3`$D5OQ9W2euXk2k5 zufT9|XAx!WJlx!_bH6Q#%-eVH5MFyouG8r3o zL%Bj$gXde;fBgqiT+C~@TCPcJzpf=0vxIh|ED1x+2`LA!A=tpfC)pQ(t*Bl`d5)sP zeHgZ5g{8JuT&=UVd>3@y#bf67$!Upb?Ko-Mtdh>J@rri^3>0Nr5KX5@^ z%;GN)tI%d~mN-|Hnp^#tN;LbT!Xk|2p$K&9KkD;`59f0Jv)1a2Vc@|Dbr?5wdky81 zFFdakwSwx!by{L7mGGg_tBk*dMpN2=UC~k1i}7BD){#qNdVyeUY6Qi8bWZ_UM^G~( z{kp(QNjyTXm%>}+^EIz%1RE?Q(uL9iGms_hv0Lfwkm*E^5{ZE-@0RxZaJXPHg`QKt zyQ%LTPREW^iLZ(T1#|}5Vw<2~6jcLwNWv!RS4Rs)7Q8pVMx#z9t^k7j)$8)}t5%K~ zZVW`vT|NICnM<1xDfZ;zteya@{N5ZP7VRpsJ>GhAwd#}nYoS9YA?GuHT-V$ukJ`V2 zpo>~A@(&Qu#Uo+V@gmRl6R_{z-1M#7+!~p@cTHkWUQMTpmV|xIt()4w&Fili^7oIM*={YrCa3~^arqbM3Yg6WHdnufiw50I<0K6Nu`3ECP(Rg_ZlJ%d_~CUc7LVPT=Id{}lBG+tw-59wN; z+??y$+;Snc=W|l9{muMj%*yxXiMd&e&(0`U*0GuXrE$$KQ9i7!GcaV5%ohZ6Pg!GD zxy@8#DtqnMIATi;%U?cxr8Z7ut;4(JjN;1d3F1 z7YBP<3Cid~C-;?|VrWWrCe5Wz#bUf%7&h9@j`h6m*P~2D*@GSoWosUn>g0qVB-_8; zy)^dCsk}?G1Un}My>-j2E^}bmWpaLPx+@G%&1f84j@r$67abT?FF41@B!$l5E!+Rs z=&`!4hYJ*{zG zR9v^Qpy;2tp`

o*-tS?37&=x%<_HNlFF9ENIq530c?N|IBC9f=9jVPpCcXtfi>u zUvRJF-_HyV7O_hXv&|LvC~j!D=JdgmJOY?2KHq&1vhB zXq9Bq0Ztje7ak_&H!kOmSqNt`Eoml@f<7+oRH)L=g&+3{i?y%zad^rGTL}Iefr4!G zrG!|VQZkigcG(e@-Cg&^L`BCZ(~opN`$EM9U5eE!Dm2P|M+JP!x;IXsmc;ooF&USg zFp1xVY-@h}h^8ukZ0>#T9e)q&Ws7AO;16ZJ*Sb_jhD|Na_!J`~XClctN1u z*ZNaT4D?U-kFUHDK>lAe^ngL`-~Rb$J|(H9za7;xhC3;@iqUF7UoBOU_&Lnl`ERrF zt6*{aXw8W)IUla%G%kFsQ5`u20G-ytY)i;wL;J^09KM=4Dlh{hYIRE0_wxFH56Y+)ElS$$avg3Yi)hP7`+C9bv}TJ^k{o zOA~T=Q%?~?BW{!n#>Zu9x^rI1&K_Xn+X*fAKVpWVAO+HotKA6M*YqoI)wcAtOw%;+ z*Bx_s&t|S*`%v34*d(4+;-&1^=;){kz^rQW6eYS-(Vq>;g4wr=SM$uS{yKNm$dN?3 z=RZupS{m{mj*Q$Liq8Mb*6Y=cpNegLjX&h0>na}GSPzT;JXi26Nc3BunCv}>w7-j> zgzAY`)nXExndlwEpSwKYzVXn;KJ=feGxPm}Kk&=#r^BUgCfjL@qhsUZV&h_aWz&=5 zZaksnY;$#Y3#7}^tW&u3)pI}fqxdllxyn40JIZvga0J5ElH{|&)UxirJ!KCM4^M=D z`tFn22;*n{w3CkV@S%;N`o=kC%X+s=@H2~~1cv$w>3V$X(kSqI9>>J5zDG}Q%fX9Z zj;ZsF9r{-|3!dC&q;Ub0W!!#Q%rxw!E1dY}+jgD>XaUQiOlgHR`UM zQZ;g*4WQQW7lKBFHxkpq#ey>Ar`!Nw>_kBIlY_SpNYfJtB$L@ISudD@p7@3t7UY}v z(y!kD-u@zgv|;}a*Q9h7h1KMFo-*4Jv#=pveg#x`K@Tc8L@G$?c-Un3h41P!M#Sif8ei^fhXAjEQ z1XnVe2*6w27h+AGF$ zwB5UVuP`?6)Y`7xSx4BE>RmQj)+1eig;C34I9`B!v=sJ&mP+5i;8uqMS%m__Y~L>a zT?x>%;deQ`vmC;zP}o#m4_y2gr)+Y9_lNmU2nJSydoX;o^y{JbpxCdwjsJc|vkqVY z`JJ?mkcQ9eg33tg`=6h!cYN!S03R|mIAl_W4Q)JTDAFrQxw5|3i8@+)UU(kw*w@PP zj%lp8NY{WMr7IsKiDz2+so4LCPnz5*{@<17?24FVVGt*Lz+N`dcFZ(Z#iod60;yF9 z;$v#qCVq7pavcdpBrUkTjXA^GdshiFF}r*j+62)am63gaxrQ{fGB#muIEItGXqze- zpMDt2^LbHHb^cAToh;`l@1_BjL;Dy6jgn*9JHUE3@of#()VaW2OX+N#Q4*JGs;4gu zUB1-U4!HtYXyOKC=8c7l?nO+WECYECrDwHObTd6Y)`WIMWxv!8mMBlIZH_Vy#dG(u zi)`x_BV5N;a7fGDn&d$0o5;bLQrD_F>u>S#`5e7H_ literal 0 HcmV?d00001 diff --git a/icons/src/en/mtlnovel/icon.png b/icons/src/en/mtlnovel/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8fb24068f49618fe6664ca0e9770c335da5489f4 GIT binary patch literal 3746 zcmV;T4qfqyP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3#rmgOq0h5s{(8iHv=GaMSR)|;AQK_E$RR^9#=-?!WZA z_k%zeQ=dP6r9b04{qpg`YYjiX_PhE#3H6!idGMMr+RC=t`fMcq;qLe8nW*XA$gP&o zrjEzd`3yX!Jb!zJGoOt6k=?t`9jSoQ5*CUfX!P+q=XzTZ@4rq@;C#hu@z>5t!FnIDX3{P2O7AA^4&{TNJ)N0P_Cb zc3vRwRrl6=cRghg&5uW2?uE`le=lH9@w}Ef3V%YooTG76mYGn#u6YfP>6;I*vYk(U z`R=#ZbDe%-VhS1x*AOPOSYM4Lv@jvY$7F}!p~MzftZ+7ix)|vWZ(ICXx1IH-udKX0 zLxX2Bqy49c`(F?LUYN8^^t%I){}mW5rx|ACNwDh^8_`yttXoU1aW17nIdW04Cud z{&qL4Q26!LF@?m04`iJM$7N0Pk&^b?oK-Mqokw#;eavBB(aa(FNZaDNmpPYT&+=$> zKTvQrCrySxD>nceWzuVYK(#_2a{t^ zk<8a)t-OX#YrW@nnu(8}(nIh}^K{>rw&k@9?U`^VbmAcH5Lrzt8Q8kS_o!3BLbc41 z!}euM9oRW8+pd?6U}$85xnsR;A7cr~g^M1>8Y1p7$98sI&dHTE4_k9dnaWcId#ZzYV{ zx=I+6X{|P?Ni*=47Arm#(VemQx2H|0WOhL+!B9tVsmwJHZtP2W0K!1oC~8PDBSp#} zVA#6)W=rhr*^-8{=*U7&G~f}}d$j=e*uy&CGql|yEDv5E4iYzlwHxmwuW zE2)RK*j`?9eC#$+`WZTg7Ch%V2hoUX!;*nSID>kI$V5PC>7(W+pl0{RW-vC(*v-8N zRYqs>2QNUyHIA=0+>edqK^Dj>vz={q>Wxg1rX;hHhY+A-T5sW!CzvjZ(ln~z(+fbC z8q?_DMHxI&H_w}z@w*m49>C!#?z`b|l1#2Kspy4dxk&c7o~4*);Z9Brzas69wSR%M z<&3lwE)!4RFI9_?V6&h@$eYCqx28V8xB_BAQpVFU_mS~3oFoIDctkWPj25vFO!RpT zh)w{FCD_Xp5I_X0QpT&tr+q;Xa-?=ZY6p@`MKGpxrfUaqcH1lV6J|FG)Jy4l2@Mdj z6%&`c(VL;{UNFbMhWVb}{d1Ual-&zv+o@8~XlZ1dba~w<1Ts99v6`c~n&+i)AwW34 zQY$e*R@_XgrR-B4#XxQ&7HsLOpDY~ulLFG&z5!+pn|Y3+%d}V`pH6oXf#{k}rJHyL z@rWe2`bwybo!N3Oi_M=A?NeTBBau{=>HBp4tH2*+pCqx_h zsZs%gw&Pq5zHqC#?8?-oFa>v0%AI@6Y;!uc(v`*2cqM#M=v1}1<`dstFud&j8Q?pZ zozx-k!O&vn#=CL5%omSAJC4t|zjB%%_>B82r+NE~ISbhKUEJL`>0S{x=|n7SQA`l0 zRNcoDs*duMX*dZZ$W?e;=ho9-MhByPS&zi1O(~I&s!Gk=5k5`tb^8i`JP;GN`r=%~W=$ zNJ-l`rZPeDxJRu@Xw*mfN9Hg!j>eaGZwGR9UkU@s3 zYS`tgIX!S4Pni!X5L~zP{&v^DF9`-J0$t{As2|HB2h* z&Ytlxj?{;*GHCyOB~O&Snuf*;m2a-@XAl1L`u#-aw8HoPI^O$!;H}Fa+unDd-*o@n zmLE*?TJOV(O?t%a{{kP{6k=|K^uhoD0fcEoLr_UWLm+T+Z)Rz1WdHzpoPCi!NW(xJ z#b47(i&h-$AmWgrI$01Eag-_+!9r;(wCZ4T=@&F}3CNWb_ zW)`#X9AEeF@%1jov%Js!Ir^1?$pD{7JjZmyBHkdL*|c=d`@|7emK5T1;&Fp6Nc_lk z+2uFRC5Hu`88NcydEyAMSn6WAi&@!FiKmI9imFk*kaJn#yv13q)>-?W{Dt9ywvypG z%@HK9gd|cBA)}58s<05FRU^ejn)c%!{$a_@99*t>dpXf!R;e8yzir1Pp8g7uOw4-UBXofT1T{ zG9*Xx(-ewD;QfrgDGvz2o4$tWs-EL000AxNkl!mIYiyJyO zgapvYpWFR>XnRZ74q8H2zfbp`bAIQ1&!2mLzaQKKA%tBBp$Z{1v3<}&KJDBOLI{fx z;*3Z=&Ilna@q&+u2ZymJ5)UZzm`VUhp}uIO2W2wQv91!F?!SUA1bW~u0Ri;~AExSH z$(FqPe!Ii@%Niy?HcMofOuYW$6XfsA4x4nyK#f5Fc=y_Dl#}pe z3ask^J|FdRe9RxC>(B%1Uu#T&eKUurCV!{-oQGd;%x)U|)?bU9JnxAcJPz!pjkK@q zwHnV~FD&!uCqFPadKEo73j^Q%=*M>U5+C1MijXhby&;1Q3G}|KaJA(yPgybyS)=C~ zr#}6j+w+ki3;!(h&SzJs`RW&zL{RovrWwz%3f^m}N`iohH8@bbmkX~wM_@D> zYy7kl;F&KbV{9+f9^m;yrDVuv03@WXx8Pn>Rg~~$`w`wM$&1mo6yz}dY86Knn-M(3 zVEYIF?Aet~&+(`E_Gq~wa~&?`qZ7|kye~h-UP`6~BHj>$plKRqWo5xdW)qGlAK^yP zL;StGioK{H%GU4qQ(9V@P(le;!0mR^)6>J^;-VodEZ7|tT-S952M1|tYKl}q+Qu1h zI-S(j)#3GeiJsSW-tIjMmmx z+S}WinVE_GY;$u{N1(E@l7@zc;Pks(6c!dTGBSb?kpZ?^t=mr^JWSQq)eH;_;C8zW zox|b4>2w;ikGR@7+_+6I2MsF`eLqh;$Wo4z7Ko~ZgjsE_AR8@_# z*>VMh*nGjt%1YFGPEHP;ot;cfOrR)A(5Wf$yyRrEZ)r1Ml zGB6cB6^RW>P+MDzqA1An{W<65<evHu5Gv$S7M(|JAr5ALZ17;IXY1ONa4 M07*qoM6N<$f}u}Pe*gdg literal 0 HcmV?d00001 diff --git a/icons/src/en/novelhold/icon.png b/icons/src/en/novelhall/icon.png similarity index 100% rename from icons/src/en/novelhold/icon.png rename to icons/src/en/novelhall/icon.png diff --git a/icons/src/en/novelpub/icon.png b/icons/src/en/novelpub/icon.png deleted file mode 100644 index b9716bdd2504e88435dc51270f7b5aa2210b9fda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2827 zcmV+m3-t7fP)0B{sAPDvUbyMZ?g}x_1LqPzZZgjZhiCREK;Cwq5O<{EZbtZe zGeX@(UY_rb&^mm`ijn&&Si=r3Pcz6>`gl3eK2S+JgJ!UA2>$wggAq<5<*%XlP?`@B z*|tN>8$O8@zuED69)*z z>O361wD(?sd^%AYz6*zEHZpwIw{{lu3Lk`Pk#+`6BMdm%tt%T|>q9RQEW@`5@A*R1 zzG`?YK)#aljWEUqC#Qt3{~zQka31=>Vb}({RzKYsk?&6_~|KYsk6|IwpI zU%!40m9t^k{rmTyJbCi%+qY2AAP`x!Xi>d-^$HXykS$xb{Q2{*TD8hL;MA#8*|TTo z>8)G0-0jJ)j;7DJWX6mcb?Ve9Qlto0<;s<-M2Qk($BupW?3p__8#F*ij~*>ms#Kgf zaY~jf89#pf=+UG5`};R-+SEE`;lhQ6VF1v(ckkR3Szs}E@Zcs*nv^S7?%1(oKY#w5 zJ$rVJ964&#sIheE(lcky+`M`7(4j-knl;0cV#SKxxN*aI8x9{nJbCiuE?v5e8#m6i zG=JpCk+f;kCP>j}I|p#*7v%8dz8ZtyiyJnAN&KBlGG)qu0RvvVc=6@Sm-6MyGpu35hTp$`cV^`eA3o&ClShkl5EmFk zV8fjV5hAcXU#Cx>9wkbY*s)_{S<<9Q&z(D`Vc1cnN)bdIuU)$qH*Q=lvU>Gu7XVtbW=-VC zk)g3dx=ouldeV?wq)3s{r%%sb z88c>l`t&J}V2aMxpg{vghvGeA#E3h0?sR7Hb?esQU8ZoZ%a<>^08rn)eVK*?iifx^ zYSgIEhlMcIWFuh+YS?}6-aT_JV#H>|!mC%W%ua-Zi1@Fgy?y(Zp5425j~+ex`t|G9 zeLsErboJ_0grC9c0SkNpm!U8sC^+b6k=(g+3m_4S#s|J)D(cCA|2P^+R`B6$^*n$6 zT;m4~8l)BS=FQ8~2M->|w%`Hk(W3{`q{q-TS+ZnkQ1Rl$!3aYuR;;LOGJpPjJiu3_ z*w3FoPn|loaN)uzI?|3>?cKXq3zCWXnkrSQlqpkg*sy^R23DOGj!3W}CYgx2#0XCj zVET_AKaLL|1q;GxrgZDpjsElJ&ohj;!(m&tY!TOpcLrq1l7)!t)TtAil{j(YR;^m` z6osl>xpE>$8!}{wcC1;mrT|KlCJiJ=m@pwoX|-SgTDx{FF~uBIX5+?<3OAGpD+#f5 z>C)i`hIQ@QmDPLp>?!AW?AQ@=F&gqOUc5MU>ePTGpAduipL25BlP6CyxNhCL*osEJ zfBzm^aX!$qTK)R&B1MXvIdkF$iVPNnK|~gU$nGs$wv=+yk9(3NNkSH*heQU! zSz*|)VZcG+*WrIECqLjg4DH>H(FaUuI7I1!s4jnp_X@Cv+ zSppNWg8<=FvSbNU#*7&QIzWKBljex23Kc5AxQiDr@^sRqNgNWODVoIaj~_qw z@82JQ*b9HKEW6+ac4RL7kO=I$ckiw z7hgdTp<(>??b|Vc9#rh~>C^P!CvD0RHgDcc4^+T@dUovC;cTG@Z^c6n!%0e)F3lkU zV*L2=1TAME3&3`KNbE=^ln%fbEx;Na2zJncr#oM-RTd7hdJXx?{L4QXh z4as!Y!KEOA4+I2JZ?#I%M1xQlE?lTuwJM(pBAB8i!)nTC_?4bfqef|b=FFLu^5Btr z2tx$~{}N^NKwD=4LL(`lL4+;&ia#SdTJz@3_wV1&`8hd$9zJ}y2to`?oADUN;i95N zi+1kZ8TA1mj3#GmWf+t%Uq196zlnOulP5>Q>8Ao@<%0(g!X`MYP+G8HfoT=}1OlCG znl)=y@P)Q>=FGtoYh@tyRi~Nq@V7KuI!nVsLXw`lckj9k5a|Hbp!QK^!OSR*hPaFv zF+wVfHkT<=hC^a5(x{1;#SH+(#ew8FGzIvWXqFqKDprPQGL*T63KiPAbt_z8mP|zB zp&^e5>JukUSgis0AiL!_)6Hq z5uTDO!HAj*>@^f5teDZDM@5i=`m(=zf+}#KGK7_ zsqzROAe>K9V9v~$GtEx!gm4~!SQ;lFYzGb;KvSbSn#hR{i7x_5_EAsyIT}KslecTv zjunU+lpd9lt)xqH7eoQPln??bG><5kbYN8&zh47PIPToJLk|_NdeBo-t1~bf5D{JE}t%}j)2vry> zn?0xu6~D?tYokiwUgE<0AntyMKjoq|{sF66wQ49dp4V+a*BmN0E)!&59^p5urc%ZA z?%kUb5vJ1k=00fs$a;?;km%NA)HAR8bXAR8dN*#Ox9 zg%Us^_}eu$gX|Eq0Seg`W@7FC{rw>O&vn@$<~D#r@UH`g9f0iD9d@$;vH`LIvH`LI dvH=QH?SE-~+n2jc$guzb002ovPDHLkV1m)IPiX)E diff --git a/icons/src/en/novelupdates/icon.png b/icons/src/en/novelupdates/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..78c0dd481dcbb019066b791389cf01b1d0ce9202 GIT binary patch literal 4124 zcmaJ^2|QHm`=4%glXPXL%{1Xgm@_lRFp*`(n6X62zMH{d%oxL1q8cGdizHjLiJ=r( znow5^4M~v}$zOk%RRi)76h5U@}o3;()XS zENK{$KN%lIC)q|Fvh#@w^wA|k3=V?zBG5tw6cWP=96<>R4n;@kL)P@7h4WQ16arp@ zFaq@vr7X${6u=_D{x6VUJhv|(UvElrpfpsS^;4u%6T01AUc0h9&|KqFCT00#bk zL4?-mL|?QG7Wdtj@J%1$&tTBdP$-kh)MO$wsdPUmOjlPI3c#UoxP}m+5gHlH@QTm~ z4&D1h1C|u(LnqT1WNI*YRil?THH@JT5qkR95-2oF%fA%|hkg%~Fl5jOFB%l42|y{7 z)pf0*Lm4)t|8wJ~=uo>z8VPDc3Z;h8eT4hryZ48%Fn0gj&?->q4cdxM7H*1H5SHo_ zMj-_=2v~iHkfTW?6VU(`Fw#XC>A(>vZ4)F6W{kvY>)_yUT_g&D#A0-Q==hnemNp6n z!vFwQN5>cjGtt&T!BHj%I6?;t19Sik@I#gm9Ln$t_96YSOBUK)lQqWS{--P&LnnDL zsB}9jHRwkMSo>2M)KGsa4UDlxYQn${!$;0k6duP5y~} z6bg<2w6%<301CCXZiJ38&Ipdh07wjAWQ2fxmnHrrW-vetVPt|q!eRdBFs(ADJl zw`BQ25@z7)^zYOczWiN0q+nsi(1oSJXDNe0ATbL9*2pfRYvM{YQ3h*V?E)n~mFQ*KKLhN)Z9vH5Jh zNyu@$hGP`$gf~|A;Az>BM2G76J?blB&;$1 zi3F`N>OgBMevVvI0ha#{q@ni(k@?HXxEp&{3h>w@m1;c?nK71{)P`iYn}v9#(=W6v z2}*svTa;y!=S5ZKJB?0FzB0YQL{Mw z{w}+-YiMHXv%qiV_qf;L)lb@c3wO?L{hX>Y87A54R->15o8zdna|n(Qb3;KrUO$>i zSM)&Jly9E|sE=HZtUQ_0k7~OLHGh_v8G_yFu4yB;P~uYdv?jLoimG#kTJ-HExXa}0 zifrbC@hq1XymXpMzaX!i6;F`yHnR#`SPVRXm_?_=)-)|n_xgmjJ(^8u4!S?QjTh0@ z$k@q0Z}6ZmA+Wm2pc02!X78YK5)zgs+OwyNCdWfPv|ht4^F0agPb(?v&GlW}F^ko7 zgPdiy_D!ej*N)a*i{CQD!Eft}IMD>DbuXCI$aH&~Ey9T)!c`VtjCqhxJs7!_G11_D z_l@tFQfECViHk7zhzZ|fQiR&Xj*S_RVP<|i>D~xzUeqUG;@Rp@&AvYMEgN=FXYeyO z*PUZ}{_@+E3c*X{GYyo+IAoZ1f2Z7HBB2P#<3qf-;!FapG1ykv`*%O}D zqjL)*-Rc(+2M|~GwDTGdr+vK8-&yke@@!V#)NOqn06ufb#8@(U?$|7n7eyzKv0}M8!i573y7X%l;K5PRNIx3PZ z_6(&-E2NCF!?QmiiOld(A9fMm`%wJb^HVo4rk4tyYv~Rxv~yHQ#0ro8k|9l|!Cz3~z;GVYNt*HdrwY7sb16>`+}B zTF4Eu<;jm0a`xw)BfnB3`y{_JEb8hphn9Sl7M(8~6iskknfy~wQrsG_{|)(--{Uh^ z!Ef#A`GYsNo69AQ1lUvzDldG?R3IlL52ejU{TkCFh4eesF_TfG$8p7Rq84__khrc! z?%~b;@4svoR3C|MnJ=;jVK*YPSWjgHA8*vhONA}56m;WVUf;3ruATAgSzc!)&VGbD zcdtByE*_!0d)m{2@ao!)-xu+*3Np<|i7wi%3vJVFW$&(BkqY~z!i;=$pyxo^W5L{= zTtk4^iyLi}4|e*M)#$k|P1c3ZFIswi7`!b=ty(j|wEmukZ!v{smH*&aC$voaj+=>z z>R|*~!)9;HG2Y`{-cA}4hhWYDv-`MR*BrJZFUcaELeZHJv|mas11%m64df zXJVMRrtw8t9@g%*$JIr_3FFu_@eS36y-kPbzH&G`G=E0X-R<67Z**o~=Dc6j!om$L z{evicGQtG^218@T*Gn8WEwDu<6-aA5oH#IlpsJ)pFuR~ETYY0cJh%5C@8BQSpIDze zlbJ72?>_V}c(++OTgAKcUFKS3(hoT>sRKDL_K{(SV!NUPv9Y$jQ^ULEJoKu{ zyS(qekDZO1o-cWL^aK$ts`9`CZDzv7EE~SGOF!Xtvn>A0@L<|A^{1cCkD*Npc(2Gv zZxNOAJ))^!Tt)czPZ2J$!O#G7TvFBd@4${Eypp7^)7kvz&!;xwXQXg|ytlYu`eX&S zyC-b$$;N!d7J4T=(?S%vtxnRo^ARRpc!cfCjr`mi@4zp&DgQE9{?keG#ycr&ng$#A|MHM-$*3uE2G3tmb81$#6Z0=V|xLfHA;hR(=SPMglC=^V}!SLeH!?3ow;05wLaBSs_p@R zqV=~In|U|a`8$)J;m5t?3Cx;~x%t=mc52sL-SiPFpPC$q)QQM*=ZG=ZW>;CCSz;Sm z%SdL=SUVXBvvRMEM;jMuAm0#JH5R{t8tr5Lzf5YC*^{@&V=AuzCr_mrM+1Bv6we8~pqLb$B z+qxa#@k!=^{Vk_sl&p4icrH2gEN|kL9tXU0u^C9GV?W*v=VvA!4CWi?nutAT}wM5R<-bF!aWQV^wJJp0nYJdfSe zapDag6ey+QtroH(rPgFVGS}k99$#Ko>*Qp#_)Z>}wOKigFtu^y+s2QllV{upjK`!H zcy5@v>}8pu!NPv0M@!=u&YV&eT(7+5`Qf$SyZ+9CJEc>LB)5KRrSv0{=Lf8Io8?2E zgt$I=D1z@C*g%$<(;npeFUYg?Mn!h2{3~>5L@9+%FW< z;56rROdwg(kxy)|f)H+Q3qx01P9I~8v`joZQ=-6eYK+L;*@BWb-t&BMsQO6fxuExC z|I+g8Q_`DjpDuk_N2pMp|Mr$}$v|GKE!*}9aKrIuh%u8}+sd=y3 zl9zB7Gj825%dhEAO;)?DG=DiwdN9yeZpd$YyN%ee>oZz%=a7FusScr7gE8^N)-JK$ zX}egds#GmQ87i6AkPYt`xBpNHxi^u;m033Q^qi}Ij}92mZaI}GrmPMzmYmojhe-Hl zYI)??5NA-Tt0-YuROM|_mE3}f)IGZ=W;5&lZkhk1z5Pea{O`T=|7(Q*YuEh)`OmKV o__y9XIfc3=kjkm2D;woOB>QVAN2R-GR{z%tCWo*k#-6Ny0l8{9bN~PV literal 0 HcmV?d00001 diff --git a/icons/src/en/wuxiaworld/icon.png b/icons/src/en/wuxiaworld/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7c815fcd4d473604f61cf9c28a829eb49ed81459 GIT binary patch literal 1660 zcmV-?27~#DP)+pyX4HeQTG{#!EzDs5r5Ox?*n)nFuffx zJqI2Gng#R+0P*R;biGRN0eT*&e_ceo2U8`(e*`GW{VzRuzx>4_z0(GQO^pt?2jCq* zBm4(_0I1<-gnAzQazOc*AEW>QE&Fm{upaoz?Zuz zXaf!z9)>WEYi3I?LU#b_2%s1_%a(f)Y5|V=_}bvYn5La@&4C6$odEN|Eo5QzY$GiH z22jxl7dX1GT2TnUBh&`e^f3!qNKi?P@h|zV12uqZ0hlKjv=qx^6be59sD?hqNJSt- z>qAT~C~l16jQ1mS1gNI|yzpg07hYyrjwyP(uzNU4|l219VYp|>n zp$~wn8I%jQz+`<~Q5V0DG26i>BN>w{yU}@ag7pBZWj4c+YJDPgZzqocueD?|KFpXl zX74|55NoE#o)d}hRxo8d=s4KUAV0O&8<<3eJLTuL$Xjey_EhqL|(FrV$9 zPbVAA3oAc_$QSVgFwZUhp*$*i>1xP=hk0?--w8Fq+%VLSb7?D;aTZZ$rv;LG(%%T5 zU^e%S^p(K5X0WHA>J1I;tfi;`q__vz^aaEQrx48MK~tfQk<}a^g18PKeHcS?iH$cB zi+)MtYamqsUyl6%pgzofLy1j!Dp8Tt%wv#s{R5%{7>d3LG*I)r2VGMV+$0_z)<=ZOLC14mLYnil%URu2z#1$)f#~{<>ySH@g}d4 zf6g-FGS$&5%{BcufmPLEb2EYJX41wv^Pw-N7ze5&NVEJJchxAdiu$k&29HXV*D%}s zYi?q{spzcU(oBhI=)VZ;bi0N{g_;UhI4FAPs!}fH=+q{z(8JnL>b;h2{f)qela)O^ zWlkZE+ZG?Q;;|yVGq8u^egdN|I7IAe z?&#yM8h~w4gEcF0I_Mo$702j+w#%AsBbeq!0`}Qjktd_Bg`wan)!wbpa+>rFxDs@k zcxl#sfMgZz?cRb-yOwr^)5a*0m((E`s#2+0%f7L*@|z&@=+ri%sdktRIGmt@_2vQ$ zq#uB#X#fagd=E^Jk0=iXOY4?dKP&YKfb&-h@DM2SRHLA-X^5Z;LO%!0=>?FY$eZ`B zs7oRJa-j==BBG%WSA$UGQFnV%ZzC^A{TKij<26GFCa9bhXP?#|Vp>nz>8~FH@Ol(I zU7NDd`kNmPDO_Tbi{6~%Macr?xm!rAsa~$W zux1TH%j4T`ouO%LulX{7e_I)N`W&5Ye!iL^4Z08DE!(aHl`+4UDpiu#?PU8bLe*G%tKzeQ{6y3PC&od_QtaU)+}eK@fKVqGmVr#eH?ry>DCx zh^}4M7Z1dn1aSo*uG&R?aa*`aX#Cj&s10000 { - const novelName = $(h).text(); - const novelUrl = $(h).find("a").attr("href"); - const novelCover = $(h).find("img").attr("src"); - - if (!novelUrl) { - return null; - } - - return { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - }) - .get() - .filter((sr) => sr !== null); -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - let novel: Novel.instance = { - url: novelUrl, - chapters: [], - }; - - const result = await fetchApi(novelUrl).then((res) => res.text()); - let $ = parseHTML(result); - - novel.name = $("h1").text(); - novel.cover = $(".novel-cover").find("a > img").attr("src"); - novel.author = $( - "div.novel-details > div:nth-child(5) > div.novel-detail-body" - ) - .find("li") - .map((_, el) => $(el).text()) - .get() - .join(", "); - - novel.genres = $( - "div.novel-details > div:nth-child(2) > div.novel-detail-body" - ) - .find("li") - .map((_, el) => $(el).text()) - .get() - .join(","); - - novel.summary = $( - "div.novel-right > div > div:nth-child(1) > div.novel-detail-body" - ).text(); - - novel.chapters = $("ul.chapter-chs > li > a") - .map((_, el) => { - const chapterUrl = $(el).attr("href"); - const chapterName = $(el).text(); - - return { - name: chapterName, - releaseTime: "", - url: chapterUrl, - } as Chapter.Item; - }) - .get(); - - return novel; - }; - -export const popularNovels: Plugin.popularNovels = async function (page) { - return []; /** TO DO */ -}; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const result = await fetchApi(chapterUrl).then((res) => res.text()); - let loadedCheerio = parseHTML(result); - - const chapterText = loadedCheerio("#contentall").html() || ""; - - return chapterText; -}; -export const fetchImage: Plugin.fetchImage = fetchFile; diff --git a/plugins/english/NovelOnline.ts b/plugins/english/NovelOnline.ts new file mode 100644 index 0000000..0de18b8 --- /dev/null +++ b/plugins/english/NovelOnline.ts @@ -0,0 +1,115 @@ +import { load as parseHTML } from "cheerio"; +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Plugin } from "@typings/plugin"; +import { Filters } from "@libs/filterInputs"; + +class NovelsOnline implements Plugin.PluginBase { + id = "NO.net"; + name = "novelsOnline"; + site = "https://novelsonline.net"; + icon = "src/coverNotAvailable.jpg"; + filters?: Filters | undefined; + version = "1.0.0"; + + async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { + return []; /** TO DO */ + } + async parseNovelAndChapters(novelUrl: string): Promise { + let novel: Plugin.SourceNovel = { + url: novelUrl, + chapters: [], + }; + + const result = await fetchApi(novelUrl).then((res) => res.text()); + + let $ = parseHTML(result); + + novel.name = $("h1").text(); + novel.cover = $(".novel-cover").find("a > img").attr("src"); + novel.author = $( + "div.novel-details > div:nth-child(5) > div.novel-detail-body" + ) + .find("li") + .map((_, el) => $(el).text()) + .get() + .join(", "); + + novel.genres = $( + "div.novel-details > div:nth-child(2) > div.novel-detail-body" + ) + .find("li") + .map((_, el) => $(el).text()) + .get() + .join(","); + + novel.summary = $( + "div.novel-right > div > div:nth-child(1) > div.novel-detail-body" + ).text(); + + novel.chapters = $("ul.chapter-chs > li > a") + .map((_, el) => { + const chapterUrl = $(el).attr("href"); + const chapterName = $(el).text(); + + return { + name: chapterName, + releaseTime: "", + url: chapterUrl, + } as Plugin.ChapterItem; + }) + .get(); + + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const result = await fetchApi(chapterUrl).then((res) => res.text()); + let loadedCheerio = parseHTML(result); + + const chapterText = loadedCheerio("#contentall").html() || ""; + + return chapterText; + } + async searchNovels(searchTerm: string, pageNo: number): Promise { + const result = await fetchApi( + "https://novelsonline.net/sResults.php", + { + headers: { + Accept: "*/*", + "Accept-Language": "pl,en-US;q=0.7,en;q=0.3", + "Content-Type": + "application/x-www-form-urlencoded; charset=UTF-8", + }, + method: "POST", + body: "q=" + encodeURIComponent(searchTerm), + }, + ).then((res) => res.text()); + + let $ = parseHTML(result); + + const headers = $("li"); + return headers + .map((i, h) => { + const novelName = $(h).text(); + const novelUrl = $(h).find("a").attr("href"); + const novelCover = $(h).find("img").attr("src"); + + if (!novelUrl) { + return null; + } + + return { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + }) + .get() + .filter((sr) => sr !== null) + } + async fetchImage(url: string): Promise { + return fetchFile(url); + } + +} + +export default new NovelsOnline(); diff --git a/plugins/english/lightnovelpub.broken.ts b/plugins/english/lightnovelpub.broken.ts deleted file mode 100644 index 9419dd5..0000000 --- a/plugins/english/lightnovelpub.broken.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { load as parseHTML } from "cheerio"; -import { fetchApi, fetchFile } from "@libs/fetch"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; - -export const id = "lightnovelpub"; -export const name = "LightNovelPub"; -export const version = "1.0.0"; -export const icon = "src/en/lightnovelpub/icon.png"; -export const site = "https://www.lightnovelpub.com/"; - - -const baseUrl = site; -const pluginId = id; - -const headers = { - Accept: "application/json", - "Content-Type": "application/json", -}; - -export const popularNovels: Plugin.popularNovels = async function (page) { - const url = `${baseUrl}browse/all/popular/all/${page}`; - - const body = await fetchApi(url, {}, pluginId).then((r) => r.text()); - - const loadedCheerio = parseHTML(body); - - const novels: Novel.Item[] = []; - - loadedCheerio(".novel-item.ads").remove(); - - loadedCheerio(".novel-item").each(function () { - const novelName = loadedCheerio(this) - .find(".novel-title") - .text() - .trim(); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = - baseUrl + - loadedCheerio(this) - .find(".novel-title > a") - .attr("href") - ?.substring(1); - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const url = novelUrl; - const body = await fetchApi(url, {}, pluginId).then((r) => r.text()); - - let loadedCheerio = parseHTML(body); - - const novel: Novel.instance = { - url, - chapters: [], - }; - - novel.name = loadedCheerio("h1.novel-title").text().trim(); - - novel.cover = loadedCheerio("figure.cover > img").attr("data-src"); - - novel.genres = ""; - - loadedCheerio(".categories > ul > li > a").each(function () { - novel.genres += loadedCheerio(this).text() + ","; - }); - - novel.genres = novel.genres.slice(0, -1); - - loadedCheerio("div.header-stats > span").each(function () { - if (loadedCheerio(this).find("small").text() === "Status") { - novel.status = loadedCheerio(this).find("strong").text(); - } - }); - - novel.author = loadedCheerio(".author > a > span").text(); - - novel.summary = loadedCheerio(".summary > .content").text().trim(); - - const delay = (ms: number) => new Promise((res) => setTimeout(res, ms)); - - let lastPage = 1; - - lastPage = parseInt( - loadedCheerio( - "#novel > header > div.header-body.container > div.novel-info > div.header-stats > span:nth-child(1) > strong" - ) - .text() - ?.trim() - ); - - lastPage = Math.ceil(lastPage / 100); - - async function getChapters() { - let chapter: Chapter.Item[] = []; - - for (let i = 1; i <= lastPage; i++) { - const chaptersUrl = `${novelUrl}/chapters/page-${i}`; - - const chaptersHtml = await fetchApi( - chaptersUrl, - { headers: headers }, - pluginId - ).then((r) => r.text()); - - loadedCheerio = parseHTML(chaptersHtml); - - loadedCheerio(".chapter-list li").each(function () { - const chapterName = loadedCheerio(this) - .find(".chapter-title") - .text() - .trim(); - - const releaseDate = loadedCheerio(this) - .find(".chapter-update") - .text() - .trim(); - - const chapterUrl = - baseUrl + - loadedCheerio(this) - .find("a") - .attr("href") - ?.substring(1); - - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - - await delay(1000); - } - - return chapter; - } - - novel.chapters = await getChapters(); - - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const body = await fetchApi(chapterUrl, {}, pluginId).then((r) => r.text()); - - const loadedCheerio = parseHTML(body); - - let chapterText = loadedCheerio("#chapter-container").html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const url = `${baseUrl}lnsearchlive`; - const link = `${baseUrl}search`; - const response = await fetchApi(link, {}, pluginId).then((r) => r.text()); - const token = parseHTML(response); - let verifytoken = token("#novelSearchForm > input").attr("value"); - - let formData = new FormData(); - formData.append("inputContent", searchTerm); - - const body = await fetchApi( - url, - { - method: "POST", - headers: { LNRequestVerifyToken: verifytoken! }, - body: formData, - }, - pluginId - ).then((r) => r.text()); - - let loadedCheerio = parseHTML(body); - - let novels: Novel.Item[] = []; - - let results = JSON.parse(loadedCheerio("body").text()); - - loadedCheerio = parseHTML(results.resultview); - - loadedCheerio(".novel-item").each(function () { - const novelName = loadedCheerio(this) - .find("h4.novel-title") - .text() - .trim(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = - baseUrl + loadedCheerio(this).find("a").attr("href")?.substring(1); - - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, - }); - }); - - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async function (url) { - return await fetchFile(url, { headers: headers }); -}; diff --git a/plugins/english/lightnovelpub.ts b/plugins/english/lightnovelpub.ts new file mode 100644 index 0000000..eed37ab --- /dev/null +++ b/plugins/english/lightnovelpub.ts @@ -0,0 +1,173 @@ +import { load as parseHTML } from "cheerio"; +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Plugin } from "@typings/plugin"; +import { Filters } from "@libs/filterInputs"; + + +class LightNovelPub implements Plugin.PluginBase { + id = "lightnovelpub"; + name = "LightNovelPub"; + version = "1.0.0"; + icon = "src/en/lightnovelpub/icon.png"; + filters?: Filters | undefined; + site = "https://www.lightnovelpub.com/"; + baseUrl = this.site; + headers = { + Accept: "application/json", + "Content-Type": "application/json", + }; + async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { + const url = `${this.baseUrl}browse/all/popular/all/${pageNo}`; + + const body = await fetchApi(url).then((r) => r.text()); + + const loadedCheerio = parseHTML(body); + + const novels: Plugin.NovelItem[] = []; + + loadedCheerio(".novel-item.ads").remove(); + + loadedCheerio(".novel-item").each((idx, ele) => { + const novelName = loadedCheerio(ele) + .find(".novel-title") + .text() + .trim(); + const novelCover = loadedCheerio(ele).find("img").attr("data-src"); + const novelUrl = + this.baseUrl + + loadedCheerio(ele) + .find(".novel-title > a") + .attr("href") + ?.substring(1); + + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const url = novelUrl; + const body = await fetchApi(url).then((r) => r.text()); + + let loadedCheerio = parseHTML(body); + + const novel: Plugin.SourceNovel = { + url, + chapters: [], + }; + + novel.name = loadedCheerio("h1.novel-title").text().trim(); + + novel.cover = loadedCheerio("figure.cover > img").attr("data-src"); + + novel.genres = ""; + + loadedCheerio(".categories > ul > li > a").each(function () { + novel.genres += loadedCheerio(this).text() + ","; + }); + + novel.genres = novel.genres.slice(0, -1); + + loadedCheerio("div.header-stats > span").each(function () { + if (loadedCheerio(this).find("small").text() === "Status") { + novel.status = loadedCheerio(this).find("strong").text(); + } + }); + + novel.author = loadedCheerio(".author > a > span").text(); + + novel.summary = loadedCheerio(".summary > .content").text().trim(); + const delay = (ms: number) => new Promise((res) => setTimeout(res, ms)); + await delay(1000); + const chapterListUrl = novelUrl + '/chapters?chorder=desc'; + + const chapterListBody = await fetchApi(chapterListUrl).then(r => r.text()); + const loadedChapterList = parseHTML(chapterListBody); + + + const lastNumber = parseInt( + loadedChapterList('ul.chapter-list > li:nth-child(1)').attr('data-chapterno') ?? '0' + ); + const lastChapterUrl = loadedChapterList('ul.chapter-list > li:nth-child(1) > a').attr('href'); + + if(lastChapterUrl){ + const chapterUrlPrefix = this.baseUrl + lastChapterUrl.split('/').slice(1, -1).join('/'); + const chapters: Plugin.ChapterItem[] = []; + for(let i = 1; i <= lastNumber; i++){ + chapters.push({ + chapterNumber: i, + name: 'Chapter ' + i, + url: chapterUrlPrefix + '/chapter-' + i, + }) + } + novel.chapters = chapters; + } + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then((r) => r.text()); + + const loadedCheerio = parseHTML(body); + + let chapterText = loadedCheerio("#chapter-container").html() || ''; + + return chapterText; + } + async searchNovels(searchTerm: string, pageNo: number): Promise { + const url = `${this.baseUrl}lnsearchlive`; + const link = `${this.baseUrl}search`; + const response = await fetchApi(link).then((r) => r.text()); + const token = parseHTML(response); + let verifytoken = token("#novelSearchForm > input").attr("value"); + + let formData = new FormData(); + formData.append("inputContent", searchTerm); + + const body = await fetchApi( + url, + { + method: "POST", + headers: { LNRequestVerifyToken: verifytoken! }, + body: formData, + }, + ).then((r) => r.text()); + + let loadedCheerio = parseHTML(body); + + let novels: Plugin.NovelItem[] = []; + + let results = JSON.parse(loadedCheerio("body").text()); + + loadedCheerio = parseHTML(results.resultview); + + loadedCheerio(".novel-item").each((idx, ele) => { + const novelName = loadedCheerio(ele) + .find("h4.novel-title") + .text() + .trim(); + const novelCover = loadedCheerio(ele).find("img").attr("src"); + const novelUrl = + this.baseUrl + loadedCheerio(ele).find("a").attr("href")?.substring(1); + + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + + return novels; + } + async fetchImage(url: string): Promise { + return fetchFile(url, {headers: this.headers}); + } + +} + +export default new LightNovelPub(); \ No newline at end of file diff --git a/plugins/english/lightnovelupdates.broken.ts b/plugins/english/lightnovelupdates.ts similarity index 68% rename from plugins/english/lightnovelupdates.broken.ts rename to plugins/english/lightnovelupdates.ts index e73c784..01b5c1e 100644 --- a/plugins/english/lightnovelupdates.broken.ts +++ b/plugins/english/lightnovelupdates.ts @@ -1,25 +1,23 @@ import { load as parseHTML } from "cheerio"; import { fetchApi, fetchFile } from "@libs/fetch"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; +import { Plugin } from "@typings/plugin"; +import { Filters } from "@libs/filterInputs"; -export const id = "LightNovelUpdates"; -export const name = "Light Novel Updates"; -export const version = "1.0.0"; -export const icon = "src/en/lightnovelupdates/icon.png"; -export const site = "https://www.lightnovelupdates.com/"; +class LightNovelUpdates implements Plugin.PluginBase { + id = "LightNovelUpdates"; + name = "Light Novel Updates"; + version = "1.0.0"; + icon = "src/en/lightnovelupdates/icon.png"; + site = "https://www.lightnovelupdates.com/"; + baseUrl = this.site; + async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { + let url = `${this.baseUrl}novel/page/${pageNo}/?m_orderby=rating`; - -const pluginId = id; -const baseUrl = site; - -export const popularNovels: Plugin.popularNovels = async function (page) { - let url = `${baseUrl}novel/page/${page}/?m_orderby=rating`; - - const body = await fetchApi(url, {}, pluginId).then((r) => r.text()); + const body = await fetchApi(url).then((r) => r.text()); const loadedCheerio = parseHTML(body); - let novels: Novel.Item[] = []; + let novels: Plugin.NovelItem[] = []; loadedCheerio(".page-item-detail").each(function () { const novelName = loadedCheerio(this).find(".h5 > a").text(); @@ -38,17 +36,15 @@ export const popularNovels: Plugin.popularNovels = async function (page) { }); return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { + } + async parseNovelAndChapters(novelUrl: string): Promise { const url = novelUrl; - const body = await fetchApi(url, {}, pluginId).then((r) => r.text()); + const body = await fetchApi(url).then((r) => r.text()); let loadedCheerio = parseHTML(body); - const novel: Novel.instance = { + const novel: Plugin.SourceNovel = { url, chapters: [], }; @@ -82,7 +78,7 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = novel.summary = loadedCheerio("div.summary__content").text(); - const chapter: Chapter.Item[] = []; + const chapter: Plugin.ChapterItem[] = []; const novelId = loadedCheerio(".rating-post-id").attr("value")!; @@ -96,7 +92,6 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = method: "POST", body: formData, }, - pluginId ); const text = await data.text(); @@ -119,23 +114,20 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = novel.chapters = chapter.reverse(); return novel; - }; + } + async parseChapter(chapterUrl: string): Promise { + const chapterText = 'unable to load'; -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const chapterText = (await NovelUpdatesScraper.parseChapter(chapterUrl)) - .chapterText; + return chapterText; + } + async searchNovels(searchTerm: string, pageNo: number): Promise { + const url = `${this.baseUrl}?s=${searchTerm}&post_type=wp-manga&m_orderby=rating`; - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const url = `${baseUrl}?s=${searchTerm}&post_type=wp-manga&m_orderby=rating`; - - const body = await fetchApi(url, {}, pluginId).then((r) => r.text()); + const body = await fetchApi(url).then((r) => r.text()); const loadedCheerio = parseHTML(body); - let novels: Novel.Item[] = []; + let novels: Plugin.NovelItem[] = []; loadedCheerio(".c-tabs-item__content").each(function () { const novelName = loadedCheerio(this).find(".h4 > a").text(); @@ -151,11 +143,11 @@ export const searchNovels: Plugin.searchNovels = async function (searchTerm) { }); }); return novels; -}; + } + async fetchImage(url: string): Promise { + return fetchFile(url); + } -export const fetchImage: Plugin.fetchImage = async function (url) { - const headers = { - Referer: baseUrl, - }; - return await fetchFile(url, { headers: headers }); -}; +} + +export default new LightNovelUpdates(); \ No newline at end of file diff --git a/plugins/english/lightnovelworld.ts b/plugins/english/lightnovelworld.ts new file mode 100644 index 0000000..7893044 --- /dev/null +++ b/plugins/english/lightnovelworld.ts @@ -0,0 +1,173 @@ +import { load as parseHTML } from "cheerio"; +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Plugin } from "@typings/plugin"; +import { Filters } from "@libs/filterInputs"; + + +class LightNovelWorld implements Plugin.PluginBase { + id = "lightnovelworld"; + name = "LightNovelWorld"; + site = "https://www.webnovelworld.org/"; + version = "1.0.0"; + filters?: Filters | undefined; + icon = "src/en/lightnovelworld/icon.png"; + baseUrl = this.site; + headers = { + Accept: "application/json", + "Content-Type": "application/json", + }; + async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { + const url = `${this.baseUrl}browse/all/popular/all/${pageNo}`; + + const body = await fetchApi(url).then((r) => r.text()); + + const loadedCheerio = parseHTML(body); + + const novels: Plugin.NovelItem[] = []; + + loadedCheerio(".novel-item.ads").remove(); + + loadedCheerio(".novel-item").each((idx, ele) => { + const novelName = loadedCheerio(ele) + .find(".novel-title") + .text() + .trim(); + const novelCover = loadedCheerio(ele).find("img").attr("data-src"); + const novelUrl = + this.baseUrl + + loadedCheerio(ele) + .find(".novel-title > a") + .attr("href") + ?.substring(1); + + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const url = novelUrl; + const body = await fetchApi(url).then((r) => r.text()); + + let loadedCheerio = parseHTML(body); + + const novel: Plugin.SourceNovel = { + url, + chapters: [], + }; + + novel.name = loadedCheerio("h1.novel-title").text().trim(); + + novel.cover = loadedCheerio("figure.cover > img").attr("data-src"); + + novel.genres = ""; + + loadedCheerio(".categories > ul > li > a").each(function () { + novel.genres += loadedCheerio(this).text() + ","; + }); + + novel.genres = novel.genres.slice(0, -1); + + loadedCheerio("div.header-stats > span").each(function () { + if (loadedCheerio(this).find("small").text() === "Status") { + novel.status = loadedCheerio(this).find("strong").text(); + } + }); + + novel.author = loadedCheerio(".author > a > span").text(); + + novel.summary = loadedCheerio(".summary > .content").text().trim(); + const delay = (ms: number) => new Promise((res) => setTimeout(res, ms)); + await delay(1000); + const chapterListUrl = novelUrl + '/chapters?chorder=desc'; + + const chapterListBody = await fetchApi(chapterListUrl).then(r => r.text()); + const loadedChapterList = parseHTML(chapterListBody); + + + const lastNumber = parseInt( + loadedChapterList('ul.chapter-list > li:nth-child(1)').attr('data-chapterno') ?? '0' + ); + const lastChapterUrl = loadedChapterList('ul.chapter-list > li:nth-child(1) > a').attr('href'); + + if(lastChapterUrl){ + const chapterUrlPrefix = this.baseUrl + lastChapterUrl.split('/').slice(1, -1).join('/'); + const chapters: Plugin.ChapterItem[] = []; + for(let i = 1; i <= lastNumber; i++){ + chapters.push({ + chapterNumber: i, + name: 'Chapter ' + i, + url: chapterUrlPrefix + '/chapter-' + i, + }) + } + novel.chapters = chapters; + } + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then((r) => r.text()); + + const loadedCheerio = parseHTML(body); + + let chapterText = loadedCheerio("#chapter-container").html() || ''; + + return chapterText; + } + async searchNovels(searchTerm: string, pageNo: number): Promise { + const url = `${this.baseUrl}lnsearchlive`; + const link = `${this.baseUrl}search`; + const response = await fetchApi(link).then((r) => r.text()); + const token = parseHTML(response); + let verifytoken = token("#novelSearchForm > input").attr("value"); + + let formData = new FormData(); + formData.append("inputContent", searchTerm); + + const body = await fetchApi( + url, + { + method: "POST", + headers: { LNRequestVerifyToken: verifytoken! }, + body: formData, + }, + ).then((r) => r.text()); + + let loadedCheerio = parseHTML(body); + + let novels: Plugin.NovelItem[] = []; + + let results = JSON.parse(loadedCheerio("body").text()); + + loadedCheerio = parseHTML(results.resultview); + + loadedCheerio(".novel-item").each((idx, ele) => { + const novelName = loadedCheerio(ele) + .find("h4.novel-title") + .text() + .trim(); + const novelCover = loadedCheerio(ele).find("img").attr("src"); + const novelUrl = + this.baseUrl + loadedCheerio(ele).find("a").attr("href")?.substring(1); + + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + + return novels; + } + async fetchImage(url: string): Promise { + return fetchFile(url, {headers: this.headers}); + } + +} + +export default new LightNovelWorld(); diff --git a/plugins/english/mtlnovel.broken.ts b/plugins/english/mtlnovel.broken.ts deleted file mode 100644 index 89fa757..0000000 --- a/plugins/english/mtlnovel.broken.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { load as parseHTML } from "cheerio"; -import { fetchApi, fetchFile } from "@libs/fetch"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; - -const pluginId = "mtlnovel"; -const baseUrl = "https://www.mtlnovel.com/"; - -export const popularNovels: Plugin.popularNovels = async function (page) { - const url = `${baseUrl}alltime-rank/page/${page}`; - - const headers = { - Referer: `${baseUrl}`, - "User-Agent": - "'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36", - }; - - const body = await fetchApi( - url, - { - method: "GET", - headers: headers, - }, - pluginId - ).then((result) => result.text()); - - const loadedCheerio = parseHTML(body); - - let novels: Novel.Item[] = []; - - loadedCheerio("div.box.wide").each(function () { - const novelName = loadedCheerio(this) - .find("a.list-title") - .text() - .slice(4); - const novelCover = loadedCheerio(this).find("amp-img").attr("src"); - const novelUrl = loadedCheerio(this).find("a.list-title").attr("href"); - - if (!novelUrl) return; - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const url = novelUrl; - - let headers = { - Referer: `${baseUrl}alltime-rank/`, - "User-Agent": - "'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36", - }; - - const body = await fetchApi( - url, - { - method: "GET", - headers: headers, - }, - pluginId - ).then((result) => result.text()); - - let loadedCheerio = parseHTML(body); - - const novel: Novel.instance = { - url, - chapters: [], - }; - - novel.name = loadedCheerio("h1.entry-title").text(); - - novel.cover = loadedCheerio(".nov-head > amp-img").attr("src"); - - novel.summary = loadedCheerio("div.desc > h2").next().text().trim(); - - novel.author = loadedCheerio("#author").text(); - - novel.status = loadedCheerio("#status").text(); - - novel.genres = loadedCheerio("#genre").text().replace(/\s+/g, ""); - - const chapterListUrl = url + "chapter-list/"; - - async function getChapters() { - const listResult = await fetch(chapterListUrl); - const listBody = await listResult.text(); - - loadedCheerio = parseHTML(listBody); - - let chapter: Chapter.Item[] = []; - - loadedCheerio("div.ch-list") - .find("a.ch-link") - .each(function () { - const chapterName = loadedCheerio(this) - .text() - .replace("~ ", ""); - const releaseDate = null; - const chapterUrl = loadedCheerio(this).attr("href"); - - chapter.push({ - url: chapterUrl, - name: chapterName, - releaseTime: releaseDate, - }); - }); - return chapter.reverse(); - } - - novel.chapters = await getChapters(); - - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const body = await fetchApi(chapterUrl, {}, pluginId).then((r) => r.text()); - - const loadedCheerio = parseHTML(body); - - const chapterText = loadedCheerio("div.par").html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const searchUrl = - baseUrl + - "wp-admin/admin-ajax.php?action=autosuggest&q=" + - searchTerm + - "&__amp_source_origin=https%3A%2F%2Fwww.mtlnovel.com"; - - const res = await fetch(searchUrl); - const result = await res.json(); - - let novels: Novel.Item[] = []; - - result.items[0].results.map((item) => { - const novelName = item.title.replace(/<\/?strong>/g, ""); - const novelCover = item.thumbnail; - const novelUrl = item.permalink.replace( - "https://www.mtlnovel.com/", - "" - ); - - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - - novels.push(novel); - }); - - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async function (url) { - const headers = { - Referer: baseUrl, - }; - return await fetchFile(url, { headers: headers }); -}; - -module.exports = { - id: pluginId, - name: "MTL Novel", - version: "1.0.0", - icon: "src/en/mtlnovel/icon.png", - site: baseUrl, - protected: false, - fetchImage, - popularNovels, - parseNovelAndChapters, - parseChapter, - searchNovels, -}; diff --git a/plugins/english/mtlnovel.ts b/plugins/english/mtlnovel.ts new file mode 100644 index 0000000..60ee5bd --- /dev/null +++ b/plugins/english/mtlnovel.ts @@ -0,0 +1,155 @@ +import { load as parseHTML } from "cheerio"; +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Plugin } from "@typings/plugin"; +import { Filters } from "@libs/filterInputs"; + +class MTLNovel implements Plugin.PluginBase { + id = "mtlnovel"; + name = "MTL Novel"; + version = "1.0.0"; + icon = "src/en/mtlnovel/icon.png"; + site = "https://www.mtlnovel.com/"; + baseUrl = this.site; + async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { + const url = `${this.baseUrl}alltime-rank/page/${pageNo}`; + const body = await fetchApi(url).then((result) => result.text()); + console.log(body); + + const loadedCheerio = parseHTML(body); + + let novels: Plugin.NovelItem[] = []; + + loadedCheerio("div.box.wide").each(function () { + const novelName = loadedCheerio(this) + .find("a.list-title") + .text() + .slice(4); + const novelCover = loadedCheerio(this).find("amp-img").attr("src"); + const novelUrl = loadedCheerio(this).find("a.list-title").attr("href"); + + if (!novelUrl) return; + + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const url = novelUrl; + + let headers = { + Referer: `${this.baseUrl}alltime-rank/`, + }; + + const body = await fetchApi( + url, + { + method: "GET", + headers: headers, + }, + ).then((result) => result.text()); + + let loadedCheerio = parseHTML(body); + + const novel: Plugin.SourceNovel = { + url, + chapters: [], + }; + + novel.name = loadedCheerio("h1.entry-title").text(); + + novel.cover = loadedCheerio(".nov-head > amp-img").attr("src"); + + novel.summary = loadedCheerio("div.desc > h2").next().text().trim(); + + novel.author = loadedCheerio("#author").text(); + + novel.status = loadedCheerio("#status").text(); + + novel.genres = loadedCheerio("#genre").text().replace(/\s+/g, ""); + + const chapterListUrl = url + "chapter-list/"; + + async function getChapters() { + const listResult = await fetch(chapterListUrl); + const listBody = await listResult.text(); + + loadedCheerio = parseHTML(listBody); + + let chapter: Plugin.ChapterItem[] = []; + + loadedCheerio("div.ch-list") + .find("a.ch-link") + .each(function () { + const chapterName = loadedCheerio(this) + .text() + .replace("~ ", ""); + const releaseDate = null; + const chapterUrl = loadedCheerio(this).attr("href"); + if (chapterUrl) { + chapter.push({ + url: chapterUrl, + name: chapterName, + releaseTime: releaseDate, + }); + } + }); + return chapter.reverse(); + } + + novel.chapters = await getChapters(); + + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then((r) => r.text()); + + const loadedCheerio = parseHTML(body); + + const chapterText = loadedCheerio("div.par").html() || ''; + + return chapterText; + } + async searchNovels(searchTerm: string, pageNo: number): Promise { + const searchUrl = + this.baseUrl + + "wp-admin/admin-ajax.php?action=autosuggest&q=" + + searchTerm + + "&__amp_source_origin=https%3A%2F%2Fwww.mtlnovel.com"; + + const res = await fetch(searchUrl); + const result = await res.json(); + + let novels: Plugin.NovelItem[] = []; + interface SearchEntry { + title: string; + thumbnail: string; + permalink: string; + } + result.items[0].results.map((item: SearchEntry) => { + const novelName = item.title.replace(/<\/?strong>/g, ""); + const novelCover = item.thumbnail; + const novelUrl = item.permalink.replace( + "https://www.mtlnovel.com/", + "" + ); + + const novel = { name: novelName, cover: novelCover, url: novelUrl }; + + novels.push(novel); + }); + + return novels; + } + async fetchImage(url: string): Promise { + return fetchFile(url); + } + +} +export default new MTLNovel(); diff --git a/plugins/english/mtlreader.broken.ts b/plugins/english/mtlreader.broken.ts deleted file mode 100644 index a1e72c1..0000000 --- a/plugins/english/mtlreader.broken.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { load as parseHTML } from "cheerio"; -import { fetchApi, fetchFile } from "@libs/fetch"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; - -export const id = "mtlreader"; -export const name = "MTL Reader"; -export const version = "1.0.0"; -export const icon = "src/en/mtlreader/icon.png"; -export const site = "https://mtlreader.com/"; - - -const pluginId = id; -const baseUrl = site; - -export const popularNovels: Plugin.popularNovels = async function (page) { - const url = `${baseUrl}novels?page=${page}`; - - const body = await fetchApi(url, {}, pluginId).then((r) => r.text()); - - const loadedCheerio = parseHTML(body); - - let novels: Novel.Item[] = []; - - loadedCheerio(".col-md-4.col-sm-4").each(function () { - const novelName = loadedCheerio(this).find("h5").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("h5 > a").attr("href"); - - if (!novelUrl) return; - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const url = novelUrl; - - const body = await fetchApi(url, {}, pluginId).then((r) => r.text()); - - let loadedCheerio = parseHTML(body); - - const novel: Novel.instance = { - url, - chapters: [], - }; - - novel.name = loadedCheerio(".agent-title").text().trim(); - - novel.cover = loadedCheerio(".agent-p-img > img").attr("src"); - - novel.summary = loadedCheerio("#editdescription").text().trim(); - - novel.author = loadedCheerio("i.fa-user") - .parent() - .text() - .replace("Author: ", "") - .trim(); - - let chapter: Chapter.Item[] = []; - - loadedCheerio("tr.spaceUnder").each(function () { - const chapterName = loadedCheerio(this).find("a").text().trim(); - const releaseDate = null; - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - - if (!chapterUrl) return; - - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - - novel.chapters = chapter; - - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const body = await fetchApi(chapterUrl, {}, pluginId).then((r) => r.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio(".container ins,script,p.mtlreader").remove(); - const chapterText = loadedCheerio(".container").html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const url = `${baseUrl}search?input=${searchTerm}`; - - const body = await fetchApi(url, {}, pluginId).then((r) => r.text()); - - let loadedCheerio = parseHTML(body); - - let novels: Novel.Item[] = []; - - loadedCheerio(".col-md-4.col-sm-4").each(function () { - const novelName = loadedCheerio(this).find("h5").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("h5 > a").attr("href"); - - if (!novelUrl) return; - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async function (url) { - const headers = { - Referer: baseUrl, - }; - return await fetchFile(url, { headers: headers }); -}; diff --git a/plugins/english/mtlreader.ts b/plugins/english/mtlreader.ts new file mode 100644 index 0000000..3124aed --- /dev/null +++ b/plugins/english/mtlreader.ts @@ -0,0 +1,126 @@ +import { load as parseHTML } from "cheerio"; +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Plugin } from "@typings/plugin"; +import { Filters } from "@libs/filterInputs"; + +class MTLReader implements Plugin.PluginBase { + id = "mtlreader"; + name = "MTL Reader"; + version = "1.0.0"; + icon = "src/en/mtlreader/icon.png"; + site = "https://mtlreader.com/"; + baseUrl = this.site; + async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { + const url = `${this.baseUrl}novels?page=${pageNo}`; + + const body = await fetchApi(url).then((r) => r.text()); + + const loadedCheerio = parseHTML(body); + + let novels: Plugin.NovelItem[] = []; + + loadedCheerio(".col-md-4.col-sm-4").each(function () { + const novelName = loadedCheerio(this).find("h5").text(); + const novelCover = loadedCheerio(this).find("img").attr("src"); + const novelUrl = loadedCheerio(this).find("h5 > a").attr("href"); + + if (!novelUrl) return; + + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const url = novelUrl; + + const body = await fetchApi(url).then((r) => r.text()); + + let loadedCheerio = parseHTML(body); + + const novel: Plugin.SourceNovel = { + url, + chapters: [], + }; + + novel.name = loadedCheerio(".agent-title").text().trim(); + + novel.cover = loadedCheerio(".agent-p-img > img").attr("src"); + + novel.summary = loadedCheerio("#editdescription").text().trim(); + + novel.author = loadedCheerio("i.fa-user") + .parent() + .text() + .replace("Author: ", "") + .trim(); + + let chapter: Plugin.ChapterItem[] = []; + + loadedCheerio("tr.spaceUnder").each(function () { + const chapterName = loadedCheerio(this).find("a").text().trim(); + const releaseDate = null; + const chapterUrl = loadedCheerio(this).find("a").attr("href"); + + if (!chapterUrl) return; + + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + + novel.chapters = chapter; + + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then((r) => r.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio(".container ins,script,p.mtlreader").remove(); + const chapterText = loadedCheerio(".container").html() || ''; + + return chapterText; + } + async searchNovels(searchTerm: string, pageNo: number): Promise { + const url = `${this.baseUrl}search?input=${searchTerm}`; + + const body = await fetchApi(url).then((r) => r.text()); + + let loadedCheerio = parseHTML(body); + + let novels: Plugin.NovelItem[] = []; + + loadedCheerio(".col-md-4.col-sm-4").each(function () { + const novelName = loadedCheerio(this).find("h5").text(); + const novelCover = loadedCheerio(this).find("img").attr("src"); + const novelUrl = loadedCheerio(this).find("h5 > a").attr("href"); + + if (!novelUrl) return; + + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async fetchImage(url: string): Promise { + return fetchFile(url); + } + +} +export default new MTLReader(); diff --git a/plugins/english/novelfull.broken.ts b/plugins/english/novelfull.broken.ts deleted file mode 100644 index 3988bd6..0000000 --- a/plugins/english/novelfull.broken.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { load as parseHTML } from "cheerio"; -import { fetchApi, fetchFile } from "@libs/fetch"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; - -export const id = "novelfull"; -export const name = "NovelFull"; -export const version = "1.0.0"; -export const icon = "src/en/novelfull/icon.png"; -export const site = "https://novelfull.com/"; - - -const baseUrl = site; - -export const popularNovels: Plugin.popularNovels = async function (page) { - const url = `${baseUrl}most-popular?page=${page}`; - - const result = await fetchApi(url); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - let novels: Novel.Item[] = []; - - loadedCheerio(".col-truyen-main .list-truyen .row").each(function () { - const novelName = loadedCheerio(this) - .find("h3.truyen-title > a") - .text(); - - const novelCover = - baseUrl + loadedCheerio(this).find("img").attr("src")?.slice(1); - - const novelUrl = - baseUrl + - loadedCheerio(this) - .find("h3.truyen-title > a") - .attr("href") - ?.slice(1); - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const url = novelUrl; - - const result = await fetchApi(url); - const body = await result.text(); - - let loadedCheerio = parseHTML(body); - - const novel: Novel.instance = { - url, - chapters: [], - }; - - novel.name = loadedCheerio("div.book > img").attr("alt"); - - novel.cover = baseUrl + loadedCheerio("div.book > img").attr("src"); - - novel.summary = loadedCheerio("div.desc-text").text().trim(); - - novel.author = loadedCheerio('h3:contains("Author")') - .parent() - .contents() - .text() - .replace("Author:", ""); - - novel.genres = loadedCheerio('h3:contains("Genre")') - .siblings() - .map((i, el) => loadedCheerio(el).text()) - .toArray() - .join(","); - - novel.status = loadedCheerio('h3:contains("Status")').next().text(); - - const novelId = loadedCheerio("#rating").attr("data-novel-id")!; - - async function getChapters(id: string) { - const chapterListUrl = - baseUrl + "ajax/chapter-option?novelId=" + id; - - const data = await fetchApi(chapterListUrl); - const chapterlist = await data.text(); - - loadedCheerio = parseHTML(chapterlist); - - let chapter: Chapter.Item[] = []; - - loadedCheerio("select > option").each(function () { - const chapterName = loadedCheerio(this).text(); - const releaseDate = null; - const chapterUrl = - baseUrl + loadedCheerio(this).attr("value")?.slice(1); - - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - return chapter; - } - - novel.chapters = await getChapters(novelId); - - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const result = await fetchApi(chapterUrl); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - loadedCheerio("#chapter-content div.ads").remove(); - let chapterText = loadedCheerio("#chapter-content").html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const searchUrl = `${baseUrl}search?keyword=${searchTerm}`; - - const result = await fetchApi(searchUrl); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - let novels: Novel.Item[] = []; - - loadedCheerio(".col-truyen-main .list-truyen .row").each(function () { - const novelName = loadedCheerio(this) - .find("h3.truyen-title > a") - .text(); - - const novelCover = - baseUrl + loadedCheerio(this).find("img").attr("src")?.slice(1); - - const novelUrl = - baseUrl + - loadedCheerio(this) - .find("h3.truyen-title > a") - .attr("href") - ?.slice(1); - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async function (url) { - const headers = { - Referer: baseUrl, - }; - return await fetchFile(url, { headers: headers }); -}; diff --git a/plugins/english/novelfull.ts b/plugins/english/novelfull.ts new file mode 100644 index 0000000..f03b03d --- /dev/null +++ b/plugins/english/novelfull.ts @@ -0,0 +1,168 @@ +import { load as parseHTML } from "cheerio"; +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Plugin } from "@typings/plugin"; +import { Filters } from "@libs/filterInputs"; + + +class NovelFull implements Plugin.PluginBase { + id = "novelfull"; + name = "NovelFull"; + version = "1.0.0"; + icon = "src/en/novelfull/icon.png"; + site = "https://novelfull.com/"; + baseUrl = this.site; + async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { + const url = `${this.baseUrl}most-popular?page=${pageNo}`; + + const result = await fetchApi(url); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + + let novels: Plugin.NovelItem[] = []; + + loadedCheerio(".col-truyen-main .list-truyen .row").each((idx, ele) => { + const novelName = loadedCheerio(ele) + .find("h3.truyen-title > a") + .text(); + + const novelCover = + this.baseUrl + loadedCheerio(ele).find("img").attr("src")?.slice(1); + + const novelUrl = + this.baseUrl + + loadedCheerio(ele) + .find("h3.truyen-title > a") + .attr("href") + ?.slice(1); + + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const url = novelUrl; + + const result = await fetchApi(url); + const body = await result.text(); + + let loadedCheerio = parseHTML(body); + + const novel: Plugin.SourceNovel = { + url, + chapters: [], + }; + + novel.name = loadedCheerio("div.book > img").attr("alt"); + + novel.cover = this.baseUrl + loadedCheerio("div.book > img").attr("src"); + + novel.summary = loadedCheerio("div.desc-text").text().trim(); + + novel.author = loadedCheerio('h3:contains("Author")') + .parent() + .contents() + .text() + .replace("Author:", ""); + + novel.genres = loadedCheerio('h3:contains("Genre")') + .siblings() + .map((i, el) => loadedCheerio(el).text()) + .toArray() + .join(","); + + novel.status = loadedCheerio('h3:contains("Status")').next().text(); + + const novelId = loadedCheerio("#rating").attr("data-novel-id")!; + + async function getChapters(id: string, baseUrl: string) { + const chapterListUrl = + baseUrl + "ajax/chapter-option?novelId=" + id; + + const data = await fetchApi(chapterListUrl); + const chapterlist = await data.text(); + + loadedCheerio = parseHTML(chapterlist); + + let chapter: Plugin.ChapterItem[] = []; + + loadedCheerio("select > option").each(function () { + const chapterName = loadedCheerio(this).text(); + const releaseDate = null; + const chapterUrl = + baseUrl + loadedCheerio(this).attr("value")?.slice(1); + + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + return chapter; + } + + novel.chapters = await getChapters(novelId, this.baseUrl); + + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const result = await fetchApi(chapterUrl); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + + loadedCheerio("#chapter-content div.ads").remove(); + let chapterText = loadedCheerio("#chapter-content").html() || ''; + + return chapterText; + } + async searchNovels(searchTerm: string, pageNo: number): Promise { + const searchUrl = `${this.baseUrl}search?keyword=${searchTerm}`; + + const result = await fetchApi(searchUrl); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + + let novels: Plugin.NovelItem[] = []; + + loadedCheerio(".col-truyen-main .list-truyen .row").each((idx, ele) => { + const novelName = loadedCheerio(ele) + .find("h3.truyen-title > a") + .text(); + + const novelCover = + this.baseUrl + loadedCheerio(ele).find("img").attr("src")?.slice(1); + + const novelUrl = + this.baseUrl + + loadedCheerio(ele) + .find("h3.truyen-title > a") + .attr("href") + ?.slice(1); + + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async fetchImage(url: string): Promise { + return fetchFile(url); + } + +} + +export default new NovelFull(); diff --git a/plugins/english/novelhall.ts b/plugins/english/novelhall.ts new file mode 100644 index 0000000..15947a5 --- /dev/null +++ b/plugins/english/novelhall.ts @@ -0,0 +1,138 @@ +import { load as parseHTML } from "cheerio"; +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Plugin } from "@typings/plugin"; +import { Filters } from "@libs/filterInputs"; + +class NovelHall implements Plugin.PluginBase { + id = "novelhold"; + name = "Novel Hall"; + version = "1.0.0"; + icon = "src/en/novelhall/icon.png"; + filters?: Filters | undefined; + site = "https://novelhall.com/"; + baseUrl = this.site; + + async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { + const url = `${this.baseUrl}all2022-${pageNo}.html`; + + const body = await fetchApi(url).then((r) => r.text()); + + const loadedCheerio = parseHTML(body); + + let novels: Plugin.NovelItem[] = []; + + loadedCheerio("li.btm").each((idx, ele) => { + const novelName = loadedCheerio(ele).text().trim() + const novelUrl = + this.baseUrl + loadedCheerio(ele).find("a").attr("href"); + + const novel = { + name: novelName, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const url = novelUrl; + + const body = await fetchApi(url).then((r) => r.text()); + + let loadedCheerio = parseHTML(body); + + const novel: Plugin.SourceNovel = { + url, + chapters: [], + }; + + novel.name = loadedCheerio(".booknav2 > h1").text(); + + novel.cover = loadedCheerio('meta[property="og:image"]').attr( + "content" + ); + + novel.summary = loadedCheerio(".navtxt").text().trim(); + + novel.author = loadedCheerio('p:contains("Author")') + .text() + .replace("Author:", "") + .trim(); + + novel.status = loadedCheerio('p:contains("Status")') + .text() + .replace("Status:", "") + .replace("Active", "Ongoing") + .trim(); + + novel.genres = loadedCheerio('p:contains("Genre")') + .text() + ?.replace("Genre:", "") + .trim(); + + let chapter: Plugin.ChapterItem[] = []; + + loadedCheerio("#morelist ul > li").each((idx, ele) => { + const chapterName = loadedCheerio(ele).find("a").text().trim(); + const releaseDate = null; + const chapterUrl = + this.baseUrl + loadedCheerio(ele).find("a").attr("href"); + + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + + novel.chapters = chapter; + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then((r) => r.text()); + + let loadedCheerio = parseHTML(body); + + const chapterText = loadedCheerio(".content").html() || ''; + + return chapterText; + } + async searchNovels(searchTerm: string, pageNo: number): Promise { + const url = `${this.baseUrl}index.php?s=so&module=book&keyword=${searchTerm}`; + + const body = await fetchApi(url).then((r) => r.text()); + + let loadedCheerio = parseHTML(body); + + let novels: Plugin.NovelItem[] = []; + + loadedCheerio("#article_list_content > li").each((idx, ele) => { + const novelName = loadedCheerio(ele) + .find("h3") + .text() + .replace(/\t+/g, "") + .replace(/\n/g, " "); + const novelCover = loadedCheerio(ele).find("img").attr("data-src"); + const novelUrl = + this.baseUrl + loadedCheerio(ele).find("a").attr("href")?.slice(1); + + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async fetchImage(url: string): Promise { + return fetchFile(url); + } + +} + +export default new NovelHall(); diff --git a/plugins/english/novelhold.broken.ts b/plugins/english/novelhold.broken.ts deleted file mode 100644 index bf2a9ec..0000000 --- a/plugins/english/novelhold.broken.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { load as parseHTML } from "cheerio"; -import { fetchApi, fetchFile } from "@libs/fetch"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; - -export const id = "novelhold"; -export const name = "Novel Hold"; -export const version = "1.0.0"; -export const icon = "src/en/novelhold/icon.png"; -export const site = "https://novelhold.com/"; - - -const baseUrl = site; - -export const popularNovels: Plugin.popularNovels = async function (page) { - const url = `${baseUrl}all-${page}.html`; - - const body = await fetchApi(url).then((r) => r.text()); - - const loadedCheerio = parseHTML(body); - - let novels: Novel.Item[] = []; - - loadedCheerio("#article_list_content > li").each(function () { - const novelName = loadedCheerio(this) - .find("h3") - .text() - .replace(/\t+/g, "") - .replace(/\n/g, " "); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = - baseUrl + loadedCheerio(this).find("a").attr("href")?.slice(1); - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const url = novelUrl; - - const body = await fetchApi(url).then((r) => r.text()); - - let loadedCheerio = parseHTML(body); - - const novel: Novel.instance = { - url, - chapters: [], - }; - - novel.name = loadedCheerio(".booknav2 > h1").text(); - - novel.cover = loadedCheerio('meta[property="og:image"]').attr( - "content" - ); - - novel.summary = loadedCheerio(".navtxt").text().trim(); - - novel.author = loadedCheerio('p:contains("Author")') - .text() - .replace("Author:", "") - .trim(); - - novel.status = loadedCheerio('p:contains("Status")') - .text() - .replace("Status:", "") - .replace("Active", "Ongoing") - .trim(); - - novel.genres = loadedCheerio('p:contains("Genre")') - .text() - ?.replace("Genre:", "") - .trim(); - - let chapter: Chapter.Item[] = []; - - loadedCheerio("ul.chapterlist > li").each(function () { - const chapterName = loadedCheerio(this).find("a").text().trim(); - const releaseDate = null; - const chapterUrl = - baseUrl + loadedCheerio(this).find("a").attr("href")?.slice(1); - - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - - novel.chapters = chapter; - console.log(novel); - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const body = await fetchApi(chapterUrl).then((r) => r.text()); - - let loadedCheerio = parseHTML(body); - - const chapterText = loadedCheerio(".content").html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const url = `${baseUrl}index.php?s=so&module=book&keyword=${searchTerm}`; - - const body = await fetchApi(url).then((r) => r.text()); - - let loadedCheerio = parseHTML(body); - - let novels: Novel.Item[] = []; - - loadedCheerio("#article_list_content > li").each(function () { - const novelName = loadedCheerio(this) - .find("h3") - .text() - .replace(/\t+/g, "") - .replace(/\n/g, " "); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = - baseUrl + loadedCheerio(this).find("a").attr("href")?.slice(1); - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async function (url) { - const headers = { - Referer: baseUrl, - }; - return await fetchFile(url, { headers: headers }); -}; diff --git a/plugins/english/novelpub.broken.ts b/plugins/english/novelpub.broken.ts deleted file mode 100644 index 0aef4ae..0000000 --- a/plugins/english/novelpub.broken.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { load as parseHTML } from "cheerio"; -import { fetchApi, fetchFile } from "@libs/fetch"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; - -export const id = "novelpub.com"; -export const name = "NovelPub"; -export const site = "https://www.novelpub.com/"; -export const version = "1.0.0"; -export const icon = "src/en/novelpub/icon.png"; -const baseUrl = site; - -const headers = { - Accept: "application/json", - "Content-Type": "application/json", - "User-Agent": - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36", -}; - -export const popularNovels: Plugin.popularNovels = async function (page) { - let url = baseUrl + "browse/all/popular/all/" + page; - - const result = await fetchApi(url, { method: "GET", headers }); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - let novels: Novel.Item[] = []; - - loadedCheerio(".novel-item.ads").remove(); - - loadedCheerio(".novel-item").each(function () { - const novelName = loadedCheerio(this) - .find(".novel-title") - .text() - .trim(); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = - baseUrl + - loadedCheerio(this) - .find(".novel-title > a") - .attr("href") - ?.substring(1); - - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const url = novelUrl; - - const result = await fetchApi(url, { method: "GET", headers }); - const body = await result.text(); - - let loadedCheerio = parseHTML(body); - - let novel: Novel.instance = { url, genres: "" }; - - novel.name = loadedCheerio("h1.novel-title").text().trim(); - - novel.cover = loadedCheerio("figure.cover > img").attr("data-src"); - - loadedCheerio("div.categories > ul > li").each(function () { - novel.genres += - loadedCheerio(this) - .text() - .replace(/[\t\n]/g, "") + ","; - }); - - loadedCheerio("div.header-stats > span").each(function () { - if (loadedCheerio(this).find("small").text() === "Status") { - novel.status = loadedCheerio(this).find("strong").text(); - } - }); - - novel.genres = novel.genres?.slice(0, -1); - - novel.author = loadedCheerio(".author > a > span").text(); - - novel.summary = loadedCheerio(".summary > .content").text().trim(); - - const delay = (ms: number) => new Promise((res) => setTimeout(res, ms)); - - let lastPage = 1; - - lastPage = parseInt( - loadedCheerio( - "#novel > header > div.header-body.container > div.novel-info > div.header-stats > span:nth-child(1) > strong" - ) - .text() - ?.trim() - ); - - lastPage = Math.ceil(lastPage / 100); - - const getChapters = async () => { - let novelChapters: Chapter.Item[] = []; - - for (let i = 1; i <= lastPage; i++) { - const chaptersUrl = `${novelUrl}/chapters/page-${i}`; - - const chaptersRequest = await fetchApi(chaptersUrl, { - headers, - }); - const chaptersHtml = await chaptersRequest.text(); - - loadedCheerio = parseHTML(chaptersHtml); - - loadedCheerio(".chapter-list li").each(function () { - const chapterName = loadedCheerio(this) - .find(".chapter-title") - .text() - .trim(); - - const releaseDate = loadedCheerio(this) - .find(".chapter-update") - .text() - .trim(); - - const chapterUrl = - baseUrl + - loadedCheerio(this) - .find("a") - .attr("href") - ?.substring(1); - - novelChapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - - await delay(1000); - } - - return novelChapters; - }; - - novel.chapters = await getChapters(); - - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const url = chapterUrl; - - const result = await fetchApi(url, { method: "GET", headers }); - - const body = await result.text(); - const loadedCheerio = parseHTML(body); - - const chapterText = loadedCheerio("#chapter-container").html(); - return chapterText; -}; - -// They have API to search, pls update it, im quite lazy xD -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const url = `${baseUrl}lnwsearchlive?inputContent=${searchTerm}`; - - const result = await fetchApi(url, { method: "GET", headers }); - const body = await result.text(); - - let loadedCheerio = parseHTML(body); - - let novels: Novel.Item[] = []; - - // let results = JSON.parse(loadedCheerio('body').text()); - - // loadedCheerio = load(results.resultview); - - // loadedCheerio('.novel-item').each(function () { - // const novelName = loadedCheerio(this).find('.novel-title').text().trim(); - // const novelCover = loadedCheerio(this).find('img').attr('src'); - // const novelUrl = - // baseUrl + loadedCheerio(this).find('a').attr('href').substring(1); - - // const novel = { name: novelName, cover: novelCover, url: novelUrl }; - - // novels.push(novel); - // }); - - return novels; -}; -export const fetchImage: Plugin.fetchImage = fetchFile; diff --git a/plugins/english/novelupdates.broken.ts b/plugins/english/novelupdates.broken.ts deleted file mode 100644 index fccbe8d..0000000 --- a/plugins/english/novelupdates.broken.ts +++ /dev/null @@ -1,492 +0,0 @@ -import cheerio from "cheerio"; -import { fetchApi, fetchFile } from "@libs/fetch"; -import { FilterInputs } from "@libs/filterInputs"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; - -const pluginId = "novelupdates"; -const baseUrl = "https://www.novelupdates.com/"; - -const headers = { - "User-Agent": - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36", -}; - -function getPopularNovelsUrl( - page: number, - { showLatestNovels, filters }: Plugin.Options -) { - let url = `${baseUrl}${ - filters - ? "series-finder" - : showLatestNovels - ? "latest-series" - : "series-ranking" - }/`; - - if (!filters) { - url += "?rank=week"; - } else { - url += "?sf=1"; - } - - if (filters) { - if (Array.isArray(filters.novelType) && filters.novelType?.length) { - url += "&nt=" + filters?.novelType.join(","); - } - - if (Array.isArray(filters.genres) && filters.genres?.length) { - url += "&gi=" + filters?.genres.join(",") + "&mgi=and"; - } - - if (Array.isArray(filters.language) && filters.language?.length) { - url += "&org=" + filters?.language.join(","); - } - - if (filters.storyStatus) { - url += "&ss=" + filters?.storyStatus; - } - } - - if (!filters?.sort) { - url += "&sort=" + "sdate"; - } else { - url += "&sort=" + filters?.sort; - } - - if (!filters?.order) { - url += "&order=" + "desc"; - } else { - url += "&order=" + filters?.order; - } - - return url; -} - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { showLatestNovels, filters } -) { - const url = getPopularNovelsUrl(page, { showLatestNovels, filters }); - - const result = await fetchApi(url, { headers: headers }, pluginId); - const body = await result.text(); - - const loadedCheerio = cheerio.load(body); - - const novels: Novel.Item[] = []; - - loadedCheerio("div.search_main_box_nu").each(function (res) { - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelName = loadedCheerio(this).find(".search_title > a").text(); - const novelUrl = loadedCheerio(this) - .find(".search_title > a") - .attr("href"); - - if (!novelUrl) return; - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const url = novelUrl; - - const result = await fetchApi(url, { headers: headers }, pluginId); - const body = await result.text(); - - let loadedCheerio = cheerio.load(body); - - const novel: Novel.instance = { - url, - chapters: [], - }; - - novel.name = loadedCheerio(".seriestitlenu").text(); - - novel.cover = loadedCheerio(".seriesimg > img").attr("src"); - - novel.author = loadedCheerio("#showauthors").text().trim(); - - novel.genres = loadedCheerio("#seriesgenre") - .children("a") - .map((i, el) => loadedCheerio(el).text()) - .toArray() - .join(","); - novel.status = loadedCheerio("#editstatus").text().includes("Ongoing") - ? "Ongoing" - : "Completed"; - - let type = loadedCheerio("#showtype").text().trim(); - - let summary = loadedCheerio("#editdescription").text().trim(); - - novel.summary = summary + `\n\nType: ${type}`; - - let chapter: Chapter.Item[] = []; - - const novelId = loadedCheerio("input#mypostid").attr("value")!; - - let formData = new FormData(); - formData.append("action", "nd_getchapters"); - formData.append("mygrr", "0"); - formData.append("mypostid", novelId); - - let link = "https://www.novelupdates.com/wp-admin/admin-ajax.php"; - - const text = await fetchApi( - link, - { - method: "POST", - body: formData, - headers: headers, - }, - pluginId - ).then((data) => data.text()); - - loadedCheerio = cheerio.load(text); - - loadedCheerio("li.sp_li_chp").each(function () { - const chapterName = loadedCheerio(this).text().trim(); - - const releaseDate = null; - - const chapterUrl = - "https:" + - loadedCheerio(this).find("a").first().next().attr("href"); - - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - - novel.chapters = chapter.reverse(); - - return novel; - }; - -function getLocation(href: string) { - var match = href.match( - /^(https?:)\/\/(([^:/?#]*)(?::([0-9]+))?)([/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/ - ); - return match && `${match[1]}//${match[3]}`; -} - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - // console.log('Original URL: ', chapterUrl); - - let chapterText = ""; - - const result = await fetchApi( - chapterUrl, - { - method: "GET", - headers: headers, - }, - pluginId - ); - const body = await result.text(); - - // console.log(result.chapterUrl); - - // console.log('Redirected URL: ', result.chapterUrl); - - const loadedCheerio = cheerio.load(body); - - let isWuxiaWorld = result.chapterUrl.toLowerCase().includes("wuxiaworld"); - - let isBlogspot = result.chapterUrl.toLowerCase().includes("blogspot"); - - let isTumblr = result.chapterUrl.toLowerCase().includes("tumblr"); - - let isWattpad = result.chapterUrl.toLowerCase().includes("wattpad"); - - let isLightNovelsTls = result.chapterUrl - .toLowerCase() - .includes("lightnovelstranslations"); - - let isiNovelTranslation = result.chapterUrl - .toLowerCase() - .includes("inoveltranslation"); - - let isTravisTranslation = result.chapterUrl - .toLowerCase() - .includes("travistranslations"); - - /** - * Checks if its a wordpress site - */ - let isWordPressStr = - loadedCheerio('meta[name="generator"]').attr("content") || - loadedCheerio("footer").text(); - - let isWordPress = false; - - if (isWordPressStr) { - isWordPress = - isWordPressStr.toLowerCase().includes("wordpress") || - isWordPressStr.includes("Site Kit by Google") || - loadedCheerio(".powered-by") - .text() - .toLowerCase() - .includes("wordpress"); - } - - let isRainOfSnow = result.chapterUrl.toLowerCase().includes("rainofsnow"); - - let isWebNovel = result.chapterUrl.toLowerCase().includes("webnovel"); - - let isHostedNovel = result.chapterUrl.toLowerCase().includes("hostednovel"); - - let isScribbleHub = result.chapterUrl.toLowerCase().includes("scribblehub"); - - if (isWuxiaWorld) { - chapterText = loadedCheerio("#chapter-content").html()!; - } else if (isRainOfSnow) { - chapterText = loadedCheerio("div.content").html()!; - } else if (isTumblr) { - chapterText = loadedCheerio(".post").html()!; - } else if (isBlogspot) { - loadedCheerio(".post-share-buttons").remove(); - chapterText = loadedCheerio(".entry-content").html()!; - } else if (isHostedNovel) { - chapterText = loadedCheerio(".chapter").html()!; - } else if (isScribbleHub) { - chapterText = loadedCheerio("div.chp_raw").html()!; - } else if (isWattpad) { - chapterText = loadedCheerio(".container pre").html()!; - } else if (isTravisTranslation) { - chapterText = loadedCheerio(".reader-content").html()!; - } else if (isLightNovelsTls) { - chapterText = loadedCheerio(".text_story").html()!; - } else if (isiNovelTranslation) { - chapterText = loadedCheerio(".chakra-skeleton").html()!; - } else if (isWordPress) { - /** - * Remove wordpress bloat tags - */ - - const bloatClasses = [ - ".c-ads", - "#madara-comments", - "#comments", - ".content-comments", - ".sharedaddy", - ".wp-dark-mode-switcher", - ".wp-next-post-navi", - ".wp-block-buttons", - ".wp-block-columns", - ".post-cats", - ".sidebar", - ".author-avatar", - ".ezoic-ad", - ]; - - bloatClasses.map((tag) => loadedCheerio(tag).remove()); - - chapterText = - loadedCheerio(".entry-content").html() || - loadedCheerio(".single_post").html() || - loadedCheerio(".post-entry").html() || - loadedCheerio(".main-content").html() || - loadedCheerio("article.post").html() || - loadedCheerio(".content").html() || - loadedCheerio("#content").html() || - loadedCheerio(".page-body").html() || - loadedCheerio(".td-page-content").html()!; - } else if (isWebNovel) { - chapterText = loadedCheerio(".cha-words").html()!; - - if (!chapterText) { - chapterText = loadedCheerio("._content").html()!; - } - } else { - /** - * Remove unnecessary tags - */ - const tags = ["nav", "header", "footer", ".hidden"]; - - tags.map((tag) => loadedCheerio(tag).remove()); - - chapterText = loadedCheerio("body").html()!; - } - - if (chapterText) { - /** - * Convert relative urls to absolute - */ - chapterText = chapterText.replace( - /href="\//g, - `href="${getLocation(result.chapterUrl)}/` - ); - } - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const url = - "https://www.novelupdates.com/?s=" + - searchTerm + - "&post_type=seriesplans"; - - const result = await fetchApi(url, { headers: headers }, pluginId); - const body = await result.text(); - - const loadedCheerio = cheerio.load(body); - - let novels: Novel.Item[] = []; - - loadedCheerio("div.search_main_box_nu").each(function () { - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelName = loadedCheerio(this).find(".search_title > a").text(); - const novelUrl = loadedCheerio(this) - .find(".search_title > a") - .attr("href") - ?.split("/")[4]; - - if (!novelUrl) return; - - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, - }); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async function (url) { - return await fetchFile(url, { headers: headers }); -}; - -const filters = [ - { - key: "sort", - label: "Sort Results By", - values: [ - { label: "Last Updated", value: "sdate" }, - { label: "Rating", value: "srate" }, - { label: "Rank", value: "srank" }, - { label: "Reviews", value: "sreview" }, - { label: "Chapters", value: "srel" }, - { label: "Title", value: "abc" }, - { label: "Readers", value: "sread" }, - { label: "Frequency", value: "sfrel" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "order", - label: "Order", - values: [ - { label: "Descending", value: "desc" }, - { label: "Ascending", value: "asc" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "storyStatus", - label: "Story Status (Translation)", - values: [ - { label: "All", value: "" }, - { label: "Completed", value: "2" }, - { label: "Ongoing", value: "3" }, - { label: "Hiatus", value: "4" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "language", - label: "Language", - values: [ - { label: "Chinese", value: 495 }, - { label: "Filipino", value: 9181 }, - { label: "Indonesian", value: 9179 }, - { label: "Japanese", value: 496 }, - { label: "Khmer", value: 18657 }, - { label: "Korean", value: 497 }, - { label: "Malaysian", value: 9183 }, - { label: "Thai", value: 9954 }, - { label: "Vietnamese", value: 9177 }, - ], - inputType: FilterInputs.Checkbox, - }, - { - key: "novelType", - label: "Novel Type", - values: [ - { label: "Light Novel", value: "2443" }, - { label: "Published Novel", value: "26874" }, - { label: "Web Novel", value: "2444" }, - ], - inputType: FilterInputs.Checkbox, - }, - { - key: "genres", - label: "Genres", - values: [ - { label: "Action", value: 8 }, - { label: "Adult", value: 280 }, - { label: "Adventure", value: 13 }, - { label: "Comedy", value: 17 }, - { label: "Drama", value: 9 }, - { label: "Ecchi", value: 292 }, - { label: "Fantasy", value: 5 }, - { label: "Gender Bender", value: 168 }, - { label: "Harem", value: 3 }, - { label: "Historical", value: 330 }, - { label: "Horror", value: 343 }, - { label: "Josei", value: 324 }, - { label: "Martial Arts", value: 14 }, - { label: "Mature", value: 4 }, - { label: "Mecha", value: 10 }, - { label: "Mystery", value: 245 }, - { label: "Psychoical", value: 486 }, - { label: "Romance", value: 15 }, - { label: "School Life", value: 6 }, - { label: "Sci-fi", value: 11 }, - { label: "Seinen", value: 18 }, - { label: "Shoujo", value: 157 }, - { label: "Shoujo Ai", value: 851 }, - { label: "Shounen", value: 12 }, - { label: "Shounen Ai", value: 1692 }, - { label: "Slice of Life", value: 7 }, - { label: "Smut", value: 281 }, - { label: "Sports", value: 1357 }, - { label: "Supernatural", value: 16 }, - { label: "Tragedy", value: 132 }, - { label: "Wuxia", value: 479 }, - { label: "Xianxia", value: 480 }, - { label: "Xuanhuan", value: 3954 }, - { label: "Yaoi", value: 560 }, - { label: "Yuri", value: 922 }, - ], - inputType: FilterInputs.Checkbox, - }, -]; - -module.exports = { - id: pluginId, - name: "Novel Updates", - version: "0.5.0", - icon: "src/en/novelupdates/icon.png", - site: baseUrl, - protected: false, - fetchImage, - popularNovels, - parseNovelAndChapters, - parseChapter, - searchNovels, - filters, -}; diff --git a/plugins/english/novelupdates.ts b/plugins/english/novelupdates.ts new file mode 100644 index 0000000..1765645 --- /dev/null +++ b/plugins/english/novelupdates.ts @@ -0,0 +1,463 @@ +import { load as parseHTML } from "cheerio"; +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filters, FilterTypes } from "@libs/filterInputs"; +import { Plugin } from "@typings/plugin"; + +class NovelUpdates implements Plugin.PluginBase { + id = "novelupdates"; + name = "Novel Updates"; + version = "0.5.0"; + icon = "src/en/novelupdates/icon.png"; + site = "https://www.novelupdates.com/"; + baseUrl = this.site; + + getPopularNovelsUrl( + page: number, + { showLatestNovels, filters }: Plugin.PopularNovelsOptions + ) { + let url = `${this.baseUrl}${filters + ? "series-finder" + : showLatestNovels + ? "latest-series" + : "series-ranking" + }/`; + + if (!filters) { + url += "?rank=week"; + } else { + url += "?sf=1"; + } + + if (filters) { + if (Array.isArray(filters.novelType) && filters.novelType?.length) { + url += "&nt=" + filters?.novelType.join(","); + } + + if (Array.isArray(filters.genres) && filters.genres?.length) { + url += "&gi=" + filters?.genres.join(",") + "&mgi=and"; + } + + if (Array.isArray(filters.language) && filters.language?.length) { + url += "&org=" + filters?.language.join(","); + } + + if (filters.storyStatus) { + url += "&ss=" + filters?.storyStatus; + } + } + + if (!filters?.sort) { + url += "&sort=" + "sdate"; + } else { + url += "&sort=" + filters?.sort; + } + + if (!filters?.order) { + url += "&order=" + "desc"; + } else { + url += "&order=" + filters?.order; + } + + return url; + } + + async popularNovels(pageNo: number, { showLatestNovels, filters }: Plugin.PopularNovelsOptions): Promise { + const url = this.getPopularNovelsUrl(pageNo, { showLatestNovels, filters }); + + const result = await fetchApi(url); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + + const novels: Plugin.NovelItem[] = []; + + loadedCheerio("div.search_main_box_nu").each((idx, ele) => { + const novelCover = loadedCheerio(ele).find("img").attr("src"); + const novelName = loadedCheerio(ele).find(".search_title > a").text(); + const novelUrl = loadedCheerio(ele) + .find(".search_title > a") + .attr("href"); + + if (!novelUrl) return; + + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const url = novelUrl; + + const result = await fetchApi(url); + const body = await result.text(); + + let loadedCheerio = parseHTML(body); + + const novel: Plugin.SourceNovel = { + url, + chapters: [], + }; + + novel.name = loadedCheerio(".seriestitlenu").text(); + + novel.cover = loadedCheerio(".seriesimg > img").attr("src"); + + novel.author = loadedCheerio("#showauthors").text().trim(); + + novel.genres = loadedCheerio("#seriesgenre") + .children("a") + .map((i, el) => loadedCheerio(el).text()) + .toArray() + .join(","); + novel.status = loadedCheerio("#editstatus").text().includes("Ongoing") + ? "Ongoing" + : "Completed"; + + let type = loadedCheerio("#showtype").text().trim(); + + let summary = loadedCheerio("#editdescription").text().trim(); + + novel.summary = summary + `\n\nType: ${type}`; + + let chapter: Plugin.ChapterItem[] = []; + + const novelId = loadedCheerio("input#mypostid").attr("value")!; + + let formData = new FormData(); + formData.append("action", "nd_getchapters"); + formData.append("mygrr", "0"); + formData.append("mypostid", novelId); + + let link = "https://www.novelupdates.com/wp-admin/admin-ajax.php"; + + const text = await fetchApi( + link, + { + method: "POST", + body: formData, + }, + ).then((data) => data.text()); + + loadedCheerio = parseHTML(text); + + loadedCheerio("li.sp_li_chp").each(function () { + const chapterName = loadedCheerio(this).text().trim(); + + const releaseDate = null; + + const chapterUrl = + "https:" + + loadedCheerio(this).find("a").first().next().attr("href"); + + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + + novel.chapters = chapter.reverse(); + + return novel; + } + getLocation(href: string) { + var match = href.match( + /^(https?:)\/\/(([^:/?#]*)(?::([0-9]+))?)([/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/ + ); + return match && `${match[1]}//${match[3]}`; + } + + async parseChapter(chapterUrl: string): Promise { + let chapterText = ""; + + const result = await fetchApi( + chapterUrl, + ); + const body = await result.text(); + + // console.log(result.chapterUrl); + + // console.log('Redirected URL: ', result.chapterUrl); + + const loadedCheerio = parseHTML(body); + + let isWuxiaWorld = chapterUrl.toLowerCase().includes("wuxiaworld"); + + let isBlogspot = chapterUrl.toLowerCase().includes("blogspot"); + + let isTumblr = chapterUrl.toLowerCase().includes("tumblr"); + + let isWattpad = chapterUrl.toLowerCase().includes("wattpad"); + + let isLightNovelsTls = chapterUrl + .toLowerCase() + .includes("lightnovelstranslations"); + + let isiNovelTranslation = chapterUrl + .toLowerCase() + .includes("inoveltranslation"); + + let isTravisTranslation = chapterUrl + .toLowerCase() + .includes("travistranslations"); + + /** + * Checks if its a wordpress site + */ + let isWordPressStr = + loadedCheerio('meta[name="generator"]').attr("content") || + loadedCheerio("footer").text(); + + let isWordPress = false; + + if (isWordPressStr) { + isWordPress = + isWordPressStr.toLowerCase().includes("wordpress") || + isWordPressStr.includes("Site Kit by Google") || + loadedCheerio(".powered-by") + .text() + .toLowerCase() + .includes("wordpress"); + } + + let isRainOfSnow = chapterUrl.toLowerCase().includes("rainofsnow"); + + let isWebNovel = chapterUrl.toLowerCase().includes("webnovel"); + + let isHostedNovel = chapterUrl.toLowerCase().includes("hostednovel"); + + let isScribbleHub = chapterUrl.toLowerCase().includes("scribblehub"); + + if (isWuxiaWorld) { + chapterText = loadedCheerio("#chapter-content").html()!; + } else if (isRainOfSnow) { + chapterText = loadedCheerio("div.content").html()!; + } else if (isTumblr) { + chapterText = loadedCheerio(".post").html()!; + } else if (isBlogspot) { + loadedCheerio(".post-share-buttons").remove(); + chapterText = loadedCheerio(".entry-content").html()!; + } else if (isHostedNovel) { + chapterText = loadedCheerio(".chapter").html()!; + } else if (isScribbleHub) { + chapterText = loadedCheerio("div.chp_raw").html()!; + } else if (isWattpad) { + chapterText = loadedCheerio(".container pre").html()!; + } else if (isTravisTranslation) { + chapterText = loadedCheerio(".reader-content").html()!; + } else if (isLightNovelsTls) { + chapterText = loadedCheerio(".text_story").html()!; + } else if (isiNovelTranslation) { + chapterText = loadedCheerio(".chakra-skeleton").html()!; + } else if (isWordPress) { + /** + * Remove wordpress bloat tags + */ + + const bloatClasses = [ + ".c-ads", + "#madara-comments", + "#comments", + ".content-comments", + ".sharedaddy", + ".wp-dark-mode-switcher", + ".wp-next-post-navi", + ".wp-block-buttons", + ".wp-block-columns", + ".post-cats", + ".sidebar", + ".author-avatar", + ".ezoic-ad", + ]; + + bloatClasses.map((tag) => loadedCheerio(tag).remove()); + + chapterText = + loadedCheerio(".entry-content").html() || + loadedCheerio(".single_post").html() || + loadedCheerio(".post-entry").html() || + loadedCheerio(".main-content").html() || + loadedCheerio("article.post").html() || + loadedCheerio(".content").html() || + loadedCheerio("#content").html() || + loadedCheerio(".page-body").html() || + loadedCheerio(".td-page-content").html()!; + } else if (isWebNovel) { + chapterText = loadedCheerio(".cha-words").html()!; + + if (!chapterText) { + chapterText = loadedCheerio("._content").html()!; + } + } else { + /** + * Remove unnecessary tags + */ + const tags = ["nav", "header", "footer", ".hidden"]; + + tags.map((tag) => loadedCheerio(tag).remove()); + + chapterText = loadedCheerio("body").html()!; + } + + if (chapterText) { + /** + * Convert relative urls to absolute + */ + chapterText = chapterText.replace( + /href="\//g, + `href="${this.getLocation(chapterUrl)}/` + ); + } + + return chapterText; + } + async searchNovels(searchTerm: string, pageNo: number): Promise { + const url = + "https://www.novelupdates.com/?s=" + + searchTerm + + "&post_type=seriesplans"; + + const result = await fetchApi(url); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + + let novels: Plugin.NovelItem[] = []; + + loadedCheerio("div.search_main_box_nu").each(function () { + const novelCover = loadedCheerio(this).find("img").attr("src"); + const novelName = loadedCheerio(this).find(".search_title > a").text(); + const novelUrl = loadedCheerio(this) + .find(".search_title > a") + .attr("href") + ?.split("/")[4]; + + if (!novelUrl) return; + + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + return novels; + } + fetchImage(url: string): Promise { + return fetchFile(url); + } + + filters: Filters = { + sort: { + label: "Sort Results By", + type: FilterTypes.Picker, + options: [ + { label: "Last Updated", value: "sdate" }, + { label: "Rating", value: "srate" }, + { label: "Rank", value: "srank" }, + { label: "Reviews", value: "sreview" }, + { label: "Chapters", value: "srel" }, + { label: "Title", value: "abc" }, + { label: "Readers", value: "sread" }, + { label: "Frequency", value: "sfrel" }, + ], + value: "sdate", + }, + order: { + label: "Order", + type: FilterTypes.Picker, + options: [ + { label: "Descending", value: "desc" }, + { label: "Ascending", value: "asc" }, + ], + value: "asc" + }, + storyStatus: { + label: "Story Status (Translation)", + type: FilterTypes.Picker, + options: [ + { label: "All", value: "" }, + { label: "Completed", value: "2" }, + { label: "Ongoing", value: "3" }, + { label: "Hiatus", value: "4" }, + ], + value: "" + }, + language: { + label: "Language", + options: [ + { label: "Chinese", value: "495" }, + { label: "Filipino", value: "9181" }, + { label: "Indonesian", value: "9179" }, + { label: "Japanese", value: "496" }, + { label: "Khmer", value: "18657" }, + { label: "Korean", value: "497" }, + { label: "Malaysian", value: "9183" }, + { label: "Thai", value: "9954" }, + { label: "Vietnamese", value: "9177" }, + ], + type: FilterTypes.Picker, + value: "" + }, + novelType: { + label: "Novel Type", + type: FilterTypes.CheckboxGroup, + value: [], + options: [ + { label: "Light Novel", value: "2443" }, + { label: "Published Novel", value: "26874" }, + { label: "Web Novel", value: "2444" }, + ] + }, + genres: { + label: "Genres", + type: FilterTypes.CheckboxGroup, + value: [], + options: [ + { label: "Action", value: "8" }, + { label: "Adult", value: "280" }, + { label: "Adventure", value: "13" }, + { label: "Comedy", value: "17" }, + { label: "Drama", value: "9" }, + { label: "Ecchi", value: "292" }, + { label: "Fantasy", value: "5" }, + { label: "Gender Bender", value: "168" }, + { label: "Harem", value: "3" }, + { label: "Historical", value: "330" }, + { label: "Horror", value: "343" }, + { label: "Josei", value: "324" }, + { label: "Martial Arts", value: "14" }, + { label: "Mature", value: "4" }, + { label: "Mecha", value: "10" }, + { label: "Mystery", value: "245" }, + { label: "Psychoical", value: "486" }, + { label: "Romance", value: "15" }, + { label: "School Life", value: "6" }, + { label: "Sci-fi", value: "11" }, + { label: "Seinen", value: "18" }, + { label: "Shoujo", value: "157" }, + { label: "Shoujo Ai", value: "851" }, + { label: "Shounen", value: "12" }, + { label: "Shounen Ai", value: "1692" }, + { label: "Slice of Life", value: "7" }, + { label: "Smut", value: "281" }, + { label: "Sports", value: "1357" }, + { label: "Supernatural", value: "16" }, + { label: "Tragedy", value: "132" }, + { label: "Wuxia", value: "479" }, + { label: "Xianxia", value: "480" }, + { label: "Xuanhuan", value: "3954" }, + { label: "Yaoi", value: "560" }, + { label: "Yuri", value: "922" }, + ] + } + } + +} + +export default new NovelUpdates(); diff --git a/plugins/english/wuxiaworld.broken.ts b/plugins/english/wuxiaworld.broken.ts deleted file mode 100644 index 5c952bc..0000000 --- a/plugins/english/wuxiaworld.broken.ts +++ /dev/null @@ -1,146 +0,0 @@ -import cheerio from "cheerio"; -import { fetchApi, fetchFile } from "@libs/fetch"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; - -export const id = "wuxiaworld"; -export const name = "Wuxia World (WIP)"; -export const version = "0.5.0"; -export const icon = "src/en/wuxiaworld/icon.png"; -export const site = "https://www.wuxiaworld.com/"; - - -const pluginId = id; -const baseUrl = site; - -export const popularNovels: Plugin.popularNovels = async function (page) { - const link = `${baseUrl}api/novels`; - - const result = await fetchApi(link, {}, pluginId); - const data = await result.json(); - - let novels: Novel.Item[] = []; - - data.items.map((novel) => { - let name = novel.name; - let cover = novel.coverUrl; - let url = baseUrl + "novel/" + novel.slug + "/"; - - novels.push({ - name, - cover, - url, - }); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const url = novelUrl; - console.log(url); - const result = await fetchApi(url, {}, pluginId); - const body = await result.text(); - - const loadedCheerio = cheerio.load(body); - - const novel: Novel.instance = { - url, - chapters: [], - }; - - novel.name = loadedCheerio("h1.line-clamp-2").text(); - - novel.cover = loadedCheerio("img.absolute").attr("src"); - - novel.summary = loadedCheerio( - "div.flex-col:nth-child(4) > div > div > span > span" - ) - .text() - .trim(); - - novel.author = loadedCheerio("div.MuiGrid-container > div > div > div") - .filter(function () { - return loadedCheerio(this).text().trim() === "Author:"; - }) - .next() - .text(); - - let genres: string[] = []; - - loadedCheerio("a.MuiLink-underlineNone").each(function () { - genres.push(loadedCheerio(this).find("div > div").text()); - }); - - novel.genres = genres.join(","); - - novel.status = loadedCheerio("div.font-set-b10") - .text() - .includes("Complete"); - - let chapter: Chapter.Item[] = []; - - loadedCheerio("div.border-b").each(function () { - const name = loadedCheerio(this) - .find("a > div > div > div > span") - .text(); - const releaseTime = loadedCheerio(this) - .find("a > div > div > div > div > span") - .text(); - let url = loadedCheerio(this).find("a").attr("href")?.slice(1); - url = `${baseUrl}${url}`; - - chapter.push({ name, releaseTime, url }); - }); - - novel.chapters = chapter; - - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const result = await fetchApi(chapterUrl, {}, pluginId); - const body = await result.text(); - - const loadedCheerio = cheerio.load(body); - - loadedCheerio(".chapter-nav").remove(); - - loadedCheerio("#chapter-content > script").remove(); - - let chapterText = loadedCheerio("#chapter-content").html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const searchUrl = "https://www.wuxiaworld.com/api/novels/search?query="; - - const url = `${searchUrl}${searchTerm}`; - - const result = await fetchApi(url); - const data = await result.json(); - - const novels: Novel.Item[] = []; - - data.items.map((novel) => { - let name = novel.name; - let cover = novel.cover; - let url = baseUrl + "novel/" + novel.slug + "/"; - - novels.push({ - name, - url, - cover, - }); - }); - - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async function (url) { - const headers = { - Referer: baseUrl, - }; - return await fetchFile(url, { headers: headers }); -}; diff --git a/plugins/english/wuxiaworld.ts b/plugins/english/wuxiaworld.ts new file mode 100644 index 0000000..30060eb --- /dev/null +++ b/plugins/english/wuxiaworld.ts @@ -0,0 +1,145 @@ +import { load as parseHTML} from "cheerio"; +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Plugin } from "@typings/plugin"; +import { Filters } from "@libs/filterInputs"; + +interface NovelEntry { + name: string; + coverUrl: string; + slug: string; +} + +class WuxiaWorld implements Plugin.PluginBase { + id = "wuxiaworld"; + name = "Wuxia World"; + icon = "src/en/wuxiaworld/icon.png"; + site = "https://www.wuxiaworld.com/"; + filters?: Filters | undefined; + version = "0.5.0"; + baseUrl = this.site; + async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { + const link = `${this.baseUrl}api/novels`; + + const result = await fetch(link); + const data = await result.json(); + + let novels: Plugin.NovelItem[] = []; + + data.items.map((novel: NovelEntry) => { + let name = novel.name; + let cover = novel.coverUrl; + let url = this.baseUrl + "novel/" + novel.slug + "/"; + + novels.push({ + name, + cover, + url, + }); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const url = novelUrl; + const result = await fetchApi(url); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + + const novel: Plugin.SourceNovel = { + url, + chapters: [], + }; + + novel.name = loadedCheerio("h1.line-clamp-2").text(); + + novel.cover = loadedCheerio("img.absolute").attr("src"); + + novel.summary = loadedCheerio( + "div.flex-col:nth-child(4) > div > div > span > span" + ) + .text() + .trim(); + + novel.author = loadedCheerio("div.MuiGrid-container > div > div > div") + .filter(function () { + return loadedCheerio(this).text().trim() === "Author:"; + }) + .next() + .text(); + + let genres: string[] = []; + + loadedCheerio("a.MuiLink-underlineNone").each(function () { + genres.push(loadedCheerio(this).find("div > div").text()); + }); + + novel.genres = genres.join(","); + + novel.status = loadedCheerio("div.font-set-b10") + .text(); + + let chapter: Plugin.ChapterItem[] = []; + + loadedCheerio("div.border-b.border-gray-line-base").each((idx, ele) => { + const name = loadedCheerio(ele) + .find("a > div > div > div > span") + .text(); + const releaseTime = loadedCheerio(ele) + .find("a > div > div > div > div > span") + .text(); + let url = loadedCheerio(ele).find("a").attr("href")?.slice(1); + url = `${this.baseUrl}${url}`; + + chapter.push({ name, releaseTime, url }); + }); + + novel.chapters = chapter; + + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const result = await fetchApi(chapterUrl); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + + loadedCheerio(".chapter-nav").remove(); + + loadedCheerio("#chapter-content > script").remove(); + + let chapterText = loadedCheerio("#chapter-content").html() || ''; + + return chapterText; + } + async searchNovels(searchTerm: string, pageNo: number): Promise { + const searchUrl = "https://www.wuxiaworld.com/api/novels/search?query="; + + const url = `${searchUrl}${searchTerm}`; + + const result = await fetchApi(url); + const data = await result.json(); + + const novels: Plugin.NovelItem[] = []; + + data.items.map((novel: NovelEntry) => { + let name = novel.name; + let cover = novel.coverUrl; + let url = this.baseUrl + "novel/" + novel.slug + "/"; + + novels.push({ + name, + url, + cover, + }); + }); + + return novels; + } + fetchImage(url: string): Promise { + return fetchFile(url); + } + +} + +export default new WuxiaWorld(); \ No newline at end of file