diff --git a/README.md b/README.md index b7cd999dc..ecc03a921 100644 --- a/README.md +++ b/README.md @@ -41,15 +41,15 @@ docker run -p 8080:8080 stremio-web ### Board -![Board](/screenshots/board.png) +![Board](/assets/screenshots/board.png) ### Discover -![Discover](/screenshots/discover.png) +![Discover](/assets/screenshots/discover.png) ### Meta Details -![Meta Details](/screenshots/metadetails.png) +![Meta Details](/assets/screenshots/metadetails.png) ## License diff --git a/favicons/favicon.ico b/assets/favicons/favicon.ico similarity index 100% rename from favicons/favicon.ico rename to assets/favicons/favicon.ico diff --git a/fonts/PlusJakartaSans.ttf b/assets/fonts/PlusJakartaSans.ttf similarity index 100% rename from fonts/PlusJakartaSans.ttf rename to assets/fonts/PlusJakartaSans.ttf diff --git a/images/anonymous.png b/assets/images/anonymous.png similarity index 100% rename from images/anonymous.png rename to assets/images/anonymous.png diff --git a/images/background_1.svg b/assets/images/background_1.svg similarity index 100% rename from images/background_1.svg rename to assets/images/background_1.svg diff --git a/images/background_2.svg b/assets/images/background_2.svg similarity index 100% rename from images/background_2.svg rename to assets/images/background_2.svg diff --git a/images/calendar_placeholder.png b/assets/images/calendar_placeholder.png similarity index 100% rename from images/calendar_placeholder.png rename to assets/images/calendar_placeholder.png diff --git a/images/default_avatar.png b/assets/images/default_avatar.png similarity index 100% rename from images/default_avatar.png rename to assets/images/default_avatar.png diff --git a/images/empty.png b/assets/images/empty.png similarity index 100% rename from images/empty.png rename to assets/images/empty.png diff --git a/images/icon.png b/assets/images/icon.png similarity index 100% rename from images/icon.png rename to assets/images/icon.png diff --git a/assets/images/icon_196x196.png b/assets/images/icon_196x196.png new file mode 100644 index 000000000..d5bc3e90f Binary files /dev/null and b/assets/images/icon_196x196.png differ diff --git a/assets/images/icon_512x512.png b/assets/images/icon_512x512.png new file mode 100644 index 000000000..9569431ed Binary files /dev/null and b/assets/images/icon_512x512.png differ diff --git a/images/library_placeholder.png b/assets/images/library_placeholder.png similarity index 100% rename from images/library_placeholder.png rename to assets/images/library_placeholder.png diff --git a/images/logo.png b/assets/images/logo.png similarity index 100% rename from images/logo.png rename to assets/images/logo.png diff --git a/images/maskable_icon.png b/assets/images/maskable_icon.png similarity index 100% rename from images/maskable_icon.png rename to assets/images/maskable_icon.png diff --git a/assets/images/maskable_icon_196x196.png b/assets/images/maskable_icon_196x196.png new file mode 100644 index 000000000..eb84355ad Binary files /dev/null and b/assets/images/maskable_icon_196x196.png differ diff --git a/assets/images/maskable_icon_512x512.png b/assets/images/maskable_icon_512x512.png new file mode 100644 index 000000000..804b24a20 Binary files /dev/null and b/assets/images/maskable_icon_512x512.png differ diff --git a/images/stremio_symbol.png b/assets/images/stremio_symbol.png similarity index 100% rename from images/stremio_symbol.png rename to assets/images/stremio_symbol.png diff --git a/screenshots/board.png b/assets/screenshots/board.png similarity index 100% rename from screenshots/board.png rename to assets/screenshots/board.png diff --git a/screenshots/board_narrow.webp b/assets/screenshots/board_narrow.webp similarity index 100% rename from screenshots/board_narrow.webp rename to assets/screenshots/board_narrow.webp diff --git a/screenshots/board_wide.webp b/assets/screenshots/board_wide.webp similarity index 100% rename from screenshots/board_wide.webp rename to assets/screenshots/board_wide.webp diff --git a/screenshots/discover.png b/assets/screenshots/discover.png similarity index 100% rename from screenshots/discover.png rename to assets/screenshots/discover.png diff --git a/screenshots/metadetails.png b/assets/screenshots/metadetails.png similarity index 100% rename from screenshots/metadetails.png rename to assets/screenshots/metadetails.png diff --git a/manifest.json b/manifest.json new file mode 100644 index 000000000..3505fb7c4 --- /dev/null +++ b/manifest.json @@ -0,0 +1,59 @@ +{ + "name": "Stremio Web", + "short_name": "Stremio", + "description": "Freedom To Stream", + "background_color": "#161523", + "theme_color": "#2a2843", + "orientation": "any", + "display": "standalone", + "display_override": ["standalone"], + "scope": "./", + "start_url": "./", + "icons": [ + { + "src": "favicons/icon_256x256.ico", + "sizes": "256x256", + "type": "image/vnd.microsoft.icon" + }, + { + "src": "images/maskable_icon_512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "images/maskable_icon_196x196.png", + "sizes": "196x196", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "images/icon_512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" + }, + { + "src": "images/icon_196x196.png", + "sizes": "196x196", + "type": "image/png", + "purpose": "any" + } + ], + "screenshots": [ + { + "src": "screenshots/board_wide.webp", + "sizes": "1440x900", + "type": "image/webp", + "form_factor": "wide", + "label": "Homescreen of Stremio" + }, + { + "src": "screenshots/board_narrow.webp", + "sizes": "414x896", + "type": "image/webp", + "form_factor": "narrow", + "label": "Homescreen of Stremio" + } + ] +} \ No newline at end of file diff --git a/package.json b/package.json index 81c4771b7..0c9ca54ec 100644 --- a/package.json +++ b/package.json @@ -17,21 +17,21 @@ "@babel/runtime": "7.26.0", "@sentry/browser": "8.42.0", "@stremio/stremio-colors": "5.2.0", - "@stremio/stremio-core-web": "https://stremio.github.io/stremio-core/stremio-core-web/feat/stremio-core-web-bridge-panicking/dev/stremio-stremio-core-web-0.51.1.tgz", + "@stremio/stremio-core-web": "0.52.0", "@stremio/stremio-icons": "5.8.0", - "@stremio/stremio-video": "0.0.64", + "@stremio/stremio-video": "0.0.70", "a-color-picker": "1.2.1", "bowser": "2.11.0", "buffer": "6.0.3", "classnames": "2.5.1", "eventemitter3": "5.0.1", + "fast-equals": "^6.0.0", "filter-invalid-dom-props": "3.0.1", "hat": "^0.0.3", "i18next": "^24.0.5", "langs": "github:Stremio/nodejs-langs", "lodash.debounce": "4.0.8", "lodash.intersection": "4.4.0", - "lodash.isequal": "4.5.0", "lodash.throttle": "4.1.1", "magnet-uri": "6.2.0", "prop-types": "15.8.1", @@ -41,7 +41,7 @@ "react-i18next": "^15.1.3", "react-is": "18.3.1", "spatial-navigation-polyfill": "github:Stremio/spatial-navigation#64871b1422466f5f45d24ebc8bbd315b2ebab6a6", - "stremio-translations": "github:Stremio/stremio-translations#01aaa201e419782b26b9f2cbe4430795021426e5", + "stremio-translations": "github:Stremio/stremio-translations#7c0c337f32163aa13158bb90cd6133da43feafef", "url": "0.11.4", "use-long-press": "^3.2.0" }, @@ -53,12 +53,10 @@ "@stylistic/eslint-plugin": "^5.4.0", "@stylistic/eslint-plugin-jsx": "^4.4.1", "@types/hat": "^0.0.4", - "@types/lodash.isequal": "^4.5.8", "@types/lodash.throttle": "^4.1.9", "@types/react": "^18.3.13", "@types/react-dom": "^18.3.1", "babel-loader": "9.2.1", - "clean-webpack-plugin": "4.0.0", "copy-webpack-plugin": "12.0.2", "css-loader": "6.11.0", "cssnano": "7.0.6", @@ -82,7 +80,6 @@ "webpack": "5.97.0", "webpack-cli": "5.1.4", "webpack-dev-server": "^5.1.0", - "webpack-pwa-manifest": "^4.3.0", "workbox-webpack-plugin": "^7.3.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9fc4507b2..435a809e8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,14 +18,14 @@ importers: specifier: 5.2.0 version: 5.2.0 '@stremio/stremio-core-web': - specifier: https://stremio.github.io/stremio-core/stremio-core-web/feat/stremio-core-web-bridge-panicking/dev/stremio-stremio-core-web-0.51.1.tgz - version: https://stremio.github.io/stremio-core/stremio-core-web/feat/stremio-core-web-bridge-panicking/dev/stremio-stremio-core-web-0.51.1.tgz + specifier: 0.52.0 + version: 0.52.0 '@stremio/stremio-icons': specifier: 5.8.0 version: 5.8.0 '@stremio/stremio-video': - specifier: 0.0.64 - version: 0.0.64 + specifier: 0.0.70 + version: 0.0.70 a-color-picker: specifier: 1.2.1 version: 1.2.1 @@ -41,6 +41,9 @@ importers: eventemitter3: specifier: 5.0.1 version: 5.0.1 + fast-equals: + specifier: ^6.0.0 + version: 6.0.0 filter-invalid-dom-props: specifier: 3.0.1 version: 3.0.1 @@ -59,9 +62,6 @@ importers: lodash.intersection: specifier: 4.4.0 version: 4.4.0 - lodash.isequal: - specifier: 4.5.0 - version: 4.5.0 lodash.throttle: specifier: 4.1.1 version: 4.1.1 @@ -90,8 +90,8 @@ importers: specifier: github:Stremio/spatial-navigation#64871b1422466f5f45d24ebc8bbd315b2ebab6a6 version: https://codeload.github.com/Stremio/spatial-navigation/tar.gz/64871b1422466f5f45d24ebc8bbd315b2ebab6a6 stremio-translations: - specifier: github:Stremio/stremio-translations#01aaa201e419782b26b9f2cbe4430795021426e5 - version: https://codeload.github.com/Stremio/stremio-translations/tar.gz/01aaa201e419782b26b9f2cbe4430795021426e5 + specifier: github:Stremio/stremio-translations#7c0c337f32163aa13158bb90cd6133da43feafef + version: https://codeload.github.com/Stremio/stremio-translations/tar.gz/7c0c337f32163aa13158bb90cd6133da43feafef url: specifier: 0.11.4 version: 0.11.4 @@ -120,9 +120,6 @@ importers: '@types/hat': specifier: ^0.0.4 version: 0.0.4 - '@types/lodash.isequal': - specifier: ^4.5.8 - version: 4.5.8 '@types/lodash.throttle': specifier: ^4.1.9 version: 4.1.9 @@ -135,9 +132,6 @@ importers: babel-loader: specifier: 9.2.1 version: 9.2.1(@babel/core@7.26.0)(webpack@5.97.0) - clean-webpack-plugin: - specifier: 4.0.0 - version: 4.0.0(webpack@5.97.0) copy-webpack-plugin: specifier: 12.0.2 version: 12.0.2(webpack@5.97.0) @@ -207,9 +201,6 @@ importers: webpack-dev-server: specifier: ^5.1.0 version: 5.2.2(webpack-cli@5.1.4)(webpack@5.97.0) - webpack-pwa-manifest: - specifier: ^4.3.0 - version: 4.3.0 workbox-webpack-plugin: specifier: ^7.3.0 version: 7.3.0(@types/babel__core@7.20.5)(webpack@5.97.0) @@ -899,14 +890,6 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} - '@istanbuljs/load-nyc-config@1.1.0': resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} @@ -981,171 +964,6 @@ packages: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jimp/bmp@0.16.13': - resolution: {integrity: sha512-9edAxu7N2FX7vzkdl5Jo1BbACfycUtBQX+XBMcHA2bk62P8R0otgkHg798frgAk/WxQIzwxqOH6wMiCwrlAzdQ==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/core@0.16.13': - resolution: {integrity: sha512-qXpA1tzTnlkTku9yqtuRtS/wVntvE6f3m3GNxdTdtmc+O+Wcg9Xo2ABPMh7Nc0AHbMKzwvwgB2JnjZmlmJEObg==} - - '@jimp/custom@0.16.13': - resolution: {integrity: sha512-LTATglVUPGkPf15zX1wTMlZ0+AU7cGEGF6ekVF1crA8eHUWsGjrYTB+Ht4E3HTrCok8weQG+K01rJndCp/l4XA==} - - '@jimp/gif@0.16.13': - resolution: {integrity: sha512-yFAMZGv3o+YcjXilMWWwS/bv1iSqykFahFMSO169uVMtfQVfa90kt4/kDwrXNR6Q9i6VHpFiGZMlF2UnHClBvg==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/jpeg@0.16.13': - resolution: {integrity: sha512-BJHlDxzTlCqP2ThqP8J0eDrbBfod7npWCbJAcfkKqdQuFk0zBPaZ6KKaQKyKxmWJ87Z6ohANZoMKEbtvrwz1AA==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-blit@0.16.13': - resolution: {integrity: sha512-8Z1k96ZFxlhK2bgrY1JNWNwvaBeI/bciLM0yDOni2+aZwfIIiC7Y6PeWHTAvjHNjphz+XCt01WQmOYWCn0ML6g==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-blur@0.16.13': - resolution: {integrity: sha512-PvLrfa8vkej3qinlebyhLpksJgCF5aiysDMSVhOZqwH5nQLLtDE9WYbnsofGw4r0VVpyw3H/ANCIzYTyCtP9Cg==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-circle@0.16.13': - resolution: {integrity: sha512-RNave7EFgZrb5V5EpdvJGAEHMnDAJuwv05hKscNfIYxf0kR3KhViBTDy+MoTnMlIvaKFULfwIgaZWzyhuINMzA==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-color@0.16.13': - resolution: {integrity: sha512-xW+9BtEvoIkkH/Wde9ql4nAFbYLkVINhpgAE7VcBUsuuB34WUbcBl/taOuUYQrPEFQJ4jfXiAJZ2H/rvKjCVnQ==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-contain@0.16.13': - resolution: {integrity: sha512-QayTXw4tXMwU6q6acNTQrTTFTXpNRBe+MgTGMDU0lk+23PjlFCO/9sacflelG8lsp7vNHhAxFeHptDMAksEYzg==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - '@jimp/plugin-blit': '>=0.3.5' - '@jimp/plugin-resize': '>=0.3.5' - '@jimp/plugin-scale': '>=0.3.5' - - '@jimp/plugin-cover@0.16.13': - resolution: {integrity: sha512-BSsP71GTNaqWRcvkbWuIVH+zK7b3TSNebbhDkFK0fVaUTzHuKMS/mgY4hDZIEVt7Rf5FjadAYtsujHN9w0iSYA==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - '@jimp/plugin-crop': '>=0.3.5' - '@jimp/plugin-resize': '>=0.3.5' - '@jimp/plugin-scale': '>=0.3.5' - - '@jimp/plugin-crop@0.16.13': - resolution: {integrity: sha512-WEl2tPVYwzYL8OKme6Go2xqiWgKsgxlMwyHabdAU4tXaRwOCnOI7v4021gCcBb9zn/oWwguHuKHmK30Fw2Z/PA==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-displace@0.16.13': - resolution: {integrity: sha512-qt9WKq8vWrcjySa9DyQ0x/RBMHQeiVjdVSY1SJsMjssPUf0pS74qorcuAkGi89biN3YoGUgPkpqECnAWnYwgGA==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-dither@0.16.13': - resolution: {integrity: sha512-5/N3yJggbWQTlGZHQYJPmQXEwR52qaXjEzkp1yRBbtdaekXE3BG/suo0fqeoV/csf8ooI78sJzYmIrxNoWVtgQ==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-fisheye@0.16.13': - resolution: {integrity: sha512-2rZmTdFbT/cF9lEZIkXCYO0TsT114Q27AX5IAo0Sju6jVQbvIk1dFUTnwLDadTo8wkJlFzGqMQ24Cs8cHWOliA==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-flip@0.16.13': - resolution: {integrity: sha512-EmcgAA74FTc5u7Z+hUO/sRjWwfPPLuOQP5O64x5g4j0T12Bd29IgsYZxoutZo/rb3579+JNa/3wsSEmyVv1EpA==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - '@jimp/plugin-rotate': '>=0.3.5' - - '@jimp/plugin-gaussian@0.16.13': - resolution: {integrity: sha512-A1XKfGQD0iDdIiKqFYi8nZMv4dDVYdxbrmgR7y/CzUHhSYdcmoljLIIsZZM3Iks/Wa353W3vtvkWLuDbQbch1w==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-invert@0.16.13': - resolution: {integrity: sha512-xFMrIn7czEZbdbMzZWuaZFnlLGJDVJ82y5vlsKsXRTG2kcxRsMPXvZRWHV57nSs1YFsNqXSbrC8B98n0E32njQ==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-mask@0.16.13': - resolution: {integrity: sha512-wLRYKVBXql2GAYgt6FkTnCfE+q5NomM7Dlh0oIPGAoMBWDyTx0eYutRK6PlUrRK2yMHuroAJCglICTbxqGzowQ==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-normalize@0.16.13': - resolution: {integrity: sha512-3tfad0n9soRna4IfW9NzQdQ2Z3ijkmo21DREHbE6CGcMIxOSvfRdSvf1qQPApxjTSo8LTU4MCi/fidx/NZ0GqQ==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-print@0.16.13': - resolution: {integrity: sha512-0m6i3p01PGRkGAK9r53hDYrkyMq+tlhLOIbsSTmZyh6HLshUKlTB7eXskF5OpVd5ZUHoltlNc6R+ggvKIzxRFw==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - '@jimp/plugin-blit': '>=0.3.5' - - '@jimp/plugin-resize@0.16.13': - resolution: {integrity: sha512-qoqtN8LDknm3fJm9nuPygJv30O3vGhSBD2TxrsCnhtOsxKAqVPJtFVdGd/qVuZ8nqQANQmTlfqTiK9mVWQ7MiQ==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/plugin-rotate@0.16.13': - resolution: {integrity: sha512-Ev+Jjmj1nHYw897z9C3R9dYsPv7S2/nxdgfFb/h8hOwK0Ovd1k/+yYS46A0uj/JCKK0pQk8wOslYBkPwdnLorw==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - '@jimp/plugin-blit': '>=0.3.5' - '@jimp/plugin-crop': '>=0.3.5' - '@jimp/plugin-resize': '>=0.3.5' - - '@jimp/plugin-scale@0.16.13': - resolution: {integrity: sha512-05POQaEJVucjTiSGMoH68ZiELc7QqpIpuQlZ2JBbhCV+WCbPFUBcGSmE7w4Jd0E2GvCho/NoMODLwgcVGQA97A==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - '@jimp/plugin-resize': '>=0.3.5' - - '@jimp/plugin-shadow@0.16.13': - resolution: {integrity: sha512-nmu5VSZ9hsB1JchTKhnnCY+paRBnwzSyK5fhkhtQHHoFD5ArBQ/5wU8y6tCr7k/GQhhGq1OrixsECeMjPoc8Zw==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - '@jimp/plugin-blur': '>=0.3.5' - '@jimp/plugin-resize': '>=0.3.5' - - '@jimp/plugin-threshold@0.16.13': - resolution: {integrity: sha512-+3zArBH0OE3Rhjm4HyAokMsZlIq5gpQec33CncyoSwxtRBM2WAhUVmCUKuBo+Lr/2/4ISoY4BWpHKhMLDix6cA==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - '@jimp/plugin-color': '>=0.8.0' - '@jimp/plugin-resize': '>=0.8.0' - - '@jimp/plugins@0.16.13': - resolution: {integrity: sha512-CJLdqODEhEVs4MgWCxpWL5l95sCBlkuSLz65cxEm56X5akIsn4LOlwnKoSEZioYcZUBvHhCheH67AyPTudfnQQ==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/png@0.16.13': - resolution: {integrity: sha512-8cGqINvbWJf1G0Her9zbq9I80roEX0A+U45xFby3tDWfzn+Zz8XKDF1Nv9VUwVx0N3zpcG1RPs9hfheG4Cq2kg==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/tiff@0.16.13': - resolution: {integrity: sha512-oJY8d9u95SwW00VPHuCNxPap6Q1+E/xM5QThb9Hu+P6EGuu6lIeLaNBMmFZyblwFbwrH+WBOZlvIzDhi4Dm/6Q==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/types@0.16.13': - resolution: {integrity: sha512-mC0yVNUobFDjoYLg4hoUwzMKgNlxynzwt3cDXzumGvRJ7Kb8qQGOWJQjQFo5OxmGExqzPphkirdbBF88RVLBCg==} - peerDependencies: - '@jimp/custom': '>=0.3.5' - - '@jimp/utils@0.16.13': - resolution: {integrity: sha512-VyCpkZzFTHXtKgVO35iKN0sYR10psGpV6SkcSeV4oF7eSYlR8Bl6aQLCzVeFjvESF7mxTmIiI3/XrMobVrtxDA==} - '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -1302,15 +1120,14 @@ packages: '@stremio/stremio-colors@5.2.0': resolution: {integrity: sha512-dYlPgu9W/H7c9s1zmW5tiDnRenaUa4Hg1QCyOg1lhOcgSfM/bVTi5nnqX+IfvGTTUNA0zgzh8hI3o3miwnZxTg==} - '@stremio/stremio-core-web@https://stremio.github.io/stremio-core/stremio-core-web/feat/stremio-core-web-bridge-panicking/dev/stremio-stremio-core-web-0.51.1.tgz': - resolution: {tarball: https://stremio.github.io/stremio-core/stremio-core-web/feat/stremio-core-web-bridge-panicking/dev/stremio-stremio-core-web-0.51.1.tgz} - version: 0.51.1 + '@stremio/stremio-core-web@0.52.0': + resolution: {integrity: sha512-zT0P8JspGZ1oI9/11f3RIt7XG9b/1fOZE+xSnP+oAyhRmzzkqrnPUJkHdJdgoVD9XELDFAS2awNfl5/eRdh5kA==} '@stremio/stremio-icons@5.8.0': resolution: {integrity: sha512-IVUvQbIWfA4YEHCTed7v/sdQJCJ+OOCf84LTWpkE2W6GLQ+15WHcMEJrVkE1X3ekYJnGg3GjT0KLO6tKSU0P4w==} - '@stremio/stremio-video@0.0.64': - resolution: {integrity: sha512-29w/lwU8BB6ai8LUyCnpRc2F9kPf7cpys40NCobt70MqBP/UqvYISsrnD/ijoBwvtpKdZ6ptv5h9BbDj6rrerw==} + '@stremio/stremio-video@0.0.70': + resolution: {integrity: sha512-a0flQYAUdrZNMm7mmts2vpZOqN1nus7Hs9Mjl4mrN5rtduD0ojUyhD5J4lPcCpZ7WB0YdEUOGLXR19qHpgoKmg==} '@stylistic/eslint-plugin-jsx@4.4.1': resolution: {integrity: sha512-83SInq4u7z71vWwGG+6ViOtlOmZ6tSrDkMPhrvdBBTGMLA0gs22WSdhQ4vZP3oJ5Xg4ythvqeUiFSedvVxzhyA==} @@ -1327,9 +1144,6 @@ packages: '@surma/rollup-plugin-off-main-thread@2.2.3': resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==} - '@tokenizer/token@0.3.0': - resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1372,9 +1186,6 @@ packages: '@types/express@4.17.23': resolution: {integrity: sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==} - '@types/glob@7.2.0': - resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} - '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -1402,9 +1213,6 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/lodash.isequal@4.5.8': - resolution: {integrity: sha512-uput6pg4E/tj2LGxCZo9+y27JNyB2OZuuI/T5F+ylVDYuqICLG2/ktjxx0v6GvVntAf8TvEzeQLcV0ffRirXuA==} - '@types/lodash.throttle@4.1.9': resolution: {integrity: sha512-PCPVfpfueguWZQB7pJQK890F2scYKoDUL3iM522AptHWn7d5NQmeS/LTEHIcLr5PaTzl3dK2Z0xSUHHTHwaL5g==} @@ -1414,16 +1222,9 @@ packages: '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - '@types/minimatch@6.0.0': - resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} - deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. - '@types/node-forge@1.3.14': resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} - '@types/node@16.9.1': - resolution: {integrity: sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==} - '@types/node@24.5.2': resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} @@ -1615,10 +1416,6 @@ packages: a-color-picker@1.2.1: resolution: {integrity: sha512-aMCUKd2zTDWK2YWnjz0k3YhFc9XL0jZlPIywF6XkP6i3wdq2iHTEnl1BFPZkOVDV89M12t+zeZ8m23cfzn57/Q==} - abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} - accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -1678,9 +1475,6 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - any-base@1.1.0: - resolution: {integrity: sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==} - anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -1702,14 +1496,6 @@ packages: resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} engines: {node: '>= 0.4'} - array-union@1.0.2: - resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} - engines: {node: '>=0.10.0'} - - array-uniq@1.0.3: - resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} - engines: {node: '>=0.10.0'} - array.prototype.findlast@1.2.5: resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} engines: {node: '>= 0.4'} @@ -1809,8 +1595,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.8.7: - resolution: {integrity: sha512-bxxN2M3a4d1CRoQC//IqsR5XrLh0IJ8TCv2x6Y9N0nckNz/rTjZB3//GGscZziZOxmjP55rzxg/ze7usFI9FqQ==} + baseline-browser-mapping@2.9.14: + resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==} hasBin: true batch@0.6.1: @@ -1823,9 +1609,6 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - bmp-js@0.1.0: - resolution: {integrity: sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==} - body-parser@1.20.3: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -1857,16 +1640,9 @@ packages: bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - buffer-equal@0.0.1: - resolution: {integrity: sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==} - engines: {node: '>=0.4.0'} - buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} @@ -1908,11 +1684,8 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001745: - resolution: {integrity: sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==} - - centra@2.7.0: - resolution: {integrity: sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==} + caniuse-lite@1.0.30001763: + resolution: {integrity: sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ==} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} @@ -1944,12 +1717,6 @@ packages: resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} engines: {node: '>= 10.0'} - clean-webpack-plugin@4.0.0: - resolution: {integrity: sha512-WuWE1nyTNAyW5T7oNyys2EN0cfP2fdRxhxnIQWiAp0bMabPdHhoGxM8A6YL2GhqwgrPnnaemVE7nv5XJ2Fhh2w==} - engines: {node: '>=10.0.0'} - peerDependencies: - webpack: '>=4.0.0 <6.0.0' - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -2077,9 +1844,6 @@ packages: resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} engines: {node: '>=8'} - css-color-names@1.0.1: - resolution: {integrity: sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==} - css-declaration-sorter@7.3.0: resolution: {integrity: sha512-LQF6N/3vkAMYF4xoHLJfG718HRJh34Z8BnNhd6bosOMIVjMlhuZK5++oZa3uYAgrI5+7x2o27gUqTR2U/KjUOQ==} engines: {node: ^14 || ^16 || >=18} @@ -2219,10 +1983,6 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} - del@4.1.1: - resolution: {integrity: sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==} - engines: {node: '>=6'} - depd@1.1.2: resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} engines: {node: '>= 0.6'} @@ -2266,9 +2026,6 @@ packages: dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - dom-walk@0.1.2: - resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==} - domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} @@ -2467,10 +2224,6 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} - event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} - eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} @@ -2485,9 +2238,6 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - exif-parser@0.1.12: - resolution: {integrity: sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==} - exit@0.1.2: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} @@ -2503,6 +2253,10 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-equals@6.0.0: + resolution: {integrity: sha512-PFhhIGgdM79r5Uztdj9Zb6Tt1zKafqVfdMGwVca1z5z6fbX7DmsySSuJd8HiP6I1j505DCS83cLxo5rmSNeVEA==} + engines: {node: '>=6.0.0'} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -2534,10 +2288,6 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} - file-type@16.5.4: - resolution: {integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==} - engines: {node: '>=10'} - filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} @@ -2660,9 +2410,6 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - gifwrap@0.9.4: - resolution: {integrity: sha512-MDMwbhASQuVeD4JKd1fKgNgCRL3fGqMM4WaqpNhWO0JiMOAjbQdumbs4BbBZEy9/M00EHEjKN3HieVhCUlwjeQ==} - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2684,9 +2431,6 @@ packages: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported - global@4.4.0: - resolution: {integrity: sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==} - globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -2703,10 +2447,6 @@ packages: resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} engines: {node: '>=18'} - globby@6.1.0: - resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} - engines: {node: '>=0.10.0'} - gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -2858,9 +2598,6 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} - image-q@4.0.0: - resolution: {integrity: sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==} - image-size@0.5.5: resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} engines: {node: '>=0.10.0'} @@ -2964,9 +2701,6 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-function@1.0.2: - resolution: {integrity: sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==} - is-generator-fn@2.1.0: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} @@ -3011,18 +2745,6 @@ packages: resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} engines: {node: '>=0.10.0'} - is-path-cwd@2.2.0: - resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} - engines: {node: '>=6'} - - is-path-in-cwd@2.1.0: - resolution: {integrity: sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==} - engines: {node: '>=6'} - - is-path-inside@2.1.0: - resolution: {integrity: sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==} - engines: {node: '>=6'} - is-plain-obj@3.0.0: resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} engines: {node: '>=10'} @@ -3261,16 +2983,10 @@ packages: node-notifier: optional: true - jimp@0.16.1: - resolution: {integrity: sha512-+EKVxbR36Td7Hfd23wKGIeEyHbxShZDX6L8uJkgVW3ESA9GiTEPK08tG1XI2r/0w5Ch0HyJF5kPqF9K7EmGjaw==} - jiti@1.21.7: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true - jpeg-js@0.4.4: - resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==} - js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -3375,9 +3091,6 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - load-bmfont@1.4.2: - resolution: {integrity: sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog==} - loader-runner@4.3.0: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} @@ -3403,10 +3116,6 @@ packages: lodash.intersection@4.4.0: resolution: {integrity: sha512-N+L0cCfnqMv6mxXtSPeKt+IavbOBBSiAEkKyLasZ8BVcP9YXQgxLO12oPR8OyURwKV8l5vJKiE1M8aS70heuMg==} - lodash.isequal@4.5.0: - resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. - lodash.memoize@4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} @@ -3508,18 +3217,10 @@ packages: engines: {node: '>=4'} hasBin: true - mime@2.4.6: - resolution: {integrity: sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==} - engines: {node: '>=4.0.0'} - hasBin: true - mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - min-document@2.19.0: - resolution: {integrity: sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==} - mini-css-extract-plugin@2.9.2: resolution: {integrity: sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==} engines: {node: '>= 12.13.0'} @@ -3529,10 +3230,6 @@ packages: minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - minimatch@10.0.3: - resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} - engines: {node: 20 || >=22} - minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -3544,13 +3241,6 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -3644,9 +3334,6 @@ packages: obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - omggif@1.0.10: - resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} - on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -3698,10 +3385,6 @@ packages: resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - p-map@2.1.0: - resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} - engines: {node: '>=6'} - p-retry@6.2.1: resolution: {integrity: sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==} engines: {node: '>=16.17'} @@ -3710,9 +3393,6 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - param-case@3.0.4: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} @@ -3720,18 +3400,6 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} - parse-bmfont-ascii@1.0.6: - resolution: {integrity: sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==} - - parse-bmfont-binary@1.0.6: - resolution: {integrity: sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==} - - parse-bmfont-xml@1.1.6: - resolution: {integrity: sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==} - - parse-headers@2.0.6: - resolution: {integrity: sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==} - parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -3759,9 +3427,6 @@ packages: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} - path-is-inside@1.0.2: - resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -3776,18 +3441,6 @@ packages: resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} engines: {node: '>=18'} - peek-readable@4.1.0: - resolution: {integrity: sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==} - engines: {node: '>=8'} - - phin@2.9.3: - resolution: {integrity: sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - - phin@3.7.1: - resolution: {integrity: sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==} - engines: {node: '>= 8'} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -3799,30 +3452,14 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - pinkie-promise@2.0.1: - resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} - engines: {node: '>=0.10.0'} - - pinkie@2.0.4: - resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} - engines: {node: '>=0.10.0'} - pirates@4.0.7: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} - pixelmatch@4.0.2: - resolution: {integrity: sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==} - hasBin: true - pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -3831,10 +3468,6 @@ packages: resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} engines: {node: '>=14.16'} - pngjs@3.4.0: - resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} - engines: {node: '>=4.0.0'} - possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -4091,10 +3724,6 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} - prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -4109,9 +3738,6 @@ packages: prr@1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} - punycode@1.3.2: - resolution: {integrity: sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==} - punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} @@ -4130,11 +3756,6 @@ packages: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} - querystring@0.2.0: - resolution: {integrity: sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==} - engines: {node: '>=0.4.x'} - deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. - queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -4201,14 +3822,6 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} - readable-stream@4.7.0: - resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - readable-web-to-node-stream@3.0.4: - resolution: {integrity: sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==} - engines: {node: '>=8'} - readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -4236,9 +3849,6 @@ packages: regenerate@1.4.2: resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} - regenerator-runtime@0.13.11: - resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} @@ -4308,11 +3918,6 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rimraf@2.7.1: - resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - rollup@2.79.2: resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==} engines: {node: '>=10.0.0'} @@ -4528,9 +4133,9 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} - stremio-translations@https://codeload.github.com/Stremio/stremio-translations/tar.gz/01aaa201e419782b26b9f2cbe4430795021426e5: - resolution: {tarball: https://codeload.github.com/Stremio/stremio-translations/tar.gz/01aaa201e419782b26b9f2cbe4430795021426e5} - version: 1.44.13 + stremio-translations@https://codeload.github.com/Stremio/stremio-translations/tar.gz/7c0c337f32163aa13158bb90cd6133da43feafef: + resolution: {tarball: https://codeload.github.com/Stremio/stremio-translations/tar.gz/7c0c337f32163aa13158bb90cd6133da43feafef} + version: 1.45.0 string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} @@ -4589,10 +4194,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strtok3@6.3.0: - resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==} - engines: {node: '>=10'} - stylehacks@7.0.6: resolution: {integrity: sha512-iitguKivmsueOmTO0wmxURXBP8uqOO+zikLGZ7Mm9e/94R4w5T999Js2taS/KBOnQ/wdC3jN3vNSrkGDrlnqQg==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -4672,15 +4273,9 @@ packages: thunky@1.1.0: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} - timm@1.7.1: - resolution: {integrity: sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==} - tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} - tinycolor2@1.6.0: - resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} - tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -4692,10 +4287,6 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - token-types@4.2.1: - resolution: {integrity: sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==} - engines: {node: '>=10'} - tr46@1.0.1: resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} @@ -4821,9 +4412,6 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - url@0.11.0: - resolution: {integrity: sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==} - url@0.11.4: resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} engines: {node: '>= 0.4'} @@ -4853,9 +4441,6 @@ packages: '@types/react': optional: true - utif@2.0.1: - resolution: {integrity: sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==} - util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -4945,10 +4530,6 @@ packages: resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} engines: {node: '>=10.0.0'} - webpack-pwa-manifest@4.3.0: - resolution: {integrity: sha512-3hK8Qg58SyLCUIz4PBYnfUPM6iJ5K88h8Uhc3MxmlJcVtDF/11aBBdUTdQkqc9bo6Cb8Q1v2xdsB2XO6pzTbiA==} - engines: {node: '>=6.0.0'} - webpack-sources@1.4.3: resolution: {integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==} @@ -5087,24 +4668,6 @@ packages: resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} engines: {node: '>=18'} - xhr@2.6.0: - resolution: {integrity: sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==} - - xml-parse-from-string@1.0.1: - resolution: {integrity: sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==} - - xml2js@0.5.0: - resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} - engines: {node: '>=4.0.0'} - - xmlbuilder@11.0.1: - resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} - engines: {node: '>=4.0'} - - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -5975,12 +5538,6 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.0': - dependencies: - '@isaacs/balanced-match': 4.0.1 - '@istanbuljs/load-nyc-config@1.1.0': dependencies: camelcase: 5.3.1 @@ -6153,255 +5710,6 @@ snapshots: '@types/yargs': 17.0.33 chalk: 4.1.2 - '@jimp/bmp@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - bmp-js: 0.1.0 - - '@jimp/core@0.16.13': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/utils': 0.16.13 - any-base: 1.1.0 - buffer: 5.7.1 - exif-parser: 0.1.12 - file-type: 16.5.4 - load-bmfont: 1.4.2 - mkdirp: 0.5.6 - phin: 2.9.3 - pixelmatch: 4.0.2 - tinycolor2: 1.6.0 - transitivePeerDependencies: - - debug - - '@jimp/custom@0.16.13': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/core': 0.16.13 - transitivePeerDependencies: - - debug - - '@jimp/gif@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - gifwrap: 0.9.4 - omggif: 1.0.10 - - '@jimp/jpeg@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - jpeg-js: 0.4.4 - - '@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - - '@jimp/plugin-blur@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - - '@jimp/plugin-circle@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - - '@jimp/plugin-color@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - tinycolor2: 1.6.0 - - '@jimp/plugin-contain@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-scale@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)))': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/plugin-blit': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-scale': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) - '@jimp/utils': 0.16.13 - - '@jimp/plugin-cover@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-scale@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)))': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/plugin-crop': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-scale': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) - '@jimp/utils': 0.16.13 - - '@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - - '@jimp/plugin-displace@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - - '@jimp/plugin-dither@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - - '@jimp/plugin-fisheye@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - - '@jimp/plugin-flip@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-rotate@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)))': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/plugin-rotate': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) - '@jimp/utils': 0.16.13 - - '@jimp/plugin-gaussian@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - - '@jimp/plugin-invert@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - - '@jimp/plugin-mask@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - - '@jimp/plugin-normalize@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - - '@jimp/plugin-print@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/plugin-blit': 0.16.13(@jimp/custom@0.16.13) - '@jimp/utils': 0.16.13 - load-bmfont: 1.4.2 - transitivePeerDependencies: - - debug - - '@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - - '@jimp/plugin-rotate@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/plugin-blit': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-crop': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) - '@jimp/utils': 0.16.13 - - '@jimp/plugin-scale@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) - '@jimp/utils': 0.16.13 - - '@jimp/plugin-shadow@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blur@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/plugin-blur': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) - '@jimp/utils': 0.16.13 - - '@jimp/plugin-threshold@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-color@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/plugin-color': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) - '@jimp/utils': 0.16.13 - - '@jimp/plugins@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/plugin-blit': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-blur': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-circle': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-color': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-contain': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-scale@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))) - '@jimp/plugin-cover': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-scale@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))) - '@jimp/plugin-crop': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-displace': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-dither': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-fisheye': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-flip': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-rotate@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))) - '@jimp/plugin-gaussian': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-invert': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-mask': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-normalize': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-print': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13)) - '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) - '@jimp/plugin-rotate': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) - '@jimp/plugin-scale': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) - '@jimp/plugin-shadow': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blur@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) - '@jimp/plugin-threshold': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-color@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) - timm: 1.7.1 - transitivePeerDependencies: - - debug - - '@jimp/png@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/utils': 0.16.13 - pngjs: 3.4.0 - - '@jimp/tiff@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - utif: 2.0.1 - - '@jimp/types@0.16.13(@jimp/custom@0.16.13)': - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/bmp': 0.16.13(@jimp/custom@0.16.13) - '@jimp/custom': 0.16.13 - '@jimp/gif': 0.16.13(@jimp/custom@0.16.13) - '@jimp/jpeg': 0.16.13(@jimp/custom@0.16.13) - '@jimp/png': 0.16.13(@jimp/custom@0.16.13) - '@jimp/tiff': 0.16.13(@jimp/custom@0.16.13) - timm: 1.7.1 - - '@jimp/utils@0.16.13': - dependencies: - '@babel/runtime': 7.26.0 - regenerator-runtime: 0.13.11 - '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -6562,13 +5870,13 @@ snapshots: '@stremio/stremio-colors@5.2.0': {} - '@stremio/stremio-core-web@https://stremio.github.io/stremio-core/stremio-core-web/feat/stremio-core-web-bridge-panicking/dev/stremio-stremio-core-web-0.51.1.tgz': + '@stremio/stremio-core-web@0.52.0': dependencies: '@babel/runtime': 7.24.1 '@stremio/stremio-icons@5.8.0': {} - '@stremio/stremio-video@0.0.64': + '@stremio/stremio-video@0.0.70': dependencies: buffer: 6.0.3 color: 4.2.3 @@ -6578,7 +5886,7 @@ snapshots: hls.js: https://github.com/Stremio/hls.js/releases/download/v1.5.4-patch2/hls.js-1.5.4-patch2.tgz lodash.clonedeep: 4.5.0 magnet-uri: 6.2.0 - url: 0.11.0 + url: 0.11.4 video-name-parser: 1.4.6 vtt.js: https://codeload.github.com/jaruba/vtt.js/tar.gz/84d33d157848407d790d78423dacc41a096294f0 @@ -6607,8 +5915,6 @@ snapshots: magic-string: 0.25.9 string.prototype.matchall: 4.0.12 - '@tokenizer/token@0.3.0': {} - '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.28.4 @@ -6676,11 +5982,6 @@ snapshots: '@types/qs': 6.14.0 '@types/serve-static': 1.15.8 - '@types/glob@7.2.0': - dependencies: - '@types/minimatch': 6.0.0 - '@types/node': 24.5.2 - '@types/graceful-fs@4.1.9': dependencies: '@types/node': 24.5.2 @@ -6707,10 +6008,6 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/lodash.isequal@4.5.8': - dependencies: - '@types/lodash': 4.17.20 - '@types/lodash.throttle@4.1.9': dependencies: '@types/lodash': 4.17.20 @@ -6719,16 +6016,10 @@ snapshots: '@types/mime@1.3.5': {} - '@types/minimatch@6.0.0': - dependencies: - minimatch: 10.0.3 - '@types/node-forge@1.3.14': dependencies: '@types/node': 24.5.2 - '@types/node@16.9.1': {} - '@types/node@24.5.2': dependencies: undici-types: 7.12.0 @@ -6979,10 +6270,6 @@ snapshots: dependencies: is-plain-object: 2.0.4 - abort-controller@3.0.0: - dependencies: - event-target-shim: 5.0.1 - accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -7035,8 +6322,6 @@ snapshots: ansi-styles@5.2.0: {} - any-base@1.1.0: {} - anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -7066,12 +6351,6 @@ snapshots: is-string: 1.1.1 math-intrinsics: 1.1.0 - array-union@1.0.2: - dependencies: - array-uniq: 1.0.3 - - array-uniq@1.0.3: {} - array.prototype.findlast@1.2.5: dependencies: call-bind: 1.0.8 @@ -7126,7 +6405,7 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.6): dependencies: browserslist: 4.26.2 - caniuse-lite: 1.0.30001745 + caniuse-lite: 1.0.30001763 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -7227,7 +6506,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.8.7: {} + baseline-browser-mapping@2.9.14: {} batch@0.6.1: {} @@ -7235,8 +6514,6 @@ snapshots: binary-extensions@2.3.0: {} - bmp-js@0.1.0: {} - body-parser@1.20.3: dependencies: bytes: 3.1.2 @@ -7278,8 +6555,8 @@ snapshots: browserslist@4.26.2: dependencies: - baseline-browser-mapping: 2.8.7 - caniuse-lite: 1.0.30001745 + baseline-browser-mapping: 2.9.14 + caniuse-lite: 1.0.30001763 electron-to-chromium: 1.5.224 node-releases: 2.0.21 update-browserslist-db: 1.1.3(browserslist@4.26.2) @@ -7288,15 +6565,8 @@ snapshots: dependencies: node-int64: 0.4.0 - buffer-equal@0.0.1: {} - buffer-from@1.1.2: {} - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - buffer@6.0.3: dependencies: base64-js: 1.5.1 @@ -7339,17 +6609,11 @@ snapshots: caniuse-api@3.0.0: dependencies: browserslist: 4.26.2 - caniuse-lite: 1.0.30001745 + caniuse-lite: 1.0.30001763 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001745: {} - - centra@2.7.0: - dependencies: - follow-redirects: 1.15.11 - transitivePeerDependencies: - - debug + caniuse-lite@1.0.30001763: {} chalk@4.1.2: dependencies: @@ -7382,11 +6646,6 @@ snapshots: dependencies: source-map: 0.6.1 - clean-webpack-plugin@4.0.0(webpack@5.97.0): - dependencies: - del: 4.1.1 - webpack: 5.97.0(webpack-cli@5.1.4) - cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -7519,8 +6778,6 @@ snapshots: crypto-random-string@2.0.0: {} - css-color-names@1.0.1: {} - css-declaration-sorter@7.3.0(postcss@8.5.6): dependencies: postcss: 8.5.6 @@ -7684,16 +6941,6 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 - del@4.1.1: - dependencies: - '@types/glob': 7.2.0 - globby: 6.1.0 - is-path-cwd: 2.2.0 - is-path-in-cwd: 2.1.0 - p-map: 2.1.0 - pify: 4.0.1 - rimraf: 2.7.1 - depd@1.1.2: {} depd@2.0.0: {} @@ -7732,8 +6979,6 @@ snapshots: domhandler: 5.0.3 entities: 4.5.0 - dom-walk@0.1.2: {} - domelementtype@2.3.0: {} domhandler@4.3.1: @@ -8022,8 +7267,6 @@ snapshots: etag@1.8.1: {} - event-target-shim@5.0.1: {} - eventemitter3@4.0.7: {} eventemitter3@5.0.1: {} @@ -8042,8 +7285,6 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - exif-parser@0.1.12: {} - exit@0.1.2: {} expect@29.7.0: @@ -8092,6 +7333,8 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-equals@6.0.0: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -8124,12 +7367,6 @@ snapshots: dependencies: flat-cache: 4.0.1 - file-type@16.5.4: - dependencies: - readable-web-to-node-stream: 3.0.4 - strtok3: 6.3.0 - token-types: 4.2.1 - filelist@1.0.4: dependencies: minimatch: 5.1.6 @@ -8256,11 +7493,6 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 - gifwrap@0.9.4: - dependencies: - image-q: 4.0.0 - omggif: 1.0.10 - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -8284,11 +7516,6 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 - global@4.4.0: - dependencies: - min-document: 2.19.0 - process: 0.11.10 - globals@14.0.0: {} globals@15.15.0: {} @@ -8307,14 +7534,6 @@ snapshots: slash: 5.1.0 unicorn-magic: 0.3.0 - globby@6.1.0: - dependencies: - array-union: 1.0.2 - glob: 7.2.3 - object-assign: 4.1.1 - pify: 2.3.0 - pinkie-promise: 2.0.1 - gopd@1.2.0: {} graceful-fs@4.2.11: {} @@ -8461,10 +7680,6 @@ snapshots: ignore@7.0.5: {} - image-q@4.0.0: - dependencies: - '@types/node': 16.9.1 - image-size@0.5.5: optional: true @@ -8559,8 +7774,6 @@ snapshots: is-fullwidth-code-point@3.0.0: {} - is-function@1.0.2: {} - is-generator-fn@2.1.0: {} is-generator-function@1.1.0: @@ -8595,16 +7808,6 @@ snapshots: is-obj@1.0.1: {} - is-path-cwd@2.2.0: {} - - is-path-in-cwd@2.1.0: - dependencies: - is-path-inside: 2.1.0 - - is-path-inside@2.1.0: - dependencies: - path-is-inside: 1.0.2 - is-plain-obj@3.0.0: {} is-plain-object@2.0.4: @@ -9038,20 +8241,8 @@ snapshots: - supports-color - ts-node - jimp@0.16.1: - dependencies: - '@babel/runtime': 7.26.0 - '@jimp/custom': 0.16.13 - '@jimp/plugins': 0.16.13(@jimp/custom@0.16.13) - '@jimp/types': 0.16.13(@jimp/custom@0.16.13) - regenerator-runtime: 0.13.11 - transitivePeerDependencies: - - debug - jiti@1.21.7: {} - jpeg-js@0.4.4: {} - js-tokens@4.0.0: {} js-yaml@3.14.1: @@ -9142,19 +8333,6 @@ snapshots: lines-and-columns@1.2.4: {} - load-bmfont@1.4.2: - dependencies: - buffer-equal: 0.0.1 - mime: 1.6.0 - parse-bmfont-ascii: 1.0.6 - parse-bmfont-binary: 1.0.6 - parse-bmfont-xml: 1.1.6 - phin: 3.7.1 - xhr: 2.6.0 - xtend: 4.0.2 - transitivePeerDependencies: - - debug - loader-runner@4.3.0: {} locate-path@5.0.0: @@ -9175,8 +8353,6 @@ snapshots: lodash.intersection@4.4.0: {} - lodash.isequal@4.5.0: {} - lodash.memoize@4.1.2: {} lodash.merge@4.6.2: {} @@ -9268,14 +8444,8 @@ snapshots: mime@1.6.0: {} - mime@2.4.6: {} - mimic-fn@2.1.0: {} - min-document@2.19.0: - dependencies: - dom-walk: 0.1.2 - mini-css-extract-plugin@2.9.2(webpack@5.97.0): dependencies: schema-utils: 4.3.2 @@ -9284,10 +8454,6 @@ snapshots: minimalistic-assert@1.0.1: {} - minimatch@10.0.3: - dependencies: - '@isaacs/brace-expansion': 5.0.0 - minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -9300,12 +8466,6 @@ snapshots: dependencies: brace-expansion: 2.0.2 - minimist@1.2.8: {} - - mkdirp@0.5.6: - dependencies: - minimist: 1.2.8 - ms@2.0.0: {} ms@2.1.3: {} @@ -9392,8 +8552,6 @@ snapshots: obuf@1.1.2: {} - omggif@1.0.10: {} - on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -9454,8 +8612,6 @@ snapshots: dependencies: p-limit: 4.0.0 - p-map@2.1.0: {} - p-retry@6.2.1: dependencies: '@types/retry': 0.12.2 @@ -9464,8 +8620,6 @@ snapshots: p-try@2.2.0: {} - pako@1.0.11: {} - param-case@3.0.4: dependencies: dot-case: 3.0.4 @@ -9475,17 +8629,6 @@ snapshots: dependencies: callsites: 3.1.0 - parse-bmfont-ascii@1.0.6: {} - - parse-bmfont-binary@1.0.6: {} - - parse-bmfont-xml@1.1.6: - dependencies: - xml-parse-from-string: 1.0.1 - xml2js: 0.5.0 - - parse-headers@2.0.6: {} - parse-json@5.2.0: dependencies: '@babel/code-frame': 7.27.1 @@ -9508,8 +8651,6 @@ snapshots: path-is-absolute@1.0.1: {} - path-is-inside@1.0.2: {} - path-key@3.1.1: {} path-parse@1.0.7: {} @@ -9518,38 +8659,17 @@ snapshots: path-type@6.0.0: {} - peek-readable@4.1.0: {} - - phin@2.9.3: {} - - phin@3.7.1: - dependencies: - centra: 2.7.0 - transitivePeerDependencies: - - debug - picocolors@1.1.1: {} picomatch@2.3.1: {} picomatch@4.0.3: {} - pify@2.3.0: {} - - pify@4.0.1: {} - - pinkie-promise@2.0.1: - dependencies: - pinkie: 2.0.4 - - pinkie@2.0.4: {} + pify@4.0.1: + optional: true pirates@4.0.7: {} - pixelmatch@4.0.2: - dependencies: - pngjs: 3.4.0 - pkg-dir@4.2.0: dependencies: find-up: 4.1.0 @@ -9558,8 +8678,6 @@ snapshots: dependencies: find-up: 6.3.0 - pngjs@3.4.0: {} - possible-typed-array-names@1.1.0: {} postcss-calc@10.1.1(postcss@8.5.6): @@ -9793,8 +8911,6 @@ snapshots: process-nextick-args@2.0.1: {} - process@0.11.10: {} - prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -9814,8 +8930,6 @@ snapshots: prr@1.0.1: optional: true - punycode@1.3.2: {} - punycode@1.4.1: {} punycode@2.3.1: {} @@ -9830,8 +8944,6 @@ snapshots: dependencies: side-channel: 1.1.0 - querystring@0.2.0: {} - queue-microtask@1.2.3: {} randombytes@2.1.0: @@ -9904,18 +9016,6 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 - readable-stream@4.7.0: - dependencies: - abort-controller: 3.0.0 - buffer: 6.0.3 - events: 3.3.0 - process: 0.11.10 - string_decoder: 1.3.0 - - readable-web-to-node-stream@3.0.4: - dependencies: - readable-stream: 4.7.0 - readdirp@3.6.0: dependencies: picomatch: 2.3.1 @@ -9951,8 +9051,6 @@ snapshots: regenerate@1.4.2: {} - regenerator-runtime@0.13.11: {} - regenerator-runtime@0.14.1: {} regexp.prototype.flags@1.5.4: @@ -10021,10 +9119,6 @@ snapshots: reusify@1.1.0: {} - rimraf@2.7.1: - dependencies: - glob: 7.2.3 - rollup@2.79.2: optionalDependencies: fsevents: 2.3.3 @@ -10284,7 +9378,7 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 - stremio-translations@https://codeload.github.com/Stremio/stremio-translations/tar.gz/01aaa201e419782b26b9f2cbe4430795021426e5: {} + stremio-translations@https://codeload.github.com/Stremio/stremio-translations/tar.gz/7c0c337f32163aa13158bb90cd6133da43feafef: {} string-length@4.0.2: dependencies: @@ -10367,11 +9461,6 @@ snapshots: strip-json-comments@3.1.1: {} - strtok3@6.3.0: - dependencies: - '@tokenizer/token': 0.3.0 - peek-readable: 4.1.0 - stylehacks@7.0.6(postcss@8.5.6): dependencies: browserslist: 4.26.2 @@ -10447,12 +9536,8 @@ snapshots: thunky@1.1.0: {} - timm@1.7.1: {} - tiny-invariant@1.3.3: {} - tinycolor2@1.6.0: {} - tmpl@1.0.5: {} to-regex-range@5.0.1: @@ -10461,11 +9546,6 @@ snapshots: toidentifier@1.0.1: {} - token-types@4.2.1: - dependencies: - '@tokenizer/token': 0.3.0 - ieee754: 1.2.1 - tr46@1.0.1: dependencies: punycode: 2.3.1 @@ -10593,11 +9673,6 @@ snapshots: dependencies: punycode: 2.3.1 - url@0.11.0: - dependencies: - punycode: 1.3.2 - querystring: 0.2.0 - url@0.11.4: dependencies: punycode: 1.4.1 @@ -10622,10 +9697,6 @@ snapshots: optionalDependencies: '@types/react': 18.3.24 - utif@2.0.1: - dependencies: - pako: 1.0.11 - util-deprecate@1.0.2: {} utila@0.4.0: {} @@ -10738,14 +9809,6 @@ snapshots: flat: 5.0.2 wildcard: 2.0.1 - webpack-pwa-manifest@4.3.0: - dependencies: - css-color-names: 1.0.1 - jimp: 0.16.1 - mime: 2.4.6 - transitivePeerDependencies: - - debug - webpack-sources@1.4.3: dependencies: source-list-map: 2.0.1 @@ -10992,24 +10055,6 @@ snapshots: dependencies: is-wsl: 3.1.0 - xhr@2.6.0: - dependencies: - global: 4.4.0 - is-function: 1.0.2 - parse-headers: 2.0.6 - xtend: 4.0.2 - - xml-parse-from-string@1.0.1: {} - - xml2js@0.5.0: - dependencies: - sax: 1.4.1 - xmlbuilder: 11.0.1 - - xmlbuilder@11.0.1: {} - - xtend@4.0.2: {} - y18n@5.0.8: {} yallist@3.1.1: {} diff --git a/src/App/ErrorDialog/ErrorDialog.js b/src/App/ErrorDialog/ErrorDialog.js index a2b31ba41..eac9b34ac 100644 --- a/src/App/ErrorDialog/ErrorDialog.js +++ b/src/App/ErrorDialog/ErrorDialog.js @@ -22,7 +22,7 @@ const ErrorDialog = ({ className }) => {
{'
diff --git a/src/App/SearchParamsHandler.js b/src/App/SearchParamsHandler.js index 8834e6e0c..86f10d0c4 100644 --- a/src/App/SearchParamsHandler.js +++ b/src/App/SearchParamsHandler.js @@ -1,7 +1,7 @@ // Copyright (C) 2017-2023 Smart code 203358507 const React = require('react'); -const isEqual = require('lodash.isequal'); +const { deepEqual } = require('fast-equals'); const { withCoreSuspender, useProfile, useToast } = require('stremio/common'); const { useServices } = require('stremio/services'); @@ -18,7 +18,7 @@ const SearchParamsHandler = () => { setSearchParams((previousSearchParams) => { const currentSearchParams = Object.fromEntries(searchParams.entries()); - return isEqual(previousSearchParams, currentSearchParams) ? previousSearchParams : currentSearchParams; + return deepEqual(previousSearchParams, currentSearchParams) ? previousSearchParams : currentSearchParams; }); }; diff --git a/src/App/styles.less b/src/App/styles.less index adce0ae5c..e6fd7d747 100644 --- a/src/App/styles.less +++ b/src/App/styles.less @@ -5,7 +5,7 @@ @font-face { font-family: 'PlusJakartaSans'; - src: url('/fonts/PlusJakartaSans.ttf') format('truetype'); + src: url('/assets/fonts/PlusJakartaSans.ttf') format('truetype'); } :global { @@ -48,7 +48,7 @@ --color-x: #000000; --color-reddit: #FF4500; --color-imdb: #f5c518; - --color-trakt: #ED2224; + --color-trakt: rgb(255, 255, 255); --color-placeholder: #60606080; --color-placeholder-text: @color-surface-50; --color-placeholder-background: @color-surface-dark5-20; diff --git a/src/common/Shortcuts/Shortcuts.tsx b/src/common/Shortcuts/Shortcuts.tsx index 532e9a409..c9198a857 100644 --- a/src/common/Shortcuts/Shortcuts.tsx +++ b/src/common/Shortcuts/Shortcuts.tsx @@ -1,13 +1,15 @@ -import React, { createContext, useCallback, useContext, useEffect } from 'react'; +import React, { createContext, useCallback, useContext, useEffect, useRef } from 'react'; import shortcuts from './shortcuts.json'; const SHORTCUTS = shortcuts.map(({ shortcuts }) => shortcuts).flat(); export type ShortcutName = string; -export type ShortcutListener = () => void; +export type ShortcutListener = (combo: number) => void; interface ShortcutsContext { grouped: ShortcutGroup[], + on: (name: ShortcutName, listener: ShortcutListener) => void, + off: (name: ShortcutName, listener: ShortcutListener) => void, } const ShortcutsContext = createContext({} as ShortcutsContext); @@ -18,27 +20,38 @@ type Props = { }; const ShortcutsProvider = ({ children, onShortcut }: Props) => { - const onKeyDown = useCallback(({ ctrlKey, shiftKey, key }: KeyboardEvent) => { + const listeners = useRef>>(new Map()); + + const onKeyDown = useCallback(({ ctrlKey, shiftKey, code, key }: KeyboardEvent) => { SHORTCUTS.forEach(({ name, combos }) => combos.forEach((keys) => { const modifers = (keys.includes('Ctrl') ? ctrlKey : true) && (keys.includes('Shift') ? shiftKey : true); - if (modifers && keys.includes(key.toUpperCase())) { + if (modifers && (keys.includes(code) || keys.includes(key.toUpperCase()))) { + const combo = combos.indexOf(keys); + listeners.current.get(name)?.forEach((listener) => listener(combo)); + onShortcut(name as ShortcutName); } })); }, [onShortcut]); + const on = (name: ShortcutName, listener: ShortcutListener) => { + !listeners.current.has(name) && listeners.current.set(name, new Set()); + listeners.current.get(name)!.add(listener); + }; + + const off = (name: ShortcutName, listener: ShortcutListener) => { + listeners.current.get(name)?.delete(listener); + }; + useEffect(() => { document.addEventListener('keydown', onKeyDown); - - return () => { - document.removeEventListener('keydown', onKeyDown); - }; + return () => document.removeEventListener('keydown', onKeyDown); }, [onKeyDown]); return ( - + {children} ); @@ -50,5 +63,5 @@ const useShortcuts = () => { export { ShortcutsProvider, - useShortcuts + useShortcuts, }; diff --git a/src/common/Shortcuts/index.ts b/src/common/Shortcuts/index.ts index f7fa38a18..971003a38 100644 --- a/src/common/Shortcuts/index.ts +++ b/src/common/Shortcuts/index.ts @@ -1,5 +1,8 @@ import { ShortcutsProvider, useShortcuts } from './Shortcuts'; +import onShortcut from './onShortcut'; + export { ShortcutsProvider, useShortcuts, + onShortcut, }; diff --git a/src/common/Shortcuts/onShortcut.ts b/src/common/Shortcuts/onShortcut.ts new file mode 100644 index 000000000..f13c970cc --- /dev/null +++ b/src/common/Shortcuts/onShortcut.ts @@ -0,0 +1,15 @@ +import { DependencyList, useCallback, useEffect } from 'react'; +import { ShortcutListener, ShortcutName, useShortcuts } from './Shortcuts'; + +const onShortcut = (name: ShortcutName, listener: ShortcutListener, deps: DependencyList) => { + const shortcuts = useShortcuts(); + + const listenerCallback = useCallback(listener, deps); + + useEffect(() => { + shortcuts.on(name, listenerCallback); + return () => shortcuts.off(name, listenerCallback); + }, [listenerCallback]); +}; + +export default onShortcut; diff --git a/src/common/Shortcuts/shortcuts.json b/src/common/Shortcuts/shortcuts.json index 766288fb0..a3ac0f8fe 100644 --- a/src/common/Shortcuts/shortcuts.json +++ b/src/common/Shortcuts/shortcuts.json @@ -59,6 +59,11 @@ "label": "SETTINGS_SHORTCUT_VOLUME_DOWN", "combos": [["ArrowDown"]] }, + { + "name": "mute", + "label": "SETTINGS_SHORTCUT_MUTE", + "combos": [["M"]] + }, { "name": "subtitlesSize", "label": "SETTINGS_SHORTCUT_SUBTITLES_SIZE", @@ -83,6 +88,16 @@ "name": "infoMenu", "label": "SETTINGS_SHORTCUT_MENU_INFO", "combos": [["I"]] + }, + { + "name": "speedMenu", + "label": "SETTINGS_SHORTCUT_MENU_PLAYBACK_SPEED", + "combos": [["R"]] + }, + { + "name": "statisticsMenu", + "label": "SETTINGS_SHORTCUT_MENU_STATISTICS", + "combos": [["D"]] } ] } diff --git a/src/common/Toast/ToastItem/styles.less b/src/common/Toast/ToastItem/styles.less index 56f535695..075edeea5 100644 --- a/src/common/Toast/ToastItem/styles.less +++ b/src/common/Toast/ToastItem/styles.less @@ -27,7 +27,7 @@ &.error { .icon-container { .icon { - color: var(--color-trakt); + color: var(--danger-accent-color); } } } diff --git a/src/common/index.js b/src/common/index.js index 0b9cb252f..1b248c1ff 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -4,7 +4,7 @@ const { FileDropProvider, onFileDrop } = require('./FileDrop'); const { PlatformProvider, usePlatform } = require('./Platform'); const { ToastProvider, useToast } = require('./Toast'); const { TooltipProvider, Tooltip } = require('./Tooltips'); -const { ShortcutsProvider, useShortcuts } = require('./Shortcuts'); +const { ShortcutsProvider, useShortcuts, onShortcut } = require('./Shortcuts'); const comparatorWithPriorities = require('./comparatorWithPriorities'); const CONSTANTS = require('./CONSTANTS'); const { withCoreSuspender, useCoreSuspender } = require('./CoreSuspender'); @@ -38,6 +38,7 @@ module.exports = { usePlatform, ShortcutsProvider, useShortcuts, + onShortcut, ToastProvider, useToast, TooltipProvider, diff --git a/src/common/interfaceLanguages.json b/src/common/interfaceLanguages.json index ce3504691..91b87d5af 100644 --- a/src/common/interfaceLanguages.json +++ b/src/common/interfaceLanguages.json @@ -3,6 +3,10 @@ "name": "العربية", "codes": ["ar-AR", "ara"] }, + { + "name": "Беларуская", + "codes": ["be-BY", "bel"] + }, { "name": "български език", "codes": ["bg-BG", "bul"] @@ -13,7 +17,7 @@ }, { "name": "català", - "codes": ["ca-CA", "cat"] + "codes": ["ca-ES", "cat"] }, { "name": "čeština", @@ -43,6 +47,10 @@ "name": "español", "codes": ["es-ES", "spa"] }, + { + "name": "Eesti", + "codes": ["et-EE", "est"] + }, { "name": "euskara", "codes": ["eu-ES", "eus"] @@ -111,6 +119,10 @@ "name": "Norsk nynorsk", "codes": ["nn-NO", "nno"] }, + { + "name": "ਪੰਜਾਬੀ", + "codes": ["pa-IN", "pan"] + }, { "name": "język polski", "codes": ["pl-PL", "pol"] @@ -151,6 +163,10 @@ "name": "తెలుగు", "codes": ["te-IN", "tel"] }, + { + "name": "தமிழ்", + "codes": ["tl-TM", "tam"] + }, { "name": "Türkçe", "codes": ["tr-TR", "tur"] @@ -159,6 +175,10 @@ "name": "українська мова", "codes": ["uk-UA", "ukr"] }, + { + "name": "اُرْدُو", + "codes": ["ur-PK", "urd"] + }, { "name": "Tiếng Việt", "codes": ["vi-VN", "vie"] diff --git a/src/common/useModelState.js b/src/common/useModelState.js index 42672dc22..da637b8ff 100644 --- a/src/common/useModelState.js +++ b/src/common/useModelState.js @@ -2,7 +2,7 @@ const React = require('react'); const throttle = require('lodash.throttle'); -const isEqual = require('lodash.isequal'); +const { deepEqual } = require('fast-equals'); const intersection = require('lodash.intersection'); const { useCoreSuspender } = require('stremio/common/CoreSuspender'); const { useRouteFocused } = require('stremio-router'); @@ -19,7 +19,7 @@ const useModelState = ({ action, ...args }) => { const [state, setState] = React.useReducer( (prevState, nextState) => { return Object.keys(prevState).reduce((result, key) => { - result[key] = isEqual(prevState[key], nextState[key]) ? prevState[key] : nextState[key]; + result[key] = deepEqual(prevState[key], nextState[key]) ? prevState[key] : nextState[key]; return result; }, {}); }, diff --git a/src/components/Checkbox/Checkbox.less b/src/components/Checkbox/Checkbox.less index 9276990b3..a9df8ea9e 100644 --- a/src/components/Checkbox/Checkbox.less +++ b/src/components/Checkbox/Checkbox.less @@ -70,7 +70,7 @@ } &.error { - border-color: var(--color-trakt); + border-color: var(--danger-accent-color); } &.checked { diff --git a/src/components/MetaPreview/Ratings/Ratings.less b/src/components/MetaPreview/Ratings/Ratings.less index afe7b3637..ffba0415b 100644 --- a/src/components/MetaPreview/Ratings/Ratings.less +++ b/src/components/MetaPreview/Ratings/Ratings.less @@ -17,6 +17,7 @@ border-radius: 2rem; height: @height; width: fit-content; + backdrop-filter: blur(5px); .icon-container { display: flex; diff --git a/src/components/NavBar/HorizontalNavBar/HorizontalNavBar.js b/src/components/NavBar/HorizontalNavBar/HorizontalNavBar.js index 6be35cd5d..65bf30c94 100644 --- a/src/components/NavBar/HorizontalNavBar/HorizontalNavBar.js +++ b/src/components/NavBar/HorizontalNavBar/HorizontalNavBar.js @@ -35,7 +35,7 @@ const HorizontalNavBar = React.memo(({ className, route, query, title, backButto
{'
diff --git a/src/components/NavBar/HorizontalNavBar/NavMenu/NavMenuContent.js b/src/components/NavBar/HorizontalNavBar/NavMenu/NavMenuContent.js index de0a02212..4b2fdc87e 100644 --- a/src/components/NavBar/HorizontalNavBar/NavMenu/NavMenuContent.js +++ b/src/components/NavBar/HorizontalNavBar/NavMenu/NavMenuContent.js @@ -52,12 +52,12 @@ const NavMenuContent = ({ onClick }) => { className={styles['avatar-container']} style={{ backgroundImage: profile.auth === null ? - `url('${require('/images/anonymous.png')}')` + `url('${require('/assets/images/anonymous.png')}')` : profile.auth.user.avatar ? `url('${profile.auth.user.avatar}')` : - `url('${require('/images/default_avatar.png')}')` + `url('${require('/assets/images/default_avatar.png')}')` }} />
diff --git a/src/components/RadioButton/RadioButton.less b/src/components/RadioButton/RadioButton.less index 20d90bdef..69d179362 100644 --- a/src/components/RadioButton/RadioButton.less +++ b/src/components/RadioButton/RadioButton.less @@ -52,7 +52,7 @@ } &.error { - border-color: var(--color-trakt); + border-color: var(--danger-accent-color); } &.selected { diff --git a/src/components/Video/styles.less b/src/components/Video/styles.less index f651ff70d..907c9a943 100644 --- a/src/components/Video/styles.less +++ b/src/components/Video/styles.less @@ -19,6 +19,7 @@ padding: 0.5rem; margin-bottom: 0.5rem; border-radius: var(--border-radius); + border: 0.15rem solid transparent; @supports (scroll-margin: 1.25rem) { scroll-margin: 1.25rem; diff --git a/src/index.html b/src/index.html index 033f9a267..ff8166004 100644 --- a/src/index.html +++ b/src/index.html @@ -7,6 +7,7 @@ + Stremio - Freedom to Stream <%= htmlWebpackPlugin.tags.headTags %> diff --git a/src/router/Router/Router.js b/src/router/Router/Router.js index db4c9e957..2c7830bc3 100644 --- a/src/router/Router/Router.js +++ b/src/router/Router/Router.js @@ -5,7 +5,7 @@ const ReactIs = require('react-is'); const PropTypes = require('prop-types'); const classnames = require('classnames'); const UrlUtils = require('url'); -const isEqual = require('lodash.isequal'); +const { deepEqual } = require('fast-equals'); const { RouteFocusedProvider } = require('../RouteFocusedContext'); const Route = require('../Route'); const routeConfigForPath = require('./routeConfigForPath'); @@ -54,11 +54,11 @@ const Router = ({ className, onPathNotMatch, onRouteChange, ...props }) => { return { key: `${routeViewIndex}${routeIndex}`, component: routeConfig.component, - urlParams: view !== null && isEqual(view.urlParams, urlParams) ? + urlParams: view !== null && deepEqual(view.urlParams, urlParams) ? view.urlParams : urlParams, - queryParams: view !== null && isEqual(Array.from(view.queryParams.entries()), Array.from(queryParams.entries())) ? + queryParams: view !== null && deepEqual(Array.from(view.queryParams.entries()), Array.from(queryParams.entries())) ? view.queryParams : queryParams diff --git a/src/routes/Calendar/Placeholder/Placeholder.tsx b/src/routes/Calendar/Placeholder/Placeholder.tsx index c84e7a1b8..1f87acb26 100644 --- a/src/routes/Calendar/Placeholder/Placeholder.tsx +++ b/src/routes/Calendar/Placeholder/Placeholder.tsx @@ -17,7 +17,7 @@ const Placeholder = () => {
{'
diff --git a/src/routes/Discover/Discover.js b/src/routes/Discover/Discover.js index 6f32d1f9a..a28a86405 100644 --- a/src/routes/Discover/Discover.js +++ b/src/routes/Discover/Discover.js @@ -133,14 +133,14 @@ const Discover = ({ urlParams, queryParams }) => { discover.catalog === null ?
- {' + {'
{t('NO_CATALOG_SELECTED')}
: discover.catalog.content.type === 'Err' ?
- {' + {'
{discover.catalog.content.content}
: diff --git a/src/routes/Intro/Intro.js b/src/routes/Intro/Intro.js index f04302fc7..5a2f80aaa 100644 --- a/src/routes/Intro/Intro.js +++ b/src/routes/Intro/Intro.js @@ -296,7 +296,7 @@ const Intro = ({ queryParams }) => {
- {' + {'
{t('WEBSITE_SLOGAN_NEW_NEW')} diff --git a/src/routes/Intro/styles.less b/src/routes/Intro/styles.less index 31a09d54c..4a6f6ec8e 100644 --- a/src/routes/Intro/styles.less +++ b/src/routes/Intro/styles.less @@ -19,7 +19,7 @@ bottom: -1rem; left: -1rem; right: -1rem; - background: url('/images/background_1.svg'), url('/images/background_2.svg'); + background: url('/assets/images/background_1.svg'), url('/assets/images/background_2.svg'); background-color: var(--primary-background-color); background-position: bottom left, top right; background-size: 53%, 54%; diff --git a/src/routes/Library/Library.js b/src/routes/Library/Library.js index 16a4c79b5..8307b786a 100644 --- a/src/routes/Library/Library.js +++ b/src/routes/Library/Library.js @@ -85,7 +85,7 @@ const Library = ({ model, urlParams, queryParams }) => {
{'
{model === 'library' ? t('LIBRARY_NOT_LOADED') : t('BOARD_CONTINUE_WATCHING_NOT_LOADED')}
@@ -96,7 +96,7 @@ const Library = ({ model, urlParams, queryParams }) => {
{'
{model === 'library' ? t('LIBRARY_EMPTY') : t('BOARD_CONTINUE_WATCHING_EMPTY')}
diff --git a/src/routes/Library/Placeholder/Placeholder.tsx b/src/routes/Library/Placeholder/Placeholder.tsx index d854a2d54..a066324e0 100644 --- a/src/routes/Library/Placeholder/Placeholder.tsx +++ b/src/routes/Library/Placeholder/Placeholder.tsx @@ -17,7 +17,7 @@ const Placeholder = () => {
{'
diff --git a/src/routes/MetaDetails/MetaDetails.js b/src/routes/MetaDetails/MetaDetails.js index fd27478b5..926671080 100644 --- a/src/routes/MetaDetails/MetaDetails.js +++ b/src/routes/MetaDetails/MetaDetails.js @@ -130,20 +130,20 @@ const MetaDetails = ({ urlParams, queryParams }) => { metaPath === null ?
- {' + {'
{t('ERR_NO_META_SELECTED')}
: metaDetails.metaItem === null ?
- {' + {'
{t('ERR_NO_ADDONS_FOR_META')}
: metaDetails.metaItem.content.type === 'Err' ?
- {' + {'
{t('ERR_NO_META_FOUND')}
: diff --git a/src/routes/MetaDetails/StreamsList/StreamsList.js b/src/routes/MetaDetails/StreamsList/StreamsList.js index eebc0c3cf..7021644ab 100644 --- a/src/routes/MetaDetails/StreamsList/StreamsList.js +++ b/src/routes/MetaDetails/StreamsList/StreamsList.js @@ -132,7 +132,7 @@ const StreamsList = ({ className, video, type, onEpisodeSearch, ...props }) => { : null } - {' + {'
{t('ERR_NO_ADDONS_FOR_STREAMS')}
: @@ -148,7 +148,7 @@ const StreamsList = ({ className, video, type, onEpisodeSearch, ...props }) => {
{t('UPCOMING')}...
: null } - {' + {'
{t('NO_STREAM')}
{ showInstallAddonsButton ? diff --git a/src/routes/MetaDetails/VideosList/VideosList.js b/src/routes/MetaDetails/VideosList/VideosList.js index 8891947db..3cc3832d6 100644 --- a/src/routes/MetaDetails/VideosList/VideosList.js +++ b/src/routes/MetaDetails/VideosList/VideosList.js @@ -124,7 +124,7 @@ const VideosList = ({ className, metaItem, libraryItem, season, seasonOnSelect, metaItem.content.type === 'Err' || videosForSeason.length === 0 ?
- {' + {'
{t('ERR_NO_VIDEOS_FOR_META')}
: diff --git a/src/routes/NotFound/NotFound.js b/src/routes/NotFound/NotFound.js index d984496bc..a3c97d8c1 100644 --- a/src/routes/NotFound/NotFound.js +++ b/src/routes/NotFound/NotFound.js @@ -19,7 +19,7 @@ const NotFound = () => {
{'
{t('PAGE_NOT_FOUND')}
diff --git a/src/routes/Player/AudioMenu/AudioMenu.less b/src/routes/Player/AudioMenu/AudioMenu.less index 344ec13e7..ae3e8acb1 100644 --- a/src/routes/Player/AudioMenu/AudioMenu.less +++ b/src/routes/Player/AudioMenu/AudioMenu.less @@ -7,6 +7,7 @@ align-self: stretch; display: flex; flex-direction: column; + max-height: 25rem; width: 16rem; .header { diff --git a/src/routes/Player/BufferingLoader/BufferingLoader.js b/src/routes/Player/BufferingLoader/BufferingLoader.js index 3d5664ae4..a762506f4 100644 --- a/src/routes/Player/BufferingLoader/BufferingLoader.js +++ b/src/routes/Player/BufferingLoader/BufferingLoader.js @@ -13,7 +13,7 @@ const BufferingLoader = React.forwardRef(({ className, logo }, ref) => { className={styles['buffering-loader']} src={logo} alt={' '} - fallbackSrc={require('/images/stremio_symbol.png')} + fallbackSrc={require('/assets/images/stremio_symbol.png')} />
); diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 27f705be8..196bb813b 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -8,7 +8,7 @@ const langs = require('langs'); const { useTranslation } = require('react-i18next'); const { useRouteFocused } = require('stremio-router'); const { useServices } = require('stremio/services'); -const { onFileDrop, useSettings, useProfile, useFullscreen, useBinaryState, useToast, useStreamingServer, withCoreSuspender, CONSTANTS, useShell, usePlatform } = require('stremio/common'); +const { onFileDrop, useSettings, useProfile, useFullscreen, useBinaryState, useToast, useStreamingServer, withCoreSuspender, CONSTANTS, useShell, usePlatform, onShortcut } = require('stremio/common'); const { HorizontalNavBar, Transition, ContextMenu } = require('stremio/components'); const BufferingLoader = require('./BufferingLoader'); const VolumeChangeIndicator = require('./VolumeChangeIndicator'); @@ -29,6 +29,9 @@ const styles = require('./styles'); const Video = require('./Video'); const { default: Indicator } = require('./Indicator/Indicator'); +const findTrackByLang = (tracks, lang) => tracks.find((track) => track.lang === lang || langs.where('1', track.lang)?.[2] === lang); +const findTrackById = (tracks, id) => tracks.find((track) => track.id === id); + const Player = ({ urlParams, queryParams }) => { const { t } = useTranslation(); const services = useServices(); @@ -37,8 +40,8 @@ const Player = ({ urlParams, queryParams }) => { return queryParams.has('forceTranscoding'); }, [queryParams]); const profile = useProfile(); - const [player, videoParamsChanged, timeChanged, seek, pausedChanged, ended, nextVideo] = usePlayer(urlParams); - const [settings, updateSettings] = useSettings(); + const [player, videoParamsChanged, streamStateChanged, timeChanged, seek, pausedChanged, ended, nextVideo] = usePlayer(urlParams); + const [settings] = useSettings(); const streamingServer = useStreamingServer(); const statistics = useStatistics(player, streamingServer); const video = useVideo(); @@ -93,17 +96,12 @@ const Player = ({ urlParams, queryParams }) => { const isNavigating = React.useRef(false); const onImplementationChanged = React.useCallback(() => { - video.setProp('subtitlesSize', settings.subtitlesSize); - video.setProp('subtitlesOffset', settings.subtitlesOffset); - video.setProp('subtitlesTextColor', settings.subtitlesTextColor); - video.setProp('subtitlesBackgroundColor', settings.subtitlesBackgroundColor); - video.setProp('subtitlesOutlineColor', settings.subtitlesOutlineColor); - video.setProp('extraSubtitlesSize', settings.subtitlesSize); - video.setProp('extraSubtitlesOffset', settings.subtitlesOffset); - video.setProp('extraSubtitlesTextColor', settings.subtitlesTextColor); - video.setProp('extraSubtitlesBackgroundColor', settings.subtitlesBackgroundColor); - video.setProp('extraSubtitlesOutlineColor', settings.subtitlesOutlineColor); - }, [settings.subtitlesSize, settings.subtitlesOffset, settings.subtitlesTextColor, settings.subtitlesBackgroundColor, settings.subtitlesOutlineColor]); + video.setSubtitlesSize(settings.subtitlesSize); + video.setSubtitlesOffset(settings.subtitlesOffset); + video.setSubtitlesTextColor(settings.subtitlesTextColor); + video.setSubtitlesBackgroundColor(settings.subtitlesBackgroundColor); + video.setSubtitlesOutlineColor(settings.subtitlesOutlineColor); + }, [settings]); const handleNextVideoNavigation = React.useCallback((deepLinks, bingeWatching, ended) => { if (ended) { @@ -190,53 +188,71 @@ const Player = ({ urlParams, queryParams }) => { }, []); const onPlayRequested = React.useCallback(() => { - video.setProp('paused', false); + video.setPaused(false); setSeeking(false); }, []); const onPlayRequestedDebounced = React.useCallback(debounce(onPlayRequested, 200), []); const onPauseRequested = React.useCallback(() => { - video.setProp('paused', true); + video.setPaused(true); }, []); const onPauseRequestedDebounced = React.useCallback(debounce(onPauseRequested, 200), []); const onMuteRequested = React.useCallback(() => { - video.setProp('muted', true); + video.setMuted(true); }, []); const onUnmuteRequested = React.useCallback(() => { - video.setProp('muted', false); + video.setMuted(false); }, []); const onVolumeChangeRequested = React.useCallback((volume) => { - video.setProp('volume', volume); + video.setVolume(volume); }, []); const onSeekRequested = React.useCallback((time) => { - video.setProp('time', time); + video.setTime(time); seek(time, video.state.duration, video.state.manifest?.name); }, [video.state.duration, video.state.manifest]); const onPlaybackSpeedChanged = React.useCallback((rate) => { - video.setProp('playbackSpeed', rate); + video.setPlaybackSpeed(rate); }, []); const onSubtitlesTrackSelected = React.useCallback((id) => { video.setSubtitlesTrack(id); - }, []); + streamStateChanged({ + subtitleTrack: { + id, + embedded: true, + }, + }); + }, [streamStateChanged]); const onExtraSubtitlesTrackSelected = React.useCallback((id) => { video.setExtraSubtitlesTrack(id); - }, []); + streamStateChanged({ + subtitleTrack: { + id, + embedded: false, + }, + }); + }, [streamStateChanged]); const onAudioTrackSelected = React.useCallback((id) => { - video.setProp('selectedAudioTrackId', id); - }, []); + video.setAudioTrack(id); + streamStateChanged({ + audioTrack: { + id, + }, + }); + }, [streamStateChanged]); const onExtraSubtitlesDelayChanged = React.useCallback((delay) => { - video.setProp('extraSubtitlesDelay', delay); - }, []); + video.setSubtitlesDelay(delay); + streamStateChanged({ subtitleDelay: delay }); + }, [streamStateChanged]); const onIncreaseSubtitlesDelay = React.useCallback(() => { const delay = video.state.extraSubtitlesDelay + 250; @@ -249,8 +265,9 @@ const Player = ({ urlParams, queryParams }) => { }, [video.state.extraSubtitlesDelay, onExtraSubtitlesDelayChanged]); const onSubtitlesSizeChanged = React.useCallback((size) => { - updateSettings({ subtitlesSize: size }); - }, [updateSettings]); + video.setSubtitlesSize(size); + streamStateChanged({ subtitleSize: size }); + }, [streamStateChanged]); const onUpdateSubtitlesSize = React.useCallback((delta) => { const sizeIndex = CONSTANTS.SUBTITLES_SIZES.indexOf(video.state.subtitlesSize); @@ -259,8 +276,9 @@ const Player = ({ urlParams, queryParams }) => { }, [video.state.subtitlesSize, onSubtitlesSizeChanged]); const onSubtitlesOffsetChanged = React.useCallback((offset) => { - updateSettings({ subtitlesOffset: offset }); - }, [updateSettings]); + video.setSubtitlesOffset(offset); + streamStateChanged({ subtitleOffset: offset }); + }, [streamStateChanged]); const onDismissNextVideoPopup = React.useCallback(() => { closeNextVideoPopup(); @@ -361,6 +379,7 @@ const Player = ({ urlParams, queryParams }) => { forceTranscoding: forceTranscoding || casting, maxAudioChannels: settings.surroundSound ? 32 : 2, hardwareDecoding: settings.hardwareDecoding, + assSubtitlesStyling: settings.assSubtitlesStyling, videoMode: settings.videoMode, platform: platform.name, streamingServerURL: streamingServer.baseUrl ? @@ -387,31 +406,6 @@ const Player = ({ urlParams, queryParams }) => { } }, [player.subtitles, video.state.stream]); - React.useEffect(() => { - video.setProp('subtitlesSize', settings.subtitlesSize); - video.setProp('extraSubtitlesSize', settings.subtitlesSize); - }, [settings.subtitlesSize]); - - React.useEffect(() => { - video.setProp('subtitlesOffset', settings.subtitlesOffset); - video.setProp('extraSubtitlesOffset', settings.subtitlesOffset); - }, [settings.subtitlesOffset]); - - React.useEffect(() => { - video.setProp('subtitlesTextColor', settings.subtitlesTextColor); - video.setProp('extraSubtitlesTextColor', settings.subtitlesTextColor); - }, [settings.subtitlesTextColor]); - - React.useEffect(() => { - video.setProp('subtitlesBackgroundColor', settings.subtitlesBackgroundColor); - video.setProp('extraSubtitlesBackgroundColor', settings.subtitlesBackgroundColor); - }, [settings.subtitlesBackgroundColor]); - - React.useEffect(() => { - video.setProp('subtitlesOutlineColor', settings.subtitlesOutlineColor); - video.setProp('extraSubtitlesOutlineColor', settings.subtitlesOutlineColor); - }, [settings.subtitlesOutlineColor]); - React.useEffect(() => { !seeking && timeChanged(video.state.time, video.state.duration, video.state.manifest?.name); }, [video.state.time, video.state.duration, video.state.manifest, seeking]); @@ -444,41 +438,69 @@ const Player = ({ urlParams, queryParams }) => { } }, [player.nextVideo, video.state.time, video.state.duration]); + // Auto subtitles track selection React.useEffect(() => { if (!defaultSubtitlesSelected.current) { - const findTrackByLang = (tracks, lang) => tracks.find((track) => track.lang === lang || langs.where('1', track.lang)?.[2] === lang); - if (settings.subtitlesLanguage === null) { - onSubtitlesTrackSelected(null); - onExtraSubtitlesTrackSelected(null); + video.setSubtitlesTrack(null); + video.setExtraSubtitlesTrack(null); defaultSubtitlesSelected.current = true; return; } - const subtitlesTrack = findTrackByLang(video.state.subtitlesTracks, settings.subtitlesLanguage); - const extraSubtitlesTrack = findTrackByLang(video.state.extraSubtitlesTracks, settings.subtitlesLanguage); + const savedTrackId = player.streamState?.subtitleTrack?.id; + const subtitlesTrack = savedTrackId ? + findTrackById(video.state.subtitlesTracks, savedTrackId) : + findTrackByLang(video.state.subtitlesTracks, settings.subtitlesLanguage); + + const extraSubtitlesTrack = savedTrackId ? + findTrackById(video.state.extraSubtitlesTracks, savedTrackId) : + findTrackByLang(video.state.extraSubtitlesTracks, settings.subtitlesLanguage); if (subtitlesTrack && subtitlesTrack.id) { - onSubtitlesTrackSelected(subtitlesTrack.id); + video.setSubtitlesTrack(subtitlesTrack.id); defaultSubtitlesSelected.current = true; } else if (extraSubtitlesTrack && extraSubtitlesTrack.id) { - onExtraSubtitlesTrackSelected(extraSubtitlesTrack.id); + video.setExtraSubtitlesTrack(extraSubtitlesTrack.id); defaultSubtitlesSelected.current = true; } } - }, [video.state.subtitlesTracks, video.state.extraSubtitlesTracks]); + }, [video.state.subtitlesTracks, video.state.extraSubtitlesTracks, player.streamState]); + // Auto audio track selection React.useEffect(() => { if (!defaultAudioTrackSelected.current) { - const findTrackByLang = (tracks, lang) => tracks.find((track) => track.lang === lang || langs.where('1', track.lang)?.[2] === lang); - const audioTrack = findTrackByLang(video.state.audioTracks, settings.audioLanguage); + const savedTrackId = player.streamState?.audioTrack?.id; + const audioTrack = savedTrackId ? + findTrackById(video.state.audioTracks, savedTrackId) : + findTrackByLang(video.state.audioTracks, settings.audioLanguage); if (audioTrack && audioTrack.id) { - onAudioTrackSelected(audioTrack.id); + video.setAudioTrack(audioTrack.id); defaultAudioTrackSelected.current = true; } } - }, [video.state.audioTracks]); + }, [video.state.audioTracks, player.streamState]); + + // Saved subtitles settings + React.useEffect(() => { + if (video.state.stream !== null) { + const delay = player.streamState?.subtitleDelay; + if (typeof delay === 'number') { + video.setSubtitlesDelay(delay); + } + + const size = player.streamState?.subtitleSize; + if (typeof size === 'number') { + video.setSubtitlesSize(size); + } + + const offset = player.streamState?.subtitleOffset; + if (typeof offset === 'number') { + video.setSubtitlesOffset(offset); + } + } + }, [video.state.stream, player.streamState]); React.useEffect(() => { defaultSubtitlesSelected.current = false; @@ -568,7 +590,7 @@ const Player = ({ urlParams, queryParams }) => { const videoId = player.selected ? player.selected?.streamRequest?.path?.id : null; const video = metaItem ? metaItem.videos.find(({ id }) => id === videoId) : null; - const videoInfo = video && video.season && video.episode ? ` (${video.season}x${video.episode})`: null; + const videoInfo = video && video.season && video.episode ? ` (${video.season}x${video.episode})` : null; const videoTitle = video ? `${video.title}${videoInfo}` : null; const metaTitle = metaItem ? metaItem.name : null; const imageUrl = metaItem ? metaItem.logo : null; @@ -597,117 +619,99 @@ const Player = ({ urlParams, queryParams }) => { navigator.mediaSession.setActionHandler('nexttrack', nexVideoCallback); }, [player.nextVideo, onPlayRequested, onPauseRequested, onNextVideoRequested]); - React.useLayoutEffect(() => { - const onKeyDown = (event) => { - switch (event.code) { - case 'Space': { - if (!menusOpen && !nextVideoPopupOpen && video.state.paused !== null) { - if (video.state.paused) { - onPlayRequested(); - setSeeking(false); - } else { - onPauseRequested(); - } - } - - break; - } - case 'ArrowRight': { - if (!menusOpen && !nextVideoPopupOpen && video.state.time !== null) { - const seekDuration = event.shiftKey ? settings.seekShortTimeDuration : settings.seekTimeDuration; - setSeeking(true); - onSeekRequested(video.state.time + seekDuration); - } - - break; - } - case 'ArrowLeft': { - if (!menusOpen && !nextVideoPopupOpen && video.state.time !== null) { - const seekDuration = event.shiftKey ? settings.seekShortTimeDuration : settings.seekTimeDuration; - setSeeking(true); - onSeekRequested(video.state.time - seekDuration); - } - - break; - } - case 'ArrowUp': { - if (!menusOpen && !nextVideoPopupOpen && video.state.volume !== null) { - onVolumeChangeRequested(Math.min(video.state.volume + 5, 200)); - } - - break; - } - case 'ArrowDown': { - if (!menusOpen && !nextVideoPopupOpen && video.state.volume !== null) { - onVolumeChangeRequested(Math.max(video.state.volume - 5, 0)); - } - - break; - } - case 'KeyS': { - closeMenus(); - if ((Array.isArray(video.state.subtitlesTracks) && video.state.subtitlesTracks.length > 0) || - (Array.isArray(video.state.extraSubtitlesTracks) && video.state.extraSubtitlesTracks.length > 0)) { - toggleSubtitlesMenu(); - } - - break; - } - case 'KeyA': { - closeMenus(); - if (Array.isArray(video.state.audioTracks) && video.state.audioTracks.length > 0) { - toggleAudioMenu(); - } - - break; - } - case 'KeyI': { - closeMenus(); - if (player.metaItem !== null && player.metaItem.type === 'Ready') { - toggleSideDrawer(); - } - - break; - } - case 'KeyR': { - closeMenus(); - if (video.state.playbackSpeed !== null) { - toggleSpeedMenu(); - } - - break; - } - case 'KeyD': { - closeMenus(); - if (streamingServer.statistics !== null && streamingServer.statistics.type !== 'Err' && player.selected && typeof player.selected.stream.infoHash === 'string' && typeof player.selected.stream.fileIdx === 'number') { - toggleStatisticsMenu(); - } - - break; - } - case 'KeyG': { - onDecreaseSubtitlesDelay(); - break; - } - case 'KeyH': { - onIncreaseSubtitlesDelay(); - break; - } - case 'Minus': { - onUpdateSubtitlesSize(-1); - break; - } - case 'Equal': { - onUpdateSubtitlesSize(1); - break; - } - case 'Escape': { - closeMenus(); - !settings.escExitFullscreen && window.history.back(); - break; - } + onShortcut('playPause', () => { + if (!menusOpen && !nextVideoPopupOpen && video.state.paused !== null) { + if (video.state.paused) { + onPlayRequested(); + setSeeking(false); + } else { + onPauseRequested(); } - }; + } + }, [menusOpen, nextVideoPopupOpen, video.state.paused, onPlayRequested, onPauseRequested]); + + onShortcut('seekForward', (combo) => { + if (!menusOpen && !nextVideoPopupOpen && video.state.time !== null) { + const seekDuration = combo === 1 ? settings.seekShortTimeDuration : settings.seekTimeDuration; + setSeeking(true); + onSeekRequested(video.state.time + seekDuration); + } + }, [menusOpen, nextVideoPopupOpen, video.state.time, onSeekRequested]); + + onShortcut('seekBackward', (combo) => { + if (!menusOpen && !nextVideoPopupOpen && video.state.time !== null) { + const seekDuration = combo === 1 ? settings.seekShortTimeDuration : settings.seekTimeDuration; + setSeeking(true); + onSeekRequested(video.state.time - seekDuration); + } + }, [menusOpen, nextVideoPopupOpen, video.state.time, onSeekRequested]); + + onShortcut('mute', () => { + video.state.muted === true ? onUnmuteRequested() : onMuteRequested(); + }, [video.state.muted]); + + onShortcut('volumeUp', () => { + if (!menusOpen && !nextVideoPopupOpen && video.state.volume !== null) { + onVolumeChangeRequested(Math.min(video.state.volume + 5, 200)); + } + }, [menusOpen, nextVideoPopupOpen, video.state.volume]); + + onShortcut('volumeDown', () => { + if (!menusOpen && !nextVideoPopupOpen && video.state.volume !== null) { + onVolumeChangeRequested(Math.min(video.state.volume - 5, 200)); + } + }, [menusOpen, nextVideoPopupOpen, video.state.volume]); + + onShortcut('subtitlesDelay', (combo) => { + combo === 1 ? onIncreaseSubtitlesDelay() : onDecreaseSubtitlesDelay(); + }, [onIncreaseSubtitlesDelay, onDecreaseSubtitlesDelay]); + + onShortcut('subtitlesSize', (combo) => { + combo === 1 ? onUpdateSubtitlesSize(-1) : onUpdateSubtitlesSize(1); + }, [onUpdateSubtitlesSize, onUpdateSubtitlesSize]); + + onShortcut('subtitlesMenu', () => { + closeMenus(); + if (video.state?.subtitlesTracks?.length > 0 || video.state?.extraSubtitlesTracks?.length > 0) { + toggleSubtitlesMenu(); + } + }, [video.state.subtitlesTracks, video.state.extraSubtitlesTracks, toggleSubtitlesMenu]); + + onShortcut('audioMenu', () => { + closeMenus(); + if (video.state?.audioTracks?.length > 0) { + toggleAudioMenu(); + } + }, [video.state.audioTracks, toggleAudioMenu]); + + onShortcut('infoMenu', () => { + closeMenus(); + if (player.metaItem?.type === 'Ready') { + toggleSideDrawer(); + } + }, [player.metaItem, toggleSideDrawer]); + + onShortcut('speedMenu', () => { + closeMenus(); + if (video.state.playbackSpeed !== null) { + toggleSpeedMenu(); + } + }, [video.state.playbackSpeed, toggleSpeedMenu]); + + onShortcut('statisticsMenu', () => { + closeMenus(); + const stream = player.selected?.stream; + if (streamingServer?.statistics?.type !== 'Err' && typeof stream === 'string' && typeof stream === 'number') { + toggleStatisticsMenu(); + } + }, [player.selected, streamingServer.statistics, toggleStatisticsMenu]); + + onShortcut('exit', () => { + closeMenus(); + !settings.escExitFullscreen && window.history.back(); + }, [settings.escExitFullscreen]); + + React.useLayoutEffect(() => { const onKeyUp = (event) => { if (event.code === 'ArrowRight' || event.code === 'ArrowLeft') { setSeeking(false); @@ -725,39 +729,14 @@ const Player = ({ urlParams, queryParams }) => { } }; if (routeFocused) { - window.addEventListener('keydown', onKeyDown); window.addEventListener('keyup', onKeyUp); window.addEventListener('wheel', onWheel); } return () => { - window.removeEventListener('keydown', onKeyDown); window.removeEventListener('keyup', onKeyUp); window.removeEventListener('wheel', onWheel); }; - }, [ - player.metaItem, - player.selected, - streamingServer.statistics, - settings.seekTimeDuration, - settings.seekShortTimeDuration, - settings.escExitFullscreen, - routeFocused, - menusOpen, - nextVideoPopupOpen, - video.state.paused, - video.state.time, - video.state.volume, - video.state.audioTracks, - video.state.subtitlesTracks, - video.state.extraSubtitlesTracks, - video.state.playbackSpeed, - toggleSubtitlesMenu, - toggleStatisticsMenu, - toggleSideDrawer, - onDecreaseSubtitlesDelay, - onIncreaseSubtitlesDelay, - onUpdateSubtitlesSize, - ]); + }, [routeFocused, menusOpen, video.state.volume]); React.useEffect(() => { video.events.on('error', onError); diff --git a/src/routes/Player/SubtitlesMenu/Stepper/Stepper.tsx b/src/routes/Player/SubtitlesMenu/Stepper/Stepper.tsx index 0d402a455..8f9e19d8a 100644 --- a/src/routes/Player/SubtitlesMenu/Stepper/Stepper.tsx +++ b/src/routes/Player/SubtitlesMenu/Stepper/Stepper.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useRef } from 'react'; +import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import classNames from 'classnames'; import Icon from '@stremio/stremio-icons/react'; @@ -37,6 +37,18 @@ const Stepper = ({ className, label, value, unit, step, min, max, disabled, onCh timeout.cancel(); }; + const decreaseDisabled = useMemo(() => { + return disabled || typeof value !== 'number' || (typeof min === 'number' && value <= min); + }, [disabled, min, value]); + + const increaseDisabled = useMemo(() => { + return disabled || typeof value !== 'number' || (typeof max === 'number' && value >= max); + }, [disabled, max, value]); + + const valueLabel = useMemo(() => { + return (disabled || typeof value !== 'number') ? '--' : `${value}${unit}`; + }, [disabled, value, unit]); + const updateValue = useCallback((delta: number) => { onChange(clamp(localValue.current + delta, min, max)); }, [onChange]); @@ -72,7 +84,7 @@ const Stepper = ({ className, label, value, unit, step, min, max, disabled, onCh
- { disabled ? '--' : `${value}${unit}` } + { valueLabel }
- -
- - { - shell.active && - - } - { - shell.active && - - } - -
; }); diff --git a/src/routes/Settings/General/User/User.tsx b/src/routes/Settings/General/User/User.tsx index 6b44e9903..7555e521e 100644 --- a/src/routes/Settings/General/User/User.tsx +++ b/src/routes/Settings/General/User/User.tsx @@ -14,12 +14,12 @@ const User = ({ profile }: Props) => { const avatar = useMemo(() => ( !profile.auth ? - `url('${require('/images/anonymous.png')}')` + `url('${require('/assets/images/anonymous.png')}')` : profile.auth.user.avatar ? `url('${profile.auth.user.avatar}')` : - `url('${require('/images/default_avatar.png')}')` + `url('${require('/assets/images/default_avatar.png')}')` ), [profile.auth]); const onLogout = useCallback(() => { diff --git a/src/routes/Settings/Interface/Interface.tsx b/src/routes/Settings/Interface/Interface.tsx new file mode 100644 index 000000000..a4b429a56 --- /dev/null +++ b/src/routes/Settings/Interface/Interface.tsx @@ -0,0 +1,57 @@ +import React, { forwardRef } from 'react'; +import { useServices } from 'stremio/services'; +import { MultiselectMenu, Toggle } from 'stremio/components'; +import { Section, Option } from '../components'; +import useInterfaceOptions from './useInterfaceOptions'; + +type Props = { + profile: Profile, +}; + +const Interface = forwardRef(({ profile }: Props, ref) => { + const { shell } = useServices(); + + const { + interfaceLanguageSelect, + quitOnCloseToggle, + escExitFullscreenToggle, + hideSpoilersToggle, + } = useInterfaceOptions(profile); + + return ( +
+ + { + shell.active && + + } + { + shell.active && + + } + +
+ ); +}); + +export default Interface; diff --git a/src/routes/Settings/Interface/index.ts b/src/routes/Settings/Interface/index.ts new file mode 100644 index 000000000..480fa5ff4 --- /dev/null +++ b/src/routes/Settings/Interface/index.ts @@ -0,0 +1,2 @@ +import Interface from './Interface'; +export default Interface; diff --git a/src/routes/Settings/General/useGeneralOptions.ts b/src/routes/Settings/Interface/useInterfaceOptions.ts similarity index 96% rename from src/routes/Settings/General/useGeneralOptions.ts rename to src/routes/Settings/Interface/useInterfaceOptions.ts index a4ab84c5e..67780b7e1 100644 --- a/src/routes/Settings/General/useGeneralOptions.ts +++ b/src/routes/Settings/Interface/useInterfaceOptions.ts @@ -2,7 +2,7 @@ import { useMemo } from 'react'; import { interfaceLanguages, useLanguageSorting } from 'stremio/common'; import { useServices } from 'stremio/services'; -const useGeneralOptions = (profile: Profile) => { +const useInterfaceOptions = (profile: Profile) => { const { core } = useServices(); const interfaceLanguageOptions = useMemo(() => @@ -89,4 +89,4 @@ const useGeneralOptions = (profile: Profile) => { }; }; -export default useGeneralOptions; +export default useInterfaceOptions; diff --git a/src/routes/Settings/Menu/Menu.tsx b/src/routes/Settings/Menu/Menu.tsx index ceafee94b..33cf41dc0 100644 --- a/src/routes/Settings/Menu/Menu.tsx +++ b/src/routes/Settings/Menu/Menu.tsx @@ -26,6 +26,9 @@ const Menu = ({ selected, streamingServer, onSelect }: Props) => { + diff --git a/src/routes/Settings/Player/Player.tsx b/src/routes/Settings/Player/Player.tsx index 6c493d479..213757cc3 100644 --- a/src/routes/Settings/Player/Player.tsx +++ b/src/routes/Settings/Player/Player.tsx @@ -19,6 +19,7 @@ const Player = forwardRef(({ profile }: Props, ref) => { subtitlesTextColorInput, subtitlesBackgroundColorInput, subtitlesOutlineColorInput, + assSubtitlesStylingToggle, audioLanguageSelect, surroundSoundToggle, seekTimeDurationSelect, @@ -149,6 +150,15 @@ const Player = forwardRef(({ profile }: Props, ref) => { /> } + { + shell.active && + + } ); diff --git a/src/routes/Settings/Player/usePlayerOptions.ts b/src/routes/Settings/Player/usePlayerOptions.ts index f913697b6..27081817b 100644 --- a/src/routes/Settings/Player/usePlayerOptions.ts +++ b/src/routes/Settings/Player/usePlayerOptions.ts @@ -92,6 +92,22 @@ const usePlayerOptions = (profile: Profile) => { } }), [profile.settings]); + const assSubtitlesStylingToggle = useMemo(() => ({ + checked: profile.settings.assSubtitlesStyling, + onClick: () => { + core.transport.dispatch({ + action: 'Ctx', + args: { + action: 'UpdateSettings', + args: { + ...profile.settings, + assSubtitlesStyling: !profile.settings.assSubtitlesStyling + } + } + }); + } + }), [profile.settings]); + const subtitlesOutlineColorInput = useMemo(() => ({ value: profile.settings.subtitlesOutlineColor, onChange: (value: string) => { @@ -341,6 +357,7 @@ const usePlayerOptions = (profile: Profile) => { subtitlesTextColorInput, subtitlesBackgroundColorInput, subtitlesOutlineColorInput, + assSubtitlesStylingToggle, audioLanguageSelect, surroundSoundToggle, seekTimeDurationSelect, diff --git a/src/routes/Settings/Settings.tsx b/src/routes/Settings/Settings.tsx index 2db68da2f..727da9e82 100644 --- a/src/routes/Settings/Settings.tsx +++ b/src/routes/Settings/Settings.tsx @@ -9,6 +9,7 @@ import { MainNavBars } from 'stremio/components'; import { SECTIONS } from './constants'; import Menu from './Menu'; import General from './General'; +import Interface from './Interface'; import Player from './Player'; import Streaming from './Streaming'; import Shortcuts from './Shortcuts'; @@ -23,12 +24,14 @@ const Settings = () => { const sectionsContainerRef = useRef(null); const generalSectionRef = useRef(null); + const interfaceSectionRef = useRef(null); const playerSectionRef = useRef(null); const streamingServerSectionRef = useRef(null); const shortcutsSectionRef = useRef(null); const sections = useMemo(() => ([ { ref: generalSectionRef, id: SECTIONS.GENERAL }, + { ref: interfaceSectionRef, id: SECTIONS.INTERFACE }, { ref: playerSectionRef, id: SECTIONS.PLAYER }, { ref: streamingServerSectionRef, id: SECTIONS.STREAMING }, { ref: shortcutsSectionRef, id: SECTIONS.SHORTCUTS }, @@ -82,6 +85,10 @@ const Settings = () => { ref={generalSectionRef} profile={profile} /> + { btRequestTimeout: settings.btRequestTimeout }; const isCustomTorrentProfileSelected = Object.values(TORRENT_PROFILES).every((torrentProfile) => { - return !isEqual(torrentProfile, selectedTorrentProfile); + return !deepEqual(torrentProfile, selectedTorrentProfile); }); return { options: Object.keys(TORRENT_PROFILES) diff --git a/src/routes/Settings/components/Option/Option.less b/src/routes/Settings/components/Option/Option.less index 181cfa33b..70e80e6f5 100644 --- a/src/routes/Settings/components/Option/Option.less +++ b/src/routes/Settings/components/Option/Option.less @@ -22,8 +22,8 @@ gap: 0.75rem; .icon { - width: 3rem; - height: 3rem; + width: 4rem; + height: 4rem; color: var(--primary-foreground-color); } diff --git a/src/routes/Settings/constants.ts b/src/routes/Settings/constants.ts index 001f3e3e3..eeabcf8a3 100644 --- a/src/routes/Settings/constants.ts +++ b/src/routes/Settings/constants.ts @@ -1,6 +1,7 @@ const SECTIONS = { GENERAL: 'general', PLAYER: 'player', + INTERFACE: 'interface', STREAMING: 'streaming', SHORTCUTS: 'shortcuts', }; diff --git a/src/types/models/Ctx.d.ts b/src/types/models/Ctx.d.ts index e6c0e14e4..fad9c2f4b 100644 --- a/src/types/models/Ctx.d.ts +++ b/src/types/models/Ctx.d.ts @@ -42,6 +42,7 @@ type Settings = { subtitlesOutlineColor: string, subtitlesSize: number, subtitlesTextColor: string, + assSubtitlesStyling: boolean, surroundSound: boolean, pauseOnMinimize: boolean, }; diff --git a/src/types/models/Player.d.ts b/src/types/models/Player.d.ts index 7f7dbc318..321127316 100644 --- a/src/types/models/Player.d.ts +++ b/src/types/models/Player.d.ts @@ -30,6 +30,23 @@ type SeriesInfo = { season: number, }; +type SubtitlesTrackState = { + id: string, + embedded: boolean, +}; + +type AudioTrackState = { + id: string, +}; + +type StreamState = { + subtitleTrack?: SubtitlesTrackState, + subtitleDelay?: number, + subtitleSize?: number, + subtitleOffset?: number, + audioTrack?: AudioTrackState, +}; + type Player = { addon: Addon | null, libraryItem: LibraryItemPlayer | null, @@ -42,6 +59,7 @@ type Player = { subtitlesPath: ResourceRequestPath, } | null, seriesInfo: SeriesInfo | null, + streamState: StreamState | null, subtitles: Subtitle[], title: string | null, }; diff --git a/webpack.config.js b/webpack.config.js index df9835c87..8768d753f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,11 +7,9 @@ const webpack = require('webpack'); const threadLoader = require('thread-loader'); const HtmlWebPackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const WorkboxPlugin = require('workbox-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); -const WebpackPwaManifest = require('webpack-pwa-manifest'); const packageJson = require('./package.json'); const COMMIT_HASH = execSync('git rev-parse HEAD').toString().trim(); @@ -44,7 +42,8 @@ module.exports = (env, argv) => ({ }, output: { path: path.join(__dirname, 'build'), - filename: `${COMMIT_HASH}/scripts/[name].js` + filename: `${COMMIT_HASH}/scripts/[name].js`, + clean: true, }, module: { rules: [ @@ -155,7 +154,7 @@ module.exports = (env, argv) => ({ exclude: /node_modules/, type: 'asset/resource', generator: { - filename: `${COMMIT_HASH}/fonts/[name][ext][query]` + filename: 'fonts/[name][ext][query]' } }, { @@ -221,9 +220,6 @@ module.exports = (env, argv) => ({ new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'] }), - new CleanWebpackPlugin({ - cleanOnceBeforeBuildPatterns: ['*'] - }), argv.mode === 'production' && new WorkboxPlugin.GenerateSW({ maximumFileSizeToCacheInBytes: 20000000, @@ -232,10 +228,11 @@ module.exports = (env, argv) => ({ }), new CopyWebpackPlugin({ patterns: [ - { from: 'favicons', to: 'favicons' }, - { from: 'images', to: 'images' }, - { from: 'screenshots/*.webp', to: './' }, + { from: 'assets/favicons', to: 'favicons' }, + { from: 'assets/images', to: 'images' }, + { from: 'assets/screenshots/*.webp', to: 'screenshots/[name][ext]' }, { from: '.well-known', to: '.well-known' }, + { from: 'manifest.json', to: 'manifest.json' }, ] }), new MiniCssExtractPlugin({ @@ -248,56 +245,5 @@ module.exports = (env, argv) => ({ faviconsPath: 'favicons', imagesPath: 'images', }), - new WebpackPwaManifest({ - name: 'Stremio Web', - short_name: 'Stremio', - description: 'Freedom To Stream', - background_color: '#161523', - theme_color: '#2a2843', - orientation: 'any', - display: 'standalone', - display_override: ['standalone'], - scope: './', - start_url: './', - publicPath: './', - icons: [ - { - src: 'images/icon.png', - destination: 'icons', - sizes: [196, 512], - purpose: 'any' - }, - { - src: 'images/maskable_icon.png', - destination: 'maskable_icons', - sizes: [196, 512], - purpose: 'maskable', - ios: true - }, - { - src: 'favicons/favicon.ico', - destination: 'favicons', - sizes: [256], - } - ], - screenshots : [ - { - src: 'screenshots/board_wide.webp', - sizes: '1440x900', - type: 'image/webp', - form_factor: 'wide', - label: 'Homescreen of Stremio' - }, - { - src: 'screenshots/board_narrow.webp', - sizes: '414x896', - type: 'image/webp', - form_factor: 'narrow', - label: 'Homescreen of Stremio' - } - ], - fingerprints: false, - ios: true - }), ].filter(Boolean) });