From 1efe5de0acfafb0326df0e24b9b25f69d3a73bea Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Wed, 5 Jul 2023 15:54:41 +0200 Subject: [PATCH 01/12] feat: remove unnecessary notice --- src/main/resources/sponsorblock/host/values/strings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/sponsorblock/host/values/strings.xml b/src/main/resources/sponsorblock/host/values/strings.xml index d451ce290..7f63c88ca 100644 --- a/src/main/resources/sponsorblock/host/values/strings.xml +++ b/src/main/resources/sponsorblock/host/values/strings.xml @@ -190,5 +190,4 @@ About sponsor.ajay.app Data is provided by the SponsorBlock API. Tap here to learn more and see downloads for other platforms - ReVanced integration by JakubWeg,\nrecoded by oSumAtrIX From 1f490d3fe759df3a4adc909397a8bc074a3db618 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 5 Jul 2023 13:57:34 +0000 Subject: [PATCH 02/12] chore(release): 2.182.0-dev.1 [skip ci] # [2.182.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.181.0...v2.182.0-dev.1) (2023-07-05) ### Features * remove unnecessary notice ([1efe5de](https://github.com/revanced/revanced-patches/commit/1efe5de0acfafb0326df0e24b9b25f69d3a73bea)) --- CHANGELOG.md | 7 +++++++ README.md | 16 ---------------- gradle.properties | 2 +- patches.json | 2 +- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e201fcbbd..0518318bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [2.182.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.181.0...v2.182.0-dev.1) (2023-07-05) + + +### Features + +* remove unnecessary notice ([7e9f0b2](https://github.com/revanced/revanced-patches/commit/7e9f0b2d02e910984f08777fefcd2ad7df6a21ee)) + # [2.181.0](https://github.com/revanced/revanced-patches/compare/v2.180.0...v2.181.0) (2023-07-03) diff --git a/README.md b/README.md index f28416a9d..46d31a2f1 100644 --- a/README.md +++ b/README.md @@ -229,22 +229,6 @@ The official ReVanced Patches. | `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "dbrady://relay". | all | -### [📦 `com.onelouder.baconreader`](https://play.google.com/store/apps/details?id=com.onelouder.baconreader) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "http://baconreader.com/auth". | all | -
- -### [📦 `com.onelouder.baconreader.premium`](https://play.google.com/store/apps/details?id=com.onelouder.baconreader.premium) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "http://baconreader.com/auth". | all | -
- ### [📦 `com.rubenmayayo.reddit`](https://play.google.com/store/apps/details?id=com.rubenmayayo.reddit)
diff --git a/gradle.properties b/gradle.properties index 68798c58c..f0df19635 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ kotlin.code.style = official -version = 2.181.0 +version = 2.182.0-dev.1 diff --git a/patches.json b/patches.json index fd1baebe9..687994262 100644 --- a/patches.json +++ b/patches.json @@ -1 +1 @@ -[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"auto-claim-channel-points","description":"Automatically claim Channel Points.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-embedded-ads","description":"Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"bypass-certificate-checks","description":"Bypasses certificate checks which prevent YouTube Music from working on Android Auto.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"infinity://localhost\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"ml.docilealligator.infinityforreddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"dbrady://relay\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"free.reddit.news","versions":[]},{"name":"reddit.news","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://baconreader.com/auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.onelouder.baconreader","versions":[]},{"name":"com.onelouder.baconreader.premium","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://rubenmayayo.com\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.rubenmayayo.reddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"redditisfun://auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.andrewshu.android.reddit","versions":[]},{"name":"com.andrewshu.android.redditdonation","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://redditsync/auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]},{"name":"com.laurencedawson.reddit_sync.pro","versions":[]},{"name":"com.laurencedawson.reddit_sync.dev","versions":[]}]},{"name":"change-package-name","description":"Changes the package name.","version":"0.0.1","excluded":true,"options":[{"key":"packageName","title":"Package name","description":"The name of the package to rename of the app.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"client-spoof","description":"Spoofs a patched client to allow playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-signature-verification"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":true,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-ads","description":"Disables ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["DisablePiracyDetectionPatch"],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-player-popup-panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-screenshot-popup","description":"Disables the popup that shows up when taking a screenshot.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"disable-shorts-on-startup","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-switching-emoji-to-sticker-in-message-input-field","description":"Disables switching from emoji to sticker search mode in message input field","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-typing-indicator","description":"Disables the indicator while typing a message","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-android-debugging","description":"Enables Android debugging capabilities.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"enable-debugging","description":"Adds debugging options.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"enable-on-demand","description":"Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.lite","versions":[]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"export-all-activities","description":"Makes all app activities exportable.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"external-downloads","description":"Adds support to download and save YouTube videos using an external app.","version":"0.0.1","excluded":false,"options":[],"dependencies":["external-downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Removes ads from Inshorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.nis.app","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["VerticalScrollPatch"],"compatiblePackages":[{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"hide-ads","description":"Removes ads from the Reddit.","version":"0.0.2","excluded":false,"options":[],"dependencies":["hide-subreddit-banner","hide-comment-ads"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-get-premium","HideAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-filter-bar","description":"Hides the filter bar in video feeds.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFilterBarResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-floating-microphone-button","description":"Hides the floating microphone button which appears in search.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFloatingMicrophoneButtonResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"hide-inbox-ads","description":"Hides ads in inbox.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"hide-info-cards","description":"Hides info cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-layout-components","description":"Hides general layout components.","version":"0.0.1","excluded":false,"options":[],"dependencies":["LithoFilterPatch","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-load-more-button","description":"Hides the button under videos that loads similar videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-load-more-button-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-buttons","description":"Adds the option to hide video player previous and next buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-overlay","description":"Hides the dark background overlay from the player when player controls are visible.","version":"0.0.2","excluded":false,"options":[],"dependencies":["HidePlayerOverlayResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-recommended-users","description":"Hides recommended users.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-seekbar","description":"Hides the seekbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","SeekbarColorBytecodePatch","SeekbarPreferencesPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-shorts-components","description":"Hides components from YouTube Shorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","LithoFilterPatch","HideShortsComponentsResourcePatch","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-timeline-ads","description":"Removes ads from the timeline.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.instagram.android","versions":["275.0.0.27.98"]}]},{"name":"hide-timestamp","description":"Hides timestamp in video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-video-action-buttons","description":"Adds the options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0","9.71.0-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the option to watch in VR from the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"navigation-buttons","description":"Adds options to hide or change navigation buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"old-quality-layout","description":"Enables the original video quality flyout in the video player settings.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","OldQualityLayoutResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-information","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-badge-tab","description":"Removes the badge tab from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-broadcasts-restriction","description":"Enables starting/stopping NetGuard via broadcasts.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"eu.faircode.netguard","versions":[]}]},{"name":"remove-debugging-detection","description":"Removes the USB and wireless debugging checks.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.scb.phone","versions":[]}]},{"name":"remove-device-restrictions","description":"Removes restrictions from using the app on any device.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.recorder","versions":[]}]},{"name":"remove-notification-badge","description":"Removes the red notification badge from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-player-controls-background","description":"Removes the background from the video player controls.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-screen-capture-restriction","description":"Removes the restriction of capturing audio from apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":["remove-screen-capture-restriction-resource-patch"],"compatiblePackages":[]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"sanitize-sharing-links","description":"Removes (tracking) query parameters from the URLs when sharing links.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","EnableSeekbarTappingResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sponsorblock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","video-information","player-type-hook","player-controls-bytecode-patch","sponsorblock-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"spoof-wifi-connection","description":"Spoofs an existing Wi-Fi connection.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":["litho-color-hook","SeekbarColorBytecodePatch","ThemeResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"unlock-paid-widgets","description":"Unlocks paid widgets of the app","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":[]}]},{"name":"unlock-plus","description":"Unlocks plus features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureDetectionPatch"],"compatiblePackages":[{"name":"com.microblink.photomath","versions":["8.20.0"]}]},{"name":"unlock-premium","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"io.yuka.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureVerificationPatch","LicenseValidationPatch"],"compatiblePackages":[{"name":"com.zombodroid.MemeGenerator","versions":["4.6364","4.6370","4.6375","4.6377"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.vsco.cam","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.wakdev.apps.nfctools.se","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-pro","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.candylink.openvpn","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"tv.trakt.trakt","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"vanced-microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button","client-spoof"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"vanced-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"video-speed","description":"Adds custom video speeds and ability to remember the playback speed you chose in the video playback speed flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["custom-video-speed","remember-playback-speed"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]}] \ No newline at end of file +[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"auto-claim-channel-points","description":"Automatically claim Channel Points.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-embedded-ads","description":"Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"bypass-certificate-checks","description":"Bypasses certificate checks which prevent YouTube Music from working on Android Auto.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"infinity://localhost\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"ml.docilealligator.infinityforreddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"dbrady://relay\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"free.reddit.news","versions":[]},{"name":"reddit.news","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://rubenmayayo.com\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.rubenmayayo.reddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"redditisfun://auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.andrewshu.android.reddit","versions":[]},{"name":"com.andrewshu.android.redditdonation","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://redditsync/auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]},{"name":"com.laurencedawson.reddit_sync.pro","versions":[]},{"name":"com.laurencedawson.reddit_sync.dev","versions":[]}]},{"name":"change-package-name","description":"Changes the package name.","version":"0.0.1","excluded":true,"options":[{"key":"packageName","title":"Package name","description":"The name of the package to rename of the app.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"client-spoof","description":"Spoofs a patched client to allow playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-signature-verification"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":true,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-ads","description":"Disables ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["DisablePiracyDetectionPatch"],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-player-popup-panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-screenshot-popup","description":"Disables the popup that shows up when taking a screenshot.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"disable-shorts-on-startup","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-switching-emoji-to-sticker-in-message-input-field","description":"Disables switching from emoji to sticker search mode in message input field","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-typing-indicator","description":"Disables the indicator while typing a message","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-android-debugging","description":"Enables Android debugging capabilities.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"enable-debugging","description":"Adds debugging options.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"enable-on-demand","description":"Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.lite","versions":[]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"export-all-activities","description":"Makes all app activities exportable.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"external-downloads","description":"Adds support to download and save YouTube videos using an external app.","version":"0.0.1","excluded":false,"options":[],"dependencies":["external-downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Removes ads from Inshorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.nis.app","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["VerticalScrollPatch"],"compatiblePackages":[{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"hide-ads","description":"Removes ads from the Reddit.","version":"0.0.2","excluded":false,"options":[],"dependencies":["hide-subreddit-banner","hide-comment-ads"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-get-premium","HideAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-filter-bar","description":"Hides the filter bar in video feeds.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFilterBarResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-floating-microphone-button","description":"Hides the floating microphone button which appears in search.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFloatingMicrophoneButtonResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"hide-inbox-ads","description":"Hides ads in inbox.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"hide-info-cards","description":"Hides info cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-layout-components","description":"Hides general layout components.","version":"0.0.1","excluded":false,"options":[],"dependencies":["LithoFilterPatch","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-load-more-button","description":"Hides the button under videos that loads similar videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-load-more-button-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-buttons","description":"Adds the option to hide video player previous and next buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-overlay","description":"Hides the dark background overlay from the player when player controls are visible.","version":"0.0.2","excluded":false,"options":[],"dependencies":["HidePlayerOverlayResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-recommended-users","description":"Hides recommended users.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-seekbar","description":"Hides the seekbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","SeekbarColorBytecodePatch","SeekbarPreferencesPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-shorts-components","description":"Hides components from YouTube Shorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","LithoFilterPatch","HideShortsComponentsResourcePatch","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-timeline-ads","description":"Removes ads from the timeline.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.instagram.android","versions":["275.0.0.27.98"]}]},{"name":"hide-timestamp","description":"Hides timestamp in video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-video-action-buttons","description":"Adds the options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0","9.71.0-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the option to watch in VR from the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"navigation-buttons","description":"Adds options to hide or change navigation buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"old-quality-layout","description":"Enables the original video quality flyout in the video player settings.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","OldQualityLayoutResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-information","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-badge-tab","description":"Removes the badge tab from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-broadcasts-restriction","description":"Enables starting/stopping NetGuard via broadcasts.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"eu.faircode.netguard","versions":[]}]},{"name":"remove-debugging-detection","description":"Removes the USB and wireless debugging checks.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.scb.phone","versions":[]}]},{"name":"remove-device-restrictions","description":"Removes restrictions from using the app on any device.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.recorder","versions":[]}]},{"name":"remove-notification-badge","description":"Removes the red notification badge from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-player-controls-background","description":"Removes the background from the video player controls.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-screen-capture-restriction","description":"Removes the restriction of capturing audio from apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":["remove-screen-capture-restriction-resource-patch"],"compatiblePackages":[]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"sanitize-sharing-links","description":"Removes (tracking) query parameters from the URLs when sharing links.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","EnableSeekbarTappingResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sponsorblock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","video-information","player-type-hook","player-controls-bytecode-patch","sponsorblock-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"spoof-wifi-connection","description":"Spoofs an existing Wi-Fi connection.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":["litho-color-hook","SeekbarColorBytecodePatch","ThemeResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"unlock-paid-widgets","description":"Unlocks paid widgets of the app","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":[]}]},{"name":"unlock-plus","description":"Unlocks plus features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureDetectionPatch"],"compatiblePackages":[{"name":"com.microblink.photomath","versions":["8.20.0"]}]},{"name":"unlock-premium","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"io.yuka.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureVerificationPatch","LicenseValidationPatch"],"compatiblePackages":[{"name":"com.zombodroid.MemeGenerator","versions":["4.6364","4.6370","4.6375","4.6377"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.vsco.cam","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.wakdev.apps.nfctools.se","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-pro","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.candylink.openvpn","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"tv.trakt.trakt","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"vanced-microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button","client-spoof"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"vanced-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"video-speed","description":"Adds custom video speeds and ability to remember the playback speed you chose in the video playback speed flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["custom-video-speed","remember-playback-speed"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]}] \ No newline at end of file From f8f5326670577906d929fa8153b1650c30a29bc6 Mon Sep 17 00:00:00 2001 From: Valerio Mazza <92364106+vlemazza@users.noreply.github.com> Date: Wed, 5 Jul 2023 22:19:44 +0200 Subject: [PATCH 03/12] feat(slideforreddit): add `change-oauth-client-id` patch (#2571) --- .../fingerprints/GetClientIdFingerprint.kt | 11 ++++++ .../api/patch/ChangeOAuthClientIdPatch.kt | 36 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/slide/api/fingerprints/GetClientIdFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/slide/api/patch/ChangeOAuthClientIdPatch.kt diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/slide/api/fingerprints/GetClientIdFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/slide/api/fingerprints/GetClientIdFingerprint.kt new file mode 100644 index 000000000..9caed9852 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/slide/api/fingerprints/GetClientIdFingerprint.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.reddit.customclients.slide.api.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +object GetClientIdFingerprint : MethodFingerprint( + customFingerprint = custom@{ methodDef, classDef -> + if (!classDef.type.endsWith("Credentials;")) return@custom false + + methodDef.name == "getClientId" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/slide/api/patch/ChangeOAuthClientIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/slide/api/patch/ChangeOAuthClientIdPatch.kt new file mode 100644 index 000000000..90a9372fc --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/slide/api/patch/ChangeOAuthClientIdPatch.kt @@ -0,0 +1,36 @@ +package app.revanced.patches.reddit.customclients.slide.api.patch + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Package +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch +import app.revanced.patches.reddit.customclients.ChangeOAuthClientIdPatchAnnotation +import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.GetClientIdFingerprint + +@ChangeOAuthClientIdPatchAnnotation +@Description("Changes the OAuth client ID. " + + "The OAuth application type has to be \"Installed app\" " + + "and the redirect URI has to be set to \"http://www.ccrama.me\".") +@Compatibility([Package("me.ccrama.redditslide")]) +class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch( + "http://www.ccrama.me", Options, listOf(GetClientIdFingerprint) +) { + override fun List.patch(context: BytecodeContext): PatchResult { + first().mutableMethod.addInstructions( + 0, + """ + const-string v0, "$clientId" + return-object v0 + """ + ) + + return PatchResultSuccess() + } + + companion object Options : AbstractChangeOAuthClientIdPatch.Options.ChangeOAuthClientIdOptionsContainer() +} From a9d9fc64d43f528b26ac809d58c8eb817fd3a371 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 5 Jul 2023 20:22:07 +0000 Subject: [PATCH 04/12] chore(release): 2.182.0-dev.2 [skip ci] # [2.182.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.182.0-dev.1...v2.182.0-dev.2) (2023-07-05) ### Features * **slideforreddit:** add `change-oauth-client-id` patch ([#2571](https://github.com/revanced/revanced-patches/issues/2571)) ([f8f5326](https://github.com/revanced/revanced-patches/commit/f8f5326670577906d929fa8153b1650c30a29bc6)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0518318bc..7f719314a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [2.182.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.182.0-dev.1...v2.182.0-dev.2) (2023-07-05) + + +### Features + +* **slideforreddit:** add `change-oauth-client-id` patch ([#2571](https://github.com/revanced/revanced-patches/issues/2571)) ([8cd60ee](https://github.com/revanced/revanced-patches/commit/8cd60eea36bd49514ed1c42bf362dce7e9675fca)) + # [2.182.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.181.0...v2.182.0-dev.1) (2023-07-05) diff --git a/gradle.properties b/gradle.properties index f0df19635..ef745ace2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ kotlin.code.style = official -version = 2.182.0-dev.1 +version = 2.182.0-dev.2 From 04bac73a18108bf3016224bb7d6a9d1408e27eb0 Mon Sep 17 00:00:00 2001 From: Pun Date: Thu, 6 Jul 2023 03:38:39 +0700 Subject: [PATCH 05/12] build: update gradle (#2583) Co-authored-by: oSumAtrIX --- .gitattributes | 9 +++++++++ build.gradle.kts | 2 +- gradle.properties | 2 ++ gradle/wrapper/gradle-wrapper.jar | Bin 62076 -> 63375 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- gradlew | 5 ++++- 6 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..097f9f98d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# Linux start script should use lf +/gradlew text eol=lf + +# These are Windows script files and should use crlf +*.bat text eol=crlf + diff --git a/build.gradle.kts b/build.gradle.kts index 44d0470c5..7fb48980a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - kotlin("jvm") version "1.8.10" + kotlin("jvm") version "1.8.20" } group = "app.revanced" diff --git a/gradle.properties b/gradle.properties index ef745ace2..6093cf935 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,4 @@ +org.gradle.parallel=true +org.gradle.caching=true kotlin.code.style = official version = 2.182.0-dev.2 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c1962a79e29d3e0ab67b14947c167a862655af9b..033e24c4cdf41af1ab109bc7f253b2b887023340 100644 GIT binary patch delta 16170 zcmezKgt`Ac^M;UYUiouMKD(J27&_S)7>p+;X3NwEB$i}^6eX6W78NJvIA^3LXQvkF zCFdj-7f%g|4wnuU`Pash#^J0VypdJQt*X)Iwq%u~_rfhRg4Qn6G;>($8rxnlYfhPw z@cB6nHa{QDSExTQ-EIZHruXz;@A`{&o>y6#*~_n%J@@pz-*4XE-v0CT`}qG11+4c| zF7%(4?0MW(-?>_B-OL$hA2`=capb!GHS^pd-o59eBQBJg>*~Dvty{Y@H}T}5{}HpAOYGfj4JnBTfrSCxY(bZImNLJr*>aXwMz>>vxb#+C zz3`i14noTXrbcc!x8%b2K7+NZl*}H8D@A_Po|MaeCtpMGhf+v=Oqh$@=miY(zZU(O_bq!Otf4-di{0+X(%wl1GCQVXWbLRO!U8MsC8_TO+wt06= zoqs?5E8os!r8w^UM9qmoBfr(x&3mY8;?S&qeZIM=w zRQm0snRUWwzqZM_jP(+>z4gw!+Is^!rQ*dmDg=2aN~}Dhy;JJ_IjPm$`z2bBx(Vo9 zJ-Vm&a>e;$CPi#&@xlAVS@s-iQjN^KQn6y%e(ldyvlp9}>diaVW#P>bIqhm<`b?eh zqkQKlExmKv%_v%ZQRH05{!O26y>4EcF0!SQ-7M@wYg=8$;+AeUp8LmEJxj=`zf~~# zFt2oW#P&kR*S~E(O}X{OM!J8C+0)9|TYh!k_*}!BCQ>bR@yK*Dvw~|!lBN9}-t9Yd zeaXGrsW-g;uWr5f;J%*9)=!r`uFWtqxW4#|KUY5co!y74wsG*bX+C-y75g^uWAf1@ zi>3vHGGAMLZedl~{xjh-bw1`x+vt2=a#TmIKCk>)= zisDSGtWEp2UP`=OuG#TnLKoLXz3G)=<-S4NefupwGS+JTT3G+rpk(t!D@XJBWzODr zryJBQbC$oiyi`H3PuY9*T{8vo$y@jz@tiA@%Rk^#BK(f=*SEq~=1a`xl>93HlE386 zB}TTmLx1Wo|LxQX>b$PJh1s&|sZeWo>^=1YzUP_qy>falvp8?Q(D-wnN9N+l?X0Ui zxz`!ra9Y;sd0o514Ni57VS-g5qrO}=#Q*JEYwSB4a0s8=NW)=|!1`ZAe1_nn4H;HMhZJ8Jt z*jX4D>=+mr@{7{-(lg0pLvLpXtjP-ZvYje)?DnesfEAaoZjx(jOZ-u!W4fW( za&hhhd52f~gv++-pJUY9&@R>XTi(2~^`?hSWdd;jaA@zd2{--`1{(RElNmqD`^xDv6x;}^R zi~crQ)0y;g)#?*-cbh0ZJk5Wp{&1Ls{Ad~zd<7LO5Nrs;!jxrdxOjbW)xrn=PS`9y^@QI_TVg=mWHH+CM z?{KbXD)+SJ_$FN0zC?3UP|AMy=P!4>``vPDwGICtw#^**J{+v_t8>5WPL3>(s6VaN zG9f@?e{_cP0+y|dCT!cr>*DOZvZX2GYUHHb8{Tf}p3VCu|3$NZ?aOXE%i51ijg>;u zzxbyAa<`mU&DrS3xIEct=l5sxs?U9|eLiRJ?_cxp|6}-Ix9{r21IKk=9M~d}c4WfU z%pGFKN@dMIcxq4Dp;?yqaz}5BcADXG#q|$^>tzLN#CGju`*|_&z#fTr84(u>!VfDs zpD0@$`p)o+NbLGqE349uKAS0f{?4sOamzG%BijmEZ|}+aHRs_ePxkb?vd7ELp0Yi^ zwrWq9c9iLS>q}qnOgp|^cY9p+yoYf!t?ih#1^$_y-uOqFr#vWKphEq`MbWl|b87{z zZ(H>A!|tzV>r3D1&VFt7_DFZ$%`M?R=Y{@D&vvXoyvmU0%%}FWyWjk~&m@S*%qrd% zxw^1uN1fREhyOd=R(gg>ZJU(;>uXfr;gVH*4qce2WoNYgY|r7pXZ|jADyxgjxOB$L zl_jBLUuIgzl-TyBU#{;${_>uBW7AwG5#!P$;Pmrj)6S~_b3|h5=N=B45gJ$YS&cI! zm_1_d(_POeK7Bij^Eq?H>9ZnY&*x3~IW2!D-^Le<&P;o4R(diz&q#0T?yKdsm+h8F zS}&^Dv2^+!tDjGF4;mFoq&qQ4y*O&iJl7(90ry?DbBm835cLsQ&B;4oI>PDX0S-OM zFL!DdB;GtwyCx$-beg`#TJ;O{X%_nBxn8wtE8qRNrj{?o`e;_0K5tDcJKMfv%)Ivv zQvSPN_531u@6j*ixMgp8_BvM^YiI^8d>1@ltZD_{s?!EHGgLa=-aeiBqrCLpl*+O% zGagQ}(UnsE&9-;a`$)g3Qu(*Hysr7E7-|=4@vfqvVUCbGt8(AUJ1Z?>kFV6tuc&|5 zXTp(rQTcF_<}9b1Ci6Swv_xF^HD`-WUHiOePU3{T!z>;8B1c@0U-&96?(1Ca@P+rR zul#2xrnM9@y0Jd^rmdt)cwHwrKv-*dPoDSV2V~$1V`Yqh0U#; z{9h*jlQ^_tPoA*Q^pjH^_%6(<+T8eE*y#&veHvTzyuS_KzUT-1YnvzchUcB*(vLTb zT{4UX`2TX{hR*o!Dw{ocpzFv@9wNGkFyt&5nEoPmDv{L?f%#`#!P_lz1}x)2ASj z$=Zru6Biu{SeBP<5alU;SAaLxdx=+tdXi}Bi2H#SCp}2#ZQ?6A`2=^4$nEm;bW!2u|^UvGtoT;Vk|3$YqUx>hG>n`^>}adR_bZsd*YVjkZ7R^m47*=~;ewV{D+5`UBR}8~=FoG_UMC z@kPja$Af7q&i)sRo|L>@ZTeET!*q6-kn44kZ<9XgEHxK9ti^I`_SZYVXA7Iw$JSfz zOXa%%RpJNl@riK<#jdVW@!5Cz;>o>y8t?vX`jURK=I~c9-|A_v4d!?)?f!nmT}*~SIQ6O%dTzua+jW6ycXU$>0+M{RyH>5E0!2Cw$i^5Ew?*7CeBsA=5I z^Rdji?eI;rILDtd0la*TrlM<47IJyEz4`x|y)AjS`j%Xtl9Wk`Q-ZD>Upf2Plk29D zs*79Cb}4Q3t@k%I4?V4TQcOiu{il{ioAc&kR*{K6?=0H~b8nQzf7Z2j|L(lkfa~Fe*%Pna zTm0Saa)xc`_nPwME0c8nR%T5R5xoAUAnolulfPo^y{eB6lykqXKQ#M;%|=iDV6DAD z3zpqipEK2|inI9(-}j5rXCD=oc6)F+22by@`ssV=+{9%Ub5h#m98c#cev!?TV#|1= z#PdPg@4^Y@n+H7i_!dW$mK{DEzoa#DUFs{2`hMs8hm=;X=G!}?lH)DAi=6VVJ*>$q z`rffDU)Xn}-(t-}&Z=c?^ONdxIspI)wiypv7_99aG0sC9~{(ihn|ik%bB zS_G+RI%V~ST>etea?5*$Rn@lo{|(0-W%x`bW~ekzc%*H-g>{>Kee>;(wqR9WyI|7@ zg07K>v?0sHT~ZsL9X@um&1SkXGYDsmzWhUT8S_)nCLJtC{9i+ zm#c^LG|xtH)`VQWYOg-?O!dq?Im|9>jP9&FkyEw2n*@cLI8_*pIZYN^a{n}`$0zMl zWJJ!@TU}+Fla_WzZQnLc?^2Ssuz>b0*XZ3hYqxhtPhWrS-RiU7?Z5B6Imz(S``>l@ z>m1(Qd3vXM+keaF_c;Ckygu08nIZXq?+mS-SLzR^#=LV}?=;IRbC1;dPZMURSHEza z7kntRCW=$``OZr}Oy-35qWY5# zCS^|JXf7^UH!aq?blt@r*POX`o;&>YjzV{@+^u8Jt6pf=%sY0vq;6`v*vFrniW<+I zep=jmX3dnesr4qlmrSzvL_OxVy>eo6Y2L*1-Af`De~$W@b9JY$-Sg@djn^~ptovLw zSASYyd;7d+ewk(`UP_z3yR_rBbN0^T&e;`{+vkbqo#)z~Ub)$1y2s_$3!hs&cxd-- zdRq6nXxlAa*F`7(S*f7)F#K~v`@Dy_R{7sQEUlUOW=Bk#-t~(1bM@;l-khQ_1At%Sw7~KieLRvy0mWcx$7_Y#6N#sy3aA^ zYudwKVsr1W`h2^jZudF!SAY2C=GR~P*^sj*@^N`q4fo`Wl6=t@w@r}jjx=0md@b^D znvzJo_)TFx*E0*xUOeG(rR(Ufrj0vToz(P~eR~%@yQ4qqVMW1(9(RMtd-peQOuu|> zo^153YUa7Ks~oPCw(h*0!!z^Y#A6ONQat@8##6Vs9@@A=vM=AznbZ4uvrqT6t?T1& z*WbUoeev?W`LCDV>$U!6wfnaD*Y9s%ynFNN70;IKxvwI{6CRy&T2!nx!z=3d_4WDh z?+U)SbFFV>R+853JG);#y7$c?!9AM&iH68`!=26(CkhJw__EHUWJ#e)7GLX{W43|C zHFvtq%2v8|EJ?hR+!yI1_hnne#RvnTv{e%GmsQm6t1pf_=V!4~X&e7v!!->Caw4y% z-FEXl(!B6kUa^eJ(Z&ZJH+s|;2|Q@JbM@+FU5naftm#u)*Z!F2Q4$_saHdP;Q9x~} zflSYKgRNob7yMo+v%iFU@@ie9l+HH?H(Z@8aXZuX_nEnh-Z3(gCeG1kG6IgBTcT|z z)v}B`%}6XI@Av(BuWOo%=9)=xzHcjJzN}O0S31qmnER~v^2!Aq27T`ir|hd}5H3us`f06uHnyHY-_wJBg z>8xY#Fa5YHwZDDk?<*p9sR6OJi<|$=^{^1_3*Mu&@9%^9fQH~LlRD}v&(>e^)8csd z_kX^I>hl_w*98SEEAz5g10}a_i0U|%99FU7uu*%}+Usg-B$!rSVlL8kvfAr$RBN6LWlcpR| zE;PQ9+Uovjain^r^GeNo4AskD#YC$p>dbidOk-a11!H6H#uE?pwBLoykvY7ID`aYY zSW2*x-MkKF&S{oyPn!}fj%z+Vv*_6NteV-!wrBsb>wWKG&0H5{A<7*5cbh`G(guAQ z^Y3Zip{&i@XKj4&Amobf+1IOIp6b4C)BMu#k8a)z9)9+3n0bY15xy80&3F2V5PO-bdCJx&Iyv+e_fttp}l{8 z(bceN+^e;x+x0mYmNuH*oAX#?-^{e|=e7rxi=!uKJb4wF#6PDxIyFtx_IcltH_~y1 zD${Itnps(B)nDIt(D6b2#meXNPG6Z|K7HAH-OKs>tkoM&3wNk2YMypPN2{c3mtzL+ zuG#M{{?KcF|E!wF%17S(MO>A~tajPVw~wvP+|cNo((2AzXJ7B|m|vAQIse!pm_cPzia7~`3y5ch?P zpNZp)JI}7k?~GnFmt0uj{vt3TOXTN{#F$Tec3gh&`{!g2Gb8EKK8Noa7tZ^4K_G4Z zr5}vV{Y94+#9z?oo%bM_P5wE%ppAY!Z-9~2t?TQIf3O_>wtw0Grpqo(Rjek=I|Z)& zHnGq7;8}O%f%{SR`47)8I~P*_;k9d%%RcXRzDLPgX3@e2Cv?r>dibpWmgyP!{vW*m zWa{H)9iNc+_psUmqbpDRr;6-n*|b0EntZ#Cx9j=#pm*oi#(FS&zy4Eb{qfi8i3P`# zy8dyq)lZyn@Wb1IyS96tOQlb4ekki9sZ-~U3MlWsmZE<$Gk)4LZMOQ*GapUsF4aF+ z|2duaA6tF!<9x|Kx&QhO-haw({4?m?r}u`*{}x=Ckdb7Q$7`DL$F_O@d3%E&?SGWj zF8w&pX3zTjvp#2x7d1wmSF}mf5Z~~->ZtP{vplzla+cHn)qCncoVq|E=fmee+{^w(U;p;4eUp3FeV)TMhS>t*3iZn-aZC=${FXfVf08KgKgA>ACOeE3 zO?dyERXiPHzHs{Q-Wm^Gd_4NU$HY+k>{80-i#0WKf~Gn&tm+^b#a&D zC3ol5T9It^|J&jnG*Y+(n@YUSng7`SXHoOCH+#D;S)Y32bVYn)^MQwxWBW}0%{{pP zx&48`oAr8)jcM0O{ms?V-}+jm%GeG&^S(Z_L-P3KRcGt|bqY*< zY@v|XeXWaos?Afq(`*59yN~^;Zu)pp@{d^0&%+aU*iVy??{BC-J3+qq_k`DfrMHzF zeivt5Y-%y{v|ncE&dIaqa;b0po8J8Y(3>f1+V1)>8qb*+Jmb{chY@LR-AAO}RK0Z6 zPrntS`sT~gjmM4})_;8zvH90_lhxTD;(z9!V67C&eZK3<)Y5}Kl|O8jsD$jiH0KfX zTjR%mI}ZF)$|&3Co{`s5wzRF@@0DlntfI&k)z9~jZu*>L(QU(RRlE4&3Ax`pZPnk4 zs)<*>y3MT7VQ@mMDzCI`@A=ASuU~mLH!QuUelui7);Ytei!L^2GKW5$u$)KTzdz9U zTJqc8)zdGSiLBWm^(3zG(spa}l)D*>kE?8C%dDQwF?W2pH#fu&9q{N07zqlgl`muv4 z+qLvuvGcvA)CMOD>4~40U3g+MTkF8(%5%%!y(|8-SMb2)*@~qfw&{P4y{26s8s7Pq z@Aa4Ijq9?${<=12QZtLOl8sS*B{NVb?z?v&QH9T781NXy(?3tICj#8C27+a?6%A5>siVE z;D@H8{rT;O|8LG+G++8*dRtO(k_qeU+-)0HP3bthNp^|a?A-bpPp(MaFEM(q%B$R| zJ?F95ey0aZB{~v=XQuehv%S6i?Mb`TTi>~gF|e%@uRpuEJiYgR^T+DV$F@%jm%H+!`l;_)yY~flA9cd!mtVGB zP``iCe}-cfnv3K6c2>W1&frhnGWX7tNjGOjty^vH#(I23K~v24)xPp>uMetU{2AgV ze!>01>WwE~F8*TpHTrasD%`esNfu;jG8A7A#u1raml) zb#2g^bKA|AM20Q{Bdaw_)PL9AbFH;Yh_OV^wy_g|MgI8#rxc89%P)SY=&DY46zafqJLCdFO&f5}S zL{%Kl-Mx3+z2~1qL+1rQ{ISU3wD{`>-^!MHcl*w}{ZUDWr)AbIQD0G<{&KsH`~Jy4DqH00OPdZH%3By2^_gMg_b-o4 z_A_X#4q42a^+jUp`~|JdrZ$f0GRpOCYmHQ$^v^E0TeVErt7i7YAoo9ue_N6+i*497NTV?IY%dEaa@M6ij?|W2q4=1kwG_U_$lS=G^*gn5WVLlg5 zO>WO9ot&NaO06WvO}t|E+qp_7Urqk*%*x*z%ro;q*nZX>ic$=7wkJLfn&mqE;Nt1Z zi{CAS|_)xd>T|)Npi`8Xiz6URq zWxw$KkjmDawSq_Drg)ZaGj~ofZmYAHt5@Xw=Czl|%i89BopUAASU;uCKD(ws|H`EQ zH5=NhcdR^7SUmYR%i6}5*ZCR>U$fM2{rclhLG|R*h1)E4c?wVey+viMx8)w&tC9MC z`**Bdv1yjvrP(Etr8?h5)@x|S1-{b$^wRT{OhjBvfp~0LkC{s5(dtr!riX zi{i-FS$3VdC0y~#`ekXm*fKx!dYD{S3cBCHR4toOzf*o;y{$qe^V?3DzPd#2<-mQ&vg$_!OFAAf0P*y_6b1^X9g zt;UeWUzERiEj(T?u6Ve=aijQ3!Gj;CEOC#U?4(k~r*v_%VB`VaFT%exMV;8nzKInY z|Lv*cGuPUFil<{3FfSB$kclL+O z+bh_nDgJO}|MHya5AO=O)eO_U7sTl|C5U|6!S=9Nm&xNzsiuyBxXAv+_aC>gSUW8@1IN<-)7HCUY%YdFqpY)k()swGy4ix3921%_?lVC zmcKK!Vy^sB!tS`D^0ZdKt@{D_$}c!Rl)as3()LFB^Y@9X>KJVP3TS?HcQ_Utc_Y*N z_2p+FkBj!O{;OY__lJAp61B@W4u(Eg&Dywr*9q4nZxWVW+Uap`kxOl|*A+d}n&5Rx z*O!V09{#&Bak6*sdjJ0JD?i%4+<04C+`6uzsr6ho4?w-D1@{(6T) zWrd>Zhh2i*S1udup5m&vL^ozh-io_h=G}cE`f$$Eg4c{i;V;${Z+v{iElG5u*Ww`=Nu!R6Xfri~UC*F`kw` zBFTHw#3&`z^7{eTYq@*%dwUG8cbd-RI=O4Bjo7&uYr#I>S-z@QJYB4QzL48Bea5@P z)7`#5{ykape(H~ZBDGdu|4M32nytS_{N&T=RdycyE1w_!!ZGjYjNck>-K!bm->ZvT zew-6+=XCDV;rb`9bc)0;6)P{XcboUA>$t}HJ)aCeO$)bm`^kQVZ@#t&3E^0D4>!rx5#rg?L?kw_*Uvj+T%IptEUit30bY=F3rw;E8dKb8_xbI%s_32Vq zqEXc8{T@FnB(H~=`aI5_o1uPX*M*lKck%^0rtduev^XrRC*YxhXuYlH(ci&ue47GX zR$rLs`FN$A&N{Z!yvCVU$06kd(Mpg62|+z;x|h?XTLDLePVR&xx`r!uZwhwcTazrP6zea(Nu1UE)=zU*_w+<9*@eOVQ+B+U z+53s1Le@R|WzHrp zr=+Z<5_7!^*GMgqyVZEpTGM5B27j!V{Ib(i(yATL@;lf$pP$68eQv??7q2Ut!-8(@ z3(cH(b@tNSN?}>+E3v_>3Y{1&8ZD58-(5Ld_ot5+||6cR&pWh z*1Y-EGsLdF`V{fx^7rdiYs}A2j8fk)ce=?7A%WFa9^OZnoz^*Yc#BQ(vCJ2uU)Ff^ zeyZ~jYmi(#L8YE+^2y7r#c@oTi!+{PHZBk|*uLk#R>h;MC1O{0&s%r+)!m4Cnq=sd}mS5UB1KTmYzM;;kPEv=YH5bK?j|RnfsWVW7(Eh_r(QH ze9$SvFmJIGrmMpW(Tzn%Uysbtt)BE(C(4>>^>w6FRoja5GQZ%`4 zeqBQQL~%!-ZMNZ-QE%<6mg@!=YU{>Z#^!9}@?HA3F2|IaC4C9o>OPqOrX2@8=B_bM4gj74ufEeI>9^;=cFk50?%s2%p2d z#!cF6`SPWrOU!a_n*VykxYgh4(Ea9baV!UaKREOKvQ)~vw3OLP3^ofI)vY5$+>+O?=$Uu`}@R-(v#iiOIegkx7_Sn;kv7E>W)?OcFfP>%G|Q*$krcS z&08*VIn18(J!s$g$PEcI%RCXJ*@4F|RY7`NLkZNAsI|cJf+ombZMA zzp{JQyMFt{e$8sbbFW|Of8|$n7>Z4@E-=` z*7p>uCNEp(nBnNBd0@NW=7dc>G0-ljb3Hh-ym`@7r0CWDKsYy9Wrbz9s$vZ#1& ze{lNp#hV^0q&e|MTfe zE$_W73-|LD#=9M=W$pN*_vbl#NBtptmZbQlZ$EeiJ{RgfED}_mdw$CH{|4WCOF zMhVN5zMq=^aoZxf*ps0bFTR{oar@%SRj*!@{GOwfzSi4I(sSZ+IZwv5G6yGZ*grXr zx&G&MP5C-A!MaeU3LjR3X9o{>e~4lHyo`Hy+mtOGwX6KpSobdvS$VM`>p|Rw^UE(s z9G)$_dheTnrERiBvH6!-BJ3`|`P9AO?V1@24!P`hnPly0@A0f|&$n%1cG!X*>_|lmg#4&A$cg*+8IrBFk*~?KGFTd0v79D-|?{2ey!K+9a3)u z16DHU{WJ(+JYyhuY$j9WAAtnci1qB3Uw_!wcvmxceZ%_>_ZM2W>Q^u1N$+KdJjlBx zyWxz|?H8WG(YBt!(3mGQ=iVg zTaIbXVY7Z(eVpTM$kxk=w^-luMP9vp=v>r!W0RZ9#bc9x_ME?L=rdiZf3Kd`zBRe> zzS~dCYrK9a%Hopf;gY2#d-kt=CHW~mt(SkvYXm{a^hlHQUiy{38Hf;?)M%I3L~!X|W#W6kb?rSD zxf|8qyIPLz-{8k=EdhbE@_MWmF6243th~bqWQXHSIr#xj2TRYYb7ep%mmkK z>+O1_5c{`sSK5qqxhpk(Jurw>XAgS4=GjzD8-CWBnUm@!Z9VercEhygTIScDTrZpb zp?>m&P^akF)=x`aD`M_P{p2}YzGhZnXN~#pn1}0%jwvzlFFk9N-uc$WvK`|KoPZus zbEbXvnGqDR-h1U9zfkuzSFHPF-Um!PS2ypYT1UpG`v2-T44-P2o>RP4Jfo~!Y4#lj z)3d!zcbvDlPwLXlH}}*m-|XTw$M%S(UCD&JiHqB!?d*CwlD`dz!5-^Y;As6!6fh@pGJ^ z-oHh!X0~s>7g|vt=X!m`a^u=rPcCcrpI^Wk<8K$od&KOK!6ldU4^ml=HfQLrU%d8? z)80F5{Sp1nk;f=05pWu=7x*T+w=zEpzYv}=P0T9r#MV%U z?b24$E#EKtI5o6SsAb{qZ@vFG6LQ=i+?=iF68iFN^og_4D<^EfSYjt%_@8Ok>D$Ja zsxrME1vPwm@AW7sj_0gL)cmDd>hQO!W&WeHpsb?maS>@tRozA(R zbx6x{?u%D%o_NHs+HqCvY8UH%)7I&?bzaoWT3aGJujv$%O7_lk*A7>ft$o6JQp++s zgS{wdE6e9)E2@G+_AbbZ6|1ORS{wO*^~IA-3R72Xe6H1SL1^){KHI#N=Pkb1g{>%D zuK2C^_V3J^Wv6n#T72xXl(9H4^}wt+mB82gkM9(Hetpk>_RTjBd=ubxhSvwa!VCGYaE0zti77{m-wzkJTA`4!H3= zGSEI8!xHDZQ1)4BM8^Ro-Onl0PUxK8;8Zu&r}0d-QMQptYDD^iDZIz)xAr#A%8pQL z-u7tYx4>ZEyP@UVxGwWN>ix)i_M&9T56jTAYgVZC%oMeI-}_9?(8DZmYTuU5lPiPX zPHFse(&DrB#Z%{V5BEKvR=X*8&a1GqsRy`tcG+izE?%>OeX&Ph$Td%sJZy3& zlFfXR@@}3buB&@gZ+Ew?%)jEtUs7EkZM~vu$F+rFcdzC&&ujKQX=^0IrtErp-3rlY z?eNmCcdnf~R}x+O`nT)pKM5gO+uUM5^4`|oHG6+i#K$)r^)YYx=1(~hcUJM5-?}OF zQnBJs*UigWuI%NPw*GmS*YD$}uYV}N9Fupr=aOHBM%${r-JHkf9AmeCB+jq&&zVVC z`c8dIVUES)mSS6_RPHZYwi>s1cQdXyW_{uDA7$55?*eB=oLqIY{nsYP;{B>p?=0pn zVJctHf3V?!(*^4@)_rwd;m40{T%U9HdAIj(>!nNA{=Itkt17G2LheMCOHD6#M2RLw z>6g7&Tp;4%G@a>g%B3Z5MKeBM+Znla%O~?{o&;S{6IM>ZF+mmgQ~X zTRYvuFu$C`^l)73l=-3|3qU->7%iOo0g@4E3J^ID{TLK5J3v zKcXNgmm+BTQ((e7h7>0bp{I^vEeicd6$0f_cukKAOekUa#G=NkU~XTmFxzQ@ri>*2 zrS5oR{vfBbWgHxT9anrbuFzu$teCLfX@a;#En~-_<~`15e+vlwY7KlW>Hql?KWd+T z{gi2LFFDy67%IdV7&O57G5D%@J!g!_b;c>+i`Q;FPmJ@QDA@8)wFv8OMMB{5+At?$qPs zKa2$rc*@zI+cp2eO=iY9j|wMQ2HRNcKAOyEbK+gSANvQ*zLz}Q@{i6-3Z|>(99ll} z?}nDZnzrjTVTY7|%xNjMIKMG&!iP$mQ=9cYekkn|IWV0yefJ`rqlM|P%$jmr7QJ2Xp>TAlakV((vR3`?qhCFA;$?x2@ zQ=q8zuI|QIz50ifWD-llPdj|x^_BVJJwC?pFYde87j0ZOZ(EJabQSq^n{~HsU!DHl zLFdxNYgeUmzM;ZEKzUYD#%#+c9-ELlO&CgEw@baG&G~GZ@DfPU9UU0XW@)l^Om?i zJ-o}Y?AvPRXMATDtk07X+px_{{7+FwZu^ymJi5vT@vG(3&x>u#_S|Z0Y_>wmFm*yL z@3z;@UP=8)89vrNeYZDy?^L#zIq+_egZH9kMkNcJJuP2%ZOigJdq*uHbl&uPD_7rE zc36-qx^DB8vJ4MjOUVy27fY$u*ZutCq+=MOy3g5rcH6yd6&9U!Yd>2pUdkEUS-$(5 z=>k>H6?I{U#+7)HKBQ%-tNkqblPi`^TQpYhePUl zvz2SQ44rOjeBa>cmtnS~Vb*EMB}@3L9>hPoQ@zV6bKBLjm&qcZnY`w2jx6~Re(hZ8 zx#G#G%T@TxwR$#POukz)@zJXdlRVFqZ1Lh>;t|_&uJB0ojri;SPQUJ(=*$1Ioy#Hd zs#o$AVn~@TUYU|NLpI9FH*0g`r20iw$0UN@3dPO|*XZTZPq=A3UF7Jy zb%~5yD}R~oyrn3ezI#EB_#^3*TdQA0e)Ije$K%-c4-&D=n?HU_nY7GoS=wnIhvvt@ z8DcgjKIdA()_SbxI$EkUd6#4mf1spU(8jY#rMyMVlRxIxw6Cq5UUkVP+s{qJP%`$# zw2wAlP6XVnzyAK=Z=*H=@sG@s_D3EY={<5!F?^TBaC_<&t;feZPFwWMPWjVv_E|=W z_Olf|^EVwk9})3T%*|bN*ONsv4JGZj8|F>@$Q?GhKVzjvZf92X4^{8_smdD~>(4gb z->_hc)rB2-G97_-UwNKB-2OvW`JT?>??0Ghr%}1IuU->9FX$Z7BMSkF{W7M5n zbwX>#g&k>qZG0=*-%g(Fx3b>()`n%roTDyX{yEe5n#JVCJJyQo`WpkC<+tk}h`g&8 zzD?}u^eqjmZS_yg$#b#YxnbIV*J~gBqE$>MDedY%E^>MI;vKuU$1>f^U3+Nt9p z&vuu=-1?i-u0DIU;rG+ZaHH$og_q~uv5D1NxO10Tx#zsRZ6Tgh_AT*P6#6&nl$rX{ zyDhpK56X7>PMNsGczM~{+U2*G>ez-qTHRZ4b>SC z)|;GvG4Uk`M|$Sev!9egB$abiCIt1En3{bSnkt^S@B7{NO^X?X zR!w^HocD05r~iq%7}x#(#4fzQ$GXBvx=iS6%p$H0eJ^75c6I$z(yP+EXujixz{TCM zUy2spj{Tyw$U3IJWX20W@w*)g_m`RQe`?L@EjfBA!fSs-^~QFS??P9*lx8u8UKaSZ zEbxLjpP1i4bKd& z?-sGzJ&NJ+UpS>fT-x6LY^ns{1hif}R&#LF;UKwbeGZ zSUyY;<)6G_-l5HEfytkz-P)tAdv9}Y+=*wguANb4ovU-770upxC@3cLbJ)#2QQhI` zpAVU>ujAsK9FhB3DmU)3$Tgq(N0#aVcQaGpN?B)rowN07a76Vtl~(CP$`<`;>hb0m zwlQ4~_@KQ}AbaBttBlv4*~(!F!e$A^vWs;k4us9vAy%Fs{qAV#j00a=E_-?C?r3;h zF^5n4xs{KHc!1|G{cUBBltg%#uJwG@k1)22V7=xSvgm;(ljagz@j!(`=aY>K>wn&S zHm4(QQAMn&t0d35*++hTo^a@3Y4D8=*QLy!z5lOw>odoxlb>(?U0-HX_-((8(0)PA zS-y9Cb?*INdill`_uIR6E}pk(ck93H^BS(4e4M3SeKcjEQubRfE3*X|U7Fj1wE7i9 zJy?6Mnp~T3KgTwua?2IVTARl&Br^@$UT)d_sXpLf@7v;|vIURCCbYa;lV5c0cV+FrM~>H%>dOkb%&m5M1vu2bW9QxW zHFtLH>es7lChvHcB6jj#TjHsY9H%rS++woVpOWiP;8~)p?PwJx8Fg}Vv&8bPLOW|a zgr1#NTQIZ!$(JuBOgFstFljS>ZR%g8Vc*6)?Wk9@dbVN1^a$C$iFrj6%7lUz_Fj3= zx@5Omp`OtBIIqo2+@I6fi_J4P*Lm*P_snG7@>jOK(|&($xUBbJl1_oA*p8Nl_-73F zA93!v%anJPU2Z=6htskTqGcca?s#GZao4!cx zwRi91?uPKFU*$Hu0p5&EB9p})if@j;ufW4AkFxW*=e3pyww=$D3m=Qgpl_69fPy8B zLHUzszm^sYFT%E8a&p`w`N?AW0z6RV3`-hc7fxPySah;Op~z(4e2&QqZ?u>`6+?xj zCRe}FVsfhlbML+7m^`P9WAd3d0<4f7au45#GHF)9CF{%8CR@K1V1?{{33w~Yw6zW{ zDNrLhdG1>Q8I<+)Fjp`zFf3_Y+5}Z>!6Y{w%H)`=Fj;J}_d6{nz8PSlo_AhMqVvH_ z{@GHK+23n1-CPLfdc3z}I=l$X+&hnd^78juOcpDkT#m^f-Ydz#=g>?U7!**f{<{jQ zkbUyMWo(lJK4>wC9R&+<9psrj_k$MGq2rSm9=4h+{YqeR`BCKHTXu5t!oy0F13wxt zy}JO`GUKDJ3`)lv#j1Z-CqMjXF9YccKzjlx3fA46{P3g9wX3Nw^WflbIWESWp=Oh*vw}yC^Uv?Au zr?yG?XjlbD(4oaErQ|$CCPXQ;s+h1kWn}tR%xFais+m(Bjy`GddY z@S>8$qFcec-uJ(HDSMMe{ETDw%$@x^@0ZIjuK)M#frt*5KzZ!=i@H%&L@;-}|PGd6!{ZCxF;FYV#3)=F-39UYMZ;ds6W z+IKE3Td!M_yy(b6E%r|xPb|&~2ihi9RqdA(XX?4;C-Z(i6qRZb z*QtCob;`X7ohw#E{I;JOx-Lb=kmtmgg*|4E)|zMw{1iV`sJyacc2M%oxnF8zZyn>T z$w-zF4w-m8V*8N@RYf9dfSUo#+r8ntmQFw7#{iM?HjBD%s zZZ6-nx347qFQ=hN;q7Be?=p7mHhcF_hnYL)&h;HRXWORBrsYiec;MKQZQp;2oQ(Kf zEA4$N>&HK-wT{ca{cSkd6CAHRD`MM6f#p6m*~zS{&Ey(m&aMp)Ex3RE)&Ib}dhuDy z-W1NcvLk86yNhk^OU;Yl*s|J2dl+Y*Dp?p7e*4OtkdH2br?03re_gft%9D4qKhL(& z?3R~OTGf%mq9d4F@~$NKzTeaph9aw-?)pC3-L$w|DJqKOH&#rQ`F3csZZ*B5RfFRamzeul*X=V7uH|-fq!W`(VDqORwfx z2XqA9VlNO{ZZ$nTA#IyrzId&*#6RIU>-rD0z&} z%t^e@$5vmyv7SBcUHFrp^y(MKHMB3h5GxRCFX&5|U&Q%hzv<1RDXY3Y?R_^FPE~X0 zuWvu2U!5|CndO?xy^3d+?9m0YLfD@NER+5;=kUy9-{vgrximY)Z3V{x)>EIAx^}cE z@9+>~`vh0HCC9#Wmqtg}T-BYv z+hWTKH#h#{t^Kf4zxJZ~a{YZJZY{5TelIiroBikOBI7cf??QDYTo$sEPwq7Tey4cf z``ypq+)Y1UU&Hi3w`QSo=l7@!ZH9@*T2H=AIoDq3c-(c5yd&52Bd1bj!wm!vsw}HF zd16|#K)H+GdHOU3dn>LPV$W8!N%CGdIb+n4vpwpmoOAfaud8mZN)OAK7yJFp)zEjT z-Ir!2bA<0WyL#Dq$#ZgB3NOW$=UiVC^Zm}M92Qf?`Rhv zPfuVyWS?(2t$yOetX~{V>sc%}91xgOpnYWP){J_~KT*l4Gpj#8+vKa=xhUG~E$ijY zNB%!cy0AX7v~8Ye-RYbg{}N|P_B1&^Zppp&dJdDG%+c3h>Qfdk_6(i1Z&LoR-d`?f zOIGbUbYYs_J+td))*Sx(rgx`PUR6}ar88cxDhVBXU!-+Ri*29u%k^EzU#YooOq%yi zj!Eeea{76$XJ`GbkU2szbLR%l2#qWHti~B~`F6zHr)|$CK7Tr^^FeOK>9b;K%im4= zxhj7r-^LdUChMB#yqYxqP)eLu`H}M4%l8&a-e0_9^OEUz*p5EYJ!rIRa(V=V)Qe-K z%x^977BJ6c^ILHGKqQaw>O@|7$r;Wk9qi9Ze7Un{ZQ{KHygC^XBJ=9|Uq*VcM{Czy*A$p;Qj_!`_>Rd3$-Jx|a}>YZuku^;{X^RH{Le;n&ppuIV%|JS zO!Sq_m&}FjS-W@fD4%tklyN04uCxB;1HYNi*}hrooxZ!sut@)c_Ro1wLsovg=Ck`? zdVb*3%dLMKZ%b=vR0bG5nlaBpWO;qE{nnqep0D$6pCER-_{@w&no~qSuY0l3$??mC zO-X?_clB8qf4P)9gXLpuQ_Bm9UH^m@WoGbn>|1E)@h@+VN_E#i-OIb2l8rWVPLsUj zpkTa(QFU>S!VeF(uM=|Hy}pHa{pHpDA#3=@(W72S?uGi}i|v;`?eg`CQA=mCbSQpx zwqEVtc8-hU67O?&{x|JQ-Pit!`-@M0b%C(f&ENb2OOHAzePQ0>`tYA*p&`$t&xVH- zIl{V9O1Y$N?tiiA|LhI_6id%vJTK7}!H}$@aWl2Uc;VYk(#NGeyvrU-DC9ewV|%(! zan|a9NgvIkmOWqX`7?5Ik=?rVs$XUog|5H7wPIFKz5D|nL+)i)@(Y3r{8mO^=q%gw z-%yEBCoM>8?jz?deXH#icU@VTr}XX1L>Bp@57FaPWcFTn`>;&Mr!G7$t}CfX%|$aPMB>y7QC_!}l8d|-ub8^8 zaw##23;gx&tLL5K$r*b;Ulr@iRs482@1?Vnbhh=9E6-!j*)i-TQ7>b|Lc zQQIypm9#WuO-SdACApK7_FYg42nsN$-IyN`)%fWS1KSui>oe$sS-txTU*EP4~`<%Pa=h!~CO#g0I_3!d|2EWBA4>a5so6Ir0 z&|W^ZO0DbrhkcXm3_d8Hlae^RqrR`0Z4sBiQFp;P;h$UcVve-*c?*gt&A3u{(}91T zgvW#Ar*DO2!%Jh5Uwpd0Hp}R|K|smgqIGXNC+QYT&s!0)Wcut9bD7(sOADFiZI(H0 zf8Joms}3K1!xrv5Popm)y6%40_r*-U*A%fiQ#G)}H&LJSd{9-g;Top}dn3>9-ELVQ z`1$(M$I;6^#P&DFm&&{p%?VuVb?Aw;?A$xA8y>yW_pYCI#yn>Il`ZKz`3|29*;Nr< zqg&MXrTBOA3FkG7{=Cast->T7ZSnNZp7)V{GaUq(ey)3Yi{~Q4{)nj}^*Q&%pNR)A z5_+=gac~>=+@G&!Jj`%dU#7plEwD|PeSu_8<@Wk#Ge31LozeF;CpDB!X8l8pm>~Y?{)H^9Jvd{ksI=jjH(&LDOTC&sb`p$h^oLbTS z*zBFbk=wkIeCf99B|DLq(;;&cke!e?*S=UyJrK+kEX;m$ww`G}gW z&&n@ejkD_J7ld)WROPv3eaAiDwEOr~T_sHx-&n0zPp*4fJI`|4JW=u&V^kXV!hFxm z1`f&Mi4Dgqn%(41u=zdEoppHCW@)*9s=7YKy20*0tYv<&iFwABzBqd3`vp0LPXZU8 z>Pk45mZ)3smL91)lE}M%L3(}GkMN$i%-!1$EpxAP4u5pwi?hnKcK25msoZyNokHBRyqmVe=`YTNvSdG!zB@(fi zaTZdZUAV*}sO5^(%4IMAb8LBTQ2Hh3|3BvbW(%1t0|QSs#iQYA8QeMb|Jb$*I`J;| zl3JFv!9mK=Y=x8FhBJ?SHQp<(x+8HjQ$+9YQDu=h`DOaw_A{Vn<@OCBzwQb#Ff?c~ zFepw=tdyI4uZgFA=l^|Yit^RW6(to6It;YDzi}ufFa-(;aikpdVPXr}qhfyYK#JPA zJBfvBx${C-U%j?=-PKFimS&_fxgFJ8v~}&HOTN*+zwNvJE%N@qUvas=?4RGeImz(S z_g}xa{yDSrdCha{=eMU%{&DO5{OXAv(>|U5w6dk{`NIAe-{sC6Gc@R|ZxlWEdBSX2 zxvH+YtZ$Oa8EsE?Nrbe1=JrVLZ*PiGNQ+{$J=n@6&e_3S{>j8pq z1P=Q+E(m!V`RGc{)LO3dA1~P0ojhFpGlgIFd1cZJ{R@ARERH(o)~q_TTyxI>=kCgd z?P4F5`1c;}K3XpC^)O=XsodX_h}I^wT6Z$k)?w9KP^`BU|;x!y@hwk%8ja@ihP4hpH4V+xas(Y1#*FvE>F8d`&P*W-wd%__bIQip#M;{=)L1hwzeI1+oHMT zc#>OB=D(<9hyM06TPNB+3~+gWU!<4Etv6zgu0*{tuYyq}%CjWl+Y@I`PI{SrNWv_OBy){8jZVm5@iwPAQ=B?bIDbzQ!>c*Wl?T^|{ zO*hbuxP52SvgK>5tKEygPdm4+_xA4S+q12!cWvLkecRTpY_n!tSzlwDvE!=amK`%z zF4(wy>C&Cq)eB1NvyB~6kA!Slxw<$uyjWqw-b~vc1svMOJDn#UbUgUMGk4;PgtrMH z@A)OSRxkQ>qC;?P?&R4Co(Fe1%bN-C&d4=ev@t>DOo)w<=Z9A@-)rW~D=03^k$-mh z2IC@0ky~@qG*$E1oVULH#WCR%^TC4~@{TP|cyQ*;-O$OV7Lu15th?$Dwe3_Fx_ebt z#!RVDc+q;Uw&pbE;N+Vko93VR`gHcpIldF?oIl9%NXveFDC@Q*`o5r1OQ&*eRmNsH z-ma~@C9|9zJ*qy1oMJlf`#=6%6l?b8UrG<}2IM77S|&a{Rl|61V7%Q)CcPbnB8?BS zw(T?CY$)bo@WDn|^7`~=`(#(O*9$Auu((Yt`qrx=8Z!U&KcDFGcQ-P>%=|i8@zAwa z#^Cq2TZ=!Lwd#ldFlyCL&$2gc^uMuk-Hb~P^*$z#Q>lVQM~L~xrV~A{HH1B~_MesUn)vqOiM*}0v1`8_J?N3^ZIDv$ zaaX&le!l>Nrh&9*>Z1D{GY@X4Ef4$_$x{6Jo?Ws_&ZC0DNomq z4rgq``kOOzwlB136MUY)C1cbvZ_+(JmtSR)^~>fy3_inrUeUNN)9b*w9hO4o3oD)F zkCnw4%<;;+k;|K&r)5}s;6-Pf+KcsT;~r{@>WO4QP~v=P21Ai<&3B4 zXY+kO`KW&D3LW>{(^nUY@JlT#)wq>6!&z`fg&$ko6$y^UsI^02WE+nSiN)7Zk6wW&Pn;&IvjMaw5Gb#%{A8h*qAI>)U zXL5hdN8Os$$L2r0J!9GPdX48&_s?z5{1f>r;IZ|QH-7(Qq%LY6x$q+FSC8BFi(94c z`WdAD6*<9ex6qUQ@Snli)Uz|U4 z|gP5@t+xP?=MwL{cW>r>1929^^(5nKOy-GKTiJzDTzlm9L7xN`AFN9LF79Ix6% z{4#7#wVT=pxuW zwA!W%wEkn1wR*Y!^XzML{~2xk%=_fx!-$;^-p)SZJkxO9$L%f8YomGexkY7!H-{hj zpv5-l2j8B;E}7mX)6=$bn{u}pn=Rk&(e@|pi2Wk>e~WNc~?np|M84?`TuNO8a?A5-S{ka2HL?_#m|Vzz$tCldAc3>pp(} z@mp&DxqOA6+zYc^G_ISR`n2$4VV!W@G(9ek8Js`EA8-GWd%M2g_`IIST#Zd#PUT08 zcKfPtHqrRgcg+5Qyi>jHUEQnNrvC*0TX5@FmQ?js9eg5wVXtX*yR)fv)5CwWw(eRv zyQ0V>^1SlPWaS+PwnSvRB&*D`5>NRR%eVK~pX#P(7evaqkNtVr@v{G@yPJ~2<@fA4 z@}Jh#AAVN$;%;{8L@Dd;i29dHO{906TxWJ@Y5k&)yOq|Z{#=tQR1;;P0)wwES7%ue60a;+tgZ`J9$9I0ws3fQXB{4!1#)z5vm zFe9b^tIXV)o9CYRX8UtjTLVY4&$9ICsn_nUN#CF)f0dE>ual>kn8Vk|Rg)~T43;jq zr1NFTBbUuqOO9Lh>|Iu)nd8bWJFWXonab77od;jLG25-1wQ@r+2qn&CwwZ_YKiL=_-m;tfh_Bo0 z8LjH?C%jwW&bVdHHjB*8FUF^B_pG*;XkESIOvjglB7UEiD*j3Sboku#w$#1pN8$wU z=*)Tfr&#UI%&$G4oaX60eq<5Xysi12_y3|7lk2~SHa-4UyYl`z%hOMaw|U%K^L_aP z*9-1pf6kr?sQ37G*n5vrfv(H}pMAm)udLl+trb6Y-KN~$q{umCW7^PYb=kJ9lf${ zlGl=;nLiD(7v!H1Sn6@GrdA~_YO}9K|2H4;Yho*3+}WYnRlvARH?X!KV&6J9zZ0g# zf2_XzFY_sQ>sIk%;SCmf&sBM=kFHt6d+5T z@>q?NUR};YSguwY+sY9wO=@HV%_20>`E6C@6I_8%JS?F zhosI2oatuR-Tv-qg?!lU6TW^m%R@toLcb=Svi9i2)AAV>0Ue`IT` zAOD5sPwOi$t4QmlH%+v$6kcPYvamhJsd>qSAHU;0*%r<`7g*%0vbCuzbE(SKGgcFn zLMMSy(qtiH#reY9ZG8F@_+4%`${u`Izs#`cd*7r>VG|X;ay&KO8ZN8Y{~+H|jnzkg z;(vJ~eS3H4-s2nDO3&S& zgubZfY@H{wyr@X)%apA_9*b=(W#x`9e8bzmwef#lx9w@heQIk9F9h+#vS#nl-5ehJ zdyZZB$wx`I#rk-nO%A@vUaG?@R^_*uyZ*GdWrOllhG~mA^h-QFO{M?)op`?KW>wUt zuRUk4WjAO)%6}@l_{rK8HZGU7SMgu$;hO(h;Ov?YJL~xb!+QcV^HZ;CoV9YWed^!kqEC*8A?-oO4)IgRh8W5RJQa~mUf+g zx%QhT=cm&*PPPGwTUv<{odNORdFLi=7zU*Q0XBRW3Oj2Cs)Ent#J#lK8 zVpYBKhwq86+Lms+$nkbT_run}grgbeGfPyD24;UdwE4RtpZ-$ymqrz@pMJ^xCGz6^ z^7#vl_V%Cpvi-m>R;^3yC8o6=*Bd7Pjd8qQs2h9!^b5B*PxFsjyJntuOBIqUF}HC& za<#idf_2K{5)sQV)~DPrr8{QS6bLQLPkP2^zxze>g8B%Cb!{(F&u}RoFBjlmf8e;? zlBg6my``R+X@+aqNm4>0I)KGDB;qG123AGPb}=Igc3bLCqtw|HCJm3?K$E;P>f z`;&9%{LUXQrIsEzxXtj@%ddIsWR~i>r!M$?aZO43(|NlYcFy)|oqZ>N`r2T{udBZ# zcgFLETPCF|ns@&9UnVW_{!(?BT$PZUz{<@FnM}^TUeQ)L@7uSqrsef4xqGLZNDAB* z5D2~ZdGf@P#*X=~0(V{Ll2vIhv74hF{GEBhSA{FT1uQCC(iV373d{*#d|_Gj)V2_* zY>%ZI*?wutsPHcjzjQvOO1#E7a{pqch%z^?`KKGd*!{h8Nxl8erb_NB+iV@hw}w}K zWqJGIn`PXBe=L%+q4yX!%9SMDt$+Q2kCkCfahUP9X3krY&xN*%%|00CzO+2N$;siy zPa$6UBPTm7EGN}odj2HlMyX%sx^CBhEqgyDeDPhuoA}BpyHa)Ev_7o`l1@JZ1NqaG zJ+C|b+q|H$SkNd|ppawbZ?BdYp&Wh-*MDBvc=Nyy?O)k<0-Tp$yr1xlCB;nW!2N^u zP0klKvhL=(`uzP%d4tzZi+-}E9dgg}eECakW%!qe9!mc`{zv<_k zc9pM=r^*9L?H94Fetqa!{)Fv1^EEeC&$3ooy?gSSZ6}}3%W?d+jAi2K+LNhsgV*VM zu8l3K&CGiHEiP=0m;1qEJr3&+%$I!8x|_A?u3h+o@Q*v0_hzLo*nT6n)o~@C%(Bz` z%VsfX&x&g=$*)hSllfL59QZ}d>-g;wMj@YFk-H9GJ7MDSPyf=P&lB$a56xO4#rop@ z61T9+X}`*E>TF#s`kVhu%#L)+zv^l4lBWLa{&(9fM|Yo+(o&bqwmU*Q3>Kd)yqK^0 z(B_xC*1)jZ{`-F7lV_rKE9$Eh*VR}FgCmoAzc z@Y-ql@#j`PtaG2*O+OzQY3S5?IOL0p=zIT-_2!&Tf@__s)q0m#ZP+2DW3F{AEK+(& zM6?(COMw{$7nyzu$+ES6H0j^x<9^_l%Z!JfRa}RBmS%nt-LvyW=9zeM2e zBHI$p+8KJmv);0r+B5v*vGtZ)W6?Zs@%qQSQJ$H+5Sy^h2a-AE1919tr*FW*5fou!$-|u{7ii%=aSw< zQEG%Ho#B@w1KwBd;#*yw{I@q^v$S?z%gpZySA7jWo-Hx2<>)KyHY&5` zv7Tv67!!m+0yihjps%H|MgpG;Xh78s77>_E)2%6b#(>qhb=d7-A3|@6Yd2QtKUH=n2g*KN;R86f*IsPucsfT4( z>C<`+-t=u@a*L{#ZCmBsB2}ZWd)S+~Ij+!bgH-N~IrFB4O}Mos_5O>^>{skwa@6zR zsupB<-)wx}KYK#utckgk4xMp3@na)b{{uzUGghihpOl&2`M+5H;79rk(;!>>?MJ2k zZ&^P&wEpFn?(I`j_Aj}f%e*fseW~8ZEnQodhu)aCO|AZE<|OHJw{S=$?R72N>|^2Hx~jIKPHe_6nTlEgxsL({{|s`SkMSs^FDs4? z_qwO|YijNuJ?kZB9dG^I%9W|Kyj@`4HpW$w6OSvGpDlZ}BbwD_(d@1$zM$;WiCM2* z^y2QniU^Hxi2rt_-YPxg`-JsDKHCzn_Uv~5ANa7?Dvjr|rjLKhoyAx&jy|8V&N6yk z;m3U!r>88w^fw`oNn&m2!lb2DQCYWo4z(=cFc&dkT)A7|WHr~EDz-cI6?!58Y@#}D z-(vVAt~{z#o5y?LdsIg~pV2e3Cui!ObaV?|ZJ!`-*Rbz3Lu%mL$^$iuSH4>xsbpW_ zxA^{L`33XpSf<)Db>!XRxK)2>#esinzl^8o)K$p-ZT-h})Ng_Ii~KL;ANGmed@UdG z`oKKxm-D~WFHkxb;qgm@V|U1tAJgmo{=2=YXnx^4YZu!>R?DRf_pQ!0oqVQLxu zSmTb?tFU`t*$YuQ}+rnMCk4l8Q&z0Kw&7IqKs;_y=SB2c${S!Y2?7i2#@Vl(- z6APE;+0)v8&0&Aplx~>$J8*J}!Up@N)0eN(`6|@%&+JI8BVQtsB-a3529&fkW2H*R~T$;6D)7*P){Z<>w#P%+(v3$GM=v%S$QQ;FG&3-;y z8$30wYvYetje|wkr*E9t(%rTy{bVJ>x$CW2z6DqIhVMIiyQ`{1HQd#GdGMoL_vNcs zEx!D=xNFW#$4ekz0`F1=#9KdRD*hM0pE9IkegJ{BDIiK~1 zf3uY>_u0#|Pg!o^>MwIboOkDbVM<{&zp#$cs5@t|x^M1R72jB|bu}U(R@H8W85iD8 z>arDDb+g$w^O^LMq=O5O#r=7zZagVX)pgNw!Gn52w^#p&6>(aSm&#JVtkLiLW07|y zBCZV0i!>Y)df;-ro5L`-V%J(uRT+Ii*-tK>Epj`tI|)*pJ{40 zVIA|DHH8e9rYz9dCAUuX{OuP-()BZ<3->8-taC2l?_ZoG=dT*$(7kg))=rKpJvW0H z9=9unVvkII>Gkd6);G&vS4!PIaQUU!p8Lm)UzE-BEdQvpt3Unn@=Cti*5_K$Zi!!Y zL(aBoE#4Na*?*YNYS9Cpc?>J68cvq!9mw-@xv_aC$M2ml*v?Enb;xu3;brF&>pg@0 z>z5aN*iw|=_Wa#*p{IPRUpOrGT;EnDT$%7*_oa~3|3g;1FKi^IPVbA77ns>;*I9G! zjHk=$z-4PLzx-5Kw;+-0$kwDMH*dJ?S-0cGs^*ff&tJ|;+_i1#q8H7FOXkXWtlc~- zeAx#Zkq@a}zdWxA&CX|znz!ms#ANxKxrh9n!Z>qF>qSpZ7kgM(oBh<-Z5)+e7>m81&wvXpgh2)$ht< zvlSMd{68(>_>|@KS1j8z&L`fw+nH0;e8t3^tBC)ioTt{ZJ$F@>-Z?9zS@=z0`Hu^Z zyIlLE@_zm>Q0n?|WUa&h&+RYGcARs!s(mN8tG2~1YW4K+lS`~?esR?L)Fi*RlWK2n z-}CUn#{4gQZz`6H2vvT1blSP~HOsl`qdR_duS%CYR~7!SQZ#n)ymR$mGAH>jx3Ozh zE3o}pVJdLDMf%z`o3fj#F5RCvqkez%^H=3BOy=gXt#jX4xlH@S0@Fpz{6&0~&7bZm z`A+4X`E}=?Et$)Y`Y-TLh>CjQqIf-w@owIWm}h&skA;U>dI_|>yJh}MyaA|Q*So72>n*aIDt&_x6RzF#@Q1*o9RiQJp7rpWg{MxjtH1fgIsozo?#TQII z-4wFu*u2#YPToCH*57t4wR?Q$cjUrjb8nr`eZTyp^h~YoS05kIepc{+A)G0@YNE^9 z|8md6=EQ&gC%;+j=r;i_@y6+qV$2K-0UVP9R!C0Pza~>38+_S8r0u*@<}INYGdjI`KjHrS(N5}jXfH~dF0N#wnf*Ua$Wmk zb^E*D#`7F1*4wqxPo26|we+frLd`|J81-F6)$SjUcpv^#vcfcUajLL_E7Lz+-|KI5 z8V{B{o6(@3ekDLeFLT$f`&nV3p95B!$tXMy$&}Gv<~Dz?@BG?jkt{~4^@rD-E)8C3 z8uIf}h@M_ZaNYZ7a~9TLd8He?u;B;a!(Ca=cdt{PbZ&#V(6$@PGIs55-*ik;`+Kc$ zc-h@@@$D67PnP8CpTD)&;o9N5vguXU%M9|q>b3@aeVFB@xcc+KwL6~09j)z1N}WGb zv5$AT#MUb9eI*n3d96s=awfRce=+my`Uk$LGvgXLCL6dWOf&YZ`q7uV(s$0z&d*hm z_fAgdQg@%~^z+HpgSVSF3_FBpJn`t>m8#v#);Mvs?62yrE*=gsEh4ff7SC>D|yR5?B;pwu6ux?^vG3)rR7D3PJ8Mv z-(yq%EcM6%88)Z&T#rrcLJQ|7?9=|sqI8t)_Jheu|I9efSv^?O98_X>sqNwWzSFur zlOG(P!5}|R(CI&i)$)RJsoL}nO1tJ2NT(SJFPZoG++@ScwTx39Oa9v&?H9j@e9b zw>S_t;o*9o6L#XJDWY=U8+=M@kLYD#8ors+Bw@Cn z+2oXz&704iE6P}VG%TC{rKj$>{*?k?f&hVXW#zg!QVfX%)$314$ZEpF@C?NH9epA zVXlqcf%)6pKk&)jKly~cvdp5T{NoRS`g^j6sw->`&2M+E(C>erd~dN$wac;J&OaDd zm-LwTYe%$dhE>fiLuVto$AxVt*;8%SCGh$g{XEQ7_E4GUS0JnW zVNF)~o@HUR21)&Zr&E1 zeLmyn$8S?|C2xM*D)h>1=FL58Q{U!BEnDCn5y7^h(0SG6<^aDpw+%L2b&d&e^U1wi zZ?Nans@3hm&3A>Kz4!RWyPU1+x3#vQ?G&#a^UgKC-TT*^k6&fCbu~M?jf!geOv}5Q zcy09;-rTq$D#4h-;})kKaC?W;W~M z?e7s$edo63mml+OTAq-(Eivt7z~dR26X(qSx@B+u%?&TIqkgNDxST#XpKoLF`gwX6 z44JrdjNCmp?~HW|d#~x!_u^WE*`Zx+yU%Qyc5_)I+xok{+ip+w{-Fb^~iR-6t*y7|}e_i*sn&YBm-+47J@65hdypEmeTZ>~~zO}vZ?BZ$j zF6-28p16FDw5CD*i3O=1I}~=E5u9-K?YD#fRM=JW#nzN)hNyN0g(&Dh4o+FLGhpp=y4G|`)t!9y&*_?(+SepmFOMBou3ir&8V0Ft`f};dr4uVW zPp`>z|FSnEN_)jJuZX?McaDYBNX92-#xFfrGH>b9M>Ai9U+k3=-TNZg@Zhd2iNKGh z^)+)_da7PkES`2fw1)Y9NTGIK_($DoA;&H*zbUM>@2t%I#H7j7XUw|rg3Vi0EwtwP z!5ixzRi9aQFY8H=2;r|3q`y?mZt($C@ZOv|o$q+m7MgFmRPepsz z{72~_2kh2Pv)OY}C&jH*eCK}GZ$B*V7^$}&4&R_&U%xJCPVGl-u|M8_ypFD~{3hKK zFkM>r^#Mt-`q^E(3vb^{DY~tD_td>RpG;%>Kmd9R_fe6K`g{O)sVLaFDJ z)|aiUjf}qiy0AWIv46RK@rwg3sqYH&4hiM2XMfmq>eRG?&iB5N*UDG?4s-t*t!!kY zKkW)j){CThS91Ozd-V3QpXd+s4Ql)6d2V|4Ond#Rwv3;#Cu4d=#if>OPOZ5T9+G^o zf2UBBaFyBm&AS&gZI7^UIW>Rsk_#(k-OdRvf3lam{ZYeik@SlWQ|jk!@)C+$J|*|W z`DHANJiocUc`03EXxs8S%hO5AcHw8%kmJ`SY-2ZVyPVvuKkbt6rj;k=6$x4SvU`+V zFmqKk4cW*2^W3v2wd*dm_f^jb`lS1m9XV8d|JIWkCLeD;7d zUQXTKTAI5re^zAMsYM^Ek6X;0T)%JU^?+O6X}Ps?T3cRhow0mf^8CeIlXlGbCwF$C zeH&NQ2FbZwZaJ;iD!K4Wa^BaPsQj;M#4lRCjEwhqEp78!b<4hsoA*t*7CWz0BynG5 zhTOB$?mZ>47bE=Z-v>!3oO6uIb>cnSFiq0K*?5IiSL^EKf-@WoGNeo|Pw3~`k^7~z zUSfKZb#3T#fqAM6vJFF6WZHEyI&X+LeNR5flhuC6>w)1J$yI$z{T$}H-Srd`)1Drv zn{wqc#}Q8D#;`RXPI&D|dn2$XNSn9hyS39&8Ci}C=T_b@dBs_w#~5EA!@KcFVN3GI z#~D47&DuXC*c38-PCDLU)Voa6q&u_1jz2iUpuTsSrcTK>G0W<;N%`vw13uQP|IKKaG>XxFSq`?#hjn?Ai}D$-**<4Dw-<5n_9 zwzd@7E?jf`aQ%+Hf6e(K=XwNB9nLtm`J>FkSHTj;iWv=)*}apF%?wtJx!bd9ImeP& zOl2q$8We0cckz``>g(@`m09HD8+h0A*Tu)j*PfqhvZ+*2 zUG{qTweKCrnH8@y3;8^`^ZD(&p9=HW+vHU6v3IxUFXSn#nX1^_B=fsP`R^{%#-|^} zPW8N&*Hp4(oT(z8uKC`#@y5eBTFNwB^VlN3HC_h#v4u9bWHWyI<=tP~te zs_b{MttsAYD$?!EsP)84TE}0ktxL$cV&02&Jte!lx3o@JCA*|W{!*U5K)UkBH$P2Q z3(Y9sF~eNQ{PXprkJhShXp}m^nPU^gShJda$2yLfaF%t-55#vI_#OLzJwsH))oZDv zXyw&e4&Dz;vZ9#Wg_jHZ$i&ugY~5&)6M8CeWr(b|ho`_SC$4j%O}5>Xp*NqfP(k{b!nd@QKXkpN|!I&^8sSeb8cu zZYrG2_*`uA&q4tn1}Iq4$dNz!Vx8z@nIf6V?9T-zJAag7/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. From 6c55d13c802b0dcf8d1a21999d9250395c4ab334 Mon Sep 17 00:00:00 2001 From: Sculas Date: Wed, 5 Jul 2023 23:01:27 +0200 Subject: [PATCH 06/12] feat(pixiv): add `hide-ads` patch (#2578) Co-authored-by: oSumAtrIX --- .../fingerprints/IsNotPremiumFingerprint.kt | 21 ++++++++++++ .../patches/pixiv/ads/patch/HideAdsPatch.kt | 33 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/pixiv/ads/fingerprints/IsNotPremiumFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/pixiv/ads/patch/HideAdsPatch.kt diff --git a/src/main/kotlin/app/revanced/patches/pixiv/ads/fingerprints/IsNotPremiumFingerprint.kt b/src/main/kotlin/app/revanced/patches/pixiv/ads/fingerprints/IsNotPremiumFingerprint.kt new file mode 100644 index 000000000..453ec7fe3 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/pixiv/ads/fingerprints/IsNotPremiumFingerprint.kt @@ -0,0 +1,21 @@ +package app.revanced.patches.pixiv.ads.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags + + +object IsNotPremiumFingerprint : MethodFingerprint( + "V", + AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + listOf("L"), + strings = listOf("pixivAccountManager"), + customFingerprint = custom@{ _, classDef -> + // The "isNotPremium" method is the only method in the class. + if (classDef.virtualMethods.count() != 1) return@custom false + + classDef.virtualMethods.first().let { isNotPremiumMethod -> + isNotPremiumMethod.parameterTypes.size == 0 && isNotPremiumMethod.returnType == "Z" + } + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/pixiv/ads/patch/HideAdsPatch.kt b/src/main/kotlin/app/revanced/patches/pixiv/ads/patch/HideAdsPatch.kt new file mode 100644 index 000000000..4b072f321 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/pixiv/ads/patch/HideAdsPatch.kt @@ -0,0 +1,33 @@ +package app.revanced.patches.pixiv.ads.patch + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.annotation.* +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.pixiv.ads.fingerprints.IsNotPremiumFingerprint + +@Patch +@Name("hide-ads") +@Description("Hides ads.") +@Compatibility([Package("jp.pxv.android")]) +@Version("0.0.1") +class HideAdsPatch : BytecodePatch(listOf(IsNotPremiumFingerprint)) { + override fun execute(context: BytecodeContext): PatchResult { + // Always return false in the "isNotPremium" method which normally returns !this.accountManager.isPremium. + // However, this is not the method that controls the user's premium status. + // Instead, this method is used to determine whether ads should be shown. + IsNotPremiumFingerprint.result?.mutableClass?.virtualMethods?.first()?.addInstructions( + 0, + """ + const/4 v0, 0x0 + return v0 + """ + ) ?: return IsNotPremiumFingerprint.toErrorResult() + + return PatchResultSuccess() + } +} \ No newline at end of file From ff26938651a073b4f0fe6ae311f4255ee36c9ac8 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 5 Jul 2023 21:04:56 +0000 Subject: [PATCH 07/12] chore(release): 2.182.0-dev.3 [skip ci] # [2.182.0-dev.3](https://github.com/revanced/revanced-patches/compare/v2.182.0-dev.2...v2.182.0-dev.3) (2023-07-05) ### Features * **pixiv:** add `hide-ads` patch ([#2578](https://github.com/revanced/revanced-patches/issues/2578)) ([6c55d13](https://github.com/revanced/revanced-patches/commit/6c55d13c802b0dcf8d1a21999d9250395c4ab334)) --- CHANGELOG.md | 7 +++++++ README.md | 32 ++++++++++++++++++++++++++++++++ gradle.properties | 6 +++--- patches.json | 2 +- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f719314a..56770e172 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [2.182.0-dev.3](https://github.com/revanced/revanced-patches/compare/v2.182.0-dev.2...v2.182.0-dev.3) (2023-07-05) + + +### Features + +* **pixiv:** add `hide-ads` patch ([#2578](https://github.com/revanced/revanced-patches/issues/2578)) ([862a7ec](https://github.com/revanced/revanced-patches/commit/862a7ec5b0767c28e79454a44218069d3e9cbac7)) + # [2.182.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.182.0-dev.1...v2.182.0-dev.2) (2023-07-05) diff --git a/README.md b/README.md index 46d31a2f1..2236430bb 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,14 @@ The official ReVanced Patches. | `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "infinity://localhost". | all |
+### [📦 `me.ccrama.redditslide`](https://play.google.com/store/apps/details?id=me.ccrama.redditslide) +
+ +| 💊 Patch | 📜 Description | 🏹 Target Version | +|:--------:|:--------------:|:-----------------:| +| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "http://www.ccrama.me". | all | +
+ ### [📦 `free.reddit.news`](https://play.google.com/store/apps/details?id=free.reddit.news)
@@ -229,6 +237,22 @@ The official ReVanced Patches. | `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "dbrady://relay". | all |
+### [📦 `com.onelouder.baconreader`](https://play.google.com/store/apps/details?id=com.onelouder.baconreader) +
+ +| 💊 Patch | 📜 Description | 🏹 Target Version | +|:--------:|:--------------:|:-----------------:| +| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "http://baconreader.com/auth". | all | +
+ +### [📦 `com.onelouder.baconreader.premium`](https://play.google.com/store/apps/details?id=com.onelouder.baconreader.premium) +
+ +| 💊 Patch | 📜 Description | 🏹 Target Version | +|:--------:|:--------------:|:-----------------:| +| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "http://baconreader.com/auth". | all | +
+ ### [📦 `com.rubenmayayo.reddit`](https://play.google.com/store/apps/details?id=com.rubenmayayo.reddit)
@@ -301,6 +325,14 @@ The official ReVanced Patches. | `hide-ads` | Removes general ads. | all |
+### [📦 `jp.pxv.android`](https://play.google.com/store/apps/details?id=jp.pxv.android) +
+ +| 💊 Patch | 📜 Description | 🏹 Target Version | +|:--------:|:--------------:|:-----------------:| +| `hide-ads` | Hides ads. | all | +
+ ### [📦 `com.instagram.android`](https://play.google.com/store/apps/details?id=com.instagram.android)
diff --git a/gradle.properties b/gradle.properties index 6093cf935..9f367c328 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -org.gradle.parallel=true -org.gradle.caching=true +org.gradle.parallel = true +org.gradle.caching = true kotlin.code.style = official -version = 2.182.0-dev.2 +version = 2.182.0-dev.3 diff --git a/patches.json b/patches.json index 687994262..770e3ec91 100644 --- a/patches.json +++ b/patches.json @@ -1 +1 @@ -[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"auto-claim-channel-points","description":"Automatically claim Channel Points.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-embedded-ads","description":"Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"bypass-certificate-checks","description":"Bypasses certificate checks which prevent YouTube Music from working on Android Auto.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"infinity://localhost\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"ml.docilealligator.infinityforreddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"dbrady://relay\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"free.reddit.news","versions":[]},{"name":"reddit.news","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://rubenmayayo.com\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.rubenmayayo.reddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"redditisfun://auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.andrewshu.android.reddit","versions":[]},{"name":"com.andrewshu.android.redditdonation","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://redditsync/auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]},{"name":"com.laurencedawson.reddit_sync.pro","versions":[]},{"name":"com.laurencedawson.reddit_sync.dev","versions":[]}]},{"name":"change-package-name","description":"Changes the package name.","version":"0.0.1","excluded":true,"options":[{"key":"packageName","title":"Package name","description":"The name of the package to rename of the app.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"client-spoof","description":"Spoofs a patched client to allow playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-signature-verification"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":true,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-ads","description":"Disables ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["DisablePiracyDetectionPatch"],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-player-popup-panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-screenshot-popup","description":"Disables the popup that shows up when taking a screenshot.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"disable-shorts-on-startup","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-switching-emoji-to-sticker-in-message-input-field","description":"Disables switching from emoji to sticker search mode in message input field","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-typing-indicator","description":"Disables the indicator while typing a message","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-android-debugging","description":"Enables Android debugging capabilities.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"enable-debugging","description":"Adds debugging options.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"enable-on-demand","description":"Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.lite","versions":[]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"export-all-activities","description":"Makes all app activities exportable.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"external-downloads","description":"Adds support to download and save YouTube videos using an external app.","version":"0.0.1","excluded":false,"options":[],"dependencies":["external-downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Removes ads from Inshorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.nis.app","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["VerticalScrollPatch"],"compatiblePackages":[{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"hide-ads","description":"Removes ads from the Reddit.","version":"0.0.2","excluded":false,"options":[],"dependencies":["hide-subreddit-banner","hide-comment-ads"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-get-premium","HideAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-filter-bar","description":"Hides the filter bar in video feeds.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFilterBarResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-floating-microphone-button","description":"Hides the floating microphone button which appears in search.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFloatingMicrophoneButtonResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"hide-inbox-ads","description":"Hides ads in inbox.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"hide-info-cards","description":"Hides info cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-layout-components","description":"Hides general layout components.","version":"0.0.1","excluded":false,"options":[],"dependencies":["LithoFilterPatch","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-load-more-button","description":"Hides the button under videos that loads similar videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-load-more-button-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-buttons","description":"Adds the option to hide video player previous and next buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-overlay","description":"Hides the dark background overlay from the player when player controls are visible.","version":"0.0.2","excluded":false,"options":[],"dependencies":["HidePlayerOverlayResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-recommended-users","description":"Hides recommended users.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-seekbar","description":"Hides the seekbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","SeekbarColorBytecodePatch","SeekbarPreferencesPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-shorts-components","description":"Hides components from YouTube Shorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","LithoFilterPatch","HideShortsComponentsResourcePatch","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-timeline-ads","description":"Removes ads from the timeline.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.instagram.android","versions":["275.0.0.27.98"]}]},{"name":"hide-timestamp","description":"Hides timestamp in video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-video-action-buttons","description":"Adds the options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0","9.71.0-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the option to watch in VR from the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"navigation-buttons","description":"Adds options to hide or change navigation buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"old-quality-layout","description":"Enables the original video quality flyout in the video player settings.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","OldQualityLayoutResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-information","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-badge-tab","description":"Removes the badge tab from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-broadcasts-restriction","description":"Enables starting/stopping NetGuard via broadcasts.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"eu.faircode.netguard","versions":[]}]},{"name":"remove-debugging-detection","description":"Removes the USB and wireless debugging checks.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.scb.phone","versions":[]}]},{"name":"remove-device-restrictions","description":"Removes restrictions from using the app on any device.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.recorder","versions":[]}]},{"name":"remove-notification-badge","description":"Removes the red notification badge from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-player-controls-background","description":"Removes the background from the video player controls.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-screen-capture-restriction","description":"Removes the restriction of capturing audio from apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":["remove-screen-capture-restriction-resource-patch"],"compatiblePackages":[]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"sanitize-sharing-links","description":"Removes (tracking) query parameters from the URLs when sharing links.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","EnableSeekbarTappingResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sponsorblock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","video-information","player-type-hook","player-controls-bytecode-patch","sponsorblock-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"spoof-wifi-connection","description":"Spoofs an existing Wi-Fi connection.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":["litho-color-hook","SeekbarColorBytecodePatch","ThemeResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"unlock-paid-widgets","description":"Unlocks paid widgets of the app","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":[]}]},{"name":"unlock-plus","description":"Unlocks plus features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureDetectionPatch"],"compatiblePackages":[{"name":"com.microblink.photomath","versions":["8.20.0"]}]},{"name":"unlock-premium","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"io.yuka.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureVerificationPatch","LicenseValidationPatch"],"compatiblePackages":[{"name":"com.zombodroid.MemeGenerator","versions":["4.6364","4.6370","4.6375","4.6377"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.vsco.cam","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.wakdev.apps.nfctools.se","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-pro","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.candylink.openvpn","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"tv.trakt.trakt","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"vanced-microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button","client-spoof"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"vanced-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"video-speed","description":"Adds custom video speeds and ability to remember the playback speed you chose in the video playback speed flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["custom-video-speed","remember-playback-speed"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]}] \ No newline at end of file +[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"auto-claim-channel-points","description":"Automatically claim Channel Points.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-embedded-ads","description":"Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"bypass-certificate-checks","description":"Bypasses certificate checks which prevent YouTube Music from working on Android Auto.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"infinity://localhost\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"ml.docilealligator.infinityforreddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://www.ccrama.me\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"me.ccrama.redditslide","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"dbrady://relay\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"free.reddit.news","versions":[]},{"name":"reddit.news","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://baconreader.com/auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.onelouder.baconreader","versions":[]},{"name":"com.onelouder.baconreader.premium","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://rubenmayayo.com\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.rubenmayayo.reddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"redditisfun://auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.andrewshu.android.reddit","versions":[]},{"name":"com.andrewshu.android.redditdonation","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://redditsync/auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]},{"name":"com.laurencedawson.reddit_sync.pro","versions":[]},{"name":"com.laurencedawson.reddit_sync.dev","versions":[]}]},{"name":"change-package-name","description":"Changes the package name.","version":"0.0.1","excluded":true,"options":[{"key":"packageName","title":"Package name","description":"The name of the package to rename of the app.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"client-spoof","description":"Spoofs a patched client to allow playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-signature-verification"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":true,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-ads","description":"Disables ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["DisablePiracyDetectionPatch"],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-player-popup-panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-screenshot-popup","description":"Disables the popup that shows up when taking a screenshot.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"disable-shorts-on-startup","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-switching-emoji-to-sticker-in-message-input-field","description":"Disables switching from emoji to sticker search mode in message input field","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-typing-indicator","description":"Disables the indicator while typing a message","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-android-debugging","description":"Enables Android debugging capabilities.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"enable-debugging","description":"Adds debugging options.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"enable-on-demand","description":"Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.lite","versions":[]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"export-all-activities","description":"Makes all app activities exportable.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"external-downloads","description":"Adds support to download and save YouTube videos using an external app.","version":"0.0.1","excluded":false,"options":[],"dependencies":["external-downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Removes ads from Inshorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.nis.app","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["VerticalScrollPatch"],"compatiblePackages":[{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"hide-ads","description":"Removes ads from the Reddit.","version":"0.0.2","excluded":false,"options":[],"dependencies":["hide-subreddit-banner","hide-comment-ads"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-get-premium","HideAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"jp.pxv.android","versions":[]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-filter-bar","description":"Hides the filter bar in video feeds.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFilterBarResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-floating-microphone-button","description":"Hides the floating microphone button which appears in search.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFloatingMicrophoneButtonResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"hide-inbox-ads","description":"Hides ads in inbox.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"hide-info-cards","description":"Hides info cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-layout-components","description":"Hides general layout components.","version":"0.0.1","excluded":false,"options":[],"dependencies":["LithoFilterPatch","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-load-more-button","description":"Hides the button under videos that loads similar videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-load-more-button-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-buttons","description":"Adds the option to hide video player previous and next buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-overlay","description":"Hides the dark background overlay from the player when player controls are visible.","version":"0.0.2","excluded":false,"options":[],"dependencies":["HidePlayerOverlayResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-recommended-users","description":"Hides recommended users.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-seekbar","description":"Hides the seekbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","SeekbarColorBytecodePatch","SeekbarPreferencesPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-shorts-components","description":"Hides components from YouTube Shorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","LithoFilterPatch","HideShortsComponentsResourcePatch","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-timeline-ads","description":"Removes ads from the timeline.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.instagram.android","versions":["275.0.0.27.98"]}]},{"name":"hide-timestamp","description":"Hides timestamp in video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-video-action-buttons","description":"Adds the options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0","9.71.0-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the option to watch in VR from the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"navigation-buttons","description":"Adds options to hide or change navigation buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"old-quality-layout","description":"Enables the original video quality flyout in the video player settings.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","OldQualityLayoutResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-information","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-badge-tab","description":"Removes the badge tab from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-broadcasts-restriction","description":"Enables starting/stopping NetGuard via broadcasts.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"eu.faircode.netguard","versions":[]}]},{"name":"remove-debugging-detection","description":"Removes the USB and wireless debugging checks.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.scb.phone","versions":[]}]},{"name":"remove-device-restrictions","description":"Removes restrictions from using the app on any device.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.recorder","versions":[]}]},{"name":"remove-notification-badge","description":"Removes the red notification badge from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-player-controls-background","description":"Removes the background from the video player controls.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-screen-capture-restriction","description":"Removes the restriction of capturing audio from apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":["remove-screen-capture-restriction-resource-patch"],"compatiblePackages":[]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"sanitize-sharing-links","description":"Removes (tracking) query parameters from the URLs when sharing links.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","EnableSeekbarTappingResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sponsorblock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","video-information","player-type-hook","player-controls-bytecode-patch","sponsorblock-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"spoof-wifi-connection","description":"Spoofs an existing Wi-Fi connection.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":["litho-color-hook","SeekbarColorBytecodePatch","ThemeResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"unlock-paid-widgets","description":"Unlocks paid widgets of the app","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":[]}]},{"name":"unlock-plus","description":"Unlocks plus features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureDetectionPatch"],"compatiblePackages":[{"name":"com.microblink.photomath","versions":["8.20.0"]}]},{"name":"unlock-premium","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"io.yuka.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureVerificationPatch","LicenseValidationPatch"],"compatiblePackages":[{"name":"com.zombodroid.MemeGenerator","versions":["4.6364","4.6370","4.6375","4.6377"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.vsco.cam","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.wakdev.apps.nfctools.se","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-pro","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.candylink.openvpn","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"tv.trakt.trakt","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"vanced-microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button","client-spoof"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"vanced-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"video-speed","description":"Adds custom video speeds and ability to remember the playback speed you chose in the video playback speed flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["custom-video-speed","remember-playback-speed"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]}] \ No newline at end of file From 67294c76cdc0d0442d162df37a4a848e4fd1f949 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 6 Jul 2023 20:19:10 +0200 Subject: [PATCH 08/12] chore: remove `ReadmeGenerator` This is not necessary anymore because the list of patches is now parsed and displayed by revanced/revanced-website --- README-template.md | 122 ---- README.md | 634 +----------------- .../app/revanced/meta/PatchesFileGenerator.kt | 2 +- .../app/revanced/meta/ReadmeGenerator.kt | 69 -- 4 files changed, 2 insertions(+), 825 deletions(-) delete mode 100644 README-template.md delete mode 100644 src/main/kotlin/app/revanced/meta/ReadmeGenerator.kt diff --git a/README-template.md b/README-template.md deleted file mode 100644 index 5f21d12d5..000000000 --- a/README-template.md +++ /dev/null @@ -1,122 +0,0 @@ -## 🧩 ReVanced Patches - -The official ReVanced Patches. - -## 📋 List of patches in this repository - -{{ table }} - -> Looking for the JSON variant of this? [Click here](patches.json). - -## 📝 JSON Format - -This section explains the JSON format for the [patches.json](patches.json) file. - -The file contains an array of objects, each object representing a patch. The object contains the following properties: - -| key | description | -|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `name` | The name of the patch. | -| `description` | The description of the patch. | -| `version` | The version of the patch. | -| `excluded` | Whether the patch is excluded by default. If `true`, the patch must never be included by default. | -| `options` | An array of options for this patch. | -| `options.key` | The key of the option. | -| `options.title` | The title of the option. | -| `options.description` | The description of the option. | -| `options.required` | Whether the option is required. | -| `options.choices?` | An array of choices of the option. This may be `null` if this option has no choices. The element type of this array may be any type. It can be a `String`, `Int` or something else. | -| `dependencies` | An array of dependencies, which are patch names. | -| `compatiblePackages` | An array of packages compatible with this patch. | -| `compatiblePackages.name` | The name of the package. | -| `compatiblePackages.versions` | An array of versions of the package compatible with this patch. If empty, all versions are seemingly compatible. | - -Example: - -```json -[ - { - "name": "remember-video-quality", - "description": "Adds the ability to remember the video quality you chose in the video quality flyout.", - "version": "0.0.1", - "excluded": false, - "options": [], - "dependencies": [ - "integrations", - "video-id-hook" - ], - "compatiblePackages": [ - { - "name": "com.google.android.youtube", - "versions": [ - "17.22.36", - "17.24.35", - "17.26.35", - "17.27.39", - "17.28.34", - "17.29.34", - "17.32.35", - "17.33.42" - ] - } - ] - }, - { - "name": "theme", - "description": "Enables a custom theme.", - "version": "0.0.1", - "excluded": false, - "options": [ - { - "key": "theme", - "title": "Theme", - "description": "Select a theme.", - "required": true, - "choices": [ - "Amoled" - ] - } - ], - "dependencies": [ - "locale-config-fix" - ], - "compatiblePackages": [ - { - "name": "com.google.android.youtube", - "versions": [] - } - ] - }, - { - "name": "custom-branding", - "description": "Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).", - "version": "0.0.1", - "excluded": false, - "options": [ - { - "key": "appName", - "title": "Application Name", - "description": "The name of the application it will show on your home screen.", - "required": true, - "choices": null - }, - { - "key": "appIconPath", - "title": "Application Icon Path", - "description": "A path to the icon of the application.", - "required": false, - "choices": null - } - ], - "dependencies": [ - "locale-config-fix" - ], - "compatiblePackages": [ - { - "name": "com.google.android.youtube", - "versions": [] - } - ] - } -] -``` \ No newline at end of file diff --git a/README.md b/README.md index 2236430bb..79fde2b82 100644 --- a/README.md +++ b/README.md @@ -1,635 +1,3 @@ ## 🧩 ReVanced Patches -The official ReVanced Patches. - -## 📋 List of patches in this repository - -### [📦 `com.google.android.youtube`](https://play.google.com/store/apps/details?id=com.google.android.youtube) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `always-autorepeat` | Always repeats the playing video again. | 18.19.35 | -| `client-spoof` | Spoofs a patched client to allow playback. | 18.19.35 | -| `comments` | Hides components related to comments. | 18.19.35 | -| `copy-video-url` | Adds buttons in player to copy video links. | 18.19.35 | -| `custom-branding` | Changes the YouTube launcher icon and name to your choice (defaults to ReVanced). | all | -| `custom-video-buffer` | Lets you change the buffers of videos. | 18.19.35 | -| `disable-auto-captions` | Disable forced captions from being automatically enabled. | 18.19.35 | -| `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | 18.19.35 | -| `disable-player-popup-panels` | Disables panels from appearing automatically when going into fullscreen (playlist or live chat). | 18.19.35 | -| `disable-shorts-on-startup` | Disables playing YouTube Shorts when launching YouTube. | 18.19.35 | -| `disable-zoom-haptics` | Disables haptics when zooming. | all | -| `enable-debugging` | Adds debugging options. | all | -| `external-downloads` | Adds support to download and save YouTube videos using an external app. | 18.19.35 | -| `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | 18.19.35 | -| `hide-ads` | Removes general ads. | 18.19.35 | -| `hide-album-cards` | Hides the album cards below the artist description. | 18.19.35 | -| `hide-autoplay-button` | Hides the autoplay button in the video player. | 18.19.35 | -| `hide-breaking-news-shelf` | Hides the breaking news shelf on the homepage tab. | 18.19.35 | -| `hide-captions-button` | Hides the captions button on video player. | 18.19.35 | -| `hide-cast-button` | Hides the cast button in the video player. | all | -| `hide-crowdfunding-box` | Hides the crowdfunding box between the player and video description. | 18.19.35 | -| `hide-email-address` | Hides the email address in the account switcher. | 18.19.35 | -| `hide-endscreen-cards` | Hides the suggested video cards at the end of a video in fullscreen. | 18.19.35 | -| `hide-filter-bar` | Hides the filter bar in video feeds. | 18.19.35 | -| `hide-floating-microphone-button` | Hides the floating microphone button which appears in search. | 18.19.35 | -| `hide-info-cards` | Hides info cards in videos. | 18.19.35 | -| `hide-layout-components` | Hides general layout components. | 18.19.35 | -| `hide-load-more-button` | Hides the button under videos that loads similar videos. | 18.19.35 | -| `hide-player-buttons` | Adds the option to hide video player previous and next buttons. | 18.19.35 | -| `hide-player-overlay` | Hides the dark background overlay from the player when player controls are visible. | all | -| `hide-seekbar` | Hides the seekbar. | 18.19.35 | -| `hide-shorts-components` | Hides components from YouTube Shorts. | 18.19.35 | -| `hide-timestamp` | Hides timestamp in video player. | 18.19.35 | -| `hide-video-action-buttons` | Adds the options to hide action buttons under a video. | 18.19.35 | -| `hide-watch-in-vr` | Hides the option to watch in VR from the player settings flyout panel. | 18.19.35 | -| `hide-watermark` | Hides creator's watermarks on videos. | 18.19.35 | -| `minimized-playback` | Enables minimized and background playback. | 18.19.35 | -| `navigation-buttons` | Adds options to hide or change navigation buttons. | 18.19.35 | -| `old-quality-layout` | Enables the original video quality flyout in the video player settings. | 18.19.35 | -| `open-links-externally` | Open links outside of the app directly in your browser. | 18.19.35 | -| `premium-heading` | Shows premium branding on the home screen. | all | -| `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 18.19.35 | -| `remove-player-controls-background` | Removes the background from the video player controls. | 18.19.35 | -| `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | 18.19.35 | -| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 18.19.35 | -| `sponsorblock` | Integrates SponsorBlock which allows skipping video segments such as sponsored content. | 18.19.35 | -| `spoof-app-version` | Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI. | 18.19.35 | -| `swipe-controls` | Adds volume and brightness swipe controls. | 18.19.35 | -| `tablet-mini-player` | Enables the tablet mini player layout. | 18.19.35 | -| `theme` | Applies a custom theme. | all | -| `vanced-microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG. | 18.19.35 | -| `video-ads` | Removes ads in the video player. | 18.19.35 | -| `video-speed` | Adds custom video speeds and ability to remember the playback speed you chose in the video playback speed flyout. | 18.19.35 | -| `wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 18.19.35 | -
- -### [📦 `com.google.android.apps.youtube.music`](https://play.google.com/store/apps/details?id=com.google.android.apps.youtube.music) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `background-play` | Enables playing music in the background. | all | -| `bypass-certificate-checks` | Bypasses certificate checks which prevent YouTube Music from working on Android Auto. | all | -| `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | all | -| `compact-header` | Hides the music category bar at the top of the homepage. | all | -| `exclusive-audio-playback` | Enables the option to play music without video. | all | -| `hide-get-premium` | Removes all "Get Premium" evidences from the avatar menu. | all | -| `minimized-playback-music` | Enables minimized playback on Kids music. | all | -| `music-video-ads` | Removes ads in the music player. | all | -| `upgrade-button-remover` | Removes the upgrade tab from the pivot bar. | all | -| `vanced-microg-support` | Allows YouTube Music ReVanced to run without root and under a different package name. | all | -
- -### [📦 `com.ss.android.ugc.trill`](https://play.google.com/store/apps/details?id=com.ss.android.ugc.trill) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `disable-login-requirement` | Do not force login. | all | -| `downloads` | Removes download restrictions and changes the default path to download to. | all | -| `feed-filter` | Filters tiktok videos: removing ads, removing livestreams. | all | -| `fix-google-login` | Allows logging in with a Google account. | all | -| `hide-ads` | Removes ads from TikTok. | all | -| `playback-speed` | Enables the playback speed option for all videos. | all | -| `settings` | Adds ReVanced settings to TikTok. | all | -| `show-seekbar` | Shows progress bar for all video. | all | -| `sim-spoof` | Spoofs the information which is retrieved from the sim-card. | all | -
- -### [📦 `com.zhiliaoapp.musically`](https://play.google.com/store/apps/details?id=com.zhiliaoapp.musically) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `disable-login-requirement` | Do not force login. | all | -| `downloads` | Removes download restrictions and changes the default path to download to. | all | -| `feed-filter` | Filters tiktok videos: removing ads, removing livestreams. | all | -| `fix-google-login` | Allows logging in with a Google account. | all | -| `hide-ads` | Removes ads from TikTok. | all | -| `playback-speed` | Enables the playback speed option for all videos. | all | -| `settings` | Adds ReVanced settings to TikTok. | all | -| `show-seekbar` | Shows progress bar for all video. | all | -| `sim-spoof` | Spoofs the information which is retrieved from the sim-card. | all | -
- -### [📦 `tv.twitch.android.app`](https://play.google.com/store/apps/details?id=tv.twitch.android.app) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `auto-claim-channel-points` | Automatically claim Channel Points. | 15.4.1 | -| `block-audio-ads` | Blocks audio ads in streams and VODs. | 15.4.1 | -| `block-embedded-ads` | Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker. | 15.4.1 | -| `block-video-ads` | Blocks video ads in streams and VODs. | 15.4.1 | -| `debug-mode` | Enables Twitch's internal debugging mode. | all | -| `settings` | Adds settings menu to Twitch. | all | -| `show-deleted-messages` | Shows deleted chat messages behind a clickable spoiler. | 15.4.1 | -
- -### [📦 `com.reddit.frontpage`](https://play.google.com/store/apps/details?id=com.reddit.frontpage) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `disable-screenshot-popup` | Disables the popup that shows up when taking a screenshot. | all | -| `hide-ads` | Removes ads from the Reddit. | all | -| `premium-icon-reddit` | Unlocks premium Reddit app icons. | all | -| `sanitize-sharing-links` | Removes (tracking) query parameters from the URLs when sharing links. | all | -
- -### [📦 `com.twitter.android`](https://play.google.com/store/apps/details?id=com.twitter.android) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `dynamic-color` | Replaces the default Twitter Blue with the users Material You palette. | all | -| `hide-ads` | Hides ads. | all | -| `hide-recommended-users` | Hides recommended users. | all | -| `hide-views-stats` | Hides the view stats under tweets. | 9.71.0-release.0 | -
- -### [📦 `com.facebook.orca`](https://play.google.com/store/apps/details?id=com.facebook.orca) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `disable-switching-emoji-to-sticker-in-message-input-field` | Disables switching from emoji to sticker search mode in message input field | all | -| `disable-typing-indicator` | Disables the indicator while typing a message | all | -| `hide-inbox-ads` | Hides ads in inbox. | all | -
- -### [📦 `com.laurencedawson.reddit_sync`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "http://redditsync/auth". | all | -| `disable-ads` | Disables ads. | all | -
- -### [📦 `com.spotify.music`](https://play.google.com/store/apps/details?id=com.spotify.music) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `hide-premium-navbar` | Removes the premium tab from the navbar. | all | -| `spotify-theme` | Applies a custom theme. | all | -
- -### [📦 `com.sony.songpal.mdr`](https://play.google.com/store/apps/details?id=com.sony.songpal.mdr) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `remove-badge-tab` | Removes the badge tab from the activity tab. | all | -| `remove-notification-badge` | Removes the red notification badge from the activity tab. | all | -
- -### [📦 `at.gv.bmf.bmf2go`](https://play.google.com/store/apps/details?id=at.gv.bmf.bmf2go) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `remove-bootloader-detection` | Removes the check for an unlocked bootloader. | all | -| `remove-root-detection` | Removes the check for root permissions. | all | -
- -### [📦 `at.gv.oe.app`](https://play.google.com/store/apps/details?id=at.gv.oe.app) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `remove-root-detection` | Removes the check for root permissions and unlocked bootloader. | all | -| `spoof-signature` | Spoofs the signature of the app. | all | -
- -### [📦 `ml.docilealligator.infinityforreddit`](https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforreddit) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "infinity://localhost". | all | -
- -### [📦 `me.ccrama.redditslide`](https://play.google.com/store/apps/details?id=me.ccrama.redditslide) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "http://www.ccrama.me". | all | -
- -### [📦 `free.reddit.news`](https://play.google.com/store/apps/details?id=free.reddit.news) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "dbrady://relay". | all | -
- -### [📦 `reddit.news`](https://play.google.com/store/apps/details?id=reddit.news) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "dbrady://relay". | all | -
- -### [📦 `com.onelouder.baconreader`](https://play.google.com/store/apps/details?id=com.onelouder.baconreader) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "http://baconreader.com/auth". | all | -
- -### [📦 `com.onelouder.baconreader.premium`](https://play.google.com/store/apps/details?id=com.onelouder.baconreader.premium) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "http://baconreader.com/auth". | all | -
- -### [📦 `com.rubenmayayo.reddit`](https://play.google.com/store/apps/details?id=com.rubenmayayo.reddit) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "http://rubenmayayo.com". | all | -
- -### [📦 `com.andrewshu.android.reddit`](https://play.google.com/store/apps/details?id=com.andrewshu.android.reddit) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "redditisfun://auth". | all | -
- -### [📦 `com.andrewshu.android.redditdonation`](https://play.google.com/store/apps/details?id=com.andrewshu.android.redditdonation) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "redditisfun://auth". | all | -
- -### [📦 `com.laurencedawson.reddit_sync.pro`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync.pro) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "http://redditsync/auth". | all | -
- -### [📦 `com.laurencedawson.reddit_sync.dev`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync.dev) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `change-oauth-client-id` | Changes the OAuth client ID. The OAuth application type has to be "Installed app" and the redirect URI has to be set to "http://redditsync/auth". | all | -
- -### [📦 `com.myprog.hexedit`](https://play.google.com/store/apps/details?id=com.myprog.hexedit) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `disable-ads` | Disables ads in HexEditor. | all | -
- -### [📦 `com.spotify.lite`](https://play.google.com/store/apps/details?id=com.spotify.lite) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `enable-on-demand` | Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads. | all | -
- -### [📦 `com.nis.app`](https://play.google.com/store/apps/details?id=com.nis.app) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `hide-ads` | Removes ads from Inshorts. | all | -
- -### [📦 `com.vanced.android.youtube`](https://play.google.com/store/apps/details?id=com.vanced.android.youtube) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `hide-ads` | Removes general ads. | all | -
- -### [📦 `jp.pxv.android`](https://play.google.com/store/apps/details?id=jp.pxv.android) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `hide-ads` | Hides ads. | all | -
- -### [📦 `com.instagram.android`](https://play.google.com/store/apps/details?id=com.instagram.android) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `hide-timeline-ads` | Removes ads from the timeline. | 275.0.0.27.98 | -
- -### [📦 `com.backdrops.wallpapers`](https://play.google.com/store/apps/details?id=com.backdrops.wallpapers) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `pro-unlock` | Unlocks pro-only functions. | 4.52 | -
- -### [📦 `de.dwd.warnapp`](https://play.google.com/store/apps/details?id=de.dwd.warnapp) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `promo-code-unlock` | Disables the validation of promo code. Any code will work to unlock all features. | all | -
- -### [📦 `net.binarymode.android.irplus`](https://play.google.com/store/apps/details?id=net.binarymode.android.irplus) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `remove-ads` | Removes all ads from the app. | all | -
- -### [📦 `eu.faircode.netguard`](https://play.google.com/store/apps/details?id=eu.faircode.netguard) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `remove-broadcasts-restriction` | Enables starting/stopping NetGuard via broadcasts. | all | -
- -### [📦 `com.scb.phone`](https://play.google.com/store/apps/details?id=com.scb.phone) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `remove-debugging-detection` | Removes the USB and wireless debugging checks. | all | -
- -### [📦 `com.google.android.apps.recorder`](https://play.google.com/store/apps/details?id=com.google.android.apps.recorder) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `remove-device-restrictions` | Removes restrictions from using the app on any device. | all | -
- -### [📦 `com.dci.dev.androidtwelvewidgets`](https://play.google.com/store/apps/details?id=com.dci.dev.androidtwelvewidgets) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-paid-widgets` | Unlocks paid widgets of the app | all | -
- -### [📦 `com.microblink.photomath`](https://play.google.com/store/apps/details?id=com.microblink.photomath) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-plus` | Unlocks plus features. | 8.20.0 | -
- -### [📦 `io.yuka.android`](https://play.google.com/store/apps/details?id=io.yuka.android) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-premium` | Unlocks premium features. | all | -
- -### [📦 `com.teslacoilsw.launcher`](https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-prime` | Unlocks Nova Prime and all functions of the app. | all | -
- -### [📦 `org.totschnig.myexpenses`](https://play.google.com/store/apps/details?id=org.totschnig.myexpenses) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks all professional features. | 3.4.9 | -
- -### [📦 `ginlemon.iconpackstudio`](https://play.google.com/store/apps/details?id=ginlemon.iconpackstudio) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks all pro features. | all | -
- -### [📦 `com.zombodroid.MemeGenerator`](https://play.google.com/store/apps/details?id=com.zombodroid.MemeGenerator) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks pro features. | 4.6377 | -
- -### [📦 `co.windyapp.android`](https://play.google.com/store/apps/details?id=co.windyapp.android) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks all pro features. | all | -
- -### [📦 `com.vsco.cam`](https://play.google.com/store/apps/details?id=com.vsco.cam) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks pro features. | all | -
- -### [📦 `com.wakdev.apps.nfctools.se`](https://play.google.com/store/apps/details?id=com.wakdev.apps.nfctools.se) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks all pro features. | all | -
- -### [📦 `com.ithebk.expensemanager`](https://play.google.com/store/apps/details?id=com.ithebk.expensemanager) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks pro features. | all | -
- -### [📦 `com.candylink.openvpn`](https://play.google.com/store/apps/details?id=com.candylink.openvpn) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks premium features. | all | -
- -### [📦 `tv.trakt.trakt`](https://play.google.com/store/apps/details?id=tv.trakt.trakt) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks pro features. | all | -
- -### [📦 `com.awedea.nyx`](https://play.google.com/store/apps/details?id=com.awedea.nyx) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks all pro features. | all | -
- -### [📦 `com.ticktick.task`](https://play.google.com/store/apps/details?id=com.ticktick.task) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-themes` | Unlocks all themes that are inaccessible until a certain level is reached. | all | -
- -### [📦 `net.dinglisch.android.taskerm`](https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-trial` | Unlocks the trial version. | all | -
- - - -> Looking for the JSON variant of this? [Click here](patches.json). - -## 📝 JSON Format - -This section explains the JSON format for the [patches.json](patches.json) file. - -The file contains an array of objects, each object representing a patch. The object contains the following properties: - -| key | description | -|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `name` | The name of the patch. | -| `description` | The description of the patch. | -| `version` | The version of the patch. | -| `excluded` | Whether the patch is excluded by default. If `true`, the patch must never be included by default. | -| `options` | An array of options for this patch. | -| `options.key` | The key of the option. | -| `options.title` | The title of the option. | -| `options.description` | The description of the option. | -| `options.required` | Whether the option is required. | -| `options.choices?` | An array of choices of the option. This may be `null` if this option has no choices. The element type of this array may be any type. It can be a `String`, `Int` or something else. | -| `dependencies` | An array of dependencies, which are patch names. | -| `compatiblePackages` | An array of packages compatible with this patch. | -| `compatiblePackages.name` | The name of the package. | -| `compatiblePackages.versions` | An array of versions of the package compatible with this patch. If empty, all versions are seemingly compatible. | - -Example: - -```json -[ - { - "name": "remember-video-quality", - "description": "Adds the ability to remember the video quality you chose in the video quality flyout.", - "version": "0.0.1", - "excluded": false, - "options": [], - "dependencies": [ - "integrations", - "video-id-hook" - ], - "compatiblePackages": [ - { - "name": "com.google.android.youtube", - "versions": [ - "17.22.36", - "17.24.35", - "17.26.35", - "17.27.39", - "17.28.34", - "17.29.34", - "17.32.35", - "17.33.42" - ] - } - ] - }, - { - "name": "theme", - "description": "Enables a custom theme.", - "version": "0.0.1", - "excluded": false, - "options": [ - { - "key": "theme", - "title": "Theme", - "description": "Select a theme.", - "required": true, - "choices": [ - "Amoled" - ] - } - ], - "dependencies": [ - "locale-config-fix" - ], - "compatiblePackages": [ - { - "name": "com.google.android.youtube", - "versions": [] - } - ] - }, - { - "name": "custom-branding", - "description": "Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).", - "version": "0.0.1", - "excluded": false, - "options": [ - { - "key": "appName", - "title": "Application Name", - "description": "The name of the application it will show on your home screen.", - "required": true, - "choices": null - }, - { - "key": "appIconPath", - "title": "Application Icon Path", - "description": "A path to the icon of the application.", - "required": false, - "choices": null - } - ], - "dependencies": [ - "locale-config-fix" - ], - "compatiblePackages": [ - { - "name": "com.google.android.youtube", - "versions": [] - } - ] - } -] -``` \ No newline at end of file +Patches for ReVanced. diff --git a/src/main/kotlin/app/revanced/meta/PatchesFileGenerator.kt b/src/main/kotlin/app/revanced/meta/PatchesFileGenerator.kt index 62667a331..dfb57d922 100644 --- a/src/main/kotlin/app/revanced/meta/PatchesFileGenerator.kt +++ b/src/main/kotlin/app/revanced/meta/PatchesFileGenerator.kt @@ -19,7 +19,7 @@ internal interface PatchesFileGenerator { ).loadPatches().also { if (it.isEmpty()) throw IllegalStateException("No patches found") }.let { bundle -> - arrayOf(JsonGenerator(), ReadmeGenerator()).forEach { it.generate(bundle) } + arrayOf(JsonGenerator()).forEach { it.generate(bundle) } } } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/meta/ReadmeGenerator.kt b/src/main/kotlin/app/revanced/meta/ReadmeGenerator.kt deleted file mode 100644 index e8a951eac..000000000 --- a/src/main/kotlin/app/revanced/meta/ReadmeGenerator.kt +++ /dev/null @@ -1,69 +0,0 @@ -package app.revanced.meta - -import app.revanced.patcher.data.Context -import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages -import app.revanced.patcher.extensions.PatchExtensions.description -import app.revanced.patcher.extensions.PatchExtensions.patchName -import app.revanced.patcher.patch.Patch -import com.unascribed.flexver.FlexVerComparator -import java.io.File - -internal class ReadmeGenerator : PatchesFileGenerator { - private companion object { - private const val TABLE_HEADER = - "| \uD83D\uDC8A Patch | \uD83D\uDCDC Description | \uD83C\uDFF9 Target Version |\n" + - "|:--------:|:--------------:|:-----------------:|" - } - - override fun generate(bundle: PatchBundlePatches) { - val output = StringBuilder() - - mutableMapOf>>>() - .apply { - for (patch in bundle) { - patch.compatiblePackages?.forEach { pkg -> - if (!contains(pkg.name)) put(pkg.name, mutableListOf()) - this[pkg.name]!!.add(patch) - } - } - } - .entries - .sortedByDescending { it.value.size } - .forEach { (`package`, patches) -> - val mostCommonVersion = buildMap { - patches.forEach { patch -> - patch.compatiblePackages?.single { compatiblePackage -> compatiblePackage.name == `package` }?.versions?.let { - it.forEach { version -> merge(version, 1, Integer::sum) } - } - } - }.let { commonMap -> - commonMap.maxByOrNull { it.value }?.value?.let { - commonMap.entries.filter { mostCommon -> mostCommon.value == it } - .maxOfWith(FlexVerComparator::compare, Map.Entry::key) - } ?: "all" - } - - output.apply { - appendLine("### [\uD83D\uDCE6 `${`package`}`](https://play.google.com/store/apps/details?id=${`package`})") - appendLine("
\n") - appendLine(TABLE_HEADER) - patches.forEach { patch -> - val recommendedPatchVersion = if ( - patch.compatiblePackages?.single { it.name == `package` }?.versions?.isNotEmpty() == true - ) mostCommonVersion else "all" - - appendLine( - "| `${patch.patchName}` " + - "| ${patch.description} " + - "| $recommendedPatchVersion |" - ) - } - appendLine("
\n") - } - } - - StringBuilder(File("README-template.md").readText()) - .replace(Regex("\\{\\{\\s?table\\s?}}"), output.toString()) - .let(File("README.md")::writeText) - } -} \ No newline at end of file From 34514b04f1eb8810da7a79f24ce2d886f23fde96 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 8 Jul 2023 03:02:32 +0400 Subject: [PATCH 09/12] feat(youtube): support version `18.23.35` (#2461) Co-authored-by: oSumAtrIX --- .../annotation/HideAdsCompatibility.kt | 2 +- .../HideGetPremiumCompatibility.kt | 2 +- .../annotations/VideoAdsCompatibility.kt | 2 +- .../annotation/CopyVideoUrlCompatibility.kt | 2 +- .../ExternalDownloadsCompatibility.kt | 2 +- .../annotation/SeekbarTappingCompatibility.kt | 2 +- .../annotation/SwipeControlsCompatibility.kt | 2 +- .../annotations/AutoCaptionsCompatibility.kt | 2 +- .../annotations/HideButtonsCompatibility.kt | 2 +- .../AutoplayButtonCompatibility.kt | 2 +- .../HideCaptionsButtonCompatibility.kt | 2 +- .../NavigationButtonsCompatibility.kt | 2 +- .../HidePlayerButtonsCompatibility.kt | 2 +- .../annotations/AlbumCardsCompatibility.kt | 2 +- .../annotations/BreakingNewsCompatibility.kt | 2 +- .../annotations/HideCommentsCompatibility.kt | 2 +- .../CrowdfundingBoxCompatibility.kt | 2 +- .../HideEndscreenCardsCompatibility.kt | 2 +- .../filterbar/annotations/HideFilterBar.kt | 2 +- ...deFloatingMicrophoneButtonCompatibility.kt | 2 +- .../HideLayoutComponentsCompatibility.kt | 2 +- .../annotations/HideInfocardsCompatibility.kt | 2 +- .../HideLoadMoreButtonCompatibility.kt | 2 +- .../HideEmailAddressCompatibility.kt | 2 +- .../CreatePlayerOverviewFingerprint.kt | 10 +- .../annotations/HideSeekbarCompatibility.kt | 2 +- .../HideShortsComponentsCompatibility.kt | 2 +- .../time/annotations/HideTimeCompatibility.kt | 2 +- .../annotations/WatchInVRCompatibility.kt | 2 +- .../annotations/HideWatermarkCompatibility.kt | 2 +- .../FullscreenPanelsCompatibility.kt | 2 +- .../PlayerPopupPanelsCompatibility.kt | 2 +- .../PlayerControlsBackgroundCompatibility.kt | 2 +- .../ReturnYouTubeDislikeCompatibility.kt | 2 +- ...TextComponentAtomicReferenceFingerprint.kt | 7 +- .../TextComponentContextFingerprint.kt | 2 +- .../annotations/WideSearchbarCompatibility.kt | 2 +- .../annotations/SponsorBlockCompatibility.kt | 2 +- .../SpoofAppVersionCompatibility.kt | 2 +- .../StartupShortsResetCompatibility.kt | 2 +- .../TabletMiniPlayerCompatibility.kt | 2 +- .../MiniPlayerOverrideFingerprint.kt | 2 +- .../MiniPlayerOverrideParentFingerprint.kt | 2 +- .../annotations/AutoRepeatCompatibility.kt | 2 +- .../CreateBottomSheetFingerprint.kt | 13 +++ .../hook/patch/BottomSheetHookPatch.kt | 43 ++++++++ .../FixBackToExitGestureCompatibility.kt | 2 +- .../annotations/ClientSpoofCompatibility.kt | 2 +- .../annotations/IntegrationsCompatibility.kt | 2 +- .../OpenLinksExternallyCompatibility.kt | 2 +- .../fingerprints/ProtobufBufferFingerprint.kt | 25 ----- .../ProtobufBufferReferenceFingerprint.kt | 18 +++ .../litho/filter/patch/LithoFilterPatch.kt | 103 +++++++++++++----- .../annotations/MicroGPatchCompatibility.kt | 2 +- .../MinimizedPlaybackCompatibility.kt | 2 +- .../MinimizedPlaybackSettingsFingerprint.kt | 2 +- ...imizedPlaybackSettingsParentFingerprint.kt | 7 +- .../annotation/PlayerControlsCompatibility.kt | 2 +- .../PlayerOverlaysHookCompatibility.kt | 2 +- .../annotation/PlayerTypeHookCompatibility.kt | 2 +- .../CustomVideoBufferCompatibility.kt | 2 +- .../annotations/HDRBrightnessCompatibility.kt | 2 +- .../VideoInformationCompatibility.kt | 2 +- .../patch/OldQualityLayoutPatch.kt | 44 -------- .../patch/OldQualityLayoutResourcePatch.kt | 36 ------ .../RememberVideoQualityCompatibility.kt | 2 +- .../NewVideoQualityChangedFingerprint.kt | 32 ++++++ ...dexMethodClassFieldReferenceFingerprint.kt | 3 + .../patch/RememberVideoQualityPatch.kt | 24 +++- .../patches/youtube/video/speed/VideoSpeed.kt | 2 - .../video/speed/VideoSpeedCompatibility.kt | 2 +- .../GetOldVideoSpeedsFingerprint.kt | 8 ++ .../ShowOldVideoSpeedMenuFingerprint.kt | 7 ++ ...ldVideoSpeedMenuIntegrationsFingerprint.kt | 7 ++ .../VideoSpeedPatchFingerprint.kt | 0 .../custom/patch/CustomVideoSpeedPatch.kt | 90 +++++++++++++-- .../annotation/VideoIdCompatibility.kt | 2 +- .../OldVideoQualityMenuCompatibility.kt} | 6 +- ...VideoQualityMenuViewInflateFingerprint.kt} | 8 +- .../patch/OldVideoQualityMenuPatch.kt | 73 +++++++++++++ .../patch/OldVideoQualityMenuResourcePatch.kt | 42 +++++++ 81 files changed, 499 insertions(+), 225 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/bottomsheet/hook/fingerprints/CreateBottomSheetFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/bottomsheet/hook/patch/BottomSheetHookPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ProtobufBufferFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ProtobufBufferReferenceFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/patch/OldQualityLayoutPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/patch/OldQualityLayoutResourcePatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/video/quality/fingerprints/NewVideoQualityChangedFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/GetOldVideoSpeedsFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/ShowOldVideoSpeedMenuFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/ShowOldVideoSpeedMenuIntegrationsFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/VideoSpeedPatchFingerprint.kt rename src/main/kotlin/app/revanced/patches/youtube/video/{oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt => videoqualitymenu/annotations/OldVideoQualityMenuCompatibility.kt} (58%) rename src/main/kotlin/app/revanced/patches/youtube/video/{oldqualitylayout/fingerprints/QualityMenuViewInflateFingerprint.kt => videoqualitymenu/fingerprints/VideoQualityMenuViewInflateFingerprint.kt} (69%) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/patch/OldVideoQualityMenuPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/patch/OldVideoQualityMenuResourcePatch.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/annotation/HideAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/annotation/HideAdsCompatibility.kt index 798560a76..5f90c5019 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/annotation/HideAdsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/general/annotation/HideAdsCompatibility.kt @@ -3,7 +3,7 @@ package app.revanced.patches.youtube.ad.general.annotation import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideAdsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/annotations/HideGetPremiumCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/annotations/HideGetPremiumCompatibility.kt index 7f3958742..f17ebada9 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/annotations/HideGetPremiumCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/annotations/HideGetPremiumCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.ad.getpremium.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideGetPremiumCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt index 6713227a1..9226b6f44 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt @@ -3,7 +3,7 @@ package app.revanced.patches.youtube.ad.video.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class VideoAdsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt index fc46729a4..93058c896 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.interaction.copyvideourl.annotation import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class CopyVideoUrlCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/annotation/ExternalDownloadsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/annotation/ExternalDownloadsCompatibility.kt index 7dc840c61..be32f73c8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/annotation/ExternalDownloadsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/annotation/ExternalDownloadsCompatibility.kt @@ -3,7 +3,7 @@ package app.revanced.patches.youtube.interaction.downloads.annotation import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class ExternalDownloadsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt index 56a7b6893..cd1b8ca07 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt @@ -3,7 +3,7 @@ package app.revanced.patches.youtube.interaction.seekbar.annotation import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class SeekbarTappingCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/annotation/SwipeControlsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/annotation/SwipeControlsCompatibility.kt index feaa5effc..ad2ec1770 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/annotation/SwipeControlsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/annotation/SwipeControlsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.interaction.swipecontrols.annotation import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class SwipeControlsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/annotations/AutoCaptionsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/annotations/AutoCaptionsCompatibility.kt index c03a3e7f9..81fb60d32 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/annotations/AutoCaptionsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/annotations/AutoCaptionsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.autocaptions.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class AutoCaptionsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/annotations/HideButtonsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/annotations/HideButtonsCompatibility.kt index 112725358..1c521c547 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/annotations/HideButtonsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/annotations/HideButtonsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.buttons.action.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideButtonsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/annotations/AutoplayButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/annotations/AutoplayButtonCompatibility.kt index 278fb0c2f..bb95ff038 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/annotations/AutoplayButtonCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/annotations/AutoplayButtonCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.buttons.autoplay.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class AutoplayButtonCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/annotations/HideCaptionsButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/annotations/HideCaptionsButtonCompatibility.kt index 849d2e18e..fc1e112a0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/annotations/HideCaptionsButtonCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/annotations/HideCaptionsButtonCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.buttons.captions.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideCaptionsButtonCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/annotations/NavigationButtonsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/annotations/NavigationButtonsCompatibility.kt index e298888c1..393ac1366 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/annotations/NavigationButtonsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/annotations/NavigationButtonsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.buttons.navigation.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class NavigationButtonsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/annotations/HidePlayerButtonsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/annotations/HidePlayerButtonsCompatibility.kt index 1f20ff2fb..15330096c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/annotations/HidePlayerButtonsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/annotations/HidePlayerButtonsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.buttons.player.hide.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HidePlayerButtonsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/annotations/AlbumCardsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/annotations/AlbumCardsCompatibility.kt index 1523ca1c2..889695eaa 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/annotations/AlbumCardsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/annotations/AlbumCardsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.albumcards.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class AlbumCardsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/annotations/BreakingNewsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/annotations/BreakingNewsCompatibility.kt index af446cfe8..635820ab5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/annotations/BreakingNewsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/annotations/BreakingNewsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.breakingnews.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class BreakingNewsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/HideCommentsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/HideCommentsCompatibility.kt index 27f8151f0..6d8b3b3e3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/HideCommentsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/HideCommentsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.comments.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideCommentsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/annotations/CrowdfundingBoxCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/annotations/CrowdfundingBoxCompatibility.kt index f6776877b..fe6894aa3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/annotations/CrowdfundingBoxCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/annotations/CrowdfundingBoxCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.crowdfundingbox.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class CrowdfundingBoxCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/annotations/HideEndscreenCardsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/annotations/HideEndscreenCardsCompatibility.kt index 47d278010..206275896 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/annotations/HideEndscreenCardsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/annotations/HideEndscreenCardsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.endscreencards.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideEndscreenCardsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/annotations/HideFilterBar.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/annotations/HideFilterBar.kt index e45cafd7b..95aa29f64 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/annotations/HideFilterBar.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/annotations/HideFilterBar.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.filterbar.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideFilterBar \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/annotations/HideFloatingMicrophoneButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/annotations/HideFloatingMicrophoneButtonCompatibility.kt index 8ab0a1e5c..b5f04f78a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/annotations/HideFloatingMicrophoneButtonCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/annotations/HideFloatingMicrophoneButtonCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.floatingmicrophone.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideFloatingMicrophoneButtonCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/annotations/HideLayoutComponentsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/annotations/HideLayoutComponentsCompatibility.kt index 926b97920..a685bf3ee 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/annotations/HideLayoutComponentsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/annotations/HideLayoutComponentsCompatibility.kt @@ -3,7 +3,7 @@ package app.revanced.patches.youtube.layout.hide.general.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideLayoutComponentsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/annotations/HideInfocardsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/annotations/HideInfocardsCompatibility.kt index 8a71676e9..520f038f6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/annotations/HideInfocardsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/annotations/HideInfocardsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.infocards.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideInfocardsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/annotations/HideLoadMoreButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/annotations/HideLoadMoreButtonCompatibility.kt index 5c580599c..a9c4bcea7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/annotations/HideLoadMoreButtonCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/annotations/HideLoadMoreButtonCompatibility.kt @@ -3,7 +3,7 @@ package app.revanced.patches.youtube.layout.hide.loadmorebutton.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideLoadMoreButtonCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/annotations/HideEmailAddressCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/annotations/HideEmailAddressCompatibility.kt index 27abf2723..3d7193394 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/annotations/HideEmailAddressCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/annotations/HideEmailAddressCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.personalinformation.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideEmailAddressCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/bytecode/fingerprints/CreatePlayerOverviewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/bytecode/fingerprints/CreatePlayerOverviewFingerprint.kt index c22588a28..1325bee97 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/bytecode/fingerprints/CreatePlayerOverviewFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/bytecode/fingerprints/CreatePlayerOverviewFingerprint.kt @@ -1,12 +1,13 @@ package app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.fingerprints +import app.revanced.extensions.containsConstantInstructionValue import app.revanced.patcher.extensions.or -import app.revanced.util.patch.LiteralValueFingerprint +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patches.youtube.layout.hide.player.overlay.resource.patch.HidePlayerOverlayResourcePatch import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode -object CreatePlayerOverviewFingerprint : LiteralValueFingerprint( +object CreatePlayerOverviewFingerprint : MethodFingerprint( returnType = "V", accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, opcodes = listOf( @@ -15,5 +16,8 @@ object CreatePlayerOverviewFingerprint : LiteralValueFingerprint( Opcode.MOVE_RESULT_OBJECT, Opcode.CHECK_CAST ), - literal = HidePlayerOverlayResourcePatch.scrimOverlayId + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("YouTubeControlsOverlay;") + && methodDef.containsConstantInstructionValue(HidePlayerOverlayResourcePatch.scrimOverlayId) + } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/annotations/HideSeekbarCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/annotations/HideSeekbarCompatibility.kt index 560e17a8e..784fa8611 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/annotations/HideSeekbarCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/annotations/HideSeekbarCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.seekbar.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideSeekbarCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/annotations/HideShortsComponentsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/annotations/HideShortsComponentsCompatibility.kt index a058e84cd..e434846d0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/annotations/HideShortsComponentsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/annotations/HideShortsComponentsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.shorts.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideShortsComponentsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/annotations/HideTimeCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/annotations/HideTimeCompatibility.kt index c3f3c7776..baa9be5ff 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/annotations/HideTimeCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/annotations/HideTimeCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.time.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideTimeCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/annotations/WatchInVRCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/annotations/WatchInVRCompatibility.kt index 9eba5cc7c..e03bee708 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/annotations/WatchInVRCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/annotations/WatchInVRCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.watchinvr.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class WatchInVRCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/annotations/HideWatermarkCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/annotations/HideWatermarkCompatibility.kt index 8d11da21a..687b50654 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/annotations/HideWatermarkCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/annotations/HideWatermarkCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.watermark.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HideWatermarkCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/annotations/FullscreenPanelsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/annotations/FullscreenPanelsCompatibility.kt index 86a2865c2..11dbf8842 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/annotations/FullscreenPanelsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/annotations/FullscreenPanelsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.panels.fullscreen.remove.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class FullscreenPanelsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/annotations/PlayerPopupPanelsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/annotations/PlayerPopupPanelsCompatibility.kt index c05d454b4..e6da79902 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/annotations/PlayerPopupPanelsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/annotations/PlayerPopupPanelsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.panels.popup.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class PlayerPopupPanelsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/annotations/PlayerControlsBackgroundCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/annotations/PlayerControlsBackgroundCompatibility.kt index ac2062c55..d7e6490f9 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/annotations/PlayerControlsBackgroundCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/annotations/PlayerControlsBackgroundCompatibility.kt @@ -2,6 +2,6 @@ package app.revanced.patches.youtube.layout.player.background.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class PlayerControlsBackgroundCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/annotations/ReturnYouTubeDislikeCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/annotations/ReturnYouTubeDislikeCompatibility.kt index aa0f3fcc5..5f3dd157e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/annotations/ReturnYouTubeDislikeCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/annotations/ReturnYouTubeDislikeCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.returnyoutubedislike.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class ReturnYouTubeDislikeCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt index 199f14889..c5955c0f2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt @@ -21,14 +21,11 @@ object TextComponentAtomicReferenceFingerprint : MethodFingerprint( Opcode.MOVE_RESULT_OBJECT, Opcode.CHECK_CAST, Opcode.MOVE_OBJECT, // CharSequence reference, and control flow label. Insert code here. - Opcode.INVOKE_VIRTUAL, + null, // invoke-interface or invoke-virtual Opcode.MOVE_RESULT, Opcode.IF_EQZ, - Opcode.INVOKE_VIRTUAL, + null, // invoke-interface or invoke-virtual Opcode.MOVE_RESULT_OBJECT, Opcode.GOTO, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL_RANGE, - Opcode.MOVE_RESULT_OBJECT, ) ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt index eee7ab2a2..7e4d3141f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt @@ -6,7 +6,7 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode /** - * Resolves against the same method that [TextComponentContextFingerprint] resolves to. + * Resolves against the same class that [TextComponentConstructorFingerprint] resolves to. */ object TextComponentContextFingerprint : MethodFingerprint( returnType = "L", diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/annotations/WideSearchbarCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/annotations/WideSearchbarCompatibility.kt index 75d3373ec..1fe97fe00 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/annotations/WideSearchbarCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/annotations/WideSearchbarCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.searchbar.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class WideSearchbarCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt index f805334ff..7eefbbd53 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.sponsorblock.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class SponsorBlockCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/annotations/SpoofAppVersionCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/annotations/SpoofAppVersionCompatibility.kt index c64f17745..04740e6fb 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/annotations/SpoofAppVersionCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/annotations/SpoofAppVersionCompatibility.kt @@ -3,7 +3,7 @@ package app.revanced.patches.youtube.layout.spoofappversion.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class SpoofAppVersionCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/annotations/StartupShortsResetCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/annotations/StartupShortsResetCompatibility.kt index 72b516851..9b2022792 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/annotations/StartupShortsResetCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/annotations/StartupShortsResetCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.startupshortsreset.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class StartupShortsResetCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/annotations/TabletMiniPlayerCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/annotations/TabletMiniPlayerCompatibility.kt index ded1563ed..4284c94d0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/annotations/TabletMiniPlayerCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/annotations/TabletMiniPlayerCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.tabletminiplayer.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class TabletMiniPlayerCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideFingerprint.kt index e43e1770f..f2210f76b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideFingerprint.kt @@ -7,7 +7,7 @@ import org.jf.dexlib2.Opcode object MiniPlayerOverrideFingerprint : MethodFingerprint( "Z", AccessFlags.STATIC or AccessFlags.PUBLIC, - listOf("L"), + listOf("Landroid/content/Context;"), opcodes = listOf( Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideParentFingerprint.kt index a4180746c..df5352235 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideParentFingerprint.kt @@ -3,5 +3,5 @@ package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint object MiniPlayerOverrideParentFingerprint : MethodFingerprint( - strings = listOf("Possible Context wrapper loop - chain of wrappers larger than 10000") + strings = listOf("Unset or unknown Input OneOf case for dynamic input") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/annotations/AutoRepeatCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/annotations/AutoRepeatCompatibility.kt index ab04bfe8d..b4b62674c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/annotations/AutoRepeatCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/annotations/AutoRepeatCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.autorepeat.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class AutoRepeatCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/bottomsheet/hook/fingerprints/CreateBottomSheetFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/bottomsheet/hook/fingerprints/CreateBottomSheetFingerprint.kt new file mode 100644 index 000000000..70c04aa39 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/bottomsheet/hook/fingerprints/CreateBottomSheetFingerprint.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.misc.bottomsheet.hook.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.youtube.video.videoqualitymenu.patch.OldVideoQualityMenuResourcePatch +import app.revanced.util.patch.LiteralValueFingerprint +import org.jf.dexlib2.AccessFlags + +object CreateBottomSheetFingerprint : LiteralValueFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L"), + returnType = "Landroid/widget/LinearLayout;", + literal = OldVideoQualityMenuResourcePatch.bottomSheetMargins +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/bottomsheet/hook/patch/BottomSheetHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/bottomsheet/hook/patch/BottomSheetHookPatch.kt new file mode 100644 index 000000000..d72b974ef --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/bottomsheet/hook/patch/BottomSheetHookPatch.kt @@ -0,0 +1,43 @@ +package app.revanced.patches.youtube.misc.bottomsheet.hook.patch + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patches.youtube.misc.bottomsheet.hook.fingerprints.CreateBottomSheetFingerprint +import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch +import org.jf.dexlib2.iface.instruction.OneRegisterInstruction + +@DependsOn([IntegrationsPatch::class]) +class BottomSheetHookPatch : BytecodePatch( + listOf(CreateBottomSheetFingerprint) +) { + override fun execute(context: BytecodeContext): PatchResult { + CreateBottomSheetFingerprint.result?.let { + it.mutableMethod.apply { + val returnLinearLayoutIndex = implementation!!.instructions.lastIndex + val linearLayoutRegister = getInstruction(returnLinearLayoutIndex).registerA + + addHook = { classDescriptor -> + addInstruction( + returnLinearLayoutIndex, + "invoke-static { v$linearLayoutRegister }, " + + "${classDescriptor}->" + + "onFlyoutMenuCreate(Landroid/widget/LinearLayout;)V" + ) + } + } + } ?: return CreateBottomSheetFingerprint.toErrorResult() + + return PatchResultSuccess() + } + + internal companion object { + internal lateinit var addHook: (String) -> Unit + private set + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/annotation/FixBackToExitGestureCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/annotation/FixBackToExitGestureCompatibility.kt index 8a470352b..bce548f11 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/annotation/FixBackToExitGestureCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/annotation/FixBackToExitGestureCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.fix.backtoexitgesture.annotation import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class FixBackToExitGestureCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/annotations/ClientSpoofCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/annotations/ClientSpoofCompatibility.kt index 13e9c51b5..24c49518a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/annotations/ClientSpoofCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/annotations/ClientSpoofCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.fix.playback.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class ClientSpoofCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt index 0bdca1b8a..9de9f53c3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.integrations.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class IntegrationsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt index 9485b3efc..233b8ce6a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.links.open.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class OpenLinksExternallyCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ProtobufBufferFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ProtobufBufferFingerprint.kt deleted file mode 100644 index 9e0997936..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ProtobufBufferFingerprint.kt +++ /dev/null @@ -1,25 +0,0 @@ -package app.revanced.patches.youtube.misc.litho.filter.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object ProtobufBufferFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.IGET_OBJECT, // References the field required below. - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - Opcode.IF_NEZ, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.CHECK_CAST, // Casts the referenced field to a specific type that stores the protobuf buffer. - Opcode.INVOKE_VIRTUAL - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ProtobufBufferReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ProtobufBufferReferenceFingerprint.kt new file mode 100644 index 000000000..aeecb9e2a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ProtobufBufferReferenceFingerprint.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.youtube.misc.litho.filter.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +object ProtobufBufferReferenceFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("I", "Ljava/nio/ByteBuffer;"), + opcodes = listOf( + Opcode.IPUT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.SUB_INT_2ADDR + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/patch/LithoFilterPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/patch/LithoFilterPatch.kt index 2b709072d..59848db09 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/patch/LithoFilterPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/patch/LithoFilterPatch.kt @@ -4,50 +4,110 @@ import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.litho.filter.fingerprints.* +import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction import org.jf.dexlib2.iface.instruction.Instruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction +import org.jf.dexlib2.immutable.ImmutableField import java.io.Closeable @DependsOn([IntegrationsPatch::class]) @Description("Hooks the method which parses the bytes into a ComponentContext to filter components.") @Version("0.0.1") class LithoFilterPatch : BytecodePatch( - listOf(ComponentContextParserFingerprint, LithoFilterFingerprint) + listOf(ComponentContextParserFingerprint, LithoFilterFingerprint, ProtobufBufferReferenceFingerprint) ), Closeable { + /** + * The following patch inserts a hook into the method that parses the bytes into a ComponentContext. + * This method contains a StringBuilder object that represents the pathBuilder of the component. + * The pathBuilder is used to filter components by their path. + * + * Additionally, the method contains a reference to the components identifier. + * The identifier is used to filter components by their identifier. + * + * In addition to that, a static field is added to the class of this method. (See protobufBufferField). + * This field holds a reference to the protobuf buffer object. + * The field is being set in another method that holds a reference to the protobuf buffer object. + * The object contains a large byte array that represents the component tree. + * This byte array is searched for strings that indicate the current component. + * + * The following pseudo code shows how the patch works: + * + * class ComponentContextParser { + * public static ByteBuffer buffer; // Inserted by this patch. + * + * public ComponentContext parseBytesToComponentContext(...) { + * ... + * if (filter(identifier, pathBuilder, buffer)); // Inserted by this patch. + * return emptyComponent; + * ... + * } + * } + * + * class SomeOtherClass { + * // Called before ComponentContextParser.parseBytesToComponentContext method. + * public void someOtherMethod(ByteBuffer byteBuffer) { + * ComponentContextParser.buffer = byteBuffer; // Inserted by this patch. + * ... + * } + * } + */ override fun execute(context: BytecodeContext): PatchResult { ComponentContextParserFingerprint.result?.also { arrayOf( EmptyComponentBuilderFingerprint, - ReadComponentIdentifierFingerprint, - ProtobufBufferFingerprint + ReadComponentIdentifierFingerprint ).forEach { fingerprint -> if (fingerprint.resolve(context, it.mutableMethod, it.mutableClass)) return@forEach return fingerprint.toErrorResult() } - }?.let { result -> + }?.let { bytesToComponentContextMethod -> + // region Add a static field that holds a reference to the protobuf buffer object. + val protobufBufferField = ImmutableField( + bytesToComponentContextMethod.mutableClass.type, + "buffer", + "Ljava/nio/ByteBuffer;", + AccessFlags.PUBLIC or AccessFlags.STATIC, + null, + null, + null + ).toMutable() + bytesToComponentContextMethod.mutableClass.staticFields.add(protobufBufferField) + + // Set the field with the reference to the protobuf buffer object. + ProtobufBufferReferenceFingerprint.result + ?.mutableMethod?.addInstruction(0, "sput-object p2, $protobufBufferField") + ?: return ProtobufBufferReferenceFingerprint.toErrorResult() + + // endregion + + // region Hook the method that parses bytes into a ComponentContext. + val builderMethodIndex = EmptyComponentBuilderFingerprint.patternScanEndIndex val emptyComponentFieldIndex = builderMethodIndex + 2 - result.mutableMethod.apply { - val insertHookIndex = result.scanResult.patternScanResult!!.endIndex + bytesToComponentContextMethod.mutableMethod.apply { + val insertHookIndex = bytesToComponentContextMethod.scanResult.patternScanResult!!.endIndex - // region Get free registers that this patch uses + // region Get free registers that this patch uses. // Registers are overwritten right after they are used in this patch, therefore free to clobber. val freeRegistersInstruction = getInstruction(insertHookIndex - 2) @@ -64,7 +124,7 @@ class LithoFilterPatch : BytecodePatch( // endregion - // region Get references that this patch needs + // region Get references that this patch needs. val builderMethodDescriptor = getInstruction(builderMethodIndex).descriptor val emptyComponentFieldDescriptor = getInstruction(emptyComponentFieldIndex).descriptor @@ -72,34 +132,18 @@ class LithoFilterPatch : BytecodePatch( val identifierRegister = getInstruction(ReadComponentIdentifierFingerprint.patternScanEndIndex).registerA - // Parameter that holds a ref to a type with a field that ref the protobuf buffer object. - val protobufParameterNumber = 3 - - // Get the field that stores an protobuf buffer required below. - val protobufBufferRefTypeRefFieldDescriptor = - getInstruction(ProtobufBufferFingerprint.patternScanStartIndex).descriptor - val protobufBufferRefTypeDescriptor = - getInstruction(ProtobufBufferFingerprint.patternScanEndIndex - 1).descriptor - val protobufBufferFieldDescriptor = "$protobufBufferRefTypeDescriptor->b:Ljava/nio/ByteBuffer;" - // endregion - // region Patch the method + // region Patch the method. // Insert the instructions that are responsible // to return an EmptyComponent instead of the original component if the filter method returns false. addInstructionsWithLabels( insertHookIndex, """ - # Get the protobuf buffer object. - - move-object/from16 v$free1, p$protobufParameterNumber - iget-object v$free1, v$free1, $protobufBufferRefTypeRefFieldDescriptor - check-cast v$free1, $protobufBufferRefTypeDescriptor - - # Register "free" now holds the protobuf buffer object + # Register "free1" holds the protobuf buffer object - iget-object v$free1, v$free1, $protobufBufferFieldDescriptor + sget-object v$free1, $protobufBufferField # Invoke the filter method. @@ -119,6 +163,8 @@ class LithoFilterPatch : BytecodePatch( ) // endregion } + + // endregion } ?: return ComponentContextParserFingerprint.toErrorResult() LithoFilterFingerprint.result?.mutableMethod?.apply { @@ -150,9 +196,6 @@ class LithoFilterPatch : BytecodePatch( private val MethodFingerprint.patternScanEndIndex get() = patternScanResult.endIndex - private val MethodFingerprint.patternScanStartIndex - get() = patternScanResult.startIndex - private val Instruction.descriptor get() = (this as ReferenceInstruction).reference.toString() diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/annotations/MicroGPatchCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/annotations/MicroGPatchCompatibility.kt index 352ed3746..30383fbf3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/annotations/MicroGPatchCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/annotations/MicroGPatchCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.microg.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class MicroGPatchCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt index 88bff32b0..782a7709c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.minimizedplayback.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class MinimizedPlaybackCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt index ca676e7a3..a184fe77d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt @@ -6,7 +6,7 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object MinimizedPlaybackSettingsFingerprint : MethodFingerprint( - returnType = "L", + returnType = "Ljava/lang/String;", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf(), opcodes = listOf( diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsParentFingerprint.kt index 59754a7fd..180547a2e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsParentFingerprint.kt @@ -8,7 +8,8 @@ import org.jf.dexlib2.AccessFlags * Class fingerprint for [MinimizedPlaybackSettingsFingerprint] */ object MinimizedPlaybackSettingsParentFingerprint : MethodFingerprint( - accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - parameters = listOf("Landroid/content/Context;", "Landroid/support/v4/media/session/MediaSessionCompat"), - strings = listOf("sessionToken must not be null") + accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, + returnType = "I", + parameters = listOf(), + strings = listOf("BiometricManager", "Failure in canAuthenticate(). FingerprintManager was null.") ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/annotation/PlayerControlsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/annotation/PlayerControlsCompatibility.kt index 296b6477b..311f48506 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/annotation/PlayerControlsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/annotation/PlayerControlsCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.playercontrols.annotation import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class PlayerControlsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/annotation/PlayerOverlaysHookCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/annotation/PlayerOverlaysHookCompatibility.kt index 89a6fa3d4..f65f81708 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/annotation/PlayerOverlaysHookCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/annotation/PlayerOverlaysHookCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.playeroverlay.annotation import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class PlayerOverlaysHookCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/annotation/PlayerTypeHookCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/annotation/PlayerTypeHookCompatibility.kt index dff4ca516..8630c376b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/annotation/PlayerTypeHookCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/annotation/PlayerTypeHookCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.playertype.annotation import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class PlayerTypeHookCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/annotations/CustomVideoBufferCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/annotations/CustomVideoBufferCompatibility.kt index 628499d60..d1c317def 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/annotations/CustomVideoBufferCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/annotations/CustomVideoBufferCompatibility.kt @@ -4,6 +4,6 @@ import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package // TODO: delete this -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class CustomVideoBufferCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/hdrbrightness/annotations/HDRBrightnessCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/video/hdrbrightness/annotations/HDRBrightnessCompatibility.kt index 29e7da076..85bb22dcf 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/hdrbrightness/annotations/HDRBrightnessCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/hdrbrightness/annotations/HDRBrightnessCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.video.hdrbrightness.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class HDRBrightnessCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/information/annotation/VideoInformationCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/video/information/annotation/VideoInformationCompatibility.kt index 2ff6163df..1b52f4df0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/information/annotation/VideoInformationCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/information/annotation/VideoInformationCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.video.information.annotation import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class VideoInformationCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/patch/OldQualityLayoutPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/patch/OldQualityLayoutPatch.kt deleted file mode 100644 index 7f9d1b77f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/patch/OldQualityLayoutPatch.kt +++ /dev/null @@ -1,44 +0,0 @@ -package app.revanced.patches.youtube.video.oldqualitylayout.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.video.oldqualitylayout.annotations.OldQualityLayoutCompatibility -import app.revanced.patches.youtube.video.oldqualitylayout.fingerprints.QualityMenuViewInflateFingerprint -import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction - -@Patch -@DependsOn([IntegrationsPatch::class, OldQualityLayoutResourcePatch::class]) -@Name("old-quality-layout") -@Description("Enables the original video quality flyout in the video player settings.") -@OldQualityLayoutCompatibility -@Version("0.0.1") -class OldQualityLayoutPatch : BytecodePatch(listOf(QualityMenuViewInflateFingerprint)) { - override fun execute(context: BytecodeContext): PatchResult { - val inflateFingerprintResult = QualityMenuViewInflateFingerprint.result!! - val method = inflateFingerprintResult.mutableMethod - val instructions = method.implementation!!.instructions - - // at this index the listener is added to the list view - val listenerInvokeRegister = instructions.size - 1 - 1 - - // get the register which stores the quality menu list view - val onItemClickViewRegister = (instructions[listenerInvokeRegister] as FiveRegisterInstruction).registerC - - // insert the integrations method - method.addInstruction( - listenerInvokeRegister, // insert the integrations instructions right before the listener - "invoke-static { v$onItemClickViewRegister }, Lapp/revanced/integrations/patches/playback/quality/OldQualityLayoutPatch;->showOldQualityMenu(Landroid/widget/ListView;)V" - ) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/patch/OldQualityLayoutResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/patch/OldQualityLayoutResourcePatch.kt deleted file mode 100644 index 965486ce5..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/patch/OldQualityLayoutResourcePatch.kt +++ /dev/null @@ -1,36 +0,0 @@ -package app.revanced.patches.youtube.video.oldqualitylayout.patch - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) -class OldQualityLayoutResourcePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.VIDEO.addPreferences( - SwitchPreference( - "revanced_show_old_video_menu", - StringResource("revanced_show_old_video_menu_title", "Use old video quality player menu"), - StringResource("revanced_show_old_video_menu_summary_on", "Old video quality menu is used"), - StringResource("revanced_show_old_video_menu_summary_off", "Old video quality menu is not used") - ) - ) - - videoQualityBottomSheetListFragmentTitle = - ResourceMappingPatch.resourceMappings.find { it.name == "video_quality_bottom_sheet_list_fragment_title" } - ?.id ?: return PatchResultError("Could not find resource") - - return PatchResultSuccess() - } - - internal companion object { - var videoQualityBottomSheetListFragmentTitle = -1L - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/quality/annotations/RememberVideoQualityCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/video/quality/annotations/RememberVideoQualityCompatibility.kt index 789e422eb..deb0185e9 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/quality/annotations/RememberVideoQualityCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/quality/annotations/RememberVideoQualityCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.video.quality.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class RememberVideoQualityCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/quality/fingerprints/NewVideoQualityChangedFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/quality/fingerprints/NewVideoQualityChangedFingerprint.kt new file mode 100644 index 000000000..f1dcf0a5b --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/video/quality/fingerprints/NewVideoQualityChangedFingerprint.kt @@ -0,0 +1,32 @@ +package app.revanced.patches.youtube.video.quality.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +object NewVideoQualityChangedFingerprint : MethodFingerprint( + returnType = "L", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L"), + opcodes = listOf( + Opcode.IGET, // Video resolution (human readable). + Opcode.IGET_OBJECT, + Opcode.IGET_BOOLEAN, + Opcode.IGET_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_DIRECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.GOTO, + Opcode.CONST_4, + Opcode.IF_NE, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IGET, + ) +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/quality/fingerprints/SetQualityByIndexMethodClassFieldReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/quality/fingerprints/SetQualityByIndexMethodClassFieldReferenceFingerprint.kt index d69bb8406..a4707a492 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/quality/fingerprints/SetQualityByIndexMethodClassFieldReferenceFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/quality/fingerprints/SetQualityByIndexMethodClassFieldReferenceFingerprint.kt @@ -3,6 +3,9 @@ package app.revanced.patches.youtube.video.quality.fingerprints import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import org.jf.dexlib2.Opcode +/** + * Resolves with the class found in [VideoQualitySetterFingerprint]. + */ object SetQualityByIndexMethodClassFieldReferenceFingerprint : MethodFingerprint( returnType = "V", parameters = listOf("L"), diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/quality/patch/RememberVideoQualityPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/quality/patch/RememberVideoQualityPatch.kt index 2877f39a1..43d32f8fe 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/quality/patch/RememberVideoQualityPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/quality/patch/RememberVideoQualityPatch.kt @@ -7,6 +7,7 @@ import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult @@ -22,10 +23,12 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.video.information.patch.VideoInformationPatch import app.revanced.patches.youtube.video.quality.annotations.RememberVideoQualityCompatibility +import app.revanced.patches.youtube.video.quality.fingerprints.NewVideoQualityChangedFingerprint import app.revanced.patches.youtube.video.quality.fingerprints.SetQualityByIndexMethodClassFieldReferenceFingerprint import app.revanced.patches.youtube.video.quality.fingerprints.VideoQualityItemOnClickParentFingerprint import app.revanced.patches.youtube.video.quality.fingerprints.VideoQualitySetterFingerprint import org.jf.dexlib2.iface.instruction.ReferenceInstruction +import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction import org.jf.dexlib2.iface.reference.FieldReference @Patch @@ -37,7 +40,8 @@ import org.jf.dexlib2.iface.reference.FieldReference class RememberVideoQualityPatch : BytecodePatch( listOf( VideoQualitySetterFingerprint, - VideoQualityItemOnClickParentFingerprint + VideoQualityItemOnClickParentFingerprint, + NewVideoQualityChangedFingerprint ) ) { override fun execute(context: BytecodeContext): PatchResult { @@ -113,6 +117,7 @@ class RememberVideoQualityPatch : BytecodePatch( VideoInformationPatch.onCreateHook(INTEGRATIONS_CLASS_DESCRIPTOR, "newVideoStarted") + // Inject a call to set the remembered quality once a video loads. VideoQualitySetterFingerprint.result?.also { if (!SetQualityByIndexMethodClassFieldReferenceFingerprint.resolve(context, it.classDef)) @@ -159,6 +164,7 @@ class RememberVideoQualityPatch : BytecodePatch( ) } ?: return VideoQualitySetterFingerprint.toErrorResult() + // Inject a call to remember the selected quality. VideoQualityItemOnClickParentFingerprint.result?.let { val onItemClickMethod = it.mutableClass.methods.find { method -> method.name == "onItemClick" } @@ -172,6 +178,22 @@ class RememberVideoQualityPatch : BytecodePatch( ) } ?: return PatchResultError("Failed to find onItemClick method") } ?: return VideoQualityItemOnClickParentFingerprint.toErrorResult() + + + // Remember video quality if not using old layout menu. + NewVideoQualityChangedFingerprint.result?.apply { + mutableMethod.apply { + val index = scanResult.patternScanResult!!.startIndex + val qualityRegister = getInstruction(index).registerA + + addInstruction( + index + 1, + "invoke-static {v$qualityRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->userChangedQualityInNewFlyout(I)V" + ) + } + } ?: return NewVideoQualityChangedFingerprint.toErrorResult() + + return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/VideoSpeed.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/VideoSpeed.kt index a079bd0f3..5c5cfff30 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/speed/VideoSpeed.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/VideoSpeed.kt @@ -19,9 +19,7 @@ import app.revanced.patches.youtube.video.speed.remember.patch.RememberPlaybackS @VideoSpeedCompatibility @Version("0.0.1") class VideoSpeed : BytecodePatch() { - override fun execute(context: BytecodeContext): PatchResult { return PatchResultSuccess() // All patches this patch depends on succeed. } - } diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/VideoSpeedCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/VideoSpeedCompatibility.kt index b97e92931..4072fa4db 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/speed/VideoSpeedCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/VideoSpeedCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.video.speed import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class VideoSpeedCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/GetOldVideoSpeedsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/GetOldVideoSpeedsFingerprint.kt new file mode 100644 index 000000000..233d1d09d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/GetOldVideoSpeedsFingerprint.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.youtube.video.speed.custom.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +object GetOldVideoSpeedsFingerprint : MethodFingerprint( + parameters = listOf("[L", "I"), + strings = listOf("menu_item_playback_speed") +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/ShowOldVideoSpeedMenuFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/ShowOldVideoSpeedMenuFingerprint.kt new file mode 100644 index 000000000..3844ab32d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/ShowOldVideoSpeedMenuFingerprint.kt @@ -0,0 +1,7 @@ +package app.revanced.patches.youtube.video.speed.custom.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +object ShowOldVideoSpeedMenuFingerprint : MethodFingerprint( + strings = listOf("PLAYBACK_RATE_MENU_BOTTOM_SHEET_FRAGMENT") +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/ShowOldVideoSpeedMenuIntegrationsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/ShowOldVideoSpeedMenuIntegrationsFingerprint.kt new file mode 100644 index 000000000..a672dff90 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/ShowOldVideoSpeedMenuIntegrationsFingerprint.kt @@ -0,0 +1,7 @@ +package app.revanced.patches.youtube.video.speed.custom.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +object ShowOldVideoSpeedMenuIntegrationsFingerprint : MethodFingerprint( + customFingerprint = { method, _ -> method.name == "showOldVideoSpeedMenu" } +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/VideoSpeedPatchFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/VideoSpeedPatchFingerprint.kt deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/patch/CustomVideoSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/patch/CustomVideoSpeedPatch.kt index 73d02788c..b166c819c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/patch/CustomVideoSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/patch/CustomVideoSpeedPatch.kt @@ -1,36 +1,46 @@ package app.revanced.patches.youtube.video.speed.custom.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.settings.preference.impl.InputType -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.TextPreference +import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable +import app.revanced.patches.shared.settings.preference.impl.* +import app.revanced.patches.youtube.misc.bottomsheet.hook.patch.BottomSheetHookPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch +import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.patches.youtube.video.speed.custom.fingerprints.SpeedArrayGeneratorFingerprint -import app.revanced.patches.youtube.video.speed.custom.fingerprints.SpeedLimiterFingerprint +import app.revanced.patches.youtube.video.speed.custom.fingerprints.* +import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.reference.FieldReference import org.jf.dexlib2.iface.reference.MethodReference +import org.jf.dexlib2.immutable.ImmutableField @Name("custom-video-speed") @Description("Adds custom video speed options.") -@DependsOn([IntegrationsPatch::class]) +@DependsOn([IntegrationsPatch::class, LithoFilterPatch::class, SettingsPatch::class, BottomSheetHookPatch::class]) @Version("0.0.1") class CustomVideoSpeedPatch : BytecodePatch( listOf( - SpeedArrayGeneratorFingerprint, SpeedLimiterFingerprint + SpeedArrayGeneratorFingerprint, + SpeedLimiterFingerprint, + GetOldVideoSpeedsFingerprint, + ShowOldVideoSpeedMenuIntegrationsFingerprint ) ) { @@ -45,7 +55,7 @@ class CustomVideoSpeedPatch : BytecodePatch( inputType = InputType.TEXT_MULTI_LINE, summary = StringResource( "revanced_custom_playback_speeds_summary", - "Add or change the video speeds available" + "Add or change the available playback speeds" ) ) ) @@ -71,7 +81,7 @@ class CustomVideoSpeedPatch : BytecodePatch( val arrayLengthConstDestination = (arrayLengthConst as OneRegisterInstruction).registerA - val videoSpeedsArrayType = "Lapp/revanced/integrations/patches/playback/speed/CustomVideoSpeedPatch;->customVideoSpeeds:[F" + val videoSpeedsArrayType = "$INTEGRATIONS_CLASS_DESCRIPTOR->customVideoSpeeds:[F" arrayGenMethod.addInstructions( arrayLengthConstIndex + 1, @@ -111,14 +121,72 @@ class CustomVideoSpeedPatch : BytecodePatch( // edit: alternatively this might work by overriding with fixed values such as 0.1x and 10x limiterMethod.replaceInstruction( limiterMinConstIndex, - "sget v$limiterMinConstDestination, Lapp/revanced/integrations/patches/playback/speed/CustomVideoSpeedPatch;->minVideoSpeed:F" + "sget v$limiterMinConstDestination, $INTEGRATIONS_CLASS_DESCRIPTOR->minVideoSpeed:F" ) limiterMethod.replaceInstruction( limiterMaxConstIndex, - "sget v$limiterMaxConstDestination, Lapp/revanced/integrations/patches/playback/speed/CustomVideoSpeedPatch;->maxVideoSpeed:F" + "sget v$limiterMaxConstDestination, $INTEGRATIONS_CLASS_DESCRIPTOR->maxVideoSpeed:F" ) + // region Force old video quality menu. + // This is necessary, because there is no known way of adding custom video speeds to the new menu. + + BottomSheetHookPatch.addHook(INTEGRATIONS_CLASS_DESCRIPTOR) + + // Required to check if the video speed menu is currently shown. + LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) + + GetOldVideoSpeedsFingerprint.result?.let { result -> + // Add a static INSTANCE field to the class. + // This is later used to call "showOldVideoSpeedMenu" on the instance. + val instanceField = ImmutableField( + result.classDef.type, + "INSTANCE", + result.classDef.type, + AccessFlags.PUBLIC or AccessFlags.STATIC, + null, + null, + null + ).toMutable() + + result.mutableClass.staticFields.add(instanceField) + // Set the INSTANCE field to the instance of the class. + // In order to prevent a conflict with another patch, add the instruction at index 1. + result.mutableMethod.addInstruction(1, "sput-object p0, $instanceField") + + // Get the "showOldVideoSpeedMenu" method. + // This is later called on the field INSTANCE. + val showOldVideoSpeedMenuMethod = ShowOldVideoSpeedMenuFingerprint.also { + if (!it.resolve(context, result.classDef)) + throw ShowOldVideoSpeedMenuFingerprint.toErrorResult() + }.result!!.method.toString() + + // Insert the call to the "showOldVideoSpeedMenu" method on the field INSTANCE. + ShowOldVideoSpeedMenuIntegrationsFingerprint.result?.mutableMethod?.apply { + addInstructionsWithLabels( + implementation!!.instructions.lastIndex, + """ + sget-object v0, $instanceField + if-nez v0, :not_null + return-void + :not_null + invoke-virtual { v0 }, $showOldVideoSpeedMenuMethod + """ + ) + } ?: return ShowOldVideoSpeedMenuIntegrationsFingerprint.toErrorResult() + } ?: return GetOldVideoSpeedsFingerprint.toErrorResult() + + // endregion + return PatchResultSuccess() } + private companion object { + private const val FILTER_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/patches/components/VideoSpeedMenuFilterPatch;" + + private const val INTEGRATIONS_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/patches/playback/speed/CustomVideoSpeedPatch;" + + } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/videoid/annotation/VideoIdCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/video/videoid/annotation/VideoIdCompatibility.kt index 660f7d8ad..a5fa69c6f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/videoid/annotation/VideoIdCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/videoid/annotation/VideoIdCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.youtube.video.videoid.annotation import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) internal annotation class VideoIdCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/annotations/OldVideoQualityMenuCompatibility.kt similarity index 58% rename from src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt rename to src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/annotations/OldVideoQualityMenuCompatibility.kt index 701f9974d..5fe280f94 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/annotations/OldVideoQualityMenuCompatibility.kt @@ -1,8 +1,8 @@ -package app.revanced.patches.youtube.video.oldqualitylayout.annotations +package app.revanced.patches.youtube.video.videoqualitymenu.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))]) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.20.39", "18.23.35"))]) @Target(AnnotationTarget.CLASS) -internal annotation class OldQualityLayoutCompatibility \ No newline at end of file +internal annotation class OldVideoQualityMenuCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/fingerprints/QualityMenuViewInflateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/fingerprints/VideoQualityMenuViewInflateFingerprint.kt similarity index 69% rename from src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/fingerprints/QualityMenuViewInflateFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/fingerprints/VideoQualityMenuViewInflateFingerprint.kt index e671f4c4e..4e2424a33 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/fingerprints/QualityMenuViewInflateFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/fingerprints/VideoQualityMenuViewInflateFingerprint.kt @@ -1,12 +1,12 @@ -package app.revanced.patches.youtube.video.oldqualitylayout.fingerprints +package app.revanced.patches.youtube.video.videoqualitymenu.fingerprints import app.revanced.patcher.extensions.or +import app.revanced.patches.youtube.video.videoqualitymenu.patch.OldVideoQualityMenuResourcePatch import app.revanced.util.patch.LiteralValueFingerprint -import app.revanced.patches.youtube.video.oldqualitylayout.patch.OldQualityLayoutResourcePatch import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode -object QualityMenuViewInflateFingerprint : LiteralValueFingerprint( +object VideoQualityMenuViewInflateFingerprint : LiteralValueFingerprint( accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("L", "L", "L"), returnType = "L", @@ -26,5 +26,5 @@ object QualityMenuViewInflateFingerprint : LiteralValueFingerprint( Opcode.MOVE_RESULT_OBJECT, Opcode.CHECK_CAST ), - literal = OldQualityLayoutResourcePatch.videoQualityBottomSheetListFragmentTitle + literal = OldVideoQualityMenuResourcePatch.videoQualityBottomSheetListFragmentTitle ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/patch/OldVideoQualityMenuPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/patch/OldVideoQualityMenuPatch.kt new file mode 100644 index 000000000..b304d1c36 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/patch/OldVideoQualityMenuPatch.kt @@ -0,0 +1,73 @@ +package app.revanced.patches.youtube.video.videoqualitymenu.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.youtube.misc.bottomsheet.hook.patch.BottomSheetHookPatch +import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch +import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch +import app.revanced.patches.youtube.video.videoqualitymenu.annotations.OldVideoQualityMenuCompatibility +import app.revanced.patches.youtube.video.videoqualitymenu.fingerprints.VideoQualityMenuViewInflateFingerprint +import org.jf.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch +@DependsOn([ + IntegrationsPatch::class, + OldVideoQualityMenuResourcePatch::class, + LithoFilterPatch::class, + BottomSheetHookPatch::class +]) +@Name("old-video-quality-menu") +@Description("Shows the old video quality with the advanced video quality options instead of the new one.") +@OldVideoQualityMenuCompatibility +@Version("0.0.1") +class OldVideoQualityMenuPatch : BytecodePatch( + listOf(VideoQualityMenuViewInflateFingerprint) +) { + override fun execute(context: BytecodeContext): PatchResult { + // region Patch for the old type of the video quality menu. + + VideoQualityMenuViewInflateFingerprint.result?.let { + it.mutableMethod.apply { + val checkCastIndex = it.scanResult.patternScanResult!!.endIndex + val listViewRegister = getInstruction(checkCastIndex).registerA + + addInstruction( + checkCastIndex + 1, + "invoke-static { v$listViewRegister }, " + + "$INTEGRATIONS_CLASS_DESCRIPTOR->" + + "showOldVideoQualityMenu(Landroid/widget/ListView;)V" + ) + } + } + + // endregion + + // region Patch for the new type of the video quality menu. + + BottomSheetHookPatch.addHook(INTEGRATIONS_CLASS_DESCRIPTOR) + + // Required to check if the video quality menu is currently shown in order to click on the "Advanced" item. + LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) + + // endregion + + return PatchResultSuccess() + } + + private companion object { + private const val FILTER_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/patches/components/VideoQualityMenuFilterPatch;" + + private const val INTEGRATIONS_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/patches/playback/quality/OldVideoQualityMenuPatch;" + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/patch/OldVideoQualityMenuResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/patch/OldVideoQualityMenuResourcePatch.kt new file mode 100644 index 000000000..52365b74b --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/patch/OldVideoQualityMenuResourcePatch.kt @@ -0,0 +1,42 @@ +package app.revanced.patches.youtube.video.videoqualitymenu.patch + +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultError +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch +import app.revanced.patches.shared.settings.preference.impl.StringResource +import app.revanced.patches.shared.settings.preference.impl.SwitchPreference +import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch + +@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) +class OldVideoQualityMenuResourcePatch : ResourcePatch { + override fun execute(context: ResourceContext): PatchResult { + SettingsPatch.PreferenceScreen.VIDEO.addPreferences( + SwitchPreference( + "revanced_show_old_video_quality_menu", + StringResource("revanced_show_old_video_quality_menu_title", "Show old video quality menu"), + StringResource("revanced_show_old_video_quality_menu_summary_on", "Old video quality menu is shown"), + StringResource("revanced_show_old_video_quality_menu_summary_off", "New video quality menu is hidden") + ) + ) + + fun findResource(name: String) = ResourceMappingPatch.resourceMappings.find { it.name == name }?.id + ?: throw PatchResultError("Could not find resource") + + // Used for the old type of the video quality menu. + videoQualityBottomSheetListFragmentTitle = findResource("video_quality_bottom_sheet_list_fragment_title") + + // Used for the new type of the video quality menu. + bottomSheetMargins = findResource("bottom_sheet_margins") + + return PatchResultSuccess() + } + + internal companion object { + var videoQualityBottomSheetListFragmentTitle = -1L + var bottomSheetMargins = -1L + } +} From 996e6134b84f9f6c61a68cb1db6c08ccd339dbc8 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 7 Jul 2023 23:06:05 +0000 Subject: [PATCH 10/12] chore(release): 2.182.0-dev.4 [skip ci] # [2.182.0-dev.4](https://github.com/revanced/revanced-patches/compare/v2.182.0-dev.3...v2.182.0-dev.4) (2023-07-07) ### Features * **youtube:** support version `18.23.35` ([#2461](https://github.com/revanced/revanced-patches/issues/2461)) ([34514b0](https://github.com/revanced/revanced-patches/commit/34514b04f1eb8810da7a79f24ce2d886f23fde96)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- patches.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56770e172..6fa582bc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [2.182.0-dev.4](https://github.com/revanced/revanced-patches/compare/v2.182.0-dev.3...v2.182.0-dev.4) (2023-07-07) + + +### Features + +* **youtube:** support version `18.23.35` ([#2461](https://github.com/revanced/revanced-patches/issues/2461)) ([d20fde1](https://github.com/revanced/revanced-patches/commit/d20fde1e57077fe9a943f9782b415d7a0249b083)) + # [2.182.0-dev.3](https://github.com/revanced/revanced-patches/compare/v2.182.0-dev.2...v2.182.0-dev.3) (2023-07-05) diff --git a/gradle.properties b/gradle.properties index 9f367c328..592c43cca 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 2.182.0-dev.3 +version = 2.182.0-dev.4 diff --git a/patches.json b/patches.json index 770e3ec91..002df2805 100644 --- a/patches.json +++ b/patches.json @@ -1 +1 @@ -[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"auto-claim-channel-points","description":"Automatically claim Channel Points.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-embedded-ads","description":"Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"bypass-certificate-checks","description":"Bypasses certificate checks which prevent YouTube Music from working on Android Auto.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"infinity://localhost\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"ml.docilealligator.infinityforreddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://www.ccrama.me\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"me.ccrama.redditslide","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"dbrady://relay\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"free.reddit.news","versions":[]},{"name":"reddit.news","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://baconreader.com/auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.onelouder.baconreader","versions":[]},{"name":"com.onelouder.baconreader.premium","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://rubenmayayo.com\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.rubenmayayo.reddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"redditisfun://auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.andrewshu.android.reddit","versions":[]},{"name":"com.andrewshu.android.redditdonation","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://redditsync/auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]},{"name":"com.laurencedawson.reddit_sync.pro","versions":[]},{"name":"com.laurencedawson.reddit_sync.dev","versions":[]}]},{"name":"change-package-name","description":"Changes the package name.","version":"0.0.1","excluded":true,"options":[{"key":"packageName","title":"Package name","description":"The name of the package to rename of the app.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"client-spoof","description":"Spoofs a patched client to allow playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-signature-verification"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":true,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-ads","description":"Disables ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["DisablePiracyDetectionPatch"],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-player-popup-panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-screenshot-popup","description":"Disables the popup that shows up when taking a screenshot.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"disable-shorts-on-startup","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-switching-emoji-to-sticker-in-message-input-field","description":"Disables switching from emoji to sticker search mode in message input field","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-typing-indicator","description":"Disables the indicator while typing a message","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-android-debugging","description":"Enables Android debugging capabilities.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"enable-debugging","description":"Adds debugging options.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"enable-on-demand","description":"Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.lite","versions":[]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"export-all-activities","description":"Makes all app activities exportable.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"external-downloads","description":"Adds support to download and save YouTube videos using an external app.","version":"0.0.1","excluded":false,"options":[],"dependencies":["external-downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Removes ads from Inshorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.nis.app","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["VerticalScrollPatch"],"compatiblePackages":[{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"hide-ads","description":"Removes ads from the Reddit.","version":"0.0.2","excluded":false,"options":[],"dependencies":["hide-subreddit-banner","hide-comment-ads"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-get-premium","HideAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"jp.pxv.android","versions":[]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-filter-bar","description":"Hides the filter bar in video feeds.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFilterBarResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-floating-microphone-button","description":"Hides the floating microphone button which appears in search.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFloatingMicrophoneButtonResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"hide-inbox-ads","description":"Hides ads in inbox.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"hide-info-cards","description":"Hides info cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-layout-components","description":"Hides general layout components.","version":"0.0.1","excluded":false,"options":[],"dependencies":["LithoFilterPatch","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-load-more-button","description":"Hides the button under videos that loads similar videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-load-more-button-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-buttons","description":"Adds the option to hide video player previous and next buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-overlay","description":"Hides the dark background overlay from the player when player controls are visible.","version":"0.0.2","excluded":false,"options":[],"dependencies":["HidePlayerOverlayResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-recommended-users","description":"Hides recommended users.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-seekbar","description":"Hides the seekbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","SeekbarColorBytecodePatch","SeekbarPreferencesPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-shorts-components","description":"Hides components from YouTube Shorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","LithoFilterPatch","HideShortsComponentsResourcePatch","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-timeline-ads","description":"Removes ads from the timeline.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.instagram.android","versions":["275.0.0.27.98"]}]},{"name":"hide-timestamp","description":"Hides timestamp in video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-video-action-buttons","description":"Adds the options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0","9.71.0-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the option to watch in VR from the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"navigation-buttons","description":"Adds options to hide or change navigation buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"old-quality-layout","description":"Enables the original video quality flyout in the video player settings.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","OldQualityLayoutResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-information","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-badge-tab","description":"Removes the badge tab from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-broadcasts-restriction","description":"Enables starting/stopping NetGuard via broadcasts.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"eu.faircode.netguard","versions":[]}]},{"name":"remove-debugging-detection","description":"Removes the USB and wireless debugging checks.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.scb.phone","versions":[]}]},{"name":"remove-device-restrictions","description":"Removes restrictions from using the app on any device.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.recorder","versions":[]}]},{"name":"remove-notification-badge","description":"Removes the red notification badge from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-player-controls-background","description":"Removes the background from the video player controls.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-screen-capture-restriction","description":"Removes the restriction of capturing audio from apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":["remove-screen-capture-restriction-resource-patch"],"compatiblePackages":[]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"sanitize-sharing-links","description":"Removes (tracking) query parameters from the URLs when sharing links.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","EnableSeekbarTappingResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sponsorblock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","video-information","player-type-hook","player-controls-bytecode-patch","sponsorblock-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"spoof-wifi-connection","description":"Spoofs an existing Wi-Fi connection.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":["litho-color-hook","SeekbarColorBytecodePatch","ThemeResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"unlock-paid-widgets","description":"Unlocks paid widgets of the app","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":[]}]},{"name":"unlock-plus","description":"Unlocks plus features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureDetectionPatch"],"compatiblePackages":[{"name":"com.microblink.photomath","versions":["8.20.0"]}]},{"name":"unlock-premium","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"io.yuka.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureVerificationPatch","LicenseValidationPatch"],"compatiblePackages":[{"name":"com.zombodroid.MemeGenerator","versions":["4.6364","4.6370","4.6375","4.6377"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.vsco.cam","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.wakdev.apps.nfctools.se","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-pro","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.candylink.openvpn","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"tv.trakt.trakt","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"vanced-microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button","client-spoof"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"vanced-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"video-speed","description":"Adds custom video speeds and ability to remember the playback speed you chose in the video playback speed flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["custom-video-speed","remember-playback-speed"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]}] \ No newline at end of file +[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"auto-claim-channel-points","description":"Automatically claim Channel Points.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-embedded-ads","description":"Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"bypass-certificate-checks","description":"Bypasses certificate checks which prevent YouTube Music from working on Android Auto.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"dbrady://relay\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"free.reddit.news","versions":[]},{"name":"reddit.news","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://rubenmayayo.com\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.rubenmayayo.reddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"redditisfun://auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.andrewshu.android.reddit","versions":[]},{"name":"com.andrewshu.android.redditdonation","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://baconreader.com/auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.onelouder.baconreader","versions":[]},{"name":"com.onelouder.baconreader.premium","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://www.ccrama.me\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"me.ccrama.redditslide","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"infinity://localhost\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"ml.docilealligator.infinityforreddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID. The OAuth application type has to be \"Installed app\" and the redirect URI has to be set to \"http://redditsync/auth\".","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]},{"name":"com.laurencedawson.reddit_sync.pro","versions":[]},{"name":"com.laurencedawson.reddit_sync.dev","versions":[]}]},{"name":"change-package-name","description":"Changes the package name.","version":"0.0.1","excluded":true,"options":[{"key":"packageName","title":"Package name","description":"The name of the package to rename of the app.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"client-spoof","description":"Spoofs a patched client to allow playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-signature-verification"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":true,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-ads","description":"Disables ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["DisablePiracyDetectionPatch"],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-player-popup-panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"disable-screenshot-popup","description":"Disables the popup that shows up when taking a screenshot.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"disable-shorts-on-startup","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"disable-switching-emoji-to-sticker-in-message-input-field","description":"Disables switching from emoji to sticker search mode in message input field","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-typing-indicator","description":"Disables the indicator while typing a message","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-android-debugging","description":"Enables Android debugging capabilities.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"enable-debugging","description":"Adds debugging options.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"enable-on-demand","description":"Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.lite","versions":[]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"export-all-activities","description":"Makes all app activities exportable.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"external-downloads","description":"Adds support to download and save YouTube videos using an external app.","version":"0.0.1","excluded":false,"options":[],"dependencies":["external-downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-ads","description":"Removes ads from Inshorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.nis.app","versions":[]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"jp.pxv.android","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["VerticalScrollPatch"],"compatiblePackages":[{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-get-premium","HideAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-ads","description":"Removes ads from the Reddit.","version":"0.0.2","excluded":false,"options":[],"dependencies":["hide-subreddit-banner","hide-comment-ads"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-filter-bar","description":"Hides the filter bar in video feeds.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFilterBarResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-floating-microphone-button","description":"Hides the floating microphone button which appears in search.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFloatingMicrophoneButtonResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"hide-inbox-ads","description":"Hides ads in inbox.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"hide-info-cards","description":"Hides info cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-layout-components","description":"Hides general layout components.","version":"0.0.1","excluded":false,"options":[],"dependencies":["LithoFilterPatch","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-load-more-button","description":"Hides the button under videos that loads similar videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-load-more-button-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-player-buttons","description":"Adds the option to hide video player previous and next buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-player-overlay","description":"Hides the dark background overlay from the player when player controls are visible.","version":"0.0.2","excluded":false,"options":[],"dependencies":["HidePlayerOverlayResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-recommended-users","description":"Hides recommended users.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-seekbar","description":"Hides the seekbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","SeekbarColorBytecodePatch","SeekbarPreferencesPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-shorts-components","description":"Hides components from YouTube Shorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","LithoFilterPatch","HideShortsComponentsResourcePatch","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-timeline-ads","description":"Removes ads from the timeline.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.instagram.android","versions":["275.0.0.27.98"]}]},{"name":"hide-timestamp","description":"Hides timestamp in video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-video-action-buttons","description":"Adds the options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0","9.71.0-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the option to watch in VR from the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"navigation-buttons","description":"Adds options to hide or change navigation buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"old-video-quality-menu","description":"Shows the old video quality with the advanced video quality options instead of the new one.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","OldVideoQualityMenuResourcePatch","LithoFilterPatch","BottomSheetHookPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.20.39","18.23.35"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-information","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.19.35","18.20.39","18.23.35"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-badge-tab","description":"Removes the badge tab from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-broadcasts-restriction","description":"Enables starting/stopping NetGuard via broadcasts.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"eu.faircode.netguard","versions":[]}]},{"name":"remove-debugging-detection","description":"Removes the USB and wireless debugging checks.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.scb.phone","versions":[]}]},{"name":"remove-device-restrictions","description":"Removes restrictions from using the app on any device.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.recorder","versions":[]}]},{"name":"remove-notification-badge","description":"Removes the red notification badge from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-player-controls-background","description":"Removes the background from the video player controls.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"remove-screen-capture-restriction","description":"Removes the restriction of capturing audio from apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":["remove-screen-capture-restriction-resource-patch"],"compatiblePackages":[]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"sanitize-sharing-links","description":"Removes (tracking) query parameters from the URLs when sharing links.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","EnableSeekbarTappingResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sponsorblock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","video-information","player-type-hook","player-controls-bytecode-patch","sponsorblock-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"spoof-wifi-connection","description":"Spoofs an existing Wi-Fi connection.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":["litho-color-hook","SeekbarColorBytecodePatch","ThemeResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"unlock-paid-widgets","description":"Unlocks paid widgets of the app","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":[]}]},{"name":"unlock-plus","description":"Unlocks plus features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureDetectionPatch"],"compatiblePackages":[{"name":"com.microblink.photomath","versions":["8.20.0"]}]},{"name":"unlock-premium","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"io.yuka.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.candylink.openvpn","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.wakdev.apps.nfctools.se","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"tv.trakt.trakt","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureVerificationPatch","LicenseValidationPatch"],"compatiblePackages":[{"name":"com.zombodroid.MemeGenerator","versions":["4.6364","4.6370","4.6375","4.6377"]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.vsco.cam","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"vanced-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"vanced-microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button","client-spoof"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]},{"name":"video-speed","description":"Adds custom video speeds and ability to remember the playback speed you chose in the video playback speed flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["custom-video-speed","remember-playback-speed"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.20.39","18.23.35"]}]},{"name":"wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35"]}]}] \ No newline at end of file From 4af3c462e30483bf0ca6d9939f66e8cf9410595e Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 8 Jul 2023 04:27:45 +0200 Subject: [PATCH 11/12] fix(youtube/hide-layout-components): hide mix playlists --- .../ConvertElementToFlatBufferFingerprint.kt | 9 ++++ .../patch/HideLayoutComponentsPatch.kt | 45 +++++++++++++++++-- 2 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/fingerprints/ConvertElementToFlatBufferFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/fingerprints/ConvertElementToFlatBufferFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/fingerprints/ConvertElementToFlatBufferFingerprint.kt new file mode 100644 index 000000000..a9ada6da1 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/fingerprints/ConvertElementToFlatBufferFingerprint.kt @@ -0,0 +1,9 @@ +package app.revanced.patches.youtube.layout.hide.general.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.Opcode + +object ConvertElementToFlatBufferFingerprint : MethodFingerprint( + strings = listOf("Failed to convert Element to Flatbuffers: %s"), + opcodes = listOf(Opcode.IGET_OBJECT) // Patched at this opcodes index +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/patch/HideLayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/patch/HideLayoutComponentsPatch.kt index 203d22ca5..00a0fd817 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/patch/HideLayoutComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/patch/HideLayoutComponentsPatch.kt @@ -1,18 +1,24 @@ package app.revanced.patches.youtube.layout.hide.general.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.TextPreference import app.revanced.patches.youtube.layout.hide.general.annotations.HideLayoutComponentsCompatibility +import app.revanced.patches.youtube.layout.hide.general.fingerprints.ConvertElementToFlatBufferFingerprint import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.PreferenceScreen @@ -23,8 +29,10 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.P @DependsOn([LithoFilterPatch::class, SettingsPatch::class]) @HideLayoutComponentsCompatibility @Version("0.0.1") -class HideLayoutComponentsPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { +class HideLayoutComponentsPatch : BytecodePatch( + listOf(ConvertElementToFlatBufferFingerprint) +) { + override fun execute(context: BytecodeContext): PatchResult { PreferenceScreen.LAYOUT.addPreferences( SwitchPreference( "revanced_hide_gray_separator", @@ -237,6 +245,35 @@ class HideLayoutComponentsPatch : ResourcePatch { LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) + // region Mix playlists + + ConvertElementToFlatBufferFingerprint.result?.let { + val returnEmptyComponentIndex = it.scanResult.stringsScanResult!!.matches.first().index + 2 + + it.mutableMethod.apply { + // The last virtual register (not parameter). Used to store the byte array + // that may contain information about a mix playlist. + val freeRegister = (implementation!!.registerCount - 1) - parameterTypes.size - 1 + + // Check if the byte array contains anything about a mix playlist. + addInstructionsWithLabels( + it.scanResult.patternScanResult!!.startIndex, + """ + invoke-static {v$freeRegister}, $FILTER_CLASS_DESCRIPTOR->filterMixPlaylists([B)Z + move-result v$freeRegister + if-nez v$freeRegister, :return_empty_component + """, + ExternalLabel("return_empty_component", getInstruction(returnEmptyComponentIndex)) + ) + + // Move the byte array to a free register. + addInstruction(0, "move-object/from16 v$freeRegister, p3") + } + + } ?: return ConvertElementToFlatBufferFingerprint.toErrorResult() + + // endregion + return PatchResultSuccess() } From 438cd972785206f6576db5d74adc1375465afeff Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 8 Jul 2023 02:32:31 +0000 Subject: [PATCH 12/12] chore(release): 2.182.0-dev.5 [skip ci] # [2.182.0-dev.5](https://github.com/revanced/revanced-patches/compare/v2.182.0-dev.4...v2.182.0-dev.5) (2023-07-08) ### Bug Fixes * **youtube/hide-layout-components:** hide mix playlists ([4af3c46](https://github.com/revanced/revanced-patches/commit/4af3c462e30483bf0ca6d9939f66e8cf9410595e)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fa582bc3..1ff5dc7d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [2.182.0-dev.5](https://github.com/revanced/revanced-patches/compare/v2.182.0-dev.4...v2.182.0-dev.5) (2023-07-08) + + +### Bug Fixes + +* **youtube/hide-layout-components:** hide mix playlists ([33a87bd](https://github.com/revanced/revanced-patches/commit/33a87bd6eac1639687ebdf96ef8924cd674f81e4)) + # [2.182.0-dev.4](https://github.com/revanced/revanced-patches/compare/v2.182.0-dev.3...v2.182.0-dev.4) (2023-07-07) diff --git a/gradle.properties b/gradle.properties index 592c43cca..ccad32ee8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 2.182.0-dev.4 +version = 2.182.0-dev.5