feat: add LNORI (#2235)

* feat: add LNORI plugin ("https://lnori.com/")

* chore: update lnori plugin icon to 96x96

* refactor: encapsulate library novel parsing into a private getLibraryNovels method

* refactor: update lnori plugin to improve TOC parsing and support multi-section content loading
This commit is contained in:
Shrey
2026-06-13 19:01:34 +05:30
committed by GitHub
parent 3fd8351a75
commit e471b54166
3 changed files with 530 additions and 116 deletions
+412
View File
@@ -0,0 +1,412 @@
import { fetchText } from '@libs/fetch';
import { Plugin } from '@/types/plugin';
import { Filters, FilterTypes } from '@libs/filterInputs';
import { load as parseHTML } from 'cheerio';
import { defaultCover } from '@libs/defaultCover';
class LnorisPlugin implements Plugin.PluginBase {
id = 'lnori';
name = 'LNORI';
icon = 'src/en/lnori/icon.png';
site = 'https://lnori.com/';
version = '1.0.0';
private async getLibraryNovels(): Promise<
{
novel: Plugin.NovelItem;
author: string;
tags: string[];
}[]
> {
const url = this.site + 'library';
const body = await fetchText(url);
const $ = parseHTML(body);
const parsedList: {
novel: Plugin.NovelItem;
author: string;
tags: string[];
}[] = [];
$('article.card').each((i, el) => {
const name = $(el).attr('data-t') || '';
const author = $(el).attr('data-a') || '';
const tagsAttr = $(el).attr('data-tags') || '';
const tags = tagsAttr.split(',').map(t => t.trim().toLowerCase());
const coverImg = $(el).find('.card-cover img').first();
let cover = coverImg.attr('src') || '';
if (cover && cover.startsWith('/')) {
cover = this.site + cover.substring(1);
}
const link = $(el).find('a.stretched-link').first();
let path = link.attr('href') || '';
if (path.startsWith('/')) {
path = path.substring(1);
}
if (path && name) {
parsedList.push({
novel: {
name,
path,
cover: cover || defaultCover,
},
author,
tags,
});
}
});
return parsedList;
}
async popularNovels(
pageNo: number,
{ filters }: Plugin.PopularNovelsOptions<typeof this.filters>,
): Promise<Plugin.NovelItem[]> {
const parsedList = await this.getLibraryNovels();
let filteredList = parsedList;
const selectedGenre = filters?.genre?.value;
if (selectedGenre) {
filteredList = filteredList.filter(item =>
item.tags.includes(selectedGenre.toLowerCase()),
);
}
const selectedSort = filters?.sort?.value;
if (selectedSort === 'title-az') {
filteredList.sort((a, b) => a.novel.name.localeCompare(b.novel.name));
} else if (selectedSort === 'title-za') {
filteredList.sort((a, b) => b.novel.name.localeCompare(a.novel.name));
}
const pageSize = 36;
const offset = (pageNo - 1) * pageSize;
return filteredList
.slice(offset, offset + pageSize)
.map(item => item.novel);
}
async parseNovel(novelPath: string): Promise<Plugin.SourceNovel> {
const url = this.site + novelPath;
const body = await fetchText(url);
const $ = parseHTML(body);
const novel: Plugin.SourceNovel = {
path: novelPath,
name: $('.hero-card h1.s-title').text().trim() || 'Untitled',
};
const coverUrl = $('.hero-card .cover-wrap img').attr('src');
if (coverUrl) {
novel.cover = coverUrl.startsWith('/')
? this.site + coverUrl.substring(1)
: coverUrl;
} else {
novel.cover = defaultCover;
}
const dataTagsAttr = $('nav.tags-box.desktop').attr('data-tags');
if (dataTagsAttr) {
try {
const parsedTags = JSON.parse(dataTagsAttr);
novel.genres = parsedTags
.map((t: { name: string }) => t.name)
.join(', ');
} catch (e) {
// Fallback
}
}
if (!novel.genres) {
const genres: string[] = [];
$('nav.tags-box.desktop a, nav.tags-box a').each((i, el) => {
const text = $(el).text().trim();
if (text) genres.push(text);
});
novel.genres = genres.join(', ');
}
const summaryParagraphs: string[] = [];
$('section.desc-box p.description').each((i, el) => {
const text = $(el).text().trim();
if (text) summaryParagraphs.push(text);
});
novel.summary = summaryParagraphs.join('\n\n');
novel.author = $('.hero-card p.author').text().trim();
// Map unique volume URLs
const volumeMap: Record<string, string> = {};
$('a[href^="/book/"]').each((i, el) => {
const href = $(el).attr('href');
const text = $(el).text().trim().replace(/\s+/g, ' ');
if (href) {
if (
!volumeMap[href] ||
(text && text.length > volumeMap[href].length)
) {
volumeMap[href] = text;
}
}
});
const getVolumeName = (href: string, text: string) => {
let cleanText = text.replace(/Start Reading/gi, '').trim();
if (!cleanText) {
const parts = href.split('/');
const slug = parts[parts.length - 1] || parts[parts.length - 2] || '';
cleanText = slug
.split('-')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');
}
return cleanText;
};
const volumeUrls = Object.keys(volumeMap);
const volumePromises = volumeUrls.map(async volUrl => {
const fullVolUrl = this.site.replace(/\/$/, '') + volUrl;
const volHtml = await fetchText(fullVolUrl);
const $vol = parseHTML(volHtml);
const volChapters: Plugin.ChapterItem[] = [];
const tocLinks = $vol(
'nav.toc-view a[href^="#"], nav#toc-list a[href^="#"]',
);
if (tocLinks.length > 0) {
tocLinks.each((i, el) => {
const href = $vol(el).attr('href');
if (!href) return;
const id = href.substring(1);
const tocTitle = $vol(el).text().trim().replace(/\s+/g, ' ');
const section = $vol(`section#${id}`);
const h2Title = section
.find('h2.chapter-title, h2, h3')
.first()
.text()
.trim();
const chapterName =
tocTitle || h2Title || `Page ${id.replace(/\D/g, '')}`;
const volTitle = getVolumeName(volUrl, volumeMap[volUrl]);
let path = volUrl;
if (path.startsWith('/')) {
path = path.substring(1);
}
path = path + '#' + id;
volChapters.push({
name: `${volTitle} - ${chapterName}`,
path,
});
});
} else {
$vol('section.chapter').each((i, el) => {
const id = $vol(el).attr('id');
if (id) {
const h2Title = $vol(el)
.find('h2.chapter-title, h2, h3')
.first()
.text()
.trim();
if (!h2Title) return;
const volTitle = getVolumeName(volUrl, volumeMap[volUrl]);
let path = volUrl;
if (path.startsWith('/')) {
path = path.substring(1);
}
path = path + '#' + id;
volChapters.push({
name: `${volTitle} - ${h2Title}`,
path,
});
}
});
}
return volChapters;
});
const chapters2D = await Promise.all(volumePromises);
const chapters = chapters2D.flat();
novel.chapters = chapters.map((chap, idx) => ({
...chap,
chapterNumber: idx + 1,
}));
return novel;
}
async parseChapter(chapterPath: string): Promise<string> {
const [pathWithoutAnchor, anchor] = chapterPath.split('#');
const url = this.site.replace(/\/$/, '') + '/' + pathWithoutAnchor;
const body = await fetchText(url);
const $ = parseHTML(body);
const tocAnchors: string[] = [];
$('nav.toc-view a[href^="#"], nav#toc-list a[href^="#"]').each((i, el) => {
const href = $(el).attr('href');
if (href) {
tocAnchors.push(href.substring(1));
}
});
const chapterSelector = anchor ? `section#${anchor}` : 'section.chapter';
const section = $(chapterSelector);
if (!section.length) {
throw new Error(`Chapter section not found: ${chapterPath}`);
}
if (tocAnchors.length > 0 && anchor) {
const currentIndex = tocAnchors.indexOf(anchor);
const nextAnchor =
currentIndex !== -1 && currentIndex + 1 < tocAnchors.length
? tocAnchors[currentIndex + 1]
: null;
const pagesContent: string[] = [];
let stepSection = section;
while (stepSection.length) {
const mainContent = stepSection.find('.main').length
? stepSection.find('.main').clone()
: stepSection.clone();
mainContent.find('h2, h3, .chapter-title').remove();
mainContent.find('img').each((i, el) => {
const src = $(el).attr('src');
if (src && src.startsWith('/')) {
$(el).attr('src', this.site.replace(/\/$/, '') + src);
}
});
mainContent.find('source').each((i, el) => {
const srcset = $(el).attr('srcset');
if (srcset && srcset.startsWith('/')) {
$(el).attr('srcset', this.site.replace(/\/$/, '') + srcset);
}
});
const html = mainContent.html();
if (html) {
pagesContent.push(html);
}
let nextSibling = stepSection.next();
while (nextSibling.length && !nextSibling.is('section.chapter')) {
nextSibling = nextSibling.next();
}
stepSection = nextSibling;
if (nextAnchor && stepSection.attr('id') === nextAnchor) {
break;
}
}
return pagesContent.join('\n');
} else {
const mainContent = section.find('.main').length
? section.find('.main').clone()
: section.clone();
mainContent.find('h2, h3, .chapter-title').remove();
mainContent.find('img').each((i, el) => {
const src = $(el).attr('src');
if (src && src.startsWith('/')) {
$(el).attr('src', this.site.replace(/\/$/, '') + src);
}
});
mainContent.find('source').each((i, el) => {
const srcset = $(el).attr('srcset');
if (srcset && srcset.startsWith('/')) {
$(el).attr('srcset', this.site.replace(/\/$/, '') + srcset);
}
});
return mainContent.html() || '';
}
}
async searchNovels(
searchTerm: string,
pageNo: number,
): Promise<Plugin.NovelItem[]> {
const parsedList = await this.getLibraryNovels();
const term = searchTerm.toLowerCase();
const filteredList = parsedList.filter(item => {
return (
item.novel.name.toLowerCase().includes(term) ||
item.author.toLowerCase().includes(term) ||
item.tags.some(t => t.includes(term))
);
});
const pageSize = 36;
const offset = (pageNo - 1) * pageSize;
return filteredList
.slice(offset, offset + pageSize)
.map(item => item.novel);
}
resolveUrl = (path: string, _isNovel?: boolean) => {
return new URL(path, this.site).href;
};
filters = {
sort: {
label: 'Sort By',
value: 'popular',
options: [
{ label: 'Popular (Default)', value: 'popular' },
{ label: 'Title A-Z', value: 'title-az' },
{ label: 'Title Z-A', value: 'title-za' },
],
type: FilterTypes.Picker,
},
genre: {
label: 'Genre',
value: '',
options: [
{ label: 'All', value: '' },
{ label: 'Academy', value: 'academy' },
{ label: 'Action', value: 'action' },
{ label: 'Adventure', value: 'adventure' },
{ label: 'Comedy', value: 'comedy' },
{ label: 'Drama', value: 'drama' },
{ label: 'Fantasy', value: 'fantasy' },
{ label: 'Harem', value: 'harem' },
{ label: 'Historical', value: 'historical' },
{ label: 'Isekai', value: 'isekai' },
{ label: 'Magic', value: 'magic' },
{ label: 'Mystery', value: 'mystery' },
{ label: 'Psychological', value: 'psychological' },
{ label: 'Reincarnation', value: 'reincarnation' },
{ label: 'Romance', value: 'romance' },
{ label: 'Sci-Fi', value: 'sci-fi' },
{ label: 'Slice of Life', value: 'slice-of-life' },
{ label: 'Tragedy', value: 'tragedy' },
{ label: 'Female Protagonist', value: 'female protagonist' },
{ label: 'Male Protagonist', value: 'male protagonist' },
],
type: FilterTypes.Picker,
},
} satisfies Filters;
}
export default new LnorisPlugin();
+118 -116
View File
@@ -131,122 +131,123 @@ import p_128 from '@plugins/english/inoveltranslation';
import p_129 from '@plugins/english/leafstudio';
import p_130 from '@plugins/english/lightnoveltranslation';
import p_131 from '@plugins/english/lnmtl';
import p_132 from '@plugins/english/mvlempyr';
import p_133 from '@plugins/english/novelbuddy';
import p_134 from '@plugins/english/novelfire';
import p_135 from '@plugins/english/novelhall';
import p_136 from '@plugins/english/novelhi';
import p_137 from '@plugins/english/novelight';
import p_138 from '@plugins/english/novelrest';
import p_139 from '@plugins/english/novelupdates';
import p_140 from '@plugins/english/pawread';
import p_141 from '@plugins/english/rainofsnow';
import p_142 from '@plugins/english/readfrom';
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/wct';
import p_148 from '@plugins/english/webnovel';
import p_149 from '@plugins/english/wtrlab';
import p_150 from '@plugins/english/wuxiaworld';
import p_151 from '@plugins/french/LighNovelFR[lightnovelwp]';
import p_152 from '@plugins/french/MTLNovel(FR)[mtlnovel]';
import p_153 from '@plugins/french/MassNovel[madara]';
import p_154 from '@plugins/french/WorldNovel[madara]';
import p_155 from '@plugins/french/chireads';
import p_156 from '@plugins/french/harkeneliwood';
import p_157 from '@plugins/french/kisswood';
import p_158 from '@plugins/french/noveldeglace';
import p_159 from '@plugins/french/novelfrance';
import p_160 from '@plugins/french/novhell';
import p_161 from '@plugins/french/warriorlegendtrad';
import p_162 from '@plugins/french/wuxialnscantrad';
import p_163 from '@plugins/french/xiaowaz';
import p_164 from '@plugins/indonesian/BacaLightNovel[lightnovelwp]';
import p_165 from '@plugins/indonesian/MTLNovel(ID)[mtlnovel]';
import p_166 from '@plugins/indonesian/MeioNovel[madara]';
import p_167 from '@plugins/indonesian/NovelBookID[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/sakuranovel';
import p_173 from '@plugins/japanese/Syosetu';
import p_174 from '@plugins/japanese/kakuyomu';
import p_175 from '@plugins/korean/Agitoon';
import p_176 from '@plugins/korean/FortuneEternal[madara]';
import p_177 from '@plugins/multi/komga';
import p_178 from '@plugins/polish/novelki';
import p_179 from '@plugins/portuguese/BetterNovels[lightnovelwp]';
import p_180 from '@plugins/portuguese/CentralNovel[lightnovelwp]';
import p_181 from '@plugins/portuguese/Kiniga[madara]';
import p_182 from '@plugins/portuguese/LaNovels[hotnovelpub]';
import p_183 from '@plugins/portuguese/LightNovelBrasil[lightnovelwp]';
import p_184 from '@plugins/portuguese/MTLNovel(PT)[mtlnovel]';
import p_185 from '@plugins/portuguese/blogdoamonnovels';
import p_186 from '@plugins/portuguese/illusia';
import p_187 from '@plugins/portuguese/novelmania';
import p_188 from '@plugins/portuguese/tsundoku';
import p_189 from '@plugins/russian/Bllate[rulate]';
import p_190 from '@plugins/russian/Bookhamster[ifreedom]';
import p_191 from '@plugins/russian/Erolate[rulate]';
import p_192 from '@plugins/russian/EzNovels[hotnovelpub]';
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/novelTL';
import p_203 from '@plugins/russian/ranobehub';
import p_204 from '@plugins/russian/ranobelib';
import p_205 from '@plugins/russian/ranoberf';
import p_206 from '@plugins/russian/renovels';
import p_207 from '@plugins/russian/topliba';
import p_208 from '@plugins/russian/zelluloza';
import p_209 from '@plugins/russian/СвободныйМирРанобэ[ifreedom]';
import p_210 from '@plugins/spanish/AllNovelRead[lightnovelwp]';
import p_211 from '@plugins/spanish/AnimesHoy12[madara]';
import p_212 from '@plugins/spanish/LightNovelDaily[hotnovelpub]';
import p_213 from '@plugins/spanish/MTLNovel(ES)[mtlnovel]';
import p_214 from '@plugins/spanish/NOVA';
import p_215 from '@plugins/spanish/PanchoTranslations[madara]';
import p_216 from '@plugins/spanish/TC&Sega[lightnovelwp]';
import p_217 from '@plugins/spanish/TraduccionesAmistosas[madara]';
import p_218 from '@plugins/spanish/hasutl';
import p_219 from '@plugins/spanish/novelasligera';
import p_220 from '@plugins/spanish/novelawuxia';
import p_221 from '@plugins/spanish/novelyra';
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/vietnamese/LNHako';
import p_245 from '@plugins/vietnamese/lightnovelvn';
import p_246 from '@plugins/vietnamese/nettruyen';
import p_247 from '@plugins/vietnamese/truyenss';
import p_132 from '@plugins/english/lnori';
import p_133 from '@plugins/english/mvlempyr';
import p_134 from '@plugins/english/novelbuddy';
import p_135 from '@plugins/english/novelfire';
import p_136 from '@plugins/english/novelhall';
import p_137 from '@plugins/english/novelhi';
import p_138 from '@plugins/english/novelight';
import p_139 from '@plugins/english/novelrest';
import p_140 from '@plugins/english/novelupdates';
import p_141 from '@plugins/english/pawread';
import p_142 from '@plugins/english/rainofsnow';
import p_143 from '@plugins/english/readfrom';
import p_144 from '@plugins/english/relibrary';
import p_145 from '@plugins/english/royalroad';
import p_146 from '@plugins/english/scribblehub';
import p_147 from '@plugins/english/vynovel';
import p_148 from '@plugins/english/wct';
import p_149 from '@plugins/english/webnovel';
import p_150 from '@plugins/english/wtrlab';
import p_151 from '@plugins/english/wuxiaworld';
import p_152 from '@plugins/french/LighNovelFR[lightnovelwp]';
import p_153 from '@plugins/french/MTLNovel(FR)[mtlnovel]';
import p_154 from '@plugins/french/MassNovel[madara]';
import p_155 from '@plugins/french/WorldNovel[madara]';
import p_156 from '@plugins/french/chireads';
import p_157 from '@plugins/french/harkeneliwood';
import p_158 from '@plugins/french/kisswood';
import p_159 from '@plugins/french/noveldeglace';
import p_160 from '@plugins/french/novelfrance';
import p_161 from '@plugins/french/novhell';
import p_162 from '@plugins/french/warriorlegendtrad';
import p_163 from '@plugins/french/wuxialnscantrad';
import p_164 from '@plugins/french/xiaowaz';
import p_165 from '@plugins/indonesian/BacaLightNovel[lightnovelwp]';
import p_166 from '@plugins/indonesian/MTLNovel(ID)[mtlnovel]';
import p_167 from '@plugins/indonesian/MeioNovel[madara]';
import p_168 from '@plugins/indonesian/NovelBookID[madara]';
import p_169 from '@plugins/indonesian/SekteNovel[lightnovelwp]';
import p_170 from '@plugins/indonesian/Vanovel[madara]';
import p_171 from '@plugins/indonesian/WBNovel[madara]';
import p_172 from '@plugins/indonesian/indowebnovel';
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/illusia';
import p_188 from '@plugins/portuguese/novelmania';
import p_189 from '@plugins/portuguese/tsundoku';
import p_190 from '@plugins/russian/Bllate[rulate]';
import p_191 from '@plugins/russian/Bookhamster[ifreedom]';
import p_192 from '@plugins/russian/Erolate[rulate]';
import p_193 from '@plugins/russian/EzNovels[hotnovelpub]';
import p_194 from '@plugins/russian/MTLNovel(RU)[mtlnovel]';
import p_195 from '@plugins/russian/NovelCool(RU)[novelcool]';
import p_196 from '@plugins/russian/Ranobes(RU)[ranobes]';
import p_197 from '@plugins/russian/Rulate[rulate]';
import p_198 from '@plugins/russian/authortoday';
import p_199 from '@plugins/russian/bookriver';
import p_200 from '@plugins/russian/ficbook';
import p_201 from '@plugins/russian/jaomix';
import p_202 from '@plugins/russian/neobook';
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/topliba';
import p_209 from '@plugins/russian/zelluloza';
import p_210 from '@plugins/russian/СвободныйМирРанобэ[ifreedom]';
import p_211 from '@plugins/spanish/AllNovelRead[lightnovelwp]';
import p_212 from '@plugins/spanish/AnimesHoy12[madara]';
import p_213 from '@plugins/spanish/LightNovelDaily[hotnovelpub]';
import p_214 from '@plugins/spanish/MTLNovel(ES)[mtlnovel]';
import p_215 from '@plugins/spanish/NOVA';
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/novelyra';
import p_223 from '@plugins/spanish/oasistranslations';
import p_224 from '@plugins/spanish/skynovels';
import p_225 from '@plugins/spanish/tunovelaligera';
import p_226 from '@plugins/spanish/yukitls';
import p_227 from '@plugins/thai/NovelLucky[madara]';
import p_228 from '@plugins/thai/NovelPDF[madara]';
import p_229 from '@plugins/turkish/ArazNovel[madara]';
import p_230 from '@plugins/turkish/EKTAPLAR[madara]';
import p_231 from '@plugins/turkish/KodeksLibrary[lightnovelwp]';
import p_232 from '@plugins/turkish/MangaTR';
import p_233 from '@plugins/turkish/NABSCANS[madara]';
import p_234 from '@plugins/turkish/Namevt[lightnovelwp]';
import p_235 from '@plugins/turkish/NovelTR[lightnovelwp]';
import p_236 from '@plugins/turkish/Noveloku[madara]';
import p_237 from '@plugins/turkish/RagnarScans[madara]';
import p_238 from '@plugins/turkish/ThNovels[hotnovelpub]';
import p_239 from '@plugins/turkish/TurkceLightNovels[madara]';
import p_240 from '@plugins/turkish/WebNovelOku[madara]';
import p_241 from '@plugins/turkish/epiknovel';
import p_242 from '@plugins/turkish/kakikata[madara]';
import p_243 from '@plugins/ukrainian/bakainua';
import p_244 from '@plugins/ukrainian/smakolykytl';
import p_245 from '@plugins/vietnamese/LNHako';
import p_246 from '@plugins/vietnamese/lightnovelvn';
import p_247 from '@plugins/vietnamese/nettruyen';
import p_248 from '@plugins/vietnamese/truyenss';
const PLUGINS: Plugin.PluginBase[] = [
p_0,
@@ -497,5 +498,6 @@ const PLUGINS: Plugin.PluginBase[] = [
p_245,
p_246,
p_247,
p_248,
];
export default PLUGINS;