fix: Bug Fixes and Feature Improvements to Linovelib Plugin (#1984)

* fix(linovelib): Searching not work

* ci: fix branch cannot be correctly identified in forked environment

* fix: BRANCH cannot be identified

* fix(linovelib): correctly get cover image in redirect case of searching

* fix: why we need a prefix slash here? remove it

* chore(linovelib): update linovelib plugin version

* fix: before LNReader puts its default UA to chrome, forcely set LNReader plugin's UA to Chrome's UA

* refactor: intgrates FetchInit into plugin

* feat: add chapter name transform

* feat(linovelib): add decryptor for shuffle scramble of original html

* feat(linovelib): use external server to extract shuffle coefficients

* fix(linovelib): extract author name more precisely

* fix(linovelib): set Referer header to bypass anti-leeching/hotlinking of image source

Also, use LocalStorage to store coefficients and chapter.js version

* refactor: delete FetchInit definition in this plugin

* fix(linovelib): replace localStorage with storage utility for better data management

* fix(linovelib): update storage import path to use the correct library

* feat(linovelib): Implement chapter number

* refactor(linovelib): as mobile site equipped with strong cloudflare challenge, move most of parsing logic to LDS server

* fix(linovelib): update API calls to use query parameters instead of POST requests for novel, chapter, and search endpoints

* fix(linovelib): add caching mechanism for novel and chapter parsing to reduce API calls

* refactor(linovelib): refactor server URL handling to use class property for API requests

* fix: apply changes pointed by review

* docs(linovelib): make some comments
This commit is contained in:
ConstasJ
2026-02-06 02:12:31 +08:00
committed by GitHub
parent 99932748de
commit 6e2e51f3dd
7 changed files with 289 additions and 733 deletions
+3 -2
View File
@@ -4755,9 +4755,10 @@
},
"node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"resolved": "https://registry.npmmirror.com/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"domelementtype": "^2.3.0"
},
@@ -12030,7 +12031,7 @@
},
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"resolved": "https://registry.npmmirror.com/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dev": true,
"requires": {
+52 -462
View File
@@ -1,15 +1,35 @@
import { CheerioAPI, load as parseHTML } from 'cheerio';
import { load as parseHTML } from 'cheerio';
import { fetchText } from '@libs/fetch';
import { FilterTypes, Filters } from '@libs/filterInputs';
import { Plugin } from '@/types/plugin';
import { NovelStatus } from '@libs/novelStatus';
import { storage } from '@libs/storage';
class Linovelib implements Plugin.PluginBase {
id = 'linovelib';
name = 'Linovelib';
icon = 'src/cn/linovelib/icon.png';
site = 'https://www.bilinovel.com';
version = '1.1.3';
version = '1.2.0';
imageRequestInit?: Plugin.ImageRequestInit | undefined = {
method: 'GET',
headers: {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36 Edg/144.0.0.0',
'Referer': 'https://www.linovelib.com',
'Accept':
'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
},
};
webStorageUtilized = true;
// The URL of the custom LDS (Linovelib Descramble Server) URL. Due to complex de-scrambling logic, an external LDS is required.
pluginSettings = {
host: {
value: 'http://example.com',
label: 'Custom LDS Host',
type: 'Text',
},
};
serverUrl = storage.get('host') || 'http://localhost:5301';
async popularNovels(
pageNo: number,
@@ -34,7 +54,8 @@ class Linovelib implements Plugin.PluginBase {
const novelName = loadedCheerio(el).find('.book-title').text();
const novelCover = loadedCheerio(el)
.find('div.book-cover > img')
.attr('data-src');
.attr('data-src')
?.replace('/https', 'https');
if (!url) return;
const novel = {
@@ -50,476 +71,45 @@ class Linovelib implements Plugin.PluginBase {
}
async parseNovel(novelPath: string): Promise<Plugin.SourceNovel> {
const url = this.site + novelPath;
const body = await fetchText(url);
if (body === '') throw Error('无法获取小说内容,请检查网络');
const loadedCheerio = parseHTML(body);
const novel: Plugin.SourceNovel = {
path: novelPath,
chapters: [],
name: loadedCheerio('#bookDetailWrapper .book-title').text(),
};
novel.cover = loadedCheerio('#bookDetailWrapper img.book-cover').attr(
'src',
// move major logic to LDS
const res = await fetchText(
`${this.serverUrl}/api/novel?path=${novelPath}`,
);
novel.summary = loadedCheerio('#bookSummary content').text();
novel.author = loadedCheerio('#bookDetailWrapper .book-rand-a a').text();
const meta = loadedCheerio('#bookDetailWrapper .book-meta').text();
novel.status = meta.includes('完结')
? NovelStatus.Completed
: NovelStatus.Ongoing;
novel.genres = loadedCheerio('.tag-small.red')
.children('a')
.map((i, el) => loadedCheerio(el).text())
.toArray()
.join(',');
// Table of Content is on a different page than the summary page
const chapter: Plugin.ChapterItem[] = [];
const idPattern = /\/(\d+)\.html/;
const novelId = url.match(idPattern)?.[1];
const chaptersUrl = this.site + loadedCheerio('#btnReadBook').attr('href');
const chaptersBody = await fetchText(chaptersUrl);
const chaptersLoadedCheerio = parseHTML(chaptersBody);
let volumeName: string, chapterId: number;
chaptersLoadedCheerio('#volumes .chapter-li:not(.volume-cover)').each(
(i, el) => {
if (chaptersLoadedCheerio(el).hasClass('chapter-bar')) {
volumeName = chaptersLoadedCheerio(el).text();
return;
} else {
const urlPart = chaptersLoadedCheerio(el)
.find('.chapter-li-a')
.attr('href');
const chapterIdMatch = urlPart?.match(idPattern);
// Sometimes the href attribute does not contain the url, but javascript:cid(0).
// Increment the previous chapter ID should result in the right URL
if (chapterIdMatch) {
chapterId = +chapterIdMatch[1];
} else {
chapterId++;
}
}
const chapterUrl = `/novel/${novelId}/${chapterId}.html`;
const chapterName =
volumeName +
' — ' +
chaptersLoadedCheerio(el).find('.chapter-index').text().trim();
const releaseDate = null;
if (!chapterId) return;
chapter.push({
name: chapterName,
releaseTime: releaseDate,
path: chapterUrl,
});
},
);
novel.chapters = chapter;
const novel = JSON.parse(res) as Plugin.SourceNovel;
return novel;
}
async parseChapter(chapterPath: string): Promise<string> {
let chapterName,
chapterText = '',
hasNextPage,
pageHasNextPage,
pageText = '';
let pageNumber = 1;
/*
* TODO: Maybe there are other ways to get the translation table
* It is embed and encrypted inside readtool.js
* UPDATE: Decrypted, see skillgg
*/
// const mapping_dict = {
// '“': '「',
// '’': '』',
// '': '是',
// '': '不',
// '': '好',
// '': '个',
// '': '开',
// '': '样',
// '': '想',
// '': '说',
// '': '年',
// '': '那',
// '': '她',
// '': '美',
// '': '自',
// '': '家',
// '': '而',
// '': '去',
// '': '都',
// '': '于',
// '': '舔',
// '': '他',
// '': '只',
// '': '看',
// '': '来',
// '': '用',
// '': '道',
// '': '得',
// '': '乳',
// '': '茎',
// '': '肉',
// '': '胸',
// '': '淫',
// '': '性',
// '': '骚',
// '”': '」',
// '': '的',
// '': '当',
// '': '人',
// '': '有',
// '': '上',
// '': '到',
// '': '地',
// '': '中',
// '': '生',
// '': '着',
// '': '和',
// '': '起',
// '': '交',
// '': '以',
// '': '可',
// '': '过',
// '': '能',
// '': '多',
// '': '心',
// '': '小',
// '': '成',
// '': '了',
// '': '把',
// '': '发',
// '': '第',
// '': '子',
// '': '事',
// '': '阴',
// '': '欲',
// '': '里',
// '': '私',
// '': '臀',
// '': '脱',
// '': '唇',
// '‘': '『',
// '': '一',
// '': '我',
// '': '在',
// '': '这',
// '': '们',
// '': '时',
// '': '为',
// '': '你',
// '': '国',
// '': '就',
// '': '要',
// '': '也',
// '': '后',
// '': '没',
// '': '下',
// '': '天',
// '': '对',
// '': '然',
// '': '学',
// '': '之',
// '': '出',
// '': '没',
// '': '如',
// '': '还',
// '': '大',
// '': '作',
// '': '种',
// '': '液',
// '': '呻',
// '': '射',
// '': '穴',
// '': '么',
// '': '裸',
// };
const skillgg: Record<string, string> = {
'\u201c': '\u300c',
'\u201d': '\u300d',
'\u2018': '\u300e',
'\u2019': '\u300f',
'\ue82c': '\u7684',
'\ue852': '\u4e00',
'\ue82d': '\u662f',
'\ue819': '\u4e86',
'\ue856': '\u6211',
'\ue857': '\u4e0d',
'\ue816': '\u4eba',
'\ue83c': '\u5728',
'\ue830': '\u4ed6',
'\ue82e': '\u6709',
'\ue836': '\u8fd9',
'\ue859': '\u4e2a',
'\ue80a': '\u4e0a',
'\ue855': '\u4eec',
'\ue842': '\u6765',
'\ue858': '\u5230',
'\ue80b': '\u65f6',
'\ue81f': '\u5927',
'\ue84a': '\u5730',
'\ue853': '\u4e3a',
'\ue81e': '\u5b50',
'\ue822': '\u4e2d',
'\ue813': '\u4f60',
'\ue85b': '\u8bf4',
'\ue807': '\u751f',
'\ue818': '\u56fd',
'\ue810': '\u5e74',
'\ue812': '\u7740',
'\ue851': '\u5c31',
'\ue801': '\u90a3',
'\ue80c': '\u548c',
'\ue815': '\u8981',
'\ue84c': '\u5979',
'\ue840': '\u51fa',
'\ue848': '\u4e5f',
'\ue835': '\u5f97',
'\ue800': '\u91cc',
'\ue826': '\u540e',
'\ue863': '\u81ea',
'\ue861': '\u4ee5',
'\ue854': '\u4f1a',
'\ue827': '\u5bb6',
'\ue83b': '\u53ef',
'\ue85d': '\u4e0b',
'\ue84d': '\u800c',
'\ue862': '\u8fc7',
'\ue81c': '\u5929',
'\ue81d': '\u53bb',
'\ue860': '\u80fd',
'\ue843': '\u5bf9',
'\ue82f': '\u5c0f',
'\ue802': '\u591a',
'\ue831': '\u7136',
'\ue84b': '\u4e8e',
'\ue837': '\u5fc3',
'\ue829': '\u5b66',
'\ue85e': '\u4e48',
'\ue83a': '\u4e4b',
'\ue832': '\u90fd',
'\ue808': '\u597d',
'\ue841': '\u770b',
'\ue821': '\u8d77',
'\ue845': '\u53d1',
'\ue803': '\u5f53',
'\ue828': '\u6ca1',
'\ue81b': '\u6210',
'\ue83e': '\u53ea',
'\ue820': '\u5982',
'\ue84e': '\u4e8b',
'\ue85a': '\u628a',
'\ue806': '\u8fd8',
'\ue83f': '\u7528',
'\ue833': '\u7b2c',
'\ue811': '\u6837',
'\ue804': '\u9053',
'\ue814': '\u60f3',
'\ue80f': '\u4f5c',
'\ue84f': '\u79cd',
'\ue80e': '\u5f00',
'\ue823': '\u7f8e',
'\ue849': '\u4e73',
'\ue805': '\u9634',
'\ue809': '\u6db2',
'\ue81a': '\u830e',
'\ue844': '\u6b32',
'\ue847': '\u547b',
'\ue850': '\u8089',
'\ue824': '\u4ea4',
'\ue85f': '\u6027',
'\ue817': '\u80f8',
'\ue85c': '\u79c1',
'\ue838': '\u7a74',
'\ue82a': '\u6deb',
'\ue83d': '\u81c0',
'\ue82b': '\u8214',
'\ue80d': '\u5c04',
'\ue839': '\u8131',
'\ue834': '\u88f8',
'\ue846': '\u9a9a',
'\ue825': '\u5507',
};
const addPage = async (pageCheerio: CheerioAPI) => {
const formatPage = async () => {
// Remove JS and notice of the website
pageCheerio(
'#acontent .adsbygoogle, #acontent script, center',
).remove();
// Load lazyloaded images
pageCheerio('#acontent img.imagecontent').each((i, el) => {
// Sometimes images are either in data-src or src
const imgSrc =
pageCheerio(el).attr('data-src') || pageCheerio(el).attr('src');
if (imgSrc) {
// Clean up img element
pageCheerio(el)
.attr('src', imgSrc)
.removeAttr('data-src')
.removeClass('lazyload');
// move major logic to LDS
const lastFetchChapterTime =
storage.get('lastFetchChapterTime_' + chapterPath) || 0;
if (Date.now() - lastFetchChapterTime < 10000) {
return storage.get('chapterContent_' + chapterPath) || '';
}
});
// Recover the original character
pageText = pageCheerio('#acontent').html() || '';
pageText = pageText.replace(/./g, char => skillgg[char] || char);
return Promise.resolve();
};
await formatPage();
chapterName =
pageCheerio('#atitle + h3').text() +
' — ' +
pageCheerio('#atitle').text();
if (chapterText === '') {
chapterText = '<h2>' + chapterName + '</h2>';
}
chapterText += pageText;
};
const loadPage = async (url: string) => {
const headers = {
'Accept':
'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language':
'zh-CN,zh;q=0.9,zh-TW;q=0.8,zh-HK;q=0.7,en;q=0.6,en-GB;q=0.5,en-US;q=0.4',
'Cache-Control': 'no-cache',
};
const body = await fetchText(url, { headers });
const pageCheerio = parseHTML(body);
await addPage(pageCheerio);
pageHasNextPage =
pageCheerio('#footlink a:last').text() === '下一页' ||
pageCheerio('#footlink a:last').text() === '下一頁'
? true
: false;
return { pageCheerio, pageHasNextPage };
};
let url = this.site + chapterPath;
const baseUrl = url;
do {
const page = await loadPage(url);
hasNextPage = page.pageHasNextPage;
if (hasNextPage === true) {
pageNumber++;
url = baseUrl.replace(/\.html/gi, `_${pageNumber}` + '.html');
}
} while (hasNextPage === true);
return chapterText;
const res = await fetchText(
`${this.serverUrl}/api/chapter?path=${chapterPath}`,
);
const resObj = JSON.parse(res);
storage.set('lastFetchChapterTime_' + chapterPath, Date.now());
storage.set('chapterContent_' + chapterPath, resObj.content);
return resObj.content;
}
async searchNovels(
searchTerm: string,
pageNo: number,
): Promise<Plugin.NovelItem[]> {
const url = `${this.site}/search/${encodeURI(searchTerm)}_${pageNo}.html`;
const body = await fetchText(url);
if (body === '') throw Error('无法获取搜索结果,请检查网络');
const pageCheerio = parseHTML(body);
const novels: Plugin.NovelItem[] = [];
// const addPage = async (pageCheerio: CheerioAPI, redirect: string) => {
// const loadSearchResults = () => {
// pageCheerio(".book-ol .book-layout").each((i, el) => {
// let nUrl = pageCheerio(el).attr("href");
// const novelName = pageCheerio(el)
// .find(".book-title")
// .text();
// const novelCover = pageCheerio(el)
// .find("div.book-cover > img")
// .attr("data-src");
// const novelUrl = this.site + nUrl;
// if (!nUrl) return;
// novels.push({
// name: novelName,
// url: novelUrl,
// cover: novelCover,
// });
// });
// };
// const novelResults = pageCheerio(".book-ol a.book-layout");
// if (novelResults.length === 0) {
// } else {
// loadSearchResults();
// }
// if (redirect.length) {
// novels.length = 0;
// const novelName = pageCheerio(
// "#bookDetailWrapper .book-title"
// ).text();
// const novelCover = pageCheerio(
// "#bookDetailWrapper div.book-cover > img"
// ).attr("src");
// const novelUrl =
// this.site +
// pageCheerio("#btnReadBook").attr("href")?.slice(0, -8) +
// ".html";
// novels.push({
// name: novelName,
// url: novelUrl,
// cover: novelCover,
// });
// }
// };
// NOTE: don't know redirect is for what, comment out for now
// const redirect = pageCheerio("div.book-layout").text();
// await addPage(pageCheerio, redirect);
pageCheerio('.book-ol .book-layout').each((i, el) => {
const nUrl = pageCheerio(el).attr('href');
const novelName = pageCheerio(el).find('.book-title').text();
const novelCover = pageCheerio(el)
.find('div.book-cover > img')
.attr('data-src');
if (!nUrl) return;
novels.push({
name: novelName,
path: nUrl,
cover: novelCover,
});
});
return novels;
// move major logic to LDS
const lastSearchTime = storage.get('lastSearchTime_' + this.id) || 0;
if (Date.now() - lastSearchTime < 5000) {
return [];
}
const res = await fetchText(
`${this.serverUrl}/api/search?keyword=${encodeURIComponent(searchTerm)}`,
);
const novelsData = JSON.parse(res).results as Plugin.NovelItem[];
storage.set('lastSearchTime_' + this.id, Date.now());
return novelsData;
}
filters = {
+228 -262
View File
@@ -1,255 +1,238 @@
import { Plugin } from '@/types/plugin';
import p_0 from '@plugins/arabic/ArNovel[madara]';
import p_1 from '@plugins/arabic/Azora[madara]';
import p_2 from '@plugins/arabic/FreeKolNovel[lightnovelwp]';
import p_3 from '@plugins/arabic/HizoManga[madara]';
import p_4 from '@plugins/arabic/KolNovel[lightnovelwp]';
import p_5 from '@plugins/arabic/Novel4Up[madara]';
import p_6 from '@plugins/arabic/NovelsParadise[lightnovelwp]';
import p_7 from '@plugins/arabic/Olaoecyou[madara]';
import p_8 from '@plugins/arabic/Riwyat[madara]';
import p_9 from '@plugins/arabic/dilartube';
import p_10 from '@plugins/arabic/rewayatclub';
import p_2 from '@plugins/arabic/dilartube';
import p_3 from '@plugins/arabic/FreeKolNovel[lightnovelwp]';
import p_4 from '@plugins/arabic/HizoManga[madara]';
import p_5 from '@plugins/arabic/KolNovel[lightnovelwp]';
import p_6 from '@plugins/arabic/Novel4Up[madara]';
import p_7 from '@plugins/arabic/NovelsParadise[lightnovelwp]';
import p_8 from '@plugins/arabic/Olaoecyou[madara]';
import p_9 from '@plugins/arabic/rewayatclub';
import p_10 from '@plugins/arabic/Riwyat[madara]';
import p_11 from '@plugins/arabic/sunovels';
import p_12 from '@plugins/chinese/69shu';
import p_13 from '@plugins/chinese/Quanben';
import p_14 from '@plugins/chinese/ixdzs8';
import p_15 from '@plugins/chinese/linovel';
import p_16 from '@plugins/chinese/linovelib';
import p_17 from '@plugins/chinese/linovelib_tw';
import p_18 from '@plugins/chinese/novel543';
import p_13 from '@plugins/chinese/ixdzs8';
import p_14 from '@plugins/chinese/linovel';
import p_15 from '@plugins/chinese/linovelib';
import p_16 from '@plugins/chinese/linovelib_tw';
import p_17 from '@plugins/chinese/novel543';
import p_18 from '@plugins/chinese/Quanben';
import p_19 from '@plugins/english/AllNovelFull[readnovelfull]';
import p_20 from '@plugins/english/AllNovel[readnovelfull]';
import p_21 from '@plugins/english/ArcaneTranslations[lightnovelwp]';
import p_22 from '@plugins/english/BelleReservoir[madara]';
import p_23 from '@plugins/english/BoxNovel[readnovelfull]';
import p_24 from '@plugins/english/CPUnovel[lightnovelwp]';
import p_25 from '@plugins/english/CitrusAurora[madara]';
import p_26 from '@plugins/english/CoralBoutique[madara]';
import p_27 from '@plugins/english/DaoNovel[madara]';
import p_28 from '@plugins/english/DaoTranslate[lightnovelwp]';
import p_29 from '@plugins/english/DaoistQuest[fictioneer]';
import p_30 from '@plugins/english/DearestRosalie[fictioneer]';
import p_31 from '@plugins/english/DragonTea[madara]';
import p_32 from '@plugins/english/Dragonholic[madara]';
import p_33 from '@plugins/english/DuskBlossoms[madara]';
import p_34 from '@plugins/english/ElloTL[lightnovelwp]';
import p_35 from '@plugins/english/Eternalune[madara]';
import p_36 from '@plugins/english/EtudeTranslations[madara]';
import p_37 from '@plugins/english/FanNovel[readwn]';
import p_38 from '@plugins/english/FansMTL[readwn]';
import p_39 from '@plugins/english/FansTranslations[madara]';
import p_40 from '@plugins/english/FirstKissNovel[madara]';
import p_41 from '@plugins/english/Foxaholic[madara]';
import p_42 from '@plugins/english/FreeWebNovel[readnovelfull]';
import p_43 from '@plugins/english/GalaxyTranslations[madara]';
import p_44 from '@plugins/english/Guavaread[madara]';
import p_45 from '@plugins/english/HiraethTranslation[madara]';
import p_46 from '@plugins/english/HotNovelPub[hotnovelpub]';
import p_47 from '@plugins/english/Ippotranslations[lightnovelwp]';
import p_48 from '@plugins/english/KeopiTranslations[lightnovelwp]';
import p_49 from '@plugins/english/KnoxT[lightnovelwp]';
import p_50 from '@plugins/english/LazyGirlTranslations[lightnovelwp]';
import p_51 from '@plugins/english/LibRead[readnovelfull]';
import p_52 from '@plugins/english/LightNovelCave[lightnovelworld]';
import p_53 from '@plugins/english/LightNovelHeaven[madara]';
import p_54 from '@plugins/english/LightNovelPlus[readnovelfull]';
import p_55 from '@plugins/english/LightNovelPubVip[lightnovelworld]';
import p_56 from '@plugins/english/LightNovelUpdates[madara]';
import p_57 from '@plugins/english/LightNovelWord[lightnovelworld]';
import p_58 from '@plugins/english/LilyontheValley[fictioneer]';
import p_59 from '@plugins/english/Ltnovel[readwn]';
import p_60 from '@plugins/english/LunarLetters[madara]';
import p_61 from '@plugins/english/MTLNovel[madara]';
import p_62 from '@plugins/english/MTLNovel[mtlnovel]';
import p_63 from '@plugins/english/Meownovel[madara]';
import p_64 from '@plugins/english/MoonlightNovels[lightnovelwp]';
import p_65 from '@plugins/english/MostNovel[madara]';
import p_66 from '@plugins/english/MysticalSeries[madara]';
import p_67 from '@plugins/english/NeoSekaiTranslations[madara]';
import p_68 from '@plugins/english/NitroManga[madara]';
import p_69 from '@plugins/english/NobleMTL[lightnovelwp]';
import p_70 from '@plugins/english/NoiceTranslations[madara]';
import p_71 from '@plugins/english/NovelBin[readnovelfull]';
import p_72 from '@plugins/english/NovelCool[novelcool]';
import p_73 from '@plugins/english/NovelFull[readnovelfull]';
import p_74 from '@plugins/english/NovelLib[fictioneer]';
import p_75 from '@plugins/english/NovelMultiverse[madara]';
import p_76 from '@plugins/english/NovelOnline';
import p_77 from '@plugins/english/NovelTranslate[madara]';
import p_78 from '@plugins/english/NovelsKnight[lightnovelwp]';
import p_79 from '@plugins/english/PandaMachineTranslations[lightnovelwp]';
import p_80 from '@plugins/english/PastelTales[madara]';
import p_81 from '@plugins/english/PenguinSquad[fictioneer]';
import p_82 from '@plugins/english/Prizma[fictioneer]';
import p_83 from '@plugins/english/Ranobes[ranobes]';
import p_84 from '@plugins/english/Ranovel[madara]';
import p_85 from '@plugins/english/ReadFanfic[madara]';
import p_86 from '@plugins/english/ReadNovelFull[readnovelfull]';
import p_87 from '@plugins/english/RequiemTranslations[lightnovelwp]';
import p_88 from '@plugins/english/SalmonLatte[madara]';
import p_89 from '@plugins/english/SleepyTranslations[madara]';
import p_90 from '@plugins/english/SonicMTL[madara]';
import p_91 from '@plugins/english/SrankManga[madara]';
import p_92 from '@plugins/english/StorySeedling';
import p_93 from '@plugins/english/SweetEscape[madara]';
import p_94 from '@plugins/english/SystemTranslation[lightnovelwp]';
import p_95 from '@plugins/english/TranslatinOtaku[madara]';
import p_96 from '@plugins/english/TranslationWeaver[lightnovelwp]';
import p_97 from '@plugins/english/UniversalNovel[lightnovelwp]';
import p_98 from '@plugins/english/VandyTranslate[lightnovelwp]';
import p_99 from '@plugins/english/VioletLily[madara]';
import p_100 from '@plugins/english/WebNovelLover[madara]';
import p_101 from '@plugins/english/WebNovelPub[lightnovelworld]';
import p_102 from '@plugins/english/WebNovelTranslation[madara]';
import p_103 from '@plugins/english/WhiteMoonlightNovels[lightnovelwp]';
import p_104 from '@plugins/english/WooksTeahouse[madara]';
import p_105 from '@plugins/english/WordExcerpt[madara]';
import p_106 from '@plugins/english/WuxiaSpace[readwn]';
import p_107 from '@plugins/english/WuxiaV[readwn]';
import p_108 from '@plugins/english/WuxiaWorldSite[madara]';
import p_109 from '@plugins/english/Wuxiabox[readwn]';
import p_110 from '@plugins/english/Wuxiafox[readwn]';
import p_111 from '@plugins/english/ZetroTranslation[madara]';
import p_112 from '@plugins/english/ao3';
import p_113 from '@plugins/english/bestlightnovel';
import p_114 from '@plugins/english/chrysanthemumgarden';
import p_115 from '@plugins/english/crimsonscrolls';
import p_116 from '@plugins/english/divinedaolibrary';
import p_117 from '@plugins/english/dreambigtl';
import p_118 from '@plugins/english/earlynovel';
import p_119 from '@plugins/english/faqwikius';
import p_120 from '@plugins/english/fenrirrealm';
import p_121 from '@plugins/english/fictionzone';
import p_122 from '@plugins/english/foxteller';
import p_123 from '@plugins/english/genesis';
import p_124 from '@plugins/english/inkitt';
import p_125 from '@plugins/english/kdtnovels';
import p_126 from '@plugins/english/leafstudio';
import p_127 from '@plugins/english/lightnovelpub';
import p_128 from '@plugins/english/lightnoveltranslation';
import p_129 from '@plugins/english/lnmtl';
import p_130 from '@plugins/english/mtlreader';
import p_131 from '@plugins/english/mvlempyr';
import p_132 from '@plugins/english/novelbuddy';
import p_133 from '@plugins/english/novelfire.paged';
import p_134 from '@plugins/english/novelfire';
import p_135 from '@plugins/english/novelhall';
import p_136 from '@plugins/english/novelight';
import p_137 from '@plugins/english/novelupdates';
import p_138 from '@plugins/english/pawread';
import p_139 from '@plugins/english/rainofsnow';
import p_140 from '@plugins/english/readfrom';
import p_141 from '@plugins/english/readlitenovel';
import p_142 from '@plugins/english/reaperscans';
import p_143 from '@plugins/english/relibrary';
import p_144 from '@plugins/english/royalroad';
import p_145 from '@plugins/english/scribblehub';
import p_146 from '@plugins/english/vynovel';
import p_147 from '@plugins/english/webnovel';
import p_148 from '@plugins/english/wtrlab';
import p_149 from '@plugins/english/wuxiaworld';
import p_150 from '@plugins/french/LighNovelFR[lightnovelwp]';
import p_151 from '@plugins/french/MTLNovel(FR)[mtlnovel]';
import p_152 from '@plugins/french/MassNovel[madara]';
import p_153 from '@plugins/french/WorldNovel[madara]';
import p_154 from '@plugins/french/chireads';
import p_155 from '@plugins/french/harkeneliwood';
import p_156 from '@plugins/french/kisswood';
import p_157 from '@plugins/french/noveldeglace';
import p_158 from '@plugins/french/novhell';
import p_159 from '@plugins/french/phenixscans';
import p_160 from '@plugins/french/warriorlegendtrad';
import p_161 from '@plugins/french/wuxialnscantrad';
import p_162 from '@plugins/french/xiaowaz';
import p_163 from '@plugins/indonesian/BacaLightNovel[lightnovelwp]';
import p_164 from '@plugins/indonesian/MTLNovel(ID)[mtlnovel]';
import p_165 from '@plugins/indonesian/MeioNovel[madara]';
import p_166 from '@plugins/indonesian/NovelBookID[madara]';
import p_167 from '@plugins/indonesian/Risenovel[madara]';
import p_168 from '@plugins/indonesian/SekteNovel[lightnovelwp]';
import p_169 from '@plugins/indonesian/Vanovel[madara]';
import p_170 from '@plugins/indonesian/WBNovel[madara]';
import p_171 from '@plugins/indonesian/indowebnovel';
import p_172 from '@plugins/indonesian/novelringan';
import p_173 from '@plugins/indonesian/sakuranovel';
import p_174 from '@plugins/japanese/Syosetu';
import p_175 from '@plugins/japanese/kakuyomu';
import p_176 from '@plugins/korean/Agitoon';
import p_177 from '@plugins/korean/FortuneEternal[madara]';
import p_178 from '@plugins/multi/komga';
import p_179 from '@plugins/polish/novelki';
import p_180 from '@plugins/portuguese/BetterNovels[lightnovelwp]';
import p_181 from '@plugins/portuguese/CentralNovel[lightnovelwp]';
import p_182 from '@plugins/portuguese/Kiniga[madara]';
import p_183 from '@plugins/portuguese/LaNovels[hotnovelpub]';
import p_184 from '@plugins/portuguese/LightNovelBrasil[lightnovelwp]';
import p_185 from '@plugins/portuguese/MTLNovel(PT)[mtlnovel]';
import p_186 from '@plugins/portuguese/blogdoamonnovels';
import p_187 from '@plugins/portuguese/novelmania';
import p_188 from '@plugins/portuguese/tsundoku';
import p_189 from '@plugins/russian/Bookhamster[ifreedom]';
import p_190 from '@plugins/russian/Erolate[rulate]';
import p_191 from '@plugins/russian/EzNovels[hotnovelpub]';
import p_192 from '@plugins/russian/LitSpace';
import p_193 from '@plugins/russian/MTLNovel(RU)[mtlnovel]';
import p_194 from '@plugins/russian/NovelCool(RU)[novelcool]';
import p_195 from '@plugins/russian/Ranobes(RU)[ranobes]';
import p_196 from '@plugins/russian/Rulate[rulate]';
import p_197 from '@plugins/russian/authortoday';
import p_198 from '@plugins/russian/bookriver';
import p_199 from '@plugins/russian/ficbook';
import p_200 from '@plugins/russian/jaomix';
import p_201 from '@plugins/russian/neobook';
import p_202 from '@plugins/russian/novelOvh';
import p_203 from '@plugins/russian/novelTL';
import p_204 from '@plugins/russian/ranobehub';
import p_205 from '@plugins/russian/ranobelib';
import p_206 from '@plugins/russian/ranoberf';
import p_207 from '@plugins/russian/renovels';
import p_208 from '@plugins/russian/ruvers';
import p_209 from '@plugins/russian/topliba';
import p_210 from '@plugins/russian/zelluloza';
import p_211 from '@plugins/russian/СвободныйМирРанобэ[ifreedom]';
import p_212 from '@plugins/spanish/AllNovelRead[lightnovelwp]';
import p_213 from '@plugins/spanish/AnimesHoy12[madara]';
import p_214 from '@plugins/spanish/LightNovelDaily[hotnovelpub]';
import p_215 from '@plugins/spanish/MTLNovel(ES)[mtlnovel]';
import p_216 from '@plugins/spanish/PanchoTranslations[madara]';
import p_217 from '@plugins/spanish/TC&Sega[lightnovelwp]';
import p_218 from '@plugins/spanish/TraduccionesAmistosas[madara]';
import p_219 from '@plugins/spanish/hasutl';
import p_220 from '@plugins/spanish/novelasligera';
import p_221 from '@plugins/spanish/novelawuxia';
import p_222 from '@plugins/spanish/oasistranslations';
import p_223 from '@plugins/spanish/skynovels';
import p_224 from '@plugins/spanish/tunovelaligera';
import p_225 from '@plugins/spanish/yukitls';
import p_226 from '@plugins/thai/NovelLucky[madara]';
import p_227 from '@plugins/thai/NovelPDF[madara]';
import p_228 from '@plugins/turkish/ArazNovel[madara]';
import p_229 from '@plugins/turkish/EKTAPLAR[madara]';
import p_230 from '@plugins/turkish/KodeksLibrary[lightnovelwp]';
import p_231 from '@plugins/turkish/MangaTR';
import p_232 from '@plugins/turkish/NABSCANS[madara]';
import p_233 from '@plugins/turkish/Namevt[lightnovelwp]';
import p_234 from '@plugins/turkish/NovelTR[lightnovelwp]';
import p_235 from '@plugins/turkish/Noveloku[madara]';
import p_236 from '@plugins/turkish/RagnarScans[madara]';
import p_237 from '@plugins/turkish/ThNovels[hotnovelpub]';
import p_238 from '@plugins/turkish/TurkceLightNovels[madara]';
import p_239 from '@plugins/turkish/WebNovelOku[madara]';
import p_240 from '@plugins/turkish/epiknovel';
import p_241 from '@plugins/turkish/kakikata[madara]';
import p_242 from '@plugins/ukrainian/bakainua';
import p_243 from '@plugins/ukrainian/smakolykytl';
import p_244 from '@plugins/ukrainian/uaranobeclub';
import p_245 from '@plugins/vietnamese/LNHako';
import p_246 from '@plugins/vietnamese/Truyenconect';
import p_247 from '@plugins/vietnamese/lightnovelvn';
import p_248 from '@plugins/vietnamese/nettruyen';
import p_249 from '@plugins/vietnamese/truyenchu';
import p_250 from '@plugins/vietnamese/truyenfull';
import p_21 from '@plugins/english/ao3';
import p_22 from '@plugins/english/ArcaneTranslations[lightnovelwp]';
import p_23 from '@plugins/english/BelleReservoir[madara]';
import p_24 from '@plugins/english/BoxNovel[readnovelfull]';
import p_25 from '@plugins/english/chrysanthemumgarden';
import p_26 from '@plugins/english/CitrusAurora[madara]';
import p_27 from '@plugins/english/CoralBoutique[madara]';
import p_28 from '@plugins/english/CPUnovel[lightnovelwp]';
import p_29 from '@plugins/english/crimsonscrolls';
import p_30 from '@plugins/english/DaoistQuest[fictioneer]';
import p_31 from '@plugins/english/DaoNovel[madara]';
import p_32 from '@plugins/english/DaoTranslate[lightnovelwp]';
import p_33 from '@plugins/english/DearestRosalie[fictioneer]';
import p_34 from '@plugins/english/divinedaolibrary';
import p_35 from '@plugins/english/Dragonholic[madara]';
import p_36 from '@plugins/english/DragonTea[madara]';
import p_37 from '@plugins/english/dreambigtl';
import p_38 from '@plugins/english/DuskBlossoms[madara]';
import p_39 from '@plugins/english/ElloTL[lightnovelwp]';
import p_40 from '@plugins/english/Eternalune[madara]';
import p_41 from '@plugins/english/EtudeTranslations[madara]';
import p_42 from '@plugins/english/FanNovel[readwn]';
import p_43 from '@plugins/english/FansMTL[readwn]';
import p_44 from '@plugins/english/FansTranslations[madara]';
import p_45 from '@plugins/english/faqwikius';
import p_46 from '@plugins/english/fenrirrealm';
import p_47 from '@plugins/english/fictionzone';
import p_48 from '@plugins/english/FirstKissNovel[madara]';
import p_49 from '@plugins/english/Foxaholic[madara]';
import p_50 from '@plugins/english/foxteller';
import p_51 from '@plugins/english/FreeWebNovel[readnovelfull]';
import p_52 from '@plugins/english/GalaxyTranslations[madara]';
import p_53 from '@plugins/english/genesis';
import p_54 from '@plugins/english/Guavaread[madara]';
import p_55 from '@plugins/english/HiraethTranslation[madara]';
import p_56 from '@plugins/english/HotNovelPub[hotnovelpub]';
import p_57 from '@plugins/english/inkitt';
import p_58 from '@plugins/english/Ippotranslations[lightnovelwp]';
import p_59 from '@plugins/english/KDTNovels[lightnovelwp]';
import p_60 from '@plugins/english/KeopiTranslations[lightnovelwp]';
import p_61 from '@plugins/english/KnoxT[lightnovelwp]';
import p_62 from '@plugins/english/LazyGirlTranslations[lightnovelwp]';
import p_63 from '@plugins/english/leafstudio';
import p_64 from '@plugins/english/LibRead[readnovelfull]';
import p_65 from '@plugins/english/LightNovelCave[lightnovelworld]';
import p_66 from '@plugins/english/LightNovelHeaven[madara]';
import p_67 from '@plugins/english/LightNovelPlus[readnovelfull]';
import p_68 from '@plugins/english/LightNovelPubVip[lightnovelworld]';
import p_69 from '@plugins/english/lightnoveltranslation';
import p_70 from '@plugins/english/LightNovelUpdates[madara]';
import p_71 from '@plugins/english/LilyontheValley[fictioneer]';
import p_72 from '@plugins/english/lnmtl';
import p_73 from '@plugins/english/Ltnovel[readwn]';
import p_74 from '@plugins/english/LunarLetters[madara]';
import p_75 from '@plugins/english/Meownovel[madara]';
import p_76 from '@plugins/english/MoonlightNovels[lightnovelwp]';
import p_77 from '@plugins/english/MostNovel[madara]';
import p_78 from '@plugins/english/MTLNovel[madara]';
import p_79 from '@plugins/english/MTLNovel[mtlnovel]';
import p_80 from '@plugins/english/mtlreader';
import p_81 from '@plugins/english/mvlempyr';
import p_82 from '@plugins/english/MysticalSeries[madara]';
import p_83 from '@plugins/english/NeoSekaiTranslations[madara]';
import p_84 from '@plugins/english/NitroManga[madara]';
import p_85 from '@plugins/english/NobleMTL[lightnovelwp]';
import p_86 from '@plugins/english/NoiceTranslations[madara]';
import p_87 from '@plugins/english/NovelBin[readnovelfull]';
import p_88 from '@plugins/english/novelbuddy';
import p_89 from '@plugins/english/NovelCool[novelcool]';
import p_90 from '@plugins/english/novelfire';
import p_91 from '@plugins/english/NovelFull[readnovelfull]';
import p_92 from '@plugins/english/novelhall';
import p_93 from '@plugins/english/novelight';
import p_94 from '@plugins/english/NovelLib[fictioneer]';
import p_95 from '@plugins/english/NovelMultiverse[madara]';
import p_96 from '@plugins/english/NovelOnline';
import p_97 from '@plugins/english/NovelsKnight[lightnovelwp]';
import p_98 from '@plugins/english/NovelTranslate[madara]';
import p_99 from '@plugins/english/novelupdates';
import p_100 from '@plugins/english/PandaMachineTranslations[lightnovelwp]';
import p_101 from '@plugins/english/PastelTales[madara]';
import p_102 from '@plugins/english/pawread';
import p_103 from '@plugins/english/PenguinSquad[fictioneer]';
import p_104 from '@plugins/english/Prizma[fictioneer]';
import p_105 from '@plugins/english/rainofsnow';
import p_106 from '@plugins/english/Ranobes[ranobes]';
import p_107 from '@plugins/english/Ranovel[madara]';
import p_108 from '@plugins/english/ReadFanfic[madara]';
import p_109 from '@plugins/english/readfrom';
import p_110 from '@plugins/english/ReadNovelFull[readnovelfull]';
import p_111 from '@plugins/english/relibrary';
import p_112 from '@plugins/english/RequiemTranslations[lightnovelwp]';
import p_113 from '@plugins/english/royalroad';
import p_114 from '@plugins/english/SalmonLatte[madara]';
import p_115 from '@plugins/english/scribblehub';
import p_116 from '@plugins/english/SleepyTranslations[madara]';
import p_117 from '@plugins/english/SonicMTL[madara]';
import p_118 from '@plugins/english/SrankManga[madara]';
import p_119 from '@plugins/english/StorySeedling';
import p_120 from '@plugins/english/SweetEscape[madara]';
import p_121 from '@plugins/english/SystemTranslation[lightnovelwp]';
import p_122 from '@plugins/english/TranslatinOtaku[madara]';
import p_123 from '@plugins/english/TranslationWeaver[lightnovelwp]';
import p_124 from '@plugins/english/UniversalNovel[lightnovelwp]';
import p_125 from '@plugins/english/VandyTranslate[lightnovelwp]';
import p_126 from '@plugins/english/VioletLily[madara]';
import p_127 from '@plugins/english/vynovel';
import p_128 from '@plugins/english/webnovel';
import p_129 from '@plugins/english/WebNovelLover[madara]';
import p_130 from '@plugins/english/WebNovelPub[lightnovelworld]';
import p_131 from '@plugins/english/WebNovelTranslation[madara]';
import p_132 from '@plugins/english/WhiteMoonlightNovels[lightnovelwp]';
import p_133 from '@plugins/english/WooksTeahouse[madara]';
import p_134 from '@plugins/english/WordExcerpt[madara]';
import p_135 from '@plugins/english/wtrlab';
import p_136 from '@plugins/english/Wuxiabox[readwn]';
import p_137 from '@plugins/english/Wuxiafox[readwn]';
import p_138 from '@plugins/english/WuxiaSpace[readwn]';
import p_139 from '@plugins/english/WuxiaV[readwn]';
import p_140 from '@plugins/english/wuxiaworld';
import p_141 from '@plugins/english/WuxiaWorldSite[madara]';
import p_142 from '@plugins/english/ZetroTranslation[madara]';
import p_143 from '@plugins/french/chireads';
import p_144 from '@plugins/french/harkeneliwood';
import p_145 from '@plugins/french/kisswood';
import p_146 from '@plugins/french/LighNovelFR[lightnovelwp]';
import p_147 from '@plugins/french/MassNovel[madara]';
import p_148 from '@plugins/french/MTLNovel(FR)[mtlnovel]';
import p_149 from '@plugins/french/noveldeglace';
import p_150 from '@plugins/french/novhell';
import p_151 from '@plugins/french/warriorlegendtrad';
import p_152 from '@plugins/french/WorldNovel[madara]';
import p_153 from '@plugins/french/wuxialnscantrad';
import p_154 from '@plugins/french/xiaowaz';
import p_155 from '@plugins/indonesian/BacaLightNovel[lightnovelwp]';
import p_156 from '@plugins/indonesian/indowebnovel';
import p_157 from '@plugins/indonesian/MeioNovel[madara]';
import p_158 from '@plugins/indonesian/MTLNovel(ID)[mtlnovel]';
import p_159 from '@plugins/indonesian/NovelBookID[madara]';
import p_160 from '@plugins/indonesian/sakuranovel';
import p_161 from '@plugins/indonesian/SekteNovel[lightnovelwp]';
import p_162 from '@plugins/indonesian/Vanovel[madara]';
import p_163 from '@plugins/indonesian/WBNovel[madara]';
import p_164 from '@plugins/japanese/kakuyomu';
import p_165 from '@plugins/japanese/Syosetu';
import p_166 from '@plugins/korean/Agitoon';
import p_167 from '@plugins/korean/FortuneEternal[madara]';
import p_168 from '@plugins/multi/komga';
import p_169 from '@plugins/polish/novelki';
import p_170 from '@plugins/portuguese/BetterNovels[lightnovelwp]';
import p_171 from '@plugins/portuguese/blogdoamonnovels';
import p_172 from '@plugins/portuguese/CentralNovel[lightnovelwp]';
import p_173 from '@plugins/portuguese/Kiniga[madara]';
import p_174 from '@plugins/portuguese/LaNovels[hotnovelpub]';
import p_175 from '@plugins/portuguese/LightNovelBrasil[lightnovelwp]';
import p_176 from '@plugins/portuguese/MTLNovel(PT)[mtlnovel]';
import p_177 from '@plugins/portuguese/novelmania';
import p_178 from '@plugins/portuguese/tsundoku';
import p_179 from '@plugins/russian/authortoday';
import p_180 from '@plugins/russian/Bookhamster[ifreedom]';
import p_181 from '@plugins/russian/bookriver';
import p_182 from '@plugins/russian/Erolate[rulate]';
import p_183 from '@plugins/russian/EzNovels[hotnovelpub]';
import p_184 from '@plugins/russian/ficbook';
import p_185 from '@plugins/russian/jaomix';
import p_186 from '@plugins/russian/MTLNovel(RU)[mtlnovel]';
import p_187 from '@plugins/russian/neobook';
import p_188 from '@plugins/russian/NovelCool(RU)[novelcool]';
import p_189 from '@plugins/russian/novelTL';
import p_190 from '@plugins/russian/ranobehub';
import p_191 from '@plugins/russian/ranobelib';
import p_192 from '@plugins/russian/ranoberf';
import p_193 from '@plugins/russian/Ranobes(RU)[ranobes]';
import p_194 from '@plugins/russian/renovels';
import p_195 from '@plugins/russian/Rulate[rulate]';
import p_196 from '@plugins/russian/topliba';
import p_197 from '@plugins/russian/zelluloza';
import p_198 from '@plugins/russian/СвободныйМирРанобэ[ifreedom]';
import p_199 from '@plugins/spanish/AllNovelRead[lightnovelwp]';
import p_200 from '@plugins/spanish/AnimesHoy12[madara]';
import p_201 from '@plugins/spanish/hasutl';
import p_202 from '@plugins/spanish/LightNovelDaily[hotnovelpub]';
import p_203 from '@plugins/spanish/MTLNovel(ES)[mtlnovel]';
import p_204 from '@plugins/spanish/novelasligera';
import p_205 from '@plugins/spanish/novelawuxia';
import p_206 from '@plugins/spanish/oasistranslations';
import p_207 from '@plugins/spanish/PanchoTranslations[madara]';
import p_208 from '@plugins/spanish/skynovels';
import p_209 from '@plugins/spanish/TC&Sega[lightnovelwp]';
import p_210 from '@plugins/spanish/TraduccionesAmistosas[madara]';
import p_211 from '@plugins/spanish/tunovelaligera';
import p_212 from '@plugins/spanish/yukitls';
import p_213 from '@plugins/thai/NovelLucky[madara]';
import p_214 from '@plugins/thai/NovelPDF[madara]';
import p_215 from '@plugins/turkish/ArazNovel[madara]';
import p_216 from '@plugins/turkish/EKTAPLAR[madara]';
import p_217 from '@plugins/turkish/epiknovel';
import p_218 from '@plugins/turkish/kakikata[madara]';
import p_219 from '@plugins/turkish/KodeksLibrary[lightnovelwp]';
import p_220 from '@plugins/turkish/MangaTR';
import p_221 from '@plugins/turkish/NABSCANS[madara]';
import p_222 from '@plugins/turkish/Namevt[lightnovelwp]';
import p_223 from '@plugins/turkish/Noveloku[madara]';
import p_224 from '@plugins/turkish/NovelTR[lightnovelwp]';
import p_225 from '@plugins/turkish/RagnarScans[madara]';
import p_226 from '@plugins/turkish/ThNovels[hotnovelpub]';
import p_227 from '@plugins/turkish/TurkceLightNovels[madara]';
import p_228 from '@plugins/turkish/WebNovelOku[madara]';
import p_229 from '@plugins/ukrainian/bakainua';
import p_230 from '@plugins/ukrainian/smakolykytl';
import p_231 from '@plugins/vietnamese/lightnovelvn';
import p_232 from '@plugins/vietnamese/LNHako';
import p_233 from '@plugins/vietnamese/nettruyen';
const PLUGINS: Plugin.PluginBase[] = [
p_0,
@@ -486,22 +469,5 @@ const PLUGINS: Plugin.PluginBase[] = [
p_231,
p_232,
p_233,
p_234,
p_235,
p_236,
p_237,
p_238,
p_239,
p_240,
p_241,
p_242,
p_243,
p_244,
p_245,
p_246,
p_247,
p_248,
p_249,
p_250,
];
export default PLUGINS;
+1
View File
@@ -66,6 +66,7 @@ const proxyHandlerMiddle: Connect.NextHandleFunction = (req, res) => {
}
res.setHeader('Access-Control-Allow-Origin', settings.CLIENT_HOST);
res.setHeader('Access-Control-Allow-Credentials', 'true');
req.headers.referer = rawUrl;
if (req.method === 'OPTIONS') {
res.statusCode = 200;
res.end();
+2 -1
View File
@@ -10,13 +10,14 @@ const REMOTE = execSync('git remote get-url origin')
const CURRENT_BRANCH = execSync('git branch --show-current')
.toString()
.replace(/[\s\n]/g, '');
const BRANCH = process.env.BRANCH ? process.env.BRANCH : CURRENT_BRANCH;
const matched = REMOTE.match(/([^:/]+?)\/([^/.]+)(\.git)?$/);
if (!matched) throw Error('Cant parse git url');
const USERNAME = matched[1];
const REPO = matched[2];
const USER_CONTENT_LINK = process.env.USER_CONTENT_BASE
? process.env.USER_CONTENT_BASE
: `https://raw.githubusercontent.com/${USERNAME}/${REPO}/${CURRENT_BRANCH}`;
: `https://raw.githubusercontent.com/${USERNAME}/${REPO}/${BRANCH}`;
const STATIC_LINK = `${USER_CONTENT_LINK}/public/static`;
// Use legacy .js/src/plugins path for backward compatibility
+1 -1
View File
@@ -34,7 +34,7 @@ if [[ "$1" == "--all-branches" ]]; then
echo "Compiling TypeScript..."
npx tsc --project tsconfig.production.json
echo "# $branch" >> $GITHUB_STEP_SUMMARY
npm run build:manifest -- --only-new 2>> $GITHUB_STEP_SUMMARY
BRANCH=$dist npm run build:manifest -- --only-new 2>> $GITHUB_STEP_SUMMARY
if [ ! -d ".dist" ] || [ -z "$(ls -A .dist)" ]; then
echo "❌ ERROR: Manifest generation failed - .dist is missing or empty"
exit 1
+1 -4
View File
@@ -25,10 +25,7 @@ export function NovelCard({ novel, onParse }: NovelCardProps) {
<div className="group cursor-pointer flex flex-col h-full">
<div className="relative mb-2 overflow-hidden rounded-lg bg-muted aspect-[3/4]">
<img
src={
(novel.cover ? '/' : '') + novel.cover ||
'/static/coverNotAvailable.webp'
}
src={novel.cover || '/static/coverNotAvailable.webp'}
alt={novel.name}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
/>