From 6d1412d7e1bc9dfe57a0d2c107e3cdd30c6b2dff Mon Sep 17 00:00:00 2001 From: RndDev123 Date: Wed, 27 Nov 2024 13:26:11 +0100 Subject: [PATCH 1/2] New Source: AnimeWorld & Updates: Shortened filter code New Source: - Anime World AnimeFenix, JKAnime and Mangafire: - Shortened filter code --- javascript/anime/src/es/animefenix.js | 404 ++--------- javascript/anime/src/es/jkanime.js | 682 ++++--------------- javascript/anime/src/it/animeworld.js | 939 ++++++++++++++++++++++++++ javascript/manga/src/all/mangafire.js | 394 ++--------- 4 files changed, 1197 insertions(+), 1222 deletions(-) create mode 100644 javascript/anime/src/it/animeworld.js diff --git a/javascript/anime/src/es/animefenix.js b/javascript/anime/src/es/animefenix.js index 3b25c047..f681425e 100644 --- a/javascript/anime/src/es/animefenix.js +++ b/javascript/anime/src/es/animefenix.js @@ -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] })) } ]; } diff --git a/javascript/anime/src/es/jkanime.js b/javascript/anime/src/es/jkanime.js index b03c8a13..f81f6164 100644 --- a/javascript/anime/src/es/jkanime.js +++ b/javascript/anime/src/es/jkanime.js @@ -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] })) } ]; } diff --git a/javascript/anime/src/it/animeworld.js b/javascript/anime/src/it/animeworld.js new file mode 100644 index 00000000..c4964a61 --- /dev/null +++ b/javascript/anime/src/it/animeworld.js @@ -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; + } +} \ No newline at end of file diff --git a/javascript/manga/src/all/mangafire.js b/javascript/manga/src/all/mangafire.js index c3befa4d..232f63e0 100644 --- a/javascript/manga/src/all/mangafire.js +++ b/javascript/manga/src/all/mangafire.js @@ -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] })) } ]; } From 61f31863f91243599f7bf714098be4aa2e41acbe Mon Sep 17 00:00:00 2001 From: RndDev123 Date: Wed, 27 Nov 2024 13:49:54 +0100 Subject: [PATCH 2/2] + --- javascript/anime/src/es/animefenix.js | 2 +- javascript/anime/src/es/jkanime.js | 2 +- javascript/manga/src/all/mangafire.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/anime/src/es/animefenix.js b/javascript/anime/src/es/animefenix.js index f681425e..14fa4e9b 100644 --- a/javascript/anime/src/es/animefenix.js +++ b/javascript/anime/src/es/animefenix.js @@ -6,7 +6,7 @@ const mangayomiSources = [{ "iconUrl": "https://www3.animefenix.tv/themes/fenix-neo/images/AveFenix.png", "typeSource": "single", "isManga": false, - "version": "0.1.1", + "version": "0.1.11", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "anime/src/es/animefenix.js" diff --git a/javascript/anime/src/es/jkanime.js b/javascript/anime/src/es/jkanime.js index f81f6164..a95d04f7 100644 --- a/javascript/anime/src/es/jkanime.js +++ b/javascript/anime/src/es/jkanime.js @@ -6,7 +6,7 @@ const mangayomiSources = [{ "iconUrl": "https://cdn.jkanime.net/logo_jk.png", "typeSource": "single", "isManga": false, - "version": "0.1.1", + "version": "0.1.11", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "anime/src/es/jkanime.js" diff --git a/javascript/manga/src/all/mangafire.js b/javascript/manga/src/all/mangafire.js index 232f63e0..eccabd8f 100644 --- a/javascript/manga/src/all/mangafire.js +++ b/javascript/manga/src/all/mangafire.js @@ -6,7 +6,7 @@ const mangayomiSources = [{ "iconUrl": "https://mangafire.to/assets/sites/mangafire/favicon.png?v3", "typeSource": "single", "isManga": true, - "version": "0.1.2", + "version": "0.1.21", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "manga/src/all/mangafire.js"