mirror of
https://github.com/kodjodevf/mangayomi-extensions.git
synced 2026-02-14 10:51:17 +00:00
New Source: AnimeWorld & Updates: Shortened filter code
New Source: - Anime World AnimeFenix, JKAnime and Mangafire: - Shortened filter code
This commit is contained in:
@@ -148,32 +148,12 @@ class DefaultExtension extends MProvider {
|
||||
type_name: "GroupFilter",
|
||||
name: "Tipo",
|
||||
state: [
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "TV",
|
||||
value: "tv"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Película",
|
||||
value: "movie"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Especial",
|
||||
value: "special"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "OVA",
|
||||
value: "ova"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "DONGHUA",
|
||||
value: "donghua"
|
||||
}
|
||||
]
|
||||
["TV", "tv"],
|
||||
["Película", "movie"],
|
||||
["Especial", "special"],
|
||||
["OVA", "ova"],
|
||||
["DONGHUA", "donghua"]
|
||||
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "SelectFilter",
|
||||
@@ -181,288 +161,68 @@ class DefaultExtension extends MProvider {
|
||||
name: "Género",
|
||||
state: 0,
|
||||
values: [
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Todos",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Acción",
|
||||
value: "accion"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Ángeles",
|
||||
value: "angeles"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Artes Marciales",
|
||||
value: "artes-marciales"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Aventura",
|
||||
value: "aventura"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Ciencia Ficción",
|
||||
value: "Ciencia Ficción"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Comedia",
|
||||
value: "comedia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Cyberpunk",
|
||||
value: "cyberpunk"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Demonios",
|
||||
value: "demonios"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Deportes",
|
||||
value: "deportes"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Dragones",
|
||||
value: "dragones"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Drama",
|
||||
value: "drama"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Ecchi",
|
||||
value: "ecchi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Escolares",
|
||||
value: "escolares"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Fantasía",
|
||||
value: "fantasia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Gore",
|
||||
value: "gore"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Harem",
|
||||
value: "harem"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Histórico",
|
||||
value: "historico"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Horror",
|
||||
value: "horror"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Infantil",
|
||||
value: "infantil"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Isekai",
|
||||
value: "isekai"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Josei",
|
||||
value: "josei"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Juegos",
|
||||
value: "juegos"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Magia",
|
||||
value: "magia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Mecha",
|
||||
value: "mecha"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Militar",
|
||||
value: "militar"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Misterio",
|
||||
value: "misterio"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Música",
|
||||
value: "Musica"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Ninjas",
|
||||
value: "ninjas"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Parodia",
|
||||
value: "parodia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Policía",
|
||||
value: "policia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Psicológico",
|
||||
value: "psicologico"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Recuerdos de la vida",
|
||||
value: "Recuerdos de la vida"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Romance",
|
||||
value: "romance"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Samurai",
|
||||
value: "samurai"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Sci-Fi",
|
||||
value: "sci-fi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Seinen",
|
||||
value: "seinen"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Shoujo",
|
||||
value: "shoujo"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Shoujo Ai",
|
||||
value: "shoujo-ai"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Shounen",
|
||||
value: "shounen"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Slice of life",
|
||||
value: "slice-of-life"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Sobrenatural",
|
||||
value: "sobrenatural"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Space",
|
||||
value: "space"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Spokon",
|
||||
value: "spokon"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Steampunk",
|
||||
value: "steampunk"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Superpoder",
|
||||
value: "superpoder"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Thriller",
|
||||
value: "thriller"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Vampiro",
|
||||
value: "vampiro"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Yaoi",
|
||||
value: "yaoi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Yuri",
|
||||
value: "yuri"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Zombies",
|
||||
value: "zombies"
|
||||
}
|
||||
]
|
||||
["Todos", ""],
|
||||
["Acción", "accion"],
|
||||
["Ángeles", "angeles"],
|
||||
["Artes Marciales", "artes-marciales"],
|
||||
["Aventura", "aventura"],
|
||||
["Ciencia Ficción", "Ciencia Ficción"],
|
||||
["Comedia", "comedia"],
|
||||
["Cyberpunk", "cyberpunk"],
|
||||
["Demonios", "demonios"],
|
||||
["Deportes", "deportes"],
|
||||
["Dragones", "dragones"],
|
||||
["Drama", "drama"],
|
||||
["Ecchi", "ecchi"],
|
||||
["Escolares", "escolares"],
|
||||
["Fantasía", "fantasia"],
|
||||
["Gore", "gore"],
|
||||
["Harem", "harem"],
|
||||
["Histórico", "historico"],
|
||||
["Horror", "horror"],
|
||||
["Infantil", "infantil"],
|
||||
["Isekai", "isekai"],
|
||||
["Josei", "josei"],
|
||||
["Juegos", "juegos"],
|
||||
["Magia", "magia"],
|
||||
["Mecha", "mecha"],
|
||||
["Militar", "militar"],
|
||||
["Misterio", "misterio"],
|
||||
["Música", "Musica"],
|
||||
["Ninjas", "ninjas"],
|
||||
["Parodia", "parodia"],
|
||||
["Policía", "policia"],
|
||||
["Psicológico", "psicologico"],
|
||||
["Recuerdos de la vida", "Recuerdos de la vida"],
|
||||
["Romance", "romance"],
|
||||
["Samurai", "samurai"],
|
||||
["Sci-Fi", "sci-fi"],
|
||||
["Seinen", "seinen"],
|
||||
["Shoujo", "shoujo"],
|
||||
["Shoujo Ai", "shoujo-ai"],
|
||||
["Shounen", "shounen"],
|
||||
["Slice of life", "slice-of-life"],
|
||||
["Sobrenatural", "sobrenatural"],
|
||||
["Space", "space"],
|
||||
["Spokon", "spokon"],
|
||||
["Steampunk", "steampunk"],
|
||||
["Superpoder", "superpoder"],
|
||||
["Thriller", "thriller"],
|
||||
["Vampiro", "vampiro"],
|
||||
["Yaoi", "yaoi"],
|
||||
["Yuri", "yuri"],
|
||||
["Zombies", "zombies"]
|
||||
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "GroupFilter",
|
||||
name: "Estado",
|
||||
state: [
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Emisión",
|
||||
value: "1"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Finalizado",
|
||||
value: "2"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Proximamente",
|
||||
value: "3"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "En Cuarentena",
|
||||
value: "4"
|
||||
}
|
||||
]
|
||||
["Emisión", "1"],
|
||||
["Finalizado", "2"],
|
||||
["Proximamente", "3"],
|
||||
["En Cuarentena", "4"]
|
||||
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "SelectFilter",
|
||||
@@ -470,37 +230,13 @@ class DefaultExtension extends MProvider {
|
||||
name: "Orden",
|
||||
state: 0,
|
||||
values: [
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Por Defecto",
|
||||
value: "default"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Recientemente Actualizados",
|
||||
value: "updated"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Recientemente Agregados",
|
||||
value: "added"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Nombre A-Z",
|
||||
value: "title"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Calificación",
|
||||
value: "likes"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Más Vistos",
|
||||
value: "visits"
|
||||
}
|
||||
]
|
||||
["Por Defecto", "default"],
|
||||
["Recientemente Actualizados", "updated"],
|
||||
["Recientemente Agregados", "added"],
|
||||
["Nombre A-Z", "title"],
|
||||
["Calificación", "likes"],
|
||||
["Más Vistos", "visits"]
|
||||
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -164,17 +164,9 @@ class DefaultExtension extends MProvider {
|
||||
name: "Filtro",
|
||||
state: 0,
|
||||
values: [
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Por fecha",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Por nombre",
|
||||
value: "nombre"
|
||||
}
|
||||
]
|
||||
["Por fecha", ""],
|
||||
["Por nombre", "nombre"]
|
||||
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "SelectFilter",
|
||||
@@ -182,212 +174,48 @@ class DefaultExtension extends MProvider {
|
||||
name: "Género",
|
||||
state: 0,
|
||||
values: [
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Género",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Accion",
|
||||
value: "accion"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Aventura",
|
||||
value: "aventura"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Autos",
|
||||
value: "autos"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Comedia",
|
||||
value: "comedia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Dementia",
|
||||
value: "dementia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Demonios",
|
||||
value: "demonios"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Misterio",
|
||||
value: "misterio"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Drama",
|
||||
value: "drama"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Ecchi",
|
||||
value: "ecchi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Fantasia",
|
||||
value: "fantasia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Juegos",
|
||||
value: "juegos"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Hentai",
|
||||
value: "hentai"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Historico",
|
||||
value: "historico"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Terror",
|
||||
value: "terror"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Magia",
|
||||
value: "magia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Artes Marciales",
|
||||
value: "artes-marciales"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Mecha",
|
||||
value: "mecha"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Musica",
|
||||
value: "musica"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Parodia",
|
||||
value: "parodia"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Samurai",
|
||||
value: "samurai"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Romance",
|
||||
value: "romance"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Colegial",
|
||||
value: "colegial"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Sci-Fi",
|
||||
value: "sci-fi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Shoujo Ai",
|
||||
value: "shoujo-ai"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Shounen Ai",
|
||||
value: "shounen-ai"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Space",
|
||||
value: "space"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Deportes",
|
||||
value: "deportes"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Super Poderes",
|
||||
value: "super-poderes"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Vampiros",
|
||||
value: "vampiros"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Yaoi",
|
||||
value: "yaoi"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Yuri",
|
||||
value: "yuri"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Harem",
|
||||
value: "harem"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Cosas de la vida",
|
||||
value: "cosas-de-la-vida"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Sobrenatural",
|
||||
value: "sobrenatural"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Militar",
|
||||
value: "militar"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Policial",
|
||||
value: "policial"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Psicologico",
|
||||
value: "psicologico"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Thriller",
|
||||
value: "thriller"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Español Latino",
|
||||
value: "latino"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Isekai",
|
||||
value: "isekai"
|
||||
}
|
||||
]
|
||||
["Género", ""],
|
||||
["Accion", "accion"],
|
||||
["Aventura", "aventura"],
|
||||
["Autos", "autos"],
|
||||
["Comedia", "comedia"],
|
||||
["Dementia", "dementia"],
|
||||
["Demonios", "demonios"],
|
||||
["Misterio", "misterio"],
|
||||
["Drama", "drama"],
|
||||
["Ecchi", "ecchi"],
|
||||
["Fantasia", "fantasia"],
|
||||
["Juegos", "juegos"],
|
||||
["Hentai", "hentai"],
|
||||
["Historico", "historico"],
|
||||
["Terror", "terror"],
|
||||
["Magia", "magia"],
|
||||
["Artes Marciales", "artes-marciales"],
|
||||
["Mecha", "mecha"],
|
||||
["Musica", "musica"],
|
||||
["Parodia", "parodia"],
|
||||
["Samurai", "samurai"],
|
||||
["Romance", "romance"],
|
||||
["Colegial", "colegial"],
|
||||
["Sci-Fi", "sci-fi"],
|
||||
["Shoujo Ai", "shoujo-ai"],
|
||||
["Shounen Ai", "shounen-ai"],
|
||||
["Space", "space"],
|
||||
["Deportes", "deportes"],
|
||||
["Super Poderes", "super-poderes"],
|
||||
["Vampiros", "vampiros"],
|
||||
["Yaoi", "yaoi"],
|
||||
["Yuri", "yuri"],
|
||||
["Harem", "harem"],
|
||||
["Cosas de la vida", "cosas-de-la-vida"],
|
||||
["Sobrenatural", "sobrenatural"],
|
||||
["Militar", "militar"],
|
||||
["Policial", "policial"],
|
||||
["Psicologico", "psicologico"],
|
||||
["Thriller", "thriller"],
|
||||
["Español Latino", "latino"],
|
||||
["Isekai", "isekai"]
|
||||
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "SelectFilter",
|
||||
@@ -395,37 +223,13 @@ class DefaultExtension extends MProvider {
|
||||
name: "Demografía",
|
||||
state: 0,
|
||||
values: [
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Demografía",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Niños",
|
||||
value: "nios"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Shoujo",
|
||||
value: "shoujo"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Shounen",
|
||||
value: "shounen"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Seinen",
|
||||
value: "seinen"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Josei",
|
||||
value: "josei"
|
||||
}
|
||||
]
|
||||
["Demografía", ""],
|
||||
["Niños", "nios"],
|
||||
["Shoujo", "shoujo"],
|
||||
["Shounen", "shounen"],
|
||||
["Seinen", "seinen"],
|
||||
["Josei", "josei"]
|
||||
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "SelectFilter",
|
||||
@@ -433,17 +237,9 @@ class DefaultExtension extends MProvider {
|
||||
name: "Categoría",
|
||||
state: 0,
|
||||
values: [
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Categoría",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Donghua",
|
||||
value: "donghua"
|
||||
}
|
||||
]
|
||||
["Categoría", ""],
|
||||
["Donghua", "donghua"]
|
||||
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "SelectFilter",
|
||||
@@ -451,37 +247,13 @@ class DefaultExtension extends MProvider {
|
||||
name: "Tipo",
|
||||
state: 0,
|
||||
values: [
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Tipo",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Animes",
|
||||
value: "animes"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Peliculas",
|
||||
value: "peliculas"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Especiales",
|
||||
value: "especiales"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Ovas",
|
||||
value: "ovas"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Onas",
|
||||
value: "onas"
|
||||
}
|
||||
]
|
||||
["Tipo", ""],
|
||||
["Animes", "animes"],
|
||||
["Peliculas", "peliculas"],
|
||||
["Especiales", "especiales"],
|
||||
["Ovas", "ovas"],
|
||||
["Onas", "onas"]
|
||||
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "SelectFilter",
|
||||
@@ -489,27 +261,11 @@ class DefaultExtension extends MProvider {
|
||||
name: "Estado",
|
||||
state: 0,
|
||||
values: [
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Estado",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "En emisión",
|
||||
value: "emision"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Finalizado",
|
||||
value: "finalizados"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Por Estrenar",
|
||||
value: "estrenos"
|
||||
}
|
||||
]
|
||||
["Estado", ""],
|
||||
["En emisión", "emision"],
|
||||
["Finalizado", "finalizados"],
|
||||
["Por Estrenar", "estrenos"]
|
||||
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "SelectFilter",
|
||||
@@ -517,232 +273,52 @@ class DefaultExtension extends MProvider {
|
||||
name: "Año",
|
||||
state: 0,
|
||||
values: [
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Año",
|
||||
value: "Año"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2024",
|
||||
value: "2024"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2023",
|
||||
value: "2023"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2022",
|
||||
value: "2022"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2021",
|
||||
value: "2021"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2020",
|
||||
value: "2020"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2019",
|
||||
value: "2019"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2018",
|
||||
value: "2018"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2017",
|
||||
value: "2017"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2016",
|
||||
value: "2016"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2015",
|
||||
value: "2015"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2014",
|
||||
value: "2014"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2013",
|
||||
value: "2013"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2012",
|
||||
value: "2012"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2011",
|
||||
value: "2011"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2010",
|
||||
value: "2010"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2009",
|
||||
value: "2009"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2008",
|
||||
value: "2008"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2007",
|
||||
value: "2007"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2006",
|
||||
value: "2006"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2005",
|
||||
value: "2005"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2004",
|
||||
value: "2004"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2003",
|
||||
value: "2003"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2002",
|
||||
value: "2002"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2001",
|
||||
value: "2001"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "2000",
|
||||
value: "2000"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1999",
|
||||
value: "1999"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1998",
|
||||
value: "1998"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1997",
|
||||
value: "1997"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1996",
|
||||
value: "1996"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1995",
|
||||
value: "1995"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1994",
|
||||
value: "1994"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1993",
|
||||
value: "1993"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1992",
|
||||
value: "1992"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1991",
|
||||
value: "1991"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1990",
|
||||
value: "1990"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1989",
|
||||
value: "1989"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1988",
|
||||
value: "1988"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1987",
|
||||
value: "1987"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1986",
|
||||
value: "1986"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1985",
|
||||
value: "1985"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1984",
|
||||
value: "1984"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1983",
|
||||
value: "1983"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1982",
|
||||
value: "1982"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "1981",
|
||||
value: "1981"
|
||||
}
|
||||
]
|
||||
["Año", "Año"],
|
||||
["2024", "2024"],
|
||||
["2023", "2023"],
|
||||
["2022", "2022"],
|
||||
["2021", "2021"],
|
||||
["2020", "2020"],
|
||||
["2019", "2019"],
|
||||
["2018", "2018"],
|
||||
["2017", "2017"],
|
||||
["2016", "2016"],
|
||||
["2015", "2015"],
|
||||
["2014", "2014"],
|
||||
["2013", "2013"],
|
||||
["2012", "2012"],
|
||||
["2011", "2011"],
|
||||
["2010", "2010"],
|
||||
["2009", "2009"],
|
||||
["2008", "2008"],
|
||||
["2007", "2007"],
|
||||
["2006", "2006"],
|
||||
["2005", "2005"],
|
||||
["2004", "2004"],
|
||||
["2003", "2003"],
|
||||
["2002", "2002"],
|
||||
["2001", "2001"],
|
||||
["2000", "2000"],
|
||||
["1999", "1999"],
|
||||
["1998", "1998"],
|
||||
["1997", "1997"],
|
||||
["1996", "1996"],
|
||||
["1995", "1995"],
|
||||
["1994", "1994"],
|
||||
["1993", "1993"],
|
||||
["1992", "1992"],
|
||||
["1991", "1991"],
|
||||
["1990", "1990"],
|
||||
["1989", "1989"],
|
||||
["1988", "1988"],
|
||||
["1987", "1987"],
|
||||
["1986", "1986"],
|
||||
["1985", "1985"],
|
||||
["1984", "1984"],
|
||||
["1983", "1983"],
|
||||
["1982", "1982"],
|
||||
["1981", "1981"]
|
||||
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "SelectFilter",
|
||||
@@ -750,32 +326,12 @@ class DefaultExtension extends MProvider {
|
||||
name: "Temporada",
|
||||
state: 0,
|
||||
values: [
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Temporada",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Invierno",
|
||||
value: "invierno"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Primavera",
|
||||
value: "primavera"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Verano",
|
||||
value: "verano"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Otoño",
|
||||
value: "otoño"
|
||||
}
|
||||
]
|
||||
["Temporada", ""],
|
||||
["Invierno", "invierno"],
|
||||
["Primavera", "primavera"],
|
||||
["Verano", "verano"],
|
||||
["Otoño", "otoño"]
|
||||
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
939
javascript/anime/src/it/animeworld.js
Normal file
939
javascript/anime/src/it/animeworld.js
Normal file
@@ -0,0 +1,939 @@
|
||||
const mangayomiSources = [{
|
||||
"name": "AnimeWorld",
|
||||
"lang": "it",
|
||||
"baseUrl": "https://www.animeworld.so",
|
||||
"apiUrl": "",
|
||||
"iconUrl": "https://i.postimg.cc/RFRGfBvP/FVLyB1I.png",
|
||||
"typeSource": "single",
|
||||
"isManga": false,
|
||||
"version": "0.0.1",
|
||||
"dateFormat": "",
|
||||
"dateFormatLocale": "",
|
||||
"pkgPath": "anime/src/it/animeworld.js"
|
||||
}];
|
||||
|
||||
class DefaultExtension extends MProvider {
|
||||
constructor () {
|
||||
super();
|
||||
this.client = new Client();
|
||||
}
|
||||
getHeaders(url) {
|
||||
throw new Error("getHeaders not implemented");
|
||||
}
|
||||
async parseAnimeList(url) {
|
||||
const res = await this.client.get(url);
|
||||
const doc = new Document(res.body);
|
||||
const elements = doc.select("div.film-list div.item");
|
||||
const list = [];
|
||||
|
||||
for (const element of elements) {
|
||||
let name = element.selectFirst('a + a').text;
|
||||
const imageUrl = element.selectFirst('img').getSrc;
|
||||
const link = element.selectFirst('a').getHref;
|
||||
const type = element.selectFirst('div.dub').text == 'DUB';
|
||||
if (type && !name.includes('ITA')) {
|
||||
name += ' (ITA)';
|
||||
}
|
||||
list.push({ name, imageUrl, link });
|
||||
}
|
||||
const hasNextPage = parseInt(doc.selectFirst('span.total').text) > parseInt(url.match(/page=(\d+)/)[1]);
|
||||
return { "list": list, "hasNextPage": hasNextPage };
|
||||
}
|
||||
parseStatus(status) {
|
||||
return {
|
||||
"in corso": 0,
|
||||
"finito": 1,
|
||||
"droppato": 3,
|
||||
"non rilasciato": 4,
|
||||
}[status.toLowerCase()] ?? 5;
|
||||
}
|
||||
async getPopular(page) {
|
||||
const res = await this.client.get(this.source.baseUrl + '/tops/ongoing');
|
||||
const doc = new Document(res.body);
|
||||
const elements = doc.select('div.content div.item');
|
||||
const list = [];
|
||||
|
||||
for (const element of elements) {
|
||||
const name = element.selectFirst('div.name').text;
|
||||
const imageUrl = element.selectFirst('img').getSrc;
|
||||
const link = element.selectFirst('a').getHref;
|
||||
list.push({ name, imageUrl, link });
|
||||
}
|
||||
return { "list": list, "hasNextPage": false };
|
||||
}
|
||||
async getLatestUpdates(page) {
|
||||
return this.parseAnimeList(`${this.source.baseUrl}/filter?sort=1&page=${page}`);
|
||||
}
|
||||
async search(query, page, filters) {
|
||||
query = query.trim().replaceAll(/\ +/g, "+");
|
||||
|
||||
// Search sometimes failed because filters were empty. I experienced this mostly on android...
|
||||
if (!filters || filters.length == 0) {
|
||||
return this.parseAnimeList(`${this.source.baseUrl}/search?keyword=${query}&page=${page}`);
|
||||
}
|
||||
|
||||
let url = `${this.source.baseUrl}/filter?sort=${filters[5].values[filters[5].state].value}&keyword=${query}`;
|
||||
|
||||
for (const filter of filters[0].state) {
|
||||
if (filter.state == true)
|
||||
url += `&type=${filter.value}`;
|
||||
}
|
||||
for (const filter of filters[1].state) {
|
||||
if (filter.state == true)
|
||||
url += `&genre=${filter.value}`;
|
||||
}
|
||||
for (const filter of filters[2].state) {
|
||||
if (filter.state == true)
|
||||
url += `&status=${filter.value}`;
|
||||
}
|
||||
for (const filter of filters[3].state) {
|
||||
if (filter.state == true)
|
||||
url += `&dub=${filter.value}`;
|
||||
}
|
||||
for (const filter of filters[4].state) {
|
||||
if (filter.state == true)
|
||||
url += `&language=${filter.value}`;
|
||||
}
|
||||
return this.parseAnimeList(url + `&page=${page}`);
|
||||
}
|
||||
async getDetail(url) {
|
||||
const res = await this.client.get(this.source.baseUrl + url);
|
||||
const doc = new Document(res.body);
|
||||
const detail = {};
|
||||
|
||||
const info = doc.selectFirst('div.info div.info');
|
||||
detail.name = info.selectFirst('h2').text;
|
||||
detail.imageUrl = info.selectFirst('img').getSrc;
|
||||
detail.description = info.selectFirst('div.desc').text;
|
||||
detail.author = info.selectFirst('dt:contains(Studio) + dd').text.trim();
|
||||
detail.status = this.parseStatus(info.selectFirst('dt:contains(Stato) + dd').text.trim());
|
||||
detail.genre = info.select('dt:contains(Genere) + dd a').map(e => e.text);
|
||||
detail.episodes = doc.select('div.server.active li.episode > a').map(e => ({
|
||||
name: 'Ep. ' + e.text,
|
||||
url: this.source.baseUrl + e.getHref
|
||||
})).reverse();
|
||||
const type = doc.selectFirst('div.info div.info dt:contains(Audio) + dd').text.trim() == 'Italiano' ?
|
||||
'Doppiato' : 'Subbato';
|
||||
if (type == 'Doppiato' && !detail.name.includes('ITA')) {
|
||||
detail.name += ' (ITA)';
|
||||
}
|
||||
return detail;
|
||||
}
|
||||
// For anime episode video list
|
||||
async getVideoList(url) {
|
||||
const res = await this.client.get(url);
|
||||
const doc = new Document(res.body);
|
||||
const promises = [];
|
||||
const videos = [];
|
||||
|
||||
const type = doc.selectFirst('div.info div.info dt:contains(Audio) + dd').text.trim() == 'Italiano' ?
|
||||
'Doppiato' : 'Subbato';
|
||||
|
||||
for (const element of doc.select('div#download a')) {
|
||||
const host = /Download (.*?) -/.exec(element.text)?.[1];
|
||||
let url = element.getHref;
|
||||
|
||||
if (!host || host == 'Diretto') {
|
||||
// ignore
|
||||
continue;
|
||||
} else if (host == 'Alternativo') {
|
||||
videos.push({url: url, originalUrl: url, quality: `Italiano ${type} Alternativo`, headers: null});
|
||||
continue;
|
||||
} else {
|
||||
url = url.replace('/d/', '/e/');
|
||||
}
|
||||
promises.push(extractAny(url, host.toLowerCase(), 'Italiano', type, host));
|
||||
}
|
||||
for (const p of (await Promise.allSettled(promises))) {
|
||||
if (p.status == 'fulfilled') {
|
||||
videos.push.apply(videos, p.value);
|
||||
}
|
||||
}
|
||||
return sortVideos(videos);
|
||||
}
|
||||
getFilterList() {
|
||||
return [
|
||||
{
|
||||
type_name: "GroupFilter",
|
||||
name: "Tipo",
|
||||
state: [
|
||||
['Anime', '0'],
|
||||
['Movie', '4'],
|
||||
['OVA', '1'],
|
||||
['ONA', '2'],
|
||||
['Special', '3'],
|
||||
['Music', '5']
|
||||
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "GroupFilter",
|
||||
name: "Generi",
|
||||
state: [
|
||||
["Arti Marziali", "3"],
|
||||
["Avanguardia", "5"],
|
||||
["Avventura", "2"],
|
||||
["Azione", "1"],
|
||||
["Bambini", "47"],
|
||||
["Commedia", "4"],
|
||||
["Demoni", "6"],
|
||||
["Drammatico", "7"],
|
||||
["Ecchi", "8"],
|
||||
["Fantasy", "9"],
|
||||
["Gioco", "10"],
|
||||
["Harem", "11"],
|
||||
["Hentai", "43"],
|
||||
["Horror", "13"],
|
||||
["Josei", "14"],
|
||||
["Magia", "16"],
|
||||
["Mecha", "18"],
|
||||
["Militari", "19"],
|
||||
["Mistero", "21"],
|
||||
["Musicale", "20"],
|
||||
["Parodia", "22"],
|
||||
["Polizia", "23"],
|
||||
["Psicologico", "24"],
|
||||
["Romantico", "46"],
|
||||
["Samurai", "26"],
|
||||
["Sci-Fi", "28"],
|
||||
["Scolastico", "27"],
|
||||
["Seinen", "29"],
|
||||
["Sentimentale", "25"],
|
||||
["Shoujo", "30"],
|
||||
["Shoujo Ai", "31"],
|
||||
["Shounen", "32"],
|
||||
["Shounen Ai", "33"],
|
||||
["Slice of Life", "34"],
|
||||
["Spazio", "35"],
|
||||
["Soprannaturale", "37"],
|
||||
["Sport", "36"],
|
||||
["Storico", "12"],
|
||||
["Superpoteri", "38"],
|
||||
["Thriller", "39"],
|
||||
["Vampiri", "40"],
|
||||
["Veicoli", "48"],
|
||||
["Yaoi", "41"],
|
||||
["Yuri", "42"]
|
||||
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "GroupFilter",
|
||||
name: "Stato",
|
||||
state: [
|
||||
["In corso", "0"],
|
||||
["Finito", "1"],
|
||||
["Non rilasciato", "2"],
|
||||
["Droppato", "3"]
|
||||
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "GroupFilter",
|
||||
name: "Sottotitoli",
|
||||
state: [
|
||||
["Subbato", "0"],
|
||||
["Doppiato", "1"]
|
||||
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "GroupFilter",
|
||||
name: "Audio",
|
||||
state: [
|
||||
["Giapponese", "jp"],
|
||||
["Italiano", "it"],
|
||||
["Cinese", "ch"],
|
||||
["Coreano", "kr"],
|
||||
["Inglese", "en"]
|
||||
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "SelectFilter",
|
||||
type: "sort",
|
||||
name: "Ordine",
|
||||
state: 0,
|
||||
values: [
|
||||
["Standard", "0"],
|
||||
["Ultime aggiunte", "1"],
|
||||
["Lista A-Z", "2"],
|
||||
["Lista Z-A", "3"],
|
||||
["Più vecchi", "4"],
|
||||
["Più recenti", "5"],
|
||||
["Più visti", "6"]
|
||||
].map(x => ({type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
},
|
||||
];
|
||||
}
|
||||
getSourcePreferences() {
|
||||
const languages = ['Italiano'];
|
||||
const types = ['Doppiato', 'Subbato'];
|
||||
const resolutions = ['1080p', '720p', '480p'];
|
||||
const hosts = ['Alternativo', 'VidGuard'];
|
||||
|
||||
return [
|
||||
{
|
||||
key: 'lang',
|
||||
listPreference: {
|
||||
title: 'Preferred Language',
|
||||
summary: 'If available, this language will be chosen by default. Priority = 0 (lower is better)',
|
||||
valueIndex: 0,
|
||||
entries: languages,
|
||||
entryValues: languages
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'type',
|
||||
listPreference: {
|
||||
title: 'Preferred Type',
|
||||
summary: 'If available, this type will be chosen by default. Priority = 1 (lower is better)',
|
||||
valueIndex: 0,
|
||||
entries: types,
|
||||
entryValues: types
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'res',
|
||||
listPreference: {
|
||||
title: 'Preferred Resolution',
|
||||
summary: 'If available, this resolution will be chosen by default. Priority = 2 (lower is better)',
|
||||
valueIndex: 0,
|
||||
entries: resolutions,
|
||||
entryValues: resolutions
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'host',
|
||||
listPreference: {
|
||||
title: 'Preferred Host',
|
||||
summary: 'If available, this hoster will be chosen by default. Priority = 3 (lower is better)',
|
||||
valueIndex: 0,
|
||||
entries: hosts,
|
||||
entryValues: hosts
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
* mangayomi-js-helpers v1.1
|
||||
*
|
||||
* # Video Extractors
|
||||
* - vidGuardExtractor
|
||||
* - doodExtractor
|
||||
* - vidozaExtractor
|
||||
* - okruExtractor
|
||||
* - amazonExtractor
|
||||
* - vidHideExtractor
|
||||
* - filemoonExtractor
|
||||
* - mixdropExtractor
|
||||
* - speedfilesExtractor
|
||||
* - burstcloudExtractor (not working, see description)
|
||||
*
|
||||
* # Video Extractor Wrappers
|
||||
* - streamWishExtractor
|
||||
* - voeExtractor
|
||||
* - mp4UploadExtractor
|
||||
* - yourUploadExtractor
|
||||
* - streamTapeExtractor
|
||||
* - sendVidExtractor
|
||||
*
|
||||
* # Video Extractor helpers
|
||||
* - extractAny
|
||||
*
|
||||
* # Playlist Extractors
|
||||
* - m3u8Extractor
|
||||
* - jwplayerExtractor
|
||||
*
|
||||
* # Extension Helpers
|
||||
* - sortVideos()
|
||||
*
|
||||
* # Uint8Array
|
||||
* - Uint8Array.fromBase64()
|
||||
* - Uint8Array.prototype.toBase64()
|
||||
* - Uint8Array.prototype.decode()
|
||||
*
|
||||
* # String
|
||||
* - String.prototype.encode()
|
||||
* - String.decode()
|
||||
* - String.prototype.reverse()
|
||||
* - String.prototype.swapcase()
|
||||
* - getRandomString()
|
||||
*
|
||||
* # Encode/Decode Functions
|
||||
* - decodeUTF8
|
||||
* - encodeUTF8
|
||||
*
|
||||
* # Url
|
||||
* - absUrl()
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Video Extractors
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
async function vidGuardExtractor(url) {
|
||||
// get html
|
||||
const res = await new Client().get(url);
|
||||
const doc = new Document(res.body);
|
||||
const script = doc.selectFirst('script:contains(eval)');
|
||||
|
||||
// eval code
|
||||
const code = script.text;
|
||||
eval?.('var window = {};');
|
||||
eval?.(code);
|
||||
const playlistUrl = globalThis.window.svg.stream;
|
||||
|
||||
// decode sig
|
||||
const encoded = playlistUrl.match(/sig=(.*?)&/)[1];
|
||||
const charCodes = [];
|
||||
|
||||
for (let i = 0; i < encoded.length; i += 2) {
|
||||
charCodes.push(parseInt(encoded.slice(i, i + 2), 16) ^ 2);
|
||||
}
|
||||
|
||||
let decoded = Uint8Array.fromBase64(
|
||||
String.fromCharCode(...charCodes))
|
||||
.slice(5, -5)
|
||||
.reverse();
|
||||
|
||||
for (let i = 0; i < decoded.length; i += 2) {
|
||||
let tmp = decoded[i];
|
||||
decoded[i] = decoded[i + 1];
|
||||
decoded[i + 1] = tmp;
|
||||
}
|
||||
|
||||
decoded = decoded.decode();
|
||||
return await m3u8Extractor(playlistUrl.replace(encoded, decoded), null);
|
||||
}
|
||||
|
||||
async function doodExtractor(url) {
|
||||
const dartClient = new Client({ 'useDartHttpClient': true, "followRedirects": false });
|
||||
let response = await dartClient.get(url);
|
||||
while ("location" in response.headers) {
|
||||
response = await dartClient.get(response.headers.location);
|
||||
}
|
||||
const newUrl = response.request.url;
|
||||
const doodhost = newUrl.match(/https:\/\/(.*?)\//, newUrl)[0].slice(8, -1);
|
||||
const md5 = response.body.match(/'\/pass_md5\/(.*?)',/, newUrl)[0].slice(11, -2);
|
||||
const token = md5.substring(md5.lastIndexOf("/") + 1);
|
||||
const expiry = new Date().valueOf();
|
||||
const randomString = getRandomString(10);
|
||||
|
||||
response = await new Client().get(`https://${doodhost}/pass_md5/${md5}`, { "Referer": newUrl });
|
||||
const videoUrl = `${response.body}${randomString}?token=${token}&expiry=${expiry}`;
|
||||
const headers = { "User-Agent": "Mangayomi", "Referer": doodhost };
|
||||
return [{ url: videoUrl, originalUrl: videoUrl, headers: headers, quality: '' }];
|
||||
}
|
||||
|
||||
async function vidozaExtractor(url) {
|
||||
let response = await new Client({ 'useDartHttpClient': true, "followRedirects": true }).get(url);
|
||||
const videoUrl = response.body.match(/https:\/\/\S*\.mp4/)[0];
|
||||
return [{ url: videoUrl, originalUrl: videoUrl, quality: '' }];
|
||||
}
|
||||
|
||||
async function okruExtractor(url) {
|
||||
const res = await new Client().get(url);
|
||||
const doc = new Document(res.body);
|
||||
const tag = doc.selectFirst('div[data-options]');
|
||||
const playlistUrl = tag.attr('data-options').match(/hlsManifestUrl.*?(h.*?id=\d+)/)[1].replaceAll('\\\\u0026', '&');
|
||||
return await m3u8Extractor(playlistUrl, null);
|
||||
}
|
||||
|
||||
async function amazonExtractor(url) {
|
||||
const res = await new Client().get(url);
|
||||
const doc = new Document(res.body);
|
||||
const videoUrl = doc.selectFirst('video').getSrc;
|
||||
return videoUrl ? [{ url: videoUrl, originalUrl: videoUrl, headers: null, quality: '' }] : [];
|
||||
}
|
||||
|
||||
async function vidHideExtractor(url) {
|
||||
const res = await new Client().get(url);
|
||||
return await jwplayerExtractor(res.body);
|
||||
}
|
||||
|
||||
async function filemoonExtractor(url, headers) {
|
||||
let res = await new Client().get(url, headers);
|
||||
const src = res.body.match(/iframe src="(.*?)"/)?.[1];
|
||||
if (src) {
|
||||
res = await new Client().get(src, {
|
||||
'Referer': url,
|
||||
'Accept-Language': 'de,en-US;q=0.7,en;q=0.3'
|
||||
});
|
||||
}
|
||||
return await jwplayerExtractor(res.body);
|
||||
}
|
||||
|
||||
async function mixdropExtractor(url) {
|
||||
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'};
|
||||
let res = await new Client({ 'useDartHttpClient': true, "followRedirects": false }).get(url, headers);
|
||||
while ("location" in res.headers) {
|
||||
res = await new Client({ 'useDartHttpClient': true, "followRedirects": false }).get(res.headers.location, headers);
|
||||
}
|
||||
const newUrl = res.request.url;
|
||||
let doc = new Document(res.body);
|
||||
|
||||
const code = doc.selectFirst('script:contains(MDCore):contains(eval)').text;
|
||||
const unpacked = unpackJs(code);
|
||||
let videoUrl = unpacked.match(/wurl="(.*?)"/)?.[1];
|
||||
|
||||
if (!videoUrl) return [];
|
||||
|
||||
videoUrl = 'https:' + videoUrl;
|
||||
headers.referer = newUrl;
|
||||
|
||||
return [{url: videoUrl, originalUrl: videoUrl, quality: '', headers: headers}];
|
||||
}
|
||||
|
||||
async function speedfilesExtractor(url) {
|
||||
let res = await new Client().get(url);
|
||||
let doc = new Document(res.body);
|
||||
|
||||
const code = doc.selectFirst('script:contains(var)').text;
|
||||
let b64;
|
||||
|
||||
// Get b64
|
||||
for (const match of code.matchAll(/(?:var|let|const)\s*\w+\s*=\s*["']([^"']+)/g)) {
|
||||
if (match[1].match(/[g-zG-Z]/)) {
|
||||
b64 = match[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// decode b64 => b64
|
||||
const step1 = Uint8Array.fromBase64(b64).reverse().decode().swapcase();
|
||||
// decode b64 => hex
|
||||
const step2 = Uint8Array.fromBase64(step1).reverse().decode();
|
||||
// decode hex => b64
|
||||
let step3 = [];
|
||||
for (let i = 0; i < step2.length; i += 2) {
|
||||
step3.push(parseInt(step2.slice(i, i + 2), 16) - 3);
|
||||
}
|
||||
step3 = String.fromCharCode(...step3.reverse()).swapcase();
|
||||
// decode b64 => url
|
||||
const videoUrl = Uint8Array.fromBase64(step3).decode();
|
||||
|
||||
return [{url: videoUrl, originalUrl: videoUrl, quality: '', headers: null}];
|
||||
}
|
||||
|
||||
/** Does not work: Client always sets 'charset=utf-8' in Content-Type. */
|
||||
async function burstcloudExtractor(url) {
|
||||
let client = new Client();
|
||||
let res = await client.get(url);
|
||||
|
||||
const id = res.body.match(/data-file-id="(.*?)"/)[1];
|
||||
const headers = {
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
'Referer': url,
|
||||
};
|
||||
const data = {
|
||||
'fileId': id
|
||||
};
|
||||
|
||||
res = await client.post(`https://www.burstcloud.co/file/play-request/`, headers, data);
|
||||
const videoUrl = res.body.match(/cdnUrl":"(.*?)"/)[1];
|
||||
return [{
|
||||
url: videoUrl,
|
||||
originalUrl: videoUrl,
|
||||
headers: { 'Referer': url.match(/.*?:\/\/.*?\//) },
|
||||
quality: ''
|
||||
}];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Video Extractor Wrappers
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
_streamWishExtractor = streamWishExtractor;
|
||||
streamWishExtractor = async (url) => {
|
||||
return (await _streamWishExtractor(url, '')).map(v => {
|
||||
v.quality = v.quality.slice(3, -1);
|
||||
return v;
|
||||
});
|
||||
}
|
||||
|
||||
_voeExtractor = voeExtractor;
|
||||
voeExtractor = async (url) => {
|
||||
return (await _voeExtractor(url, '')).map(v => {
|
||||
v.quality = v.quality.replace(/Voe: (\d+p?)/i, '$1');
|
||||
return v;
|
||||
});
|
||||
}
|
||||
|
||||
_mp4UploadExtractor = mp4UploadExtractor;
|
||||
mp4UploadExtractor = async (url) => {
|
||||
return (await _mp4UploadExtractor(url)).map(v => {
|
||||
v.quality = v.quality.match(/\d+p/)?.[0] ?? '';
|
||||
return v;
|
||||
});
|
||||
}
|
||||
|
||||
_yourUploadExtractor = yourUploadExtractor;
|
||||
yourUploadExtractor = async (url) => {
|
||||
return (await _yourUploadExtractor(url))
|
||||
.filter(v => !v.url.includes('/novideo'))
|
||||
.map(v => {
|
||||
v.quality = '';
|
||||
return v;
|
||||
});
|
||||
}
|
||||
|
||||
_streamTapeExtractor = streamTapeExtractor;
|
||||
streamTapeExtractor = async (url) => {
|
||||
return await _streamTapeExtractor(url, '');
|
||||
}
|
||||
|
||||
_sendVidExtractor = sendVidExtractor;
|
||||
sendVidExtractor = async (url) => {
|
||||
let res = await new Client().get(url);
|
||||
var videoUrl, quality;
|
||||
try {
|
||||
videoUrl = res.body.match(/og:video" content="(.*?\.mp4.*?)"/)[1];
|
||||
quality = res.body.match(/og:video:height" content="(.*?)"/)?.[1];
|
||||
quality = quality ? quality + 'p' : '';
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
if (!videoUrl) {
|
||||
return _sendVidExtractor(url, null, '');
|
||||
}
|
||||
return [{url: videoUrl, originalUrl: videoUrl, quality: quality, headers: null}];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Video Extractor Helpers
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
async function extractAny(url, method, lang, type, host, headers = null) {
|
||||
const m = extractAny.methods[method];
|
||||
return (!m) ? [] : (await m(url, headers)).map(v => {
|
||||
v.quality = v.quality ? `${lang} ${type} ${v.quality} ${host}` : `${lang} ${type} ${host}`;
|
||||
return v;
|
||||
});
|
||||
};
|
||||
|
||||
extractAny.methods = {
|
||||
'amazon': amazonExtractor,
|
||||
'burstcloud': burstcloudExtractor,
|
||||
'doodstream': doodExtractor,
|
||||
'filemoon': filemoonExtractor,
|
||||
'mixdrop': mixdropExtractor,
|
||||
'mp4upload': mp4UploadExtractor,
|
||||
'okru': okruExtractor,
|
||||
'sendvid': sendVidExtractor,
|
||||
'speedfiles': speedfilesExtractor,
|
||||
'streamtape': streamTapeExtractor,
|
||||
'streamwish': vidHideExtractor,
|
||||
'vidguard': vidGuardExtractor,
|
||||
'vidhide': vidHideExtractor,
|
||||
'vidoza': vidozaExtractor,
|
||||
'voe': voeExtractor,
|
||||
'yourupload': yourUploadExtractor
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Playlist Extractors
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
async function m3u8Extractor(url, headers = null) {
|
||||
// https://developer.apple.com/documentation/http-live-streaming/creating-a-multivariant-playlist
|
||||
// https://developer.apple.com/documentation/http-live-streaming/adding-alternate-media-to-a-playlist
|
||||
// define attribute lists
|
||||
const streamAttributes = [
|
||||
['avg_bandwidth', /AVERAGE-BANDWIDTH=(\d+)/],
|
||||
['bandwidth', /\bBANDWIDTH=(\d+)/],
|
||||
['resolution', /\bRESOLUTION=([\dx]+)/],
|
||||
['framerate', /\bFRAME-RATE=([\d\.]+)/],
|
||||
['codecs', /\bCODECS="(.*?)"/],
|
||||
['video', /\bVIDEO="(.*?)"/],
|
||||
['audio', /\bAUDIO="(.*?)"/],
|
||||
['subtitles', /\bSUBTITLES="(.*?)"/],
|
||||
['captions', /\bCLOSED-CAPTIONS="(.*?)"/]
|
||||
];
|
||||
const mediaAttributes = [
|
||||
['type', /\bTYPE=([\w-]*)/],
|
||||
['group', /\bGROUP-ID="(.*?)"/],
|
||||
['lang', /\bLANGUAGE="(.*?)"/],
|
||||
['name', /\bNAME="(.*?)"/],
|
||||
['autoselect', /\bAUTOSELECT=(\w*)/],
|
||||
['default', /\bDEFAULT=(\w*)/],
|
||||
['instream-id', /\bINSTREAM-ID="(.*?)"/],
|
||||
['assoc-lang', /\bASSOC-LANGUAGE="(.*?)"/],
|
||||
['channels', /\bCHANNELS="(.*?)"/],
|
||||
['uri', /\bURI="(.*?)"/]
|
||||
];
|
||||
const streams = [], videos = {}, audios = {}, subtitles = {}, captions = {};
|
||||
const dict = { 'VIDEO': videos, 'AUDIO': audios, 'SUBTITLES': subtitles, 'CLOSED-CAPTIONS': captions };
|
||||
|
||||
const res = await new Client().get(url, headers);
|
||||
const text = res.body;
|
||||
|
||||
// collect media
|
||||
for (const match of text.matchAll(/#EXT-X-MEDIA:(.*)/g)) {
|
||||
const info = match[1], medium = {};
|
||||
for (const attr of mediaAttributes) {
|
||||
const m = info.match(attr[1]);
|
||||
medium[attr[0]] = m ? m[1] : null;
|
||||
}
|
||||
|
||||
const type = medium.type;
|
||||
delete medium.type;
|
||||
const group = medium.group;
|
||||
delete medium.group;
|
||||
|
||||
const typedict = dict[type];
|
||||
if (typedict[group] == undefined)
|
||||
typedict[group] = [];
|
||||
typedict[group].push(medium);
|
||||
}
|
||||
|
||||
// collect streams
|
||||
for (const match of text.matchAll(/#EXT-X-STREAM-INF:(.*)\s*(.*)/g)) {
|
||||
const info = match[1], stream = { 'url': absUrl(match[2], url) };
|
||||
for (const attr of streamAttributes) {
|
||||
const m = info.match(attr[1]);
|
||||
stream[attr[0]] = m ? m[1] : null;
|
||||
}
|
||||
|
||||
stream['video'] = videos[stream.video] ?? null;
|
||||
stream['audio'] = audios[stream.audio] ?? null;
|
||||
stream['subtitles'] = subtitles[stream.subtitles] ?? null;
|
||||
stream['captions'] = captions[stream.captions] ?? null;
|
||||
|
||||
// format resolution or bandwidth
|
||||
let quality;
|
||||
if (stream.resolution) {
|
||||
quality = stream.resolution.match(/x(\d+)/)[1] + 'p';
|
||||
} else {
|
||||
quality = (parseInt(stream.avg_bandwidth ?? stream.bandwidth) / 1000000) + 'Mb/s'
|
||||
}
|
||||
|
||||
// add stream to list
|
||||
const subs = stream.subtitles?.map((s) => {
|
||||
return { file: s.uri, label: s.name };
|
||||
});
|
||||
const auds = stream.audio?.map((a) => {
|
||||
return { file: a.uri, label: a.name };
|
||||
});
|
||||
streams.push({
|
||||
url: stream.url,
|
||||
quality: quality,
|
||||
originalUrl: stream.url,
|
||||
headers: headers,
|
||||
subtitles: subs ?? null,
|
||||
audios: auds ?? null
|
||||
});
|
||||
}
|
||||
return streams.length ? streams : [{
|
||||
url: url,
|
||||
quality: '',
|
||||
originalUrl: url,
|
||||
headers: headers,
|
||||
subtitles: null,
|
||||
audios: null
|
||||
}];
|
||||
}
|
||||
|
||||
async function jwplayerExtractor(text, headers) {
|
||||
// https://docs.jwplayer.com/players/reference/playlists
|
||||
const getsetup = /setup\(({[\s\S]*?})\)/;
|
||||
const getsources = /sources:\s*(\[[\s\S]*?\])/;
|
||||
const gettracks = /tracks:\s*(\[[\s\S]*?\])/;
|
||||
const unpacked = unpackJs(text);
|
||||
|
||||
const videos = [], subtitles = [];
|
||||
|
||||
const data = eval('(' + (getsetup.exec(text) || getsetup.exec(unpacked))?.[1] + ')');
|
||||
|
||||
if (data){
|
||||
var sources = data.sources;
|
||||
var tracks = data.tracks;
|
||||
} else {
|
||||
var sources = eval('(' + (getsources.exec(text) || getsources.exec(unpacked))?.[1] + ')');
|
||||
var tracks = eval('(' + (gettracks.exec(text) || gettracks.exec(unpacked))?.[1] + ')');
|
||||
}
|
||||
for (t of tracks) {
|
||||
if (t.type == "captions") {
|
||||
subtitles.push({file: t.file, label: t.label});
|
||||
}
|
||||
}
|
||||
for (s of sources) {
|
||||
if (s.file.includes('master.m3u8')) {
|
||||
videos.push(...(await m3u8Extractor(s.file, headers)));
|
||||
} else if (s.file.includes('.mpd')) {
|
||||
|
||||
} else {
|
||||
videos.push({url: s.file, originalUrl: s.file, quality: '', headers: headers});
|
||||
}
|
||||
}
|
||||
return videos.map(v => {
|
||||
v.subtitles = subtitles;
|
||||
return v;
|
||||
});
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Extension Helpers
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
function sortVideos(videos) {
|
||||
const pref = new SharedPreferences();
|
||||
const getres = RegExp('(\\d+)p?', 'i');
|
||||
const lang = RegExp(pref.get('lang'), 'i');
|
||||
const type = RegExp(pref.get('type'), 'i');
|
||||
const res = RegExp(getres.exec(pref.get('res'))[1], 'i');
|
||||
const host = RegExp(pref.get('host'), 'i');
|
||||
|
||||
let getScore = (q, hasRes) => {
|
||||
const bLang = lang.test(q), bType = type.test(q), bRes = res.test(q), bHost = host.test(q);
|
||||
if (hasRes) {
|
||||
return bLang * (8 + bType * (4 + bRes * (2 + bHost * 1)));
|
||||
} else {
|
||||
return bLang * (8 + bType * (4 + (bHost * 3)));
|
||||
}
|
||||
}
|
||||
|
||||
return videos.sort((a, b) => {
|
||||
const resA = getres.exec(a.quality)?.[1];
|
||||
const resB = getres.exec(b.quality)?.[1];
|
||||
const score = getScore(b.quality, resB) - getScore(a.quality, resA);
|
||||
|
||||
if (score) return score;
|
||||
|
||||
const qA = resA ? a.quality.replace(resA, (9999 - parseInt(resA)).toString()) : a.quality;
|
||||
const qB = resA ? b.quality.replace(resB, (9999 - parseInt(resB)).toString()) : b.quality;
|
||||
|
||||
return qA.localeCompare(qB);
|
||||
});
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Uint8Array
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
Uint8Array.fromBase64 = function (b64) {
|
||||
// [00,01,02,03,04,05,06,07,08,\t,\n,0b,0c,\r,0e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,' ', !, ", #, $, %, &, ', (, ), *, +,',', -, ., /, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ;, <,'=', >, ?, @,A,B,C,D,E,F,G,H,I,J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, [, \, ], ^, _, `, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, {, |, }, ~,7f]
|
||||
const m = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1]
|
||||
let data = [], val = 0, bits = -8
|
||||
for (const c of b64) {
|
||||
let n = m[c.charCodeAt(0)];
|
||||
if (n == -1) break;
|
||||
val = (val << 6) + n;
|
||||
bits += 6;
|
||||
for (; bits >= 0; bits -= 8)
|
||||
data.push((val >> bits) & 0xFF);
|
||||
}
|
||||
return new Uint8Array(data);
|
||||
}
|
||||
|
||||
Uint8Array.prototype.toBase64 = function () {
|
||||
const m = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
let b64 = '', val = 0, bits = -6;
|
||||
for (const b of this) {
|
||||
val = (val << 8) + b;
|
||||
bits += 8;
|
||||
while (bits >= 0) {
|
||||
b64 += m[(val >> bits) & 0x3F];
|
||||
bits -= 6;
|
||||
}
|
||||
}
|
||||
if (bits > -6)
|
||||
b64 += m[(val << -bits) & 0x3F];
|
||||
return b64 + ['', '', '==', '='][b64.length % 4];
|
||||
}
|
||||
|
||||
Uint8Array.prototype.decode = function (encoding = 'utf-8') {
|
||||
encoding = encoding.toLowerCase();
|
||||
if (encoding == 'utf-8') {
|
||||
return decodeUTF8(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// String
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
String.prototype.encode = function (encoding = 'utf-8') {
|
||||
encoding = encoding.toLowerCase();
|
||||
if (encoding == 'utf-8') {
|
||||
return encodeUTF8(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String.decode = function (data, encoding = 'utf-8') {
|
||||
encoding = encoding.toLowerCase();
|
||||
if (encoding == 'utf-8') {
|
||||
return decodeUTF8(data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String.prototype.reverse = function () {
|
||||
return this.split('').reverse().join('');
|
||||
}
|
||||
|
||||
String.prototype.swapcase = function () {
|
||||
const isAsciiLetter = /[A-z]/;
|
||||
const result = [];
|
||||
for (const l of this)
|
||||
result.push(isAsciiLetter.test(l) ? String.fromCharCode(l.charCodeAt() ^ 32) : l);
|
||||
return result.join('');
|
||||
}
|
||||
|
||||
function getRandomString(length) {
|
||||
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
|
||||
let result = "";
|
||||
for (let i = 0; i < length; i++) {
|
||||
const random = Math.floor(Math.random() * 61);
|
||||
result += chars[random];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Encode/Decode Functions
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
function decodeUTF8(data) {
|
||||
const codes = [];
|
||||
for (let i = 0; i < data.length;) {
|
||||
const c = data[i++];
|
||||
const len = (c > 0xBF) + (c > 0xDF) + (c > 0xEF);
|
||||
let val = c & (0xFF >> (len + 1));
|
||||
for (const end = i + len; i < end; i++) {
|
||||
val = (val << 6) + (data[i] & 0x3F);
|
||||
}
|
||||
codes.push(val);
|
||||
}
|
||||
return String.fromCharCode(...codes);
|
||||
}
|
||||
|
||||
function encodeUTF8(string) {
|
||||
const data = [];
|
||||
for (const c of string) {
|
||||
const code = c.charCodeAt(0);
|
||||
const len = (code > 0x7F) + (code > 0x7FF) + (code > 0xFFFF);
|
||||
let bits = len * 6;
|
||||
|
||||
data.push((len ? ~(0xFF >> len + 1) : (0)) + (code >> bits));
|
||||
while (bits > 0) {
|
||||
data.push(0x80 + ((code >> (bits -= 6)) & 0x3F))
|
||||
}
|
||||
}
|
||||
return new Uint8Array(data);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Url
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
function absUrl(url, base) {
|
||||
if (url.search(/^\w+:\/\//) == 0) {
|
||||
return url;
|
||||
} else if (url.startsWith('/')) {
|
||||
return base.slice(0, base.lastIndexOf('/')) + url;
|
||||
} else {
|
||||
return base.slice(0, base.lastIndexOf('/') + 1) + url;
|
||||
}
|
||||
}
|
||||
@@ -168,321 +168,85 @@ class DefaultExtension extends MProvider {
|
||||
type_name: "GroupFilter",
|
||||
name: "Type",
|
||||
state: [
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Manga",
|
||||
value: "manga"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "One-Shot",
|
||||
value: "one_shot"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Doujinshi",
|
||||
value: "doujinshi"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Novel",
|
||||
value: "novel"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Manhwa",
|
||||
value: "manhwa"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Manhua",
|
||||
value: "manhua"
|
||||
}
|
||||
]
|
||||
["Manga", "manga"],
|
||||
["One-Shot", "one_shot"],
|
||||
["Doujinshi", "doujinshi"],
|
||||
["Novel", "novel"],
|
||||
["Manhwa", "manhwa"],
|
||||
["Manhua", "manhua"]
|
||||
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "GroupFilter",
|
||||
name: "Genre",
|
||||
state: [
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Action",
|
||||
value: "1"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Adventure",
|
||||
value: "78"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Avant Garde",
|
||||
value: "3"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Boys Love",
|
||||
value: "4"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Comedy",
|
||||
value: "5"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Demons",
|
||||
value: "77"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Drama",
|
||||
value: "6"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Ecchi",
|
||||
value: "7"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Fantasy",
|
||||
value: "79"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Girls Love",
|
||||
value: "9"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Gourmet",
|
||||
value: "10"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Harem",
|
||||
value: "11"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Horror",
|
||||
value: "530"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Isekai",
|
||||
value: "13"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Iyashikei",
|
||||
value: "531"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Josei",
|
||||
value: "15"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Kids",
|
||||
value: "532"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Magic",
|
||||
value: "539"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Mahou Shoujo",
|
||||
value: "533"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Martial Arts",
|
||||
value: "534"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Mecha",
|
||||
value: "19"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Military",
|
||||
value: "535"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Music",
|
||||
value: "21"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Mystery",
|
||||
value: "22"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Parody",
|
||||
value: "23"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Psychological",
|
||||
value: "536"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Reverse Harem",
|
||||
value: "25"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Romance",
|
||||
value: "26"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "School",
|
||||
value: "73"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Sci-Fi",
|
||||
value: "28"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Seinen",
|
||||
value: "537"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Shoujo",
|
||||
value: "30"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Shounen",
|
||||
value: "31"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Slice of Life",
|
||||
value: "538"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Space",
|
||||
value: "33"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Sports",
|
||||
value: "34"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "SuperPower",
|
||||
value: "75"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Supernatural",
|
||||
value: "76"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Suspense",
|
||||
value: "37"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Thriller",
|
||||
value: "38"
|
||||
},
|
||||
{
|
||||
type_name: "TriState",
|
||||
name: "Vampire",
|
||||
value: "39"
|
||||
}
|
||||
]
|
||||
["Action", "1"],
|
||||
["Adventure", "78"],
|
||||
["Avant Garde", "3"],
|
||||
["Boys Love", "4"],
|
||||
["Comedy", "5"],
|
||||
["Demons", "77"],
|
||||
["Drama", "6"],
|
||||
["Ecchi", "7"],
|
||||
["Fantasy", "79"],
|
||||
["Girls Love", "9"],
|
||||
["Gourmet", "10"],
|
||||
["Harem", "11"],
|
||||
["Horror", "530"],
|
||||
["Isekai", "13"],
|
||||
["Iyashikei", "531"],
|
||||
["Josei", "15"],
|
||||
["Kids", "532"],
|
||||
["Magic", "539"],
|
||||
["Mahou Shoujo", "533"],
|
||||
["Martial Arts", "534"],
|
||||
["Mecha", "19"],
|
||||
["Military", "535"],
|
||||
["Music", "21"],
|
||||
["Mystery", "22"],
|
||||
["Parody", "23"],
|
||||
["Psychological", "536"],
|
||||
["Reverse Harem", "25"],
|
||||
["Romance", "26"],
|
||||
["School", "73"],
|
||||
["Sci-Fi", "28"],
|
||||
["Seinen", "537"],
|
||||
["Shoujo", "30"],
|
||||
["Shounen", "31"],
|
||||
["Slice of Life", "538"],
|
||||
["Space", "33"],
|
||||
["Sports", "34"],
|
||||
["SuperPower", "75"],
|
||||
["Supernatural", "76"],
|
||||
["Suspense", "37"],
|
||||
["Thriller", "38"],
|
||||
["Vampire", "39"]
|
||||
].map(x => ({ type_name: 'TriState', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "GroupFilter",
|
||||
name: "Status",
|
||||
state: [
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Releasing",
|
||||
value: "releasing"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Completed",
|
||||
value: "completed"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Hiatus",
|
||||
value: "on_hiatus"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Discontinued",
|
||||
value: "discontinued"
|
||||
},
|
||||
{
|
||||
type_name: "CheckBox",
|
||||
name: "Not Yet Published",
|
||||
value: "info"
|
||||
}
|
||||
]
|
||||
["Releasing", "releasing"],
|
||||
["Completed", "completed"],
|
||||
["Hiatus", "on_hiatus"],
|
||||
["Discontinued", "discontinued"],
|
||||
["Not Yet Published", "info"]
|
||||
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "SelectFilter",
|
||||
type: "length",
|
||||
name: "Length",
|
||||
values: [
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: ">= 1 chapters",
|
||||
value: "1"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: ">= 3 chapters",
|
||||
value: "3"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: ">= 5 chapters",
|
||||
value: "5"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: ">= 10 chapters",
|
||||
value: "10"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: ">= 20 chapters",
|
||||
value: "20"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: ">= 30 chapters",
|
||||
value: "30"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: ">= 50 chapters",
|
||||
value: "50"
|
||||
}
|
||||
],
|
||||
[">= 1 chapters", "1"],
|
||||
[">= 3 chapters", "3"],
|
||||
[">= 5 chapters", "5"],
|
||||
[">= 10 chapters", "10"],
|
||||
[">= 20 chapters", "20"],
|
||||
[">= 30 chapters", "30"],
|
||||
[">= 50 chapters", "50"]
|
||||
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
},
|
||||
{
|
||||
type_name: "SelectFilter",
|
||||
@@ -490,32 +254,12 @@ class DefaultExtension extends MProvider {
|
||||
name: "Sort",
|
||||
state: 3,
|
||||
values: [
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Added",
|
||||
value: "recently_added"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Updated",
|
||||
value: "recently_updated"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Trending",
|
||||
value: "trending"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Most Relevance",
|
||||
value: "most_relevance"
|
||||
},
|
||||
{
|
||||
type_name: "SelectOption",
|
||||
name: "Name",
|
||||
value: "title_az"
|
||||
}
|
||||
],
|
||||
["Added", "recently_added"],
|
||||
["Updated", "recently_updated"],
|
||||
["Trending", "trending"],
|
||||
["Most Relevance", "most_relevance"],
|
||||
["Name", "title_az"]
|
||||
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user