diff --git a/src/handler/VerHdLink.test.ts b/src/handler/VerHdLink.test.ts
new file mode 100644
index 0000000..de63e08
--- /dev/null
+++ b/src/handler/VerHdLink.test.ts
@@ -0,0 +1,66 @@
+import { VerHdLink } from './VerHdLink';
+import { Fetcher } from '../utils';
+import { Dropload, EmbedExtractors, SuperVideo } from '../embed-extractor';
+import { Context } from '../types';
+jest.mock('../utils/Fetcher');
+
+// @ts-expect-error No constructor args needed
+const fetcher = new Fetcher();
+const mostraguarda = new VerHdLink(fetcher, new EmbedExtractors([new Dropload(fetcher), new SuperVideo(fetcher)]));
+const ctx: Context = { ip: '127.0.0.1' };
+
+describe('VerHdLink', () => {
+ test('does not handle non imdb movies', async () => {
+ const streams = await mostraguarda.handle(ctx, 'kitsu:123');
+
+ expect(streams).toHaveLength(0);
+ });
+
+ test('handles non-existent movies gracefully', async () => {
+ const streams = await mostraguarda.handle(ctx, 'tt12345678');
+
+ expect(streams).toHaveLength(0);
+ });
+
+ test('handle titanic', async () => {
+ const streams = await mostraguarda.handle(ctx, 'tt0120338');
+
+ expect(streams).toHaveLength(4);
+ expect(streams[0]).toStrictEqual({
+ url: expect.any(URL),
+ label: 'SuperVideo',
+ sourceId: 'supervideo_mx',
+ height: 556,
+ bytes: 1503238553,
+ countryCode: 'mx',
+ });
+ expect(streams[0]?.url.href).toMatch(/^https:\/\/.*?.m3u8/);
+ expect(streams[1]).toStrictEqual({
+ url: expect.any(URL),
+ label: 'Dropload',
+ sourceId: 'dropload_mx',
+ height: 556,
+ bytes: 1503238553,
+ countryCode: 'mx',
+ });
+ expect(streams[1]?.url.href).toMatch(/^https:\/\/.*?.m3u8/);
+ expect(streams[2]).toStrictEqual({
+ url: expect.any(URL),
+ label: 'SuperVideo',
+ sourceId: 'supervideo_es',
+ height: 544,
+ bytes: 1610612736,
+ countryCode: 'es',
+ });
+ expect(streams[2]?.url.href).toMatch(/^https:\/\/.*?.m3u8/);
+ expect(streams[3]).toStrictEqual({
+ url: expect.any(URL),
+ label: 'Dropload',
+ sourceId: 'dropload_es',
+ height: 544,
+ bytes: 1610612736,
+ countryCode: 'es',
+ });
+ expect(streams[3]?.url.href).toMatch(/^https:\/\/.*?.m3u8/);
+ });
+});
diff --git a/src/handler/VerHdLink.ts b/src/handler/VerHdLink.ts
new file mode 100644
index 0000000..93408d6
--- /dev/null
+++ b/src/handler/VerHdLink.ts
@@ -0,0 +1,53 @@
+import * as cheerio from 'cheerio';
+import { Handler } from './types';
+import { Fetcher, parseImdbId } from '../utils';
+import { EmbedExtractors } from '../embed-extractor';
+import { Context } from '../types';
+
+export class VerHdLink implements Handler {
+ readonly id = 'verhdlink';
+
+ readonly label = 'VerHdLink';
+
+ readonly contentTypes = ['movie'];
+
+ readonly languages = ['es', 'mx'];
+
+ private readonly fetcher: Fetcher;
+ private readonly embedExtractors: EmbedExtractors;
+
+ constructor(fetcher: Fetcher, embedExtractors: EmbedExtractors) {
+ this.fetcher = fetcher;
+ this.embedExtractors = embedExtractors;
+ }
+
+ readonly handle = async (ctx: Context, id: string) => {
+ if (!id.startsWith('tt')) {
+ return [];
+ }
+
+ const html = await this.fetcher.text(ctx, new URL(`https://verhdlink.cam/movie/${parseImdbId(id).id}`));
+
+ const $ = cheerio.load(html);
+
+ return Promise.all(
+ $('._player-mirrors')
+ .map((_i, el) => {
+ let countryCode = undefined;
+ if ($(el).hasClass('latino')) {
+ countryCode = 'mx';
+ } else if ($(el).hasClass('castellano')) {
+ countryCode = 'es';
+ } else {
+ return [];
+ }
+
+ return $('[data-link!=""]', el)
+ .map((_i, el) => new URL(($(el).attr('data-link') as string).replace(/^(https:)?\/\//, 'https://')))
+ .toArray()
+ .filter(embedUrl => embedUrl.host.match(/(dropload|supervideo)/))
+ .map(embedUrl => this.embedExtractors.handle(ctx, embedUrl, countryCode));
+ }),
+ );
+ };
+}
diff --git a/src/handler/index.ts b/src/handler/index.ts
index 0176e9a..56ab0d1 100644
--- a/src/handler/index.ts
+++ b/src/handler/index.ts
@@ -2,4 +2,5 @@ export * from './FrenchCloud';
export * from './KinoKiste';
export * from './MeineCloud';
export * from './MostraGuarda';
+export * from './VerHdLink';
export * from './types';
diff --git a/src/index.ts b/src/index.ts
index 9d3b4f4..a9e518e 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -3,7 +3,7 @@ import makeFetchHappen from 'make-fetch-happen';
import { flag } from 'country-emoji';
import winston from 'winston';
import { landingTemplate } from './landingTemplate';
-import { FrenchCloud, Handler, KinoKiste, MeineCloud, MostraGuarda } from './handler';
+import { FrenchCloud, Handler, KinoKiste, MeineCloud, MostraGuarda, VerHdLink } from './handler';
import { Dropload, EmbedExtractors, SuperVideo } from './embed-extractor';
import { buildManifest, Fetcher } from './utils';
import { Config, UrlResult } from './types';
@@ -44,6 +44,7 @@ const handlers: Handler[] = [
new KinoKiste(fetcher, embedExtractors),
new MeineCloud(fetcher, embedExtractors),
new MostraGuarda(fetcher, embedExtractors),
+ new VerHdLink(fetcher, embedExtractors),
];
addon.use((_req: Request, res: Response, next: NextFunction) => {
diff --git a/src/utils/__fixtures__/Fetcher/https:dropload.io3rj3nyfors6b.html b/src/utils/__fixtures__/Fetcher/https:dropload.io3rj3nyfors6b.html
new file mode 100644
index 0000000..5624316
--- /dev/null
+++ b/src/utils/__fixtures__/Fetcher/https:dropload.io3rj3nyfors6b.html
@@ -0,0 +1,502 @@
+
+
+
+
+
+ Dropload - Revolution Video Hosting
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
titanic-1997-3[subtitulado]
+
+
+
+
+
+
+
+
+
+
+
+ on Jun 29, 2023
+
+
+
+
+
+
+
+
+ 03:14:49
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Share code
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/utils/__fixtures__/Fetcher/https:dropload.ioick4ti66vt6s.html b/src/utils/__fixtures__/Fetcher/https:dropload.ioick4ti66vt6s.html
new file mode 100644
index 0000000..db7b4d4
--- /dev/null
+++ b/src/utils/__fixtures__/Fetcher/https:dropload.ioick4ti66vt6s.html
@@ -0,0 +1,502 @@
+
+
+
+
+
+ Dropload - Revolution Video Hosting
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
titanic-1997-2[castellano]
+
+
+
+
+
+
+
+
+
+
+
+ on Jun 29, 2023
+
+
+
+
+
+
+
+
+ 03:06:52
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Share code
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/utils/__fixtures__/Fetcher/https:dropload.iojjjx9j5joiz8.html b/src/utils/__fixtures__/Fetcher/https:dropload.iojjjx9j5joiz8.html
new file mode 100644
index 0000000..d5fb8b4
--- /dev/null
+++ b/src/utils/__fixtures__/Fetcher/https:dropload.iojjjx9j5joiz8.html
@@ -0,0 +1,502 @@
+
+
+
+
+
+ Dropload - Revolution Video Hosting
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
titanic-1997-[latino]
+
+
+
+
+
+
+
+
+
+
+
+ on Jun 29, 2023
+
+
+
+
+
+
+
+
+ 03:14:50
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Share code
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/utils/__fixtures__/Fetcher/https:supervideo.cc8xc9f2x2w09p b/src/utils/__fixtures__/Fetcher/https:supervideo.cc8xc9f2x2w09p
new file mode 100644
index 0000000..82e5047
--- /dev/null
+++ b/src/utils/__fixtures__/Fetcher/https:supervideo.cc8xc9f2x2w09p
@@ -0,0 +1,401 @@
+
+
+
+
+
+
+ Watch titanic 1997 3[subtitulado]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ titanic-1997-3[subtitulado]
+
+
+ -
+ on
+ Jun 29, 2023
+
+ -
+ spainman
+
+ -
+ 49 views
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/utils/__fixtures__/Fetcher/https:supervideo.ccg6okbr0kd790 b/src/utils/__fixtures__/Fetcher/https:supervideo.ccg6okbr0kd790
new file mode 100644
index 0000000..c74c5c9
--- /dev/null
+++ b/src/utils/__fixtures__/Fetcher/https:supervideo.ccg6okbr0kd790
@@ -0,0 +1,401 @@
+
+
+
+
+
+
+ Watch titanic 1997 [latino]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ titanic-1997-[latino]
+
+
+ -
+ on
+ Jun 29, 2023
+
+ -
+ spainman
+
+ -
+ 1448 views
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/utils/__fixtures__/Fetcher/https:supervideo.ccqe1fviow8uwy b/src/utils/__fixtures__/Fetcher/https:supervideo.ccqe1fviow8uwy
new file mode 100644
index 0000000..f05d463
--- /dev/null
+++ b/src/utils/__fixtures__/Fetcher/https:supervideo.ccqe1fviow8uwy
@@ -0,0 +1,401 @@
+
+
+
+
+
+
+ Watch titanic 1997 2[castellano]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ titanic-1997-2[castellano]
+
+
+ -
+ on
+ Jun 29, 2023
+
+ -
+ spainman
+
+ -
+ 257 views
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/utils/__fixtures__/Fetcher/https:verhdlink.cammoviett0120338 b/src/utils/__fixtures__/Fetcher/https:verhdlink.cammoviett0120338
new file mode 100644
index 0000000..578b59e
--- /dev/null
+++ b/src/utils/__fixtures__/Fetcher/https:verhdlink.cammoviett0120338
@@ -0,0 +1,148 @@
+
+
+
+
+
+ Movie tt0120338
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+ Latino
+
+ -
+ Castellano
+
+ -
+ Subtitulado
+
+
+
+
+ -
+ supervideo
+ -
+ dropload
+ -
+ Player HD
+
+ -
+ mixdrop
+ -
+ streamtape
+ -
+ doodstream
+
+
+ -
+ supervideo
+ -
+ dropload
+ -
+ Player HD
+
+ -
+ mixdrop
+ -
+ doodstream
+
+
+ -
+ supervideo
+ -
+ dropload
+ -
+ Player HD
+
+ -
+ mixdrop
+ -
+ streamtape
+ -
+ doodstream
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/utils/__fixtures__/Fetcher/https:verhdlink.cammoviett12345678 b/src/utils/__fixtures__/Fetcher/https:verhdlink.cammoviett12345678
new file mode 100644
index 0000000..b241097
--- /dev/null
+++ b/src/utils/__fixtures__/Fetcher/https:verhdlink.cammoviett12345678
@@ -0,0 +1,96 @@
+
+
+
+
+
+ Movie
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file