Repository: SpotX-Official/SpotX
Branch: main
Commit: 691e24fa2ecf
Files: 55
Total size: 364.4 KB
Directory structure:
gitextract_c7vys6wk/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ ├── config.yml
│ │ ├── installer-new-translation.yml
│ │ └── itranslation-fix.yml
│ └── workflows/
│ ├── auto-closes-false-positive.yml
│ ├── check_spotx.yml
│ └── update-license.yml
├── Install_New_theme.bat
├── Install_Old_theme.bat
├── LICENSE
├── README.md
├── Uninstall.bat
├── css-helper/
│ └── lyrics-color/
│ ├── colors.css
│ └── rules.css
├── js-helper/
│ ├── goofyHistory.js
│ └── sectionBlock.js
├── patches/
│ ├── Augmented translation/
│ │ └── ru.json
│ └── patches.json
├── res/
│ └── login.spa
├── run.ps1
└── scripts/
├── Install_Auto.bat
├── Install_Prem.bat
└── installer-lang/
├── be.ps1
├── bn.ps1
├── cs.ps1
├── de.ps1
├── el.ps1
├── en.ps1
├── es.ps1
├── fa.ps1
├── fi.ps1
├── fil.ps1
├── fr.ps1
├── hi.ps1
├── hu.ps1
├── id.ps1
├── it.ps1
├── ja.ps1
├── ka.ps1
├── ko.ps1
├── lv.ps1
├── pl.ps1
├── pt.ps1
├── ro.ps1
├── ru.ps1
├── sk.ps1
├── sr-Latn.ps1
├── sr.ps1
├── sv.ps1
├── ta.ps1
├── tr.ps1
├── ua.ps1
├── vi.ps1
├── zh-TW.ps1
└── zh.ps1
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: ❌ Bug report
description: Report errors or unexpected behavior
labels: ❌ bug
body:
- type: checkboxes
attributes:
label: 🧐 Have you read the FAQ and viewed similar issues?
description: ❗️❗️ Important: Please review the FAQ and check both open and closed issue, as your concern may have already been addressed. However, please be aware that if it's discovered that requested actions weren't completed, the issue may be closed without explanation.
options:
- label: I have read the FAQ
required: true
- label: I have checked older issues, open and closed
required: true
- label: I did a clean install of SpotX as described in the FAQ
required: true
- type: markdown
attributes:
value: "###"
- type: input
id: lang_spoti
attributes:
label: Сountry of your account
description: You can view your country on your account page, in paragraph Country or region.
placeholder: "e.g. Ukraine"
validations:
required: true
- type: markdown
attributes:
value: "###"
- type: dropdown
id: plan
attributes:
label: What is your Spotify Plan?
description: You can view your plan on your account page, under Your plan.
options:
- Free
- Premium
validations:
required: true
- type: markdown
attributes:
value: "###"
- type: dropdown
id: spicetify
attributes:
label: Do you have Spicetify installed?
description: Spicetify is a command line tool to customize Spotify client.
options:
- "No"
- "Yes"
validations:
required: true
- type: markdown
attributes:
value: "###"
- type: textarea
attributes:
label: ℹ Computer information
description: |
- Spotify: e.g. 1.1.90.859.gf1bb1e36 (Avoid labeling version as "latest" due to regional update variations in Spotify)
- In the open Spotify client in the upper left corner, click ••• → Help → About Spotify
- Windows: e.g. Windows 11 21H2 22000.527
- Press Win + Pause/Break to open the page to copy from.
- PowerShell: e.g. 5.1.19041.1200
- Press Win + R then type "powershell," and press Enter, type the following command Get-Host | Select-Object Version
placeholder: |
- Spotify:
- Windows:
- PowerShell:
value: |
- Spotify:
- Windows:
- PowerShell:
render: markdown
validations:
required: true
- type: textarea
attributes:
label: 📝 Description
description: List steps to reproduce the error and details on what happens and what you expected to happen.
value: |
1.
2.
3.
...
validations:
required: true
- type: textarea
attributes:
label: 📸 Screenshots
description: Place any screenshots of the issue here if needed
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: ✏️ FAQ
url: https://telegra.ph/SpotX-FAQ-09-19
about: Read the frequently asked questions, maybe it will help solve your problem right now.
================================================
FILE: .github/ISSUE_TEMPLATE/installer-new-translation.yml
================================================
name: 🌐 Installer translation
description: Translate the installer into your language
labels: 🌐 New translation
body:
- type: input
id: lang
attributes:
label: What language do you want to translate into?
description: Also note the already added languages
placeholder: e.g. English
validations:
required: true
- type: input
id: langpowershell
attributes:
label: Enter language name in PowerShell
description: Enter the following command in the PowerShell terminal $PSUICulture, write the answer in the line below. For this to work, your Windows must be in this language.
placeholder: e.g. en-US
validations:
required: true
- type: textarea
attributes:
label: 📝 Translation strings
description: |
Now you can start translating strings, a few notes before you start:
- Translation strings start after an equals sign and are enclosed in quotation marks
- There are variables before the equal sign, they do not need to be translated.
- Also, if you come across characters {0}, {1}, [Y/N] or file names, then just skip them.
Good luck to you.
value: |
Welcome = "
╔══════════════════════════════╗
║ Welcome to SpotX for Windows ║
╚══════════════════════════════╝"
Incorrect = "Oops, an incorrect value,"
Incorrect2 = "enter again through "
Download = "Error downloading"
Download2 = "Will re-request in 5 seconds..."
Download3 = "Error again"
Download4 = "Check your network settings and run the installation again"
Download5 = "Downloading Spotify"
StopScript = "Script is stopped"
MsSpoti = "The Microsoft Store version of Spotify has been detected which is not supported"
MsSpoti2 = "Uninstall Spotify Microsoft Store edition ? [Y/N]"
MsSpoti3 = "Automatically uninstalling Spotify MS..."
MsSpoti4 = "Uninstalling Spotify MS..."
Prem = "Modification for premium account..."
OldV = "Found outdated version of Spotify"
OldV2 = "Your Spotify version ({0}) is outdated, the current latest version is — {1}"
OldV3 = "Want to update ? [Y/N]"
AutoUpd = "Automatic update to the recommended version"
DelOrOver = "Remove the current version ({0}) or install over it? Y [Remove] / N [Install Over]"
DelOld = "Uninstalling old Spotify..."
NewV = "Unsupported version of Spotify found"
NewV2 = "Your Spotify version ({0}) has not been tested. The stable version for SpotX is {1}"
NewV3 = "Continue with {0} (errors may occur) ? [Y/N]"
Recom = "Install the latest version {0} ? [Y/N]"
DelNew = "Uninstalling an untested Spotify..."
DownSpoti = "Downloading and installing Spotify"
DownSpoti2 = "Please wait..."
PodcatsOff = "Off Podcasts"
PodcastsOn = "On Podcasts"
PodcatsSelect = "Hide podcasts, shows, and audiobooks on the homepage ? [Y/N]"
DowngradeNote = "It is recommended to block because there is already a newer version of Spotify"
UpdBlock = "Spotify updates blocked"
UpdUnblock = "Spotify updates are not blocked"
UpdSelect = "Block Spotify updates ? [Y/N]"
ModSpoti = "Patching Spotify..."
Error = "Error"
FileLocBroken = "Location of Spotify files is broken, uninstall Spotify client and run the script again"
Spicetify = "Spicetify detected, it must be installed after SpotX, open recommended actions in FAQ ? [Y/N]"
NoRestore = "SpotX has already been installed, xpui.bak not found. `nPlease uninstall Spotify client and run Install.bat again"
InstallComplete = "installation completed"
HostInfo = "Unwanted URLs found in hosts file"
HostBak = "Backing up hosts.bak..."
HostDel = "Trying to remove unwanted URLs from the original hosts file..."
HostError = "Something went wrong while editing the hosts file, edit it manually or run the script as administrator"
render: txt
validations:
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/itranslation-fix.yml
================================================
name: "🌐 Localization/Translation issue"
description: Report incorrect translations.
labels: 🌐 Fix translation
body:
- type: textarea
attributes:
label: ❌ Actual phrase(s)
placeholder: What is there? Please include a screenshot as that is extremely helpful.
validations:
required: true
- type: textarea
attributes:
label: ✔️ Expected phrase(s)
placeholder: What was expected?
validations:
required: true
- type: textarea
attributes:
label: ℹ Why is the current translation wrong
placeholder: Why do you feel this is incorrect?
validations:
required: true
================================================
FILE: .github/workflows/auto-closes-false-positive.yml
================================================
name: Auto Close Antivirus False Positive Issues
on:
issues:
types: [opened, reopened, edited]
jobs:
auto-close:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Check for AV-related keywords
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const title = issue.title.toLowerCase();
const actor = context.payload.sender.login;
// Проверяем, кто выполнил действие (не создателя issue, а того кто сейчас действует)
const privilegedUsers = ['amd64fox'];
if (privilegedUsers.includes(actor)) {
console.log('Issue #' + issue.number + ' action performed by @' + actor + ' - will not auto-close');
return;
}
const keywords = [
'av',
'virus',
'malware',
'trojan',
'defender',
'smartscreen',
'antivirus',
'anti-virus',
'anti virus',
'malicious',
'agenttesla',
'virustotal',
'eset',
'avast',
'avg',
'kaspersky',
'norton',
'mcafee',
'bitdefender'
];
const containsKeyword = keywords.some(keyword => {
const regex = new RegExp('\\b' + keyword + '\\b', 'i');
return regex.test(title);
});
if (containsKeyword) {
console.log('Issue #' + issue.number + ' contains AV-related keywords in title');
const comment = '# ⚠️ Automatic Closure: Antivirus False Positive\n\n' +
'> [!NOTE]\n' +
'> This issue has been automatically closed because it appears to be related to an **antivirus false positive detection**.\n\n' +
'---\n\n' +
'## 🔍 What causes false positives?\n\n' +
'Different antiviruses may respond differently to installing **SpotX**, as SpotX uses a system interpreter **PowerShell** to modify an application **Spotify**.\n\n' +
'Also, most AV use **heuristic analysis**, which looks for threats based on assumptions or by matching its own set of rules. This imperfect method also leads to a high number of false positives.\n\n' +
'---\n\n' +
'## ✅ What should you do?\n\n' +
'### Step 1: Disable Your Antivirus\n' +
'> [!IMPORTANT]\n' +
'> Before running the SpotX patcher, **temporarily disable or pause your antivirus protection**.\n\n' +
'> [!WARNING]\n' +
'> **Signs you need to disable your antivirus:**\n' +
'> - The terminal window is forcibly closed\n' +
'> - Errors flagging the script as malicious\n' +
'> - The bat installation file is deleted\n\n' +
'### Step 2: Run the Installation\n' +
'Once your antivirus is disabled, proceed with the SpotX installation.\n\n' +
'### Step 3: Re-enable Protection\n' +
'After the installation is complete, you can turn your antivirus back on. If your AV then marks some files in the Spotify folder, **add them to the exclusion list** of your antivirus.\n\n' +
'> [!TIP]\n' +
'> We do not provide instructions on how to disable AV protection or add files/folders to exclusions, as there are many different security systems and the process varies for each. The easiest solution if you don\'t know how to do this is to use [Google](https://www.google.com).\n\n' +
'---\n\n' +
'
\n\n' +
'**🤖 This issue was automatically closed by a bot.**\n\n' +
'If you believe your issue isn\'t related to a false positive, please mention **@amd64fox**\n\n' +
'
';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: comment
});
const existingLabels = issue.labels.map(label => label.name);
if (existingLabels.length > 0) {
for (const label of existingLabels) {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
name: label
});
}
}
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: ['❎ false positive']
});
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
state: 'closed',
state_reason: 'not_planned'
});
console.log('Issue #' + issue.number + ' was automatically closed');
} else {
console.log('Issue #' + issue.number + ' does not contain AV-related keywords in title');
}
================================================
FILE: .github/workflows/check_spotx.yml
================================================
name: Check Spotx for the latest Spotify
on:
workflow_dispatch:
jobs:
build:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Spotx
shell: powershell
run: |
$jsonUrl = "https://raw.githubusercontent.com/amd64fox/LoaderSpot/main/versions.json"
$resp = Invoke-RestMethod -Uri $jsonUrl
# Get a link to the x86 installer for the first version
$firstVersion = $resp.PSObject.Properties.Name | Select-Object -First 1
$x64InstallerUrl = $resp.$firstVersion.links.win.x64
# Regex to find the desired part of the link
$regex = [regex]::Match($x64InstallerUrl, "spotify_installer-(.+?)\.exe")
$version = $regex.Groups[1].Value
# Incoming parameters
$parametrs = '-Verbose -new_theme -v $version -sp-over -cache_limit 1000 -block_update_on -lyrics_stat spotify -urlform_goofy "https://docs.google.com/forms/formResponse" -idbox_goofy "9999999" -podcasts_off -adsections_off -lyrics_block'
# Run Spotx
iex "& { $(iwr -useb 'https://raw.githubusercontent.com/SpotX-Official/SpotX/refs/heads/main/run.ps1') } $parametrs"
================================================
FILE: .github/workflows/update-license.yml
================================================
name: Update License Year
on:
schedule:
- cron: '0 0 1 1 *'
workflow_dispatch:
permissions:
contents: write
jobs:
update-license:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Update year in LICENSE
run: |
CURRENT_YEAR=$(date +'%Y')
sed -i -E "s/Copyright \(c\) ([0-9]{4})(-[0-9]{4})?/Copyright (c) \1-$CURRENT_YEAR/" LICENSE
- name: Commit and push changes
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add LICENSE
if git diff --staged --quiet; then
echo "No changes needed"
else
git commit -m "chore: update license year to $(date +'%Y')"
git push
fi
================================================
FILE: Install_New_theme.bat
================================================
@echo off
:: Line for changing spotx parameters, each parameter should be separated by a space
set param=-new_theme
set url='https://raw.githubusercontent.com/SpotX-Official/SpotX/refs/heads/main/run.ps1'
set url2='https://spotx-official.github.io/SpotX/run.ps1'
set tls=[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12;
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe ^
-Command %tls% $p='%param%'; """ & { $(try { iwr -useb %url% } catch { $p+= ' -m'; iwr -useb %url2% })} $p """" | iex
pause
exit /b
================================================
FILE: Install_Old_theme.bat
================================================
@echo off
:: Line for changing spotx parameters, each parameter should be separated by a space
set param=-v 1.2.13.661.ga588f749 -confirm_spoti_recomended_over -block_update_on
set url='https://raw.githubusercontent.com/SpotX-Official/SpotX/refs/heads/main/run.ps1'
set url2='https://spotx-official.github.io/SpotX/run.ps1'
set tls=[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12;
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe ^
-Command %tls% $p='%param%'; """ & { $(try { iwr -useb %url% } catch { $p+= ' -m'; iwr -useb %url2% })} $p """" | iex
pause
exit /b
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2021-2026 amd64fox
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
- **OS:** Windows 7-11
- **Spotify:** [Official desktop version](https://loadspot.pages.dev) (Microsoft Store version is not suitable)
- **PowerShell:** 5.1 and above
Features
- **Blocks all banner, video, and audio ads** in the client
- **Hiding podcasts, episodes, and audiobooks** from the homepage (optional)
- **Block Spotify automatic updates** (optional)
- **Some native experimental features have been changed**
- **Analytics sending has been disabled**
- **Advanced installation [parameters](https://github.com/SpotX-Official/SpotX/discussions/60)**
Installation / Update
Choose installation type:
Usual installation (New theme)
#### During installation, you need to confirm some actions, also contains:
- New theme activated (new right and left sidebar, some cover change)
- All [experimental features](https://github.com/SpotX-Official/SpotX/discussions/50) included
#### Just download and run [Install_New_theme.bat](https://raw.githack.com/amd64fox/SpotX/main/Install_New_theme.bat)
or
#### Run The following command in PowerShell:
```ps1
iex "& { $(iwr -useb 'https://raw.githubusercontent.com/SpotX-Official/SpotX/refs/heads/main/run.ps1') } -new_theme"
```
#### mirror
```ps1
iex "& { $(iwr -useb 'https://spotx-official.github.io/SpotX/run.ps1') } -m -new_theme"
```
Usual installation (Old theme)
#### During installation, you need to confirm some actions, also contains:
- Forced installation of version 1.2.13 (since the old theme was removed in subsequent versions)
- Old theme activated
- Automatic blocking of Spotify updates
- All [experimental features](https://github.com/SpotX-Official/SpotX/discussions/50) included
#### Just download and run [Install_Old_theme.bat](https://raw.githack.com/amd64fox/SpotX/main/Install_Old_theme.bat)
or
#### Run The following command in PowerShell:
```ps1
iex "& { $(iwr -useb 'https://raw.githubusercontent.com/SpotX-Official/SpotX/refs/heads/main/run.ps1') } -v 1.2.13.661.ga588f749 -confirm_spoti_recomended_over -block_update_on"
```
#### mirror
```ps1
iex "& { $(iwr -useb 'https://spotx-official.github.io/SpotX/run.ps1') } -m -v 1.2.13.661.ga588f749 -confirm_spoti_recomended_over -block_update_on"
```
Full installation
Full installation without confirmation, what does it do?
- New theme activated (new right and left sidebar, some cover change)
- Hiding podcasts/episodes/audiobooks from the homepage
- Activated [static theme](https://github.com/SpotX-Official/SpotX/discussions/50#discussioncomment-4096066) spotify for lyrics
- Hiding [ad-like sections](https://github.com/SpotX-Official/SpotX/discussions/50#discussioncomment-4478943)
- All [experimental features](https://github.com/SpotX-Official/SpotX/discussions/50) included
- Removal of Spotify MS if it was found
- Installation of the recommended version of Spotify (if another client has already been found, it will be installed over)
- Blocking of Spotify updates
- After the installation is completed, the client will autorun.
#### Just download and run [Install_Auto.bat](https://raw.githack.com/amd64fox/SpotX/main/scripts/Install_Auto.bat)
or
#### Run The following command in PowerShell:
```ps1
iex "& { $(iwr -useb 'https://raw.githubusercontent.com/SpotX-Official/SpotX/refs/heads/main/run.ps1') } -confirm_uninstall_ms_spoti -confirm_spoti_recomended_over -podcasts_off -block_update_on -start_spoti -new_theme -adsections_off -lyrics_stat spotify"
```
#### mirror
```ps1
iex "& { $(iwr -useb 'https://spotx-official.github.io/SpotX/run.ps1') } -m -confirm_uninstall_ms_spoti -confirm_spoti_recomended_over -podcasts_off -block_update_on -start_spoti -new_theme -adsections_off -lyrics_stat spotify"
```
Other types of installations
Installation for premium
#### Usual installation only without ad blocking, for those who have a premium account, also contains:
- New theme activated (new right and left sidebar, some cover change)
- Disabled only audio ads in podcasts
- All [experimental features](https://github.com/SpotX-Official/SpotX/discussions/50) included
#### Just download and run [Install_Prem.bat](https://raw.githack.com/amd64fox/SpotX/main/scripts/Install_Prem.bat)
or
#### Run The following command in PowerShell:
```ps1
iex "& { $(iwr -useb 'https://raw.githubusercontent.com/SpotX-Official/SpotX/refs/heads/main/run.ps1') } -premium -new_theme"
```
#### mirror
```ps1
iex "& { $(iwr -useb 'https://spotx-official.github.io/SpotX/run.ps1') } -m -premium -new_theme"
```
Installing with parameters
You can specify various parameters for a more flexible installation, more [details here](https://github.com/SpotX-Official/SpotX/discussions/60)
Uninstall
- Just run [Uninstall.bat](https://raw.githack.com/amd64fox/SpotX/main/Uninstall.bat)
or
- Reinstall Spotify ([Full uninstall Spotify](https://github.com/amd64fox/Uninstall-Spotify) recommended)
FAQ
Read [FAQ](https://telegra.ph/SpotX-FAQ-09-19)
Disclaimer
SpotX is a tool that modifies the official Spotify client, provided as an evaluation version — use it at your own risk.
================================================
FILE: Uninstall.bat
================================================
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set "SPOTIFY_PATH=%Appdata%\Spotify"
if exist "%SPOTIFY_PATH%\chrome_elf.dll.bak" (
del /s /q "%SPOTIFY_PATH%\chrome_elf.dll" > NUL 2>&1
move "%SPOTIFY_PATH%\chrome_elf.dll.bak" "%SPOTIFY_PATH%\chrome_elf.dll" > NUL 2>&1
)
if exist "%SPOTIFY_PATH%\Spotify.dll.bak" (
del /s /q "%SPOTIFY_PATH%\Spotify.dll" > NUL 2>&1
move "%SPOTIFY_PATH%\Spotify.dll.bak" "%SPOTIFY_PATH%\Spotify.dll" > NUL 2>&1
)
if exist "%SPOTIFY_PATH%\Spotify.bak" (
del /s /q "%SPOTIFY_PATH%\Spotify.exe" > NUL 2>&1
move "%SPOTIFY_PATH%\Spotify.bak" "%SPOTIFY_PATH%\Spotify.exe" > NUL 2>&1
)
if exist "%SPOTIFY_PATH%\Apps\xpui.bak" (
del /s /q "%SPOTIFY_PATH%\Apps\xpui.spa" > NUL 2>&1
move "%SPOTIFY_PATH%\Apps\xpui.bak" "%SPOTIFY_PATH%\Apps\xpui.spa" > NUL 2>&1
)
if exist "%temp%\SpotX_Temp*" (
for /d %%i in ("%temp%\SpotX_Temp*") do (
rd /s/q "%%i" > NUL 2>&1
)
)
echo Patch successfully removed
pause
================================================
FILE: css-helper/lyrics-color/colors.css
================================================
:root {
--past: {{past}};
--current: {{current}};
--next: {{next}};
--hover: {{hover}};
--background: {{background}};
--musixmatch: {{musixmatch}};
}
================================================
FILE: css-helper/lyrics-color/rules.css
================================================
@import url('colors.css');
/* mini lyrics */
.Li269NgzkU2gI4KOP9sM,
.I2WIloMMjsBeMaIS8H3v,
.McI3hD7aCfpq015LJa6X,
.gpDSOimnzH4zTJmE7UR5 {
--lyrics-color-active: var(--current) !important;
--lyrics-color-inactive: var(--next) !important;
--lyrics-color-passed: var(--past) !important;
--lyrics-color-background: var(--background) !important;
}
/* title unsynced */
p[class*="e-"][class*="-text"].encore-text-body-small {
color: var(--musixmatch) !important;
margin-bottom: 8px !important;
}
/* fixed color of lyrics button */
[data-testid="lyrics-npv-section"]:not(._OhUGn8Plh3mRw4awIM5):not(.Sb2rC16jDkGc9eweOU8g):not(._YRfjT5prbRuSXcNK9WR):not(.RXRGSIFllAhUYWKYlANd) {
background-color:
#1f1f1f !important;
}
/* lyrics description */
.ebHsEf.I4K12o0qDoITOLr2AEs0,
.ebHsEf.OYiGFGZJDIZ4FF4ZTDK2,
.jKdLzW.LvLs_UgYs7ps5KdoCr0h,
.bWzOVV._T5UDP2tItG9WGdwO5Yi,
.hzUuLPdH48AzgQun5NYQ [data-encore-id="type"],
.hzUuLPdH48AzgQun5NYQ [data-encore-id="text"],
body .LomBcMvfM8AEmZGquAdj,
body .W_EplVEAbZrZURqfLiQC,
body .kGR_hu4tdj9PnUlSPaRL,
.GML6YUVCeJvRhGznLnqm,
body .iq4cgi0YEKr6DGaTtzUj,
body .KDhLFoEqoClhH12bsfrS {
color: var(--musixmatch) !important;
}
/* lyrics not available message */
.C3pBU1DsOUJJOAv89ZFT,
.T67LFP0PElpfkkLuegQt,
.e7eFLioNSG5PAi1qVFT4 {
color: var(--musixmatch) !important;
}
/* full cinema lyrics */
.FUYNhisXTCmbzt9IDxnT,
.tr8V5eHsUaIkOYVw7eSG,
.hW9km7ku6_iggdWDR_Lg,
.lofIAg8Ixko3mfBrbfej {
--lyrics-color-active: var(--current) !important;
--lyrics-color-inactive: var(--next) !important;
--lyrics-color-passed: var(--past) !important;
--lyrics-color-background: var(--background) !important;
}
/* fix previous lyrics for old versions */
.H2J92dVdr0ykdOX5azL1,
.KnFq2ijXFdOtyl4Iebjv {
color: var(--past) !important;
opacity: 1 !important;
}
/* hover */
.vapgYYF2HMEeLJuOWGq5:hover,
._LKG3z7SnerR0eigPCoK:hover,
.NHVfxGs2HwmI_fly2JC4:hover,
.gaHIufRWhoWbiT8S6zuM:hover,
.FQYXZaa0aDIrse54YlYO:hover {
color: var(--hover) !important;
/* remove underline */
text-decoration: none !important;
}
/* lyrics unsynced */
.HxblHEsl2WX2yhubfVIc,
.SruqsAzX8rUtY2isUZDF,
.eTLjCqbDo7QehPEPz86a,
.AEfhRyqGa3vzQrgfdwWE.Re403AJffPPuZmX7LRJj,
.NHVfxGs2HwmI_fly2JC4.E64X_eoy6xsJmDdKKHja,
.gaHIufRWhoWbiT8S6zuM.Qo3OkrSis5IWlP9Tchbr,
.AEfhRyqGa3vzQrgfdwWE .Re403AJffPPuZmX7LRJj {
color: var(--next) !important;
}
/* full screen lyrics */
.npv-lyrics__text-wrapper--previous .npv-lyrics__text {
color: var(--past) !important;
}
.npv-lyrics__text-wrapper--current .npv-lyrics__text {
color: var(--current) !important;
}
.npv-lyrics__text-wrapper--next .npv-lyrics__text {
color: var(--next) !important;
}
.npv-lyrics__text.npv-lyrics__text--credits,
.npv-lyrics__text--unsynced-warning {
color: var(--musixmatch) !important;
}
.npv-lyrics__text--unsynced {
color: var(--next) !important;
}
.npv-background-color {
background: var(--background) !important;
}
.npv-main-container {
background: transparent !important;
}
.npv-lyrics__gradient-background {
background: -webkit-gradient(linear, left top, left bottom, from(rgba(18, 18, 18, 0)), color-stop(30%, var(--background)), color-stop(60%, var(--background))) !important;
background: -webkit-linear-gradient(top, rgba(18, 18, 18, 0) 0%, var(--background) 30%, var(--background) 60%) !important;
background: linear-gradient(to bottom, rgba(18, 18, 18, 0) 0%, var(--background) 30%, var(--background) 60%) !important;
}
/* read along podcasts */
.l6lFMYQteTVnTcHnLywc,
._nDkCIVgkWayq3tqiIuW,
.B_wut2Bw4HwLr3w8rNfM {
--transcript-color-background: var(--background) !important;
--transcript-color-text: var(--next) !important;
--transcript-color-highlightText: var(--current) !important;
}
================================================
FILE: js-helper/goofyHistory.js
================================================
// max track buffer for localStorage
// when the limit is reached, old tracks will be removed from the beginning, and new ones will be added to the end
const MAX_TRACKS = 1000;
// max delay between switching tracks (ms)
const MAX_DELAY = 1000;
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
const loadTracksFromStorage = () => {
try {
const savedTracks = localStorage.getItem('sentSpotifyTracks');
return new Set(savedTracks ? JSON.parse(savedTracks) : []);
} catch (error) {
console.error('Error loading tracks from localStorage:', error);
return new Set();
}
};
const saveTracksToStorage = (tracks) => {
try {
let tracksArray = [...tracks];
if (tracksArray.length > MAX_TRACKS) {
tracksArray = tracksArray.slice(-MAX_TRACKS);
}
localStorage.setItem('sentSpotifyTracks', JSON.stringify(tracksArray));
} catch (error) {
console.error('Error saving tracks to localStorage:', error);
}
};
const unique = loadTracksFromStorage();
async function sendToGoogleForm(uri, urlForm, idBox) {
try {
await fetch(urlForm, {
"headers": {
"content-type": "application/x-www-form-urlencoded",
},
"body": "entry." + idBox + "=" + uri,
"method": "POST",
"mode": "no-cors",
});
saveTracksToStorage(unique);
} catch (error) {
console.error('Error sending uri to google form:', error);
}
}
const goofyHistory = debounce(async (e, urlForm, idBox) => {
const uri = e?.item?.uri;
if (uri && uri.includes('spotify:track:') && !unique.has(uri)) {
unique.add(uri);
await sendToGoogleForm(uri, urlForm, idBox);
}
}, MAX_DELAY);
================================================
FILE: js-helper/sectionBlock.js
================================================
const API_PATHFINDER = 'api-partner.spotify.com/pathfinder';
const API_RECOMMENDATIONS = 'api.spotify.com/v1/views/personalized-recommendations';
const BLOCKED_SECTIONS_BY_CATEGORY = {
'Party': [
'0JQ5DAnM3wGh0gz1MXnul1'
],
'Chill': [
'0JQ5DAnM3wGh0gz1MXnukV'
],
'Best of the Year': [
'0JQ5IMCbQBLupUQrQFeCzx'
],
'Best of Artists / Tracks': [
'0JQ5DAnM3wGh0gz1MXnu3C'
],
'Best of songwriters': [
'0JQ5DAnM3wGh0gz1MXnu4w'
],
'Biggest Indie Playlists': [
'0JQ5IMCbQBLhSb02SGYpDM'
],
'Charts': [
'0JQ5DAnM3wGh0gz1MXnu5g'
],
'Dinner': [
'0JQ5DAnM3wGh0gz1MXnu3p'
],
'Featured Charts': [
'0JQ5DAob0KOew1FBAMSmBz'
],
'Focus': [
'0JQ5DAob0JCuWaGLU6ntFY',
'0JQ5DAnM3wGh0gz1MXnulP'
],
'Fresh new music': [
'0JQ5DAnM3wGh0gz1MXnu3s'
],
'Gaming music': [
'0JQ5DAob0LaV9FOMJ9utY5'
],
'Happy': [
'0JQ5DAnM3wGh0gz1MXnu3q'
],
'ICE PHONK': [
'0JQ5IMCbQBLiqrNCH9VvmA'
],
'Mood': [
'0JQ5DAnM3wGh0gz1MXnucG',
'0JQ5DAob0JCuWaGLU6ntFT'
],
'Most Listened 2023': [
'0JQ5IMCbQBLicmNERjnGn5'
],
'Music to game to': [
'0JQ5DAob0Jr9ClCbkV4pZD'
],
'Popular Albums / Artists': [
'0JQ5DAnM3wGh0gz1MXnu3B'
],
'Popular new releases': [
'0JQ5DAnM3wGh0gz1MXnu3D'
],
'Popular radio': [
'0JQ5DAnM3wGh0gz1MXnu4h'
],
'Sad': [
'0JQ5DAnM3wGh0gz1MXnu3u',
'0JQ5DAnM3wGh0gz1MXnul2'
],
'Throwback': [
'0JQ5DAnM3wGh0gz1MXnu3w',
'0JQ5DAnM3wGh0gz1MXnul4'
],
'Throwback Thursday / Spotify Playlists / Good night ': [
'0JQ5DAuChZYPe9iDhh2mJz'
],
'Today`s biggest hits': [
'0JQ5DAnM3wGh0gz1MXnu3M'
],
'Trending now': [
'0JQ5DAnM3wGh0gz1MXnu3E'
],
'Workout': [
'0JQ5DAnM3wGh0gz1MXnu3x',
'0JQ5DAnM3wGh0gz1MXnul6'
],
'Now defrosting': [
'0JQ5IMCbQBLlC31GvtaB6w'
],
'Unknown': [
'0JQ5IMCbQBLqTJyy28YCa9',
'0JQ5DAnM3wGh0gz1MXnu7R'
]
};
const BLOCKED_SECTIONS = {};
for (const [category, ids] of Object.entries(BLOCKED_SECTIONS_BY_CATEGORY)) {
for (const id of ids) {
BLOCKED_SECTIONS[id] = category;
}
}
const BLOCKED_CONTENT_TYPES = new Set(['Podcast', 'Audiobook', 'Episode']);
const createSectionAdapter = (isPersonalizedRecommendations) => {
if (isPersonalizedRecommendations) {
return {
getId: (item) => {
const href = item?.href;
if (!href) return null;
const parts = href.split('/');
let id = parts[parts.length - 1];
if (id.startsWith('section')) {
id = id.substring(7);
}
return id;
},
getTitle: (item) => item?.content?.name || 'Unknown',
getRef: (item) => item?.href,
getSectionId: (item) => item?.id,
getContentItems: (item) => item?.content?.items,
getContentData: (contentItem) => contentItem?.content,
getContentType: (contentItem) => contentItem?.type,
getContentTypeName: (contentItem) => contentItem?.content_type
};
} else {
return {
getId: (item) => {
const uri = item?.uri;
if (!uri) return null;
const parts = uri.split(':');
return parts[parts.length - 1];
},
getTitle: (item) => item?.data?.title?.text || 'Unknown',
getRef: (item) => item?.uri,
getSectionId: (item) => null,
getContentItems: (item) => item?.sectionItems?.items,
getContentData: (contentItem) => contentItem?.content?.data,
getContentType: (contentItem) => null,
getContentTypeName: (contentItem) => null
};
}
};
const processShortcutsSection = (contentItems, adapter, removed) => {
if (!contentItems?.length) return false;
for (let j = contentItems.length - 1; j >= 0; j--) {
const contentItem = contentItems[j];
const contentType = adapter.getContentTypeName(contentItem);
if (contentType !== 'PODCAST_EPISODE' && contentType !== 'AUDIOBOOK') {
continue;
}
removed.push({
type: contentType,
name: contentItem?.name || 'Unknown',
uri: contentItem?.uri || 'N/A'
});
contentItems.splice(j, 1);
}
return true;
};
const isPodcastSection = (contentItems, adapter) => {
if (!contentItems?.length) return false;
return adapter.getContentType(contentItems[0]) === 'show';
};
const removeBlockedContent = (contentItems, adapter, removed) => {
if (!contentItems?.length) return;
for (let j = contentItems.length - 1; j >= 0; j--) {
const contentData = adapter.getContentData(contentItems[j]);
if (!contentData || !BLOCKED_CONTENT_TYPES.has(contentData.__typename)) {
continue;
}
removed.push({
type: contentData.__typename,
name: contentData.name || 'Unknown',
uri: contentData.uri || 'N/A'
});
contentItems.splice(j, 1);
}
};
function sectionBlock(data, type) {
const body = data?.data?.home;
const sections = body?.sectionContainer?.sections?.items;
const items = data?.content?.items || data?.data?.content?.items;
const isPersonalizedRecommendations = !!items && !body;
const targetArray = isPersonalizedRecommendations ? items : sections;
function removeSections() {
if (!targetArray?.length) return;
const adapter = createSectionAdapter(isPersonalizedRecommendations);
const removed = [];
for (let i = targetArray.length - 1; i >= 0; i--) {
const item = targetArray[i];
const sectionId = adapter.getId(item);
if (!sectionId) continue;
if (sectionId in BLOCKED_SECTIONS) {
removed.push({
id: sectionId,
knownAs: BLOCKED_SECTIONS[sectionId],
actualTitle: adapter.getTitle(item),
ref: adapter.getRef(item)
});
targetArray.splice(i, 1);
}
}
if (removed.length > 0) {
console.log(`[SectionBlock] Removed ${removed.length} blocked section(s):`, removed);
}
}
function removePodcasts() {
if (!targetArray?.length) return;
const adapter = createSectionAdapter(isPersonalizedRecommendations);
const removed = [];
for (let i = targetArray.length - 1; i >= 0; i--) {
const item = targetArray[i];
const contentItems = adapter.getContentItems(item);
if (isPersonalizedRecommendations) {
const sectionId = adapter.getSectionId(item);
if (sectionId === 'shortcuts') {
processShortcutsSection(contentItems, adapter, removed);
continue;
}
if (isPodcastSection(contentItems, adapter)) {
removed.push({
type: 'PodcastSection',
sectionId: sectionId,
sectionName: adapter.getTitle(item),
itemsCount: contentItems.length
});
targetArray.splice(i, 1);
continue;
}
}
removeBlockedContent(contentItems, adapter, removed);
}
if (removed.length > 0) {
console.log(`[SectionBlock] Removed ${removed.length} podcast/audiobook item(s):`, removed);
}
}
function removeCanvasSections() {
if (!sections?.length) return;
const removed = [];
for (let i = sections.length - 1; i >= 0; i--) {
if (sections[i]?.data?.__typename === 'HomeFeedBaselineSectionData') {
removed.push({
uri: sections[i]?.uri || 'N/A',
title: sections[i]?.data?.title?.text || 'Canvas Section'
});
sections.splice(i, 1);
}
}
if (removed.length > 0) {
console.log(`[SectionBlock] Removed ${removed.length} canvas section(s):`, removed);
}
}
if ((body?.greeting && sections) || items) {
const actions = {
section: removeSections,
podcast: removePodcasts,
canvas: removeCanvasSections,
all: () => {
removeSections();
removePodcasts();
if (!isPersonalizedRecommendations) {
removeCanvasSections();
}
}
};
if (Array.isArray(type)) {
type.forEach(t => actions[t]?.());
} else {
actions[type]?.();
}
}
}
const originalFetch = window.fetch;
window.fetch = async function (...args) {
const [url] = args;
const urlString = typeof url === 'string' ? url : url?.url || '';
const isPathfinderUrl = urlString.includes(API_PATHFINDER);
const isPersonalizedRecommendationsUrl = urlString.includes(API_RECOMMENDATIONS);
if (!isPathfinderUrl && !isPersonalizedRecommendationsUrl) {
return originalFetch.apply(this, args);
}
const response = await originalFetch.apply(this, args);
const clonedResponse = response.clone();
try {
const data = await response.json();
const shouldModify = (isPathfinderUrl && data?.data?.home) ||
(isPersonalizedRecommendationsUrl && data?.content);
if (!shouldModify) {
return clonedResponse;
}
sectionBlock(data, '');
return new Response(JSON.stringify(data), {
status: response.status,
statusText: response.statusText,
headers: response.headers
});
} catch (error) {
console.error('Fetch intercept error:', error);
return clonedResponse;
}
};
================================================
FILE: patches/Augmented translation/ru.json
================================================
{
"lang": {
"version": "1.2.80",
"language": "Russian"
},
"1": {
"match": "\"Confirm your age\"",
"replace": "\"Подтвердите свой возраст\""
},
"2": {
"match": "\"%price%/month after. Terms and conditions apply. One month free not available for users who have already tried Premium.\"",
"replace": "\"%price%/месяц спустя. Принять условия. Один месяц бесплатно, недоступно для пользователей, которые уже попробовали Premium.\""
},
"3": {
"match": "\"Offline storage location\"",
"replace": "\"Хранилище скачанных треков\""
},
"4": {
"match": "\"Click to start listening\"",
"replace": "\"Нажмите, чтобы начать прослушивание\""
},
"5": {
"match": "\"Change speed\"",
"replace": "\"Изменение скорости\""
},
"6": {
"match": "\"You need to be at least 19 years old to listen to explicit content marked with\"",
"replace": "\"Вам должно быть не менее 19 лет, чтобы слушать непристойный контент, помеченный значком\""
},
"7": {
"match": "\"Add to another playlist\"",
"replace": "\"Добавить в другой плейлист\""
},
"8": {
"match": "\"Character counter\"",
"replace": "\"Счетчик символов\""
},
"9": {
"match": "\"Toggle lightsaber hilt. Current is [{]0[}].\"",
"replace": "\"Переключить рукоять светового меча. Текущий {0}.\""
},
"10": {
"match": "\"Doors at .0.\"",
"replace": "\"Вход в {0}\""
},
"11": {
"match": "\"Show at .0.\"",
"replace": "\"Показ в {0}\""
},
"12": {
"match": "\"Your Location\"",
"replace": "\"Ваше местоположение\""
},
"13": {
"match": "\"Override certain user attributes to test regionalized content programming. The overrides are only active in this app.\"",
"replace": "\"Переопределите определенные атрибуты пользователя, чтобы протестировать региональное программирование контента. Переопределения активны только в этом приложении.\""
},
"14": {
"match": " was released this week!",
"replace": " был выпущен на этой неделе!"
},
"15": {
"match": "\"Speed [{]0[}]×\"",
"replace": "\"Скорость {0}×\""
},
"16": {
"match": "\"Artist\"",
"replace": "\"Исполнитель\""
},
"17": {
"match": "\"... of ...\"",
"replace": "\"{0} из {1}\""
},
"18": {
"match": "\"Не удалось изменить\"",
"replace": "\"Не удалось обновить\""
},
"19": {
"match": "Dynamic loudness control for podcasts - Actively maintain optimal podcast volume level for a clear and balanced sound experience",
"replace": "Динамическое управление громкостью для подкастов - активное поддержание оптимального уровня громкости подкаста для четкого и сбалансированного звукового восприятия"
},
"20": {
"match": "\"Build .0. is available\"",
"replace": "\"Сборка {0} доступна\""
},
"21": {
"match": "\"Downloading build .0....\"",
"replace": "\"Загрузка сборки {0}...\""
},
"22": {
"match": "\"Build .0. is ready to install\"",
"replace": "\"Сборка {0} готова к установке\""
},
"23": {
"match": "\"Remove\"",
"replace": "\"Удалить\""
},
"24": {
"match": "\"Do not translate\"",
"replace": "\"Не переводить\""
},
"25": {
"match": "\"Translating to .0.\"",
"replace": "\"Перевожу на {0}\""
},
"26": {
"match": "\"Translation to .0. not available\"",
"replace": "\"Перевод на {0} недоступен\""
},
"27": {
"match": "\"Translate lyrics\"",
"replace": "\"Перевести текст песни\""
},
"28": {
"match": "\"Spotify MiniPlayer\"",
"replace": "\"мини-плеер Spotify\""
},
"29": {
"match": "\"Venue\"",
"replace": "\"Место проведения\""
},
"30": {
"match": "\"We couldn't find the venue\"",
"replace": "\"Мы не смогли найти место проведения\""
},
"31": {
"match": "\"Bring back to main window\"",
"replace": "\"Вернуться к основному окну\""
},
"32": {
"match": "\"Chapter\"",
"replace": "\"Глава\""
},
"33": {
"match": "\"Song\"",
"replace": "\"Трек\""
},
"34": {
"match": "\"Episode\"",
"replace": "\"Эпизод\""
},
"35": {
"match": "\"The venue you requested couldn.t be found, please try again.\"",
"replace": "\"Запрошенное вами место проведения не найдено, попробуйте снова.\""
},
"36": {
"match": "\"There was an error fetching the venue.\"",
"replace": "\"Произошла ошибка при получении места проведения.\""
},
"37": {
"match": "\"Concerts\"",
"replace": "\"Концерты\""
},
"38": {
"match": "\"all times are local to the venue\"",
"replace": "\"все время указано по месту проведения\""
},
"39": {
"match": "\"Spotify Spotlight Presale\"",
"replace": "\"Предпродажа Spotify Spotlight\""
},
"40": {
"match": "\"Get access\"",
"replace": "\"Получить доступ\""
},
"41": {
"match": "\"Continue playing\"",
"replace": "\"Продолжить воспроизведение\""
},
"42": {
"match": "\"Fans First\"",
"replace": "\"Для фанатов\""
},
"43": {
"match": "\"Offer ends in .0.:.1.:.2.\"",
"replace": "\"До конца предложения: {0}:{1}:{2}\""
},
"44": {
"match": "\"Search in Authors\"",
"replace": "\"Искать в Авторах\""
},
"45": {
"match": "\"A soundtrack for every part of the day.\"",
"replace": "\"Саундтрек для любого времени суток.\""
},
"46": {
"match": "\"See your unique playlist\"",
"replace": "\"Посмотрите свой уникальный плейлист\""
},
"47": {
"match": "\"You.ll still get:\"",
"replace": "\"Вы также получите:\""
},
"48": {
"match": "\"Trending songs in .country. . Spotify\"",
"replace": "\"Популярные песни в %country% | Spotify\""
},
"49": {
"match": "\"Featured Charts in .country. . Spotify\"",
"replace": "\"Избранные чарты в %country% . Spotify\""
},
"50": {
"match": "\"Popular artists in .country. . Spotify\"",
"replace": "\"Популярные исполнители в %country% | Spotify\""
},
"51": {
"match": "\"Popular albums in .country. . Spotify\"",
"replace": "\"Популярные альбомы в %country% | Spotify\""
},
"52": {
"match": "\"Discover trending songs in .country. today.\"",
"replace": "\"Откройте для себя трендовые песни в %country% сегодня.\""
},
"53": {
"match": "\"Discover Featured Charts in .country. today.\"",
"replace": "\"Откройте для себя избранные чарты в %country% сегодня.\""
},
"54": {
"match": "\"Discover the most popular artists in .country. today.\"",
"replace": "\"Откройте для себя самых популярных исполнителей в %country% сегодня.\""
},
"55": {
"match": "\"Discover the most popular albums in .country. today.\"",
"replace": "\"Откройте для себя самые популярные альбомы в %country% сегодня.\""
},
"56": {
"match": "\"Close\"",
"replace": "\"Закрыть\""
},
"57": {
"match": "\"Ok, we won.t play music from this artist again.\"",
"replace": "\"Хорошо, мы больше не будем воспроизводить музыку этого исполнителя\""
},
"58": {
"match": "\"Compact list\"",
"replace": "\"Компактный список\""
},
"59": {
"match": "\"Compact grid\"",
"replace": "\"Компактная сетка\""
},
"60": {
"match": "\"Lyrics preview\"",
"replace": "\"Превью текста\""
},
"61": {
"match": "\"Show less\"",
"replace": "\"Свернуть\""
},
"62": {
"match": "\"Show more\"",
"replace": "\"Развернуть\""
},
"63": {
"match": "\"Hide lyrics\"",
"replace": "\"Скрыть текст\""
},
"64": {
"match": "\"Переключиться на видеорежим\"",
"replace": "\"К видео\""
},
"65": {
"match": "\"Переключиться на аудиорежим\"",
"replace": "\"К аудио\""
},
"66": {
"match": "\".\".name..\" was released .years. year ago this week!\"",
"replace": "\"На этой неделе исполнился %years% год с момента выхода \\\"%name%\\\"!\""
},
"67": {
"match": "((?:few|other)..)\".\".name..\" was released .years. years ago this week!\"",
"replace": "$1\"На этой неделе исполнилось %years% года с момента выхода \\\"%name%\\\"!\""
},
"68": {
"match": "(many..)\".\".name..\" was released .years. years ago this week!\"",
"replace": "$1\"На этой неделе исполнилось %years% лет с момента выхода \\\"%name%\\\"!\""
},
"69": {
"match": "\".Select Type. \"",
"replace": "\"<Выберите тип>\""
},
"70": {
"match": "\"Connect\"",
"replace": "\"Подключить устройство\""
},
"71": {
"match": "\"Синхронизация\"",
"replace": "\"Синхронизировать\""
},
"72": {
"match": "\"Browse the live events feed to find more concerts.\"",
"replace": "\"Листайте нашу афишу, чтобы найти больше концертов.\""
},
"73": {
"match": "\"No concerts found\"",
"replace": "\"Концертов не найдено\""
},
"74": {
"match": "\"Browse the live events feed to find more venues.\"",
"replace": "\"Листайте нашу афишу, чтобы найти больше площадок.\""
},
"75": {
"match": "\"No venues found\"",
"replace": "\"Площадок не найдено\""
},
"76": {
"match": "\"Concerts in Your Top Genre\"",
"replace": "\"Концерты в вашем любимом жанре\""
},
"77": {
"match": "\"Follow your favorite venues to discover and browse events happening near you\"",
"replace": "\"Подписывайтесь на любимые площадки, чтобы открывать и просматривать события рядом с вами\""
},
"78": {
"match": "\"Search results\"",
"replace": "\"Результаты поиска\""
},
"79": {
"match": "\"BPM\"",
"replace": "\"Темп\""
},
"80": {
"match": "\"Folder name is required\"",
"replace": "\"Имя папки обязательно\""
},
"81": {
"match": "\"Generate\"",
"replace": "\"Сгенерировать\""
},
"82": {
"match": "\"Retry\"",
"replace": "\"Повторить\""
},
"83": {
"match": "\"Daily\"",
"replace": "\"Ежедневно\""
},
"84": {
"match": "\"Tracks update every day by 6am\"",
"replace": "\"Треки обновляются каждый день к 6 утра\""
},
"85": {
"match": "\"Doesn.t update\"",
"replace": "\"Не обновляется\""
},
"86": {
"match": "\"Set updates\"",
"replace": "\"Настроить обновления\""
},
"87": {
"match": "\"Never\"",
"replace": "\"Никогда\""
},
"88": {
"match": "\"You can still update tracks manually\"",
"replace": "\"Вы все еще можете обновлять треки вручную\""
},
"89": {
"match": "\"Unknown\"",
"replace": "\"Неизвестно\""
},
"90": {
"match": "\"Updates daily\"",
"replace": "\"Обновляется ежедневно\""
},
"91": {
"match": "\"Updates weekly\"",
"replace": "\"Обновляется еженедельно\""
},
"92": {
"match": "\"Weekly\"",
"replace": "\"Еженедельно\""
},
"93": {
"match": "\"Every week at 6am every...\"",
"replace": "\"Каждую неделю в 6 утра каждый...\""
},
"94": {
"match": "\"Updates every .0.\"",
"replace": "\"Обновляется каждый {0}\""
},
"95": {
"match": "\"Tracks in this playlist will update daily\"",
"replace": "\"Треки в этом плейлисте будут обновляться ежедневно\""
},
"96": {
"match": "\"Tracks in this playlist won.t update\"",
"replace": "\"Треки в этом плейлисте не будут обновляться\""
},
"97": {
"match": "\"Tracks in this playlist will update every .0.\"",
"replace": "\"Треки в этом плейлисте будут обновляться каждый {0}\""
},
"98": {
"match": "\"Got it\"",
"replace": "\"Понятно\""
},
"99": {
"match": "\"This.ll reset in .0., so come back then.\"",
"replace": "\"Сброс через {0}, возвращайтесь позже.\""
},
"100": {
"match": "\"Dismiss\"",
"replace": "\"Отклонить\""
},
"101": {
"match": "\"You.ve reached the limit for prompting playlists\"",
"replace": "\"Вы достигли лимита создания плейлистов по запросу\""
},
"102": {
"match": "\"Prompt\"",
"replace": "\"Запрос\""
},
"103": {
"match": "\"Prompted Playlist\"",
"replace": "\"Плейлист по запросу\""
},
"104": {
"match": "\"Customize prompt\"",
"replace": "\"Настроить запрос\""
},
"105": {
"match": "\"Friday\"",
"replace": "\"Пятница\""
},
"106": {
"match": "\"Monday\"",
"replace": "\"Понедельник\""
},
"107": {
"match": "\"Saturday\"",
"replace": "\"Суббота\""
},
"108": {
"match": "\"Sunday\"",
"replace": "\"Воскресенье\""
},
"109": {
"match": "\"Thursday\"",
"replace": "\"Четверг\""
},
"110": {
"match": "\"Tuesday\"",
"replace": "\"Вторник\""
},
"111": {
"match": "\"Wednesday\"",
"replace": "\"Среда\""
},
"112": {
"match": "\"Generate playlist\"",
"replace": "\"Создать плейлист\""
},
"113": {
"match": "\"See what this prompt would create based on your tastes\"",
"replace": "\"Посмотрите, что этот запрос создаст на основе ваших вкусов\""
},
"114": {
"match": "\"Beta\"",
"replace": "\"Бета\""
},
"115": {
"match": "\"Generate a playlist that curates and updates\"",
"replace": "\"Создать плейлист, который подбирается и обновляется\""
},
"116": {
"match": "\"Update now\"",
"replace": "\"Обновить сейчас\""
},
"117": {
"match": "\"Something went wrong. Please try again\"",
"replace": "\"Что-то пошло не так. Пожалуйста, попробуйте снова\""
},
"118": {
"match": "\"Private\"",
"replace": "\"Приватный\""
},
"119": {
"match": "\"Public\"",
"replace": "\"Публичный\""
},
"120": {
"match": "\"Set privacy\"",
"replace": "\"Настроить приватность\""
},
"121": {
"match": "\"Only you and people you invite will be able to view this prompt and playlist\"",
"replace": "\"Только вы и приглашенные вами люди смогут видеть этот запрос и плейлист\""
},
"122": {
"match": "\"Anyone will be able to view this prompt and playlist\"",
"replace": "\"Любой сможет видеть этот запрос и плейлист\""
},
"123": {
"match": "\"Learn\"",
"replace": "\"Узнать\""
},
"124": {
"match": "\"You.re prompting with an AI. Don.t include any sensitive data. .learn. how your data is managed and shared.\"",
"replace": "\"Вы делаете запрос к ИИ. Не указывайте конфиденциальные данные. %learn%, как управляются и передаются ваши данные.\""
},
"125": {
"match": "\"New prompt\"",
"replace": "\"Новый запрос\""
},
"126": {
"match": "\"Edit prompt\"",
"replace": "\"Изменить запрос\""
},
"127": {
"match": "\"Analyzing...\"",
"replace": "\"Анализ...\""
},
"128": {
"match": "\"Update playlist\"",
"replace": "\"Обновить плейлист\""
},
"129": {
"match": "\"Updating playlist\"",
"replace": "\"Обновление плейлиста\""
},
"130": {
"match": "\"Prompt playlist options\"",
"replace": "\"Настройки плейлиста по запросу\""
},
"131": {
"match": "\"Describe your perfect playlist, in as much detail as you want...\"",
"replace": "\"Опишите свой идеальный плейлист, настолько подробно, насколько хотите...\""
},
"132": {
"match": "\"Made for\"",
"replace": "\"Сделано для\""
},
"133": {
"match": "\"Prompted by\"",
"replace": "\"По запросу\""
},
"134": {
"match": "\"Ideas\"",
"replace": "\"Идеи\""
},
"135": {
"match": "\"This.ll reset soon.\"",
"replace": "\"Скоро сбросится.\""
},
"136": {
"match": "\"Hide ideas\"",
"replace": "\"Скрыть идеи\""
},
"137": {
"match": "\"Show ideas\"",
"replace": "\"Показать идеи\""
},
"138": {
"match": "\"Name & details\"",
"replace": "\"Название и детали\""
},
"139": {
"match": "\"Notes\"",
"replace": "\"Заметки\""
},
"140": {
"match": "\"View prompt\"",
"replace": "\"Посмотреть запрос\""
},
"141": {
"match": "\"Discard this prompt.\"",
"replace": "\"Отменить этот запрос?\""
},
"142": {
"match": "\"Cancel\"",
"replace": "\"Отмена\""
},
"143": {
"match": "\"Discard\"",
"replace": "\"Отменить\""
},
"144": {
"match": "\"Any changes you.ve made won.t be saved.\"",
"replace": "\"Любые внесенные изменения не будут сохранены.\""
},
"145": {
"match": "\"What you.ll get\"",
"replace": "\"Что вы получите\""
},
"146": {
"match": "\"Collapse .0.\"",
"replace": "\"Свернуть {0}\""
},
"147": {
"match": "\"Collapsed .0.\"",
"replace": "\"Свернуто {0}\""
},
"148": {
"match": "\"Audiobooks\"",
"replace": "\"Аудиокниги\""
},
"149": {
"match": "\"Music\"",
"replace": "\"Музыка\""
},
"150": {
"match": "\"Podcasts\"",
"replace": "\"Подкасты\""
},
"151": {
"match": "\"Expand .0.\"",
"replace": "\"Развернуть {0}\""
},
"152": {
"match": "\"Expanded .0.\"",
"replace": "\"Развернуто {0}\""
},
"153": {
"match": "\"Loading more items\"",
"replace": "\"Загрузка дополнительных элементов\""
},
"154": {
"match": "\"More items loaded\"",
"replace": "\"Загружено больше элементов\""
},
"155": {
"match": "\"Played\"",
"replace": "\"Прослушано\""
},
"156": {
"match": "\"Saved\"",
"replace": "\"Сохранено\""
},
"157": {
"match": "\"Shared\"",
"replace": "\"Поделились\""
},
"158": {
"match": "\"Generating...\"",
"replace": "\"Генерация...\""
},
"159": {
"match": "\"Made for .0.\"",
"replace": "\"Сделано для {0}\""
},
"160": {
"match": "\"Prompted by .0.\"",
"replace": "\"Запрос от {0}\""
}
}
================================================
FILE: patches/patches.json
================================================
{
"free": {
"fullscreen": {
"version": {
"fr": "1.1.59",
"to": "1.1.92"
},
"match": "(return|.=.=>)\"free\"===(.+?)(return|.=.=>)\"premium\"===",
"replace": "$1\"premium\"===$2$3\"free\"==="
},
"audioads": {
"version": {
"fr": "1.1.59",
"to": "1.1.92"
},
"match": "(case .:|async enable\\(.\\){)(this.enabled=.+?\\(.{1,3},\"audio\"\\),|return this.enabled=...+?\\(.{1,3},\"audio\"\\))((;case 4:)?this.subscription=this.audioApi).+?this.onAdMessage\\)",
"replace": "$1$3.cosmosConnector.increaseStreamTime(-100000000000)"
},
"emptyblock": {
"version": {
"fr": "1.1.59",
"to": ""
},
"match": "adsEnabled:!0",
"replace": "adsEnabled:!1"
},
"playlistsponsor": {
"version": {
"fr": "1.1.59",
"to": ""
},
"match": "allSponsorships",
"replace": ""
},
"connectold": {
"version": {
"fr": "1.1.70",
"to": "1.1.92"
},
"match": [
" connect-device-list-item--disabled",
"connect-picker.unavailable-to-control",
"(\"button\",{className:.,disabled:)(..)"
],
"replace": [
"",
"spotify-connect",
"$1false"
]
},
"downloadquality": {
"version": {
"fr": "1.1.70",
"to": "1.2.29"
},
"match": "(\\(.,..jsxs\\)\\(.{1,3}|(.\\(\\).|..)createElement\\(.{1,4}),{(filterMatchQuery|filter:.,title|(variant:\"viola\",semanticColor:\"textSubdued\"|..:\"span\",variant:.{3,6}mesto,color:.{3,6}),htmlFor:\"desktop.settings.downloadQuality.+?).{1,6}get\\(\"desktop.settings.downloadQuality.title.+?(children:.{1,2}\\(.,.\\).+?,|\\(.,.\\){3,4},|,.\\)}},.\\(.,.\\)\\),)",
"replace": ""
}
},
"others": {
"discriptions": {
"version": {
"fr": "1.1.59",
"to": ""
},
"match": "((..createElement|children:\\(.{1,7}\\))\\(.{1,7},{source:).{1,7}get\\(\"about.copyright\",.\\),paragraphClassName:(?:\"[\\w]+\"|\\w+)}\\)",
"replace": "
SpotX is a modified version of the official Spotify client, provided as an evaluation version, you use it at your own risk.",
"svgtg": "",
"svggit": "",
"svgfaq": ""
},
"ForcedExp": {
"version": {
"fr": "1.1.67",
"to": ""
},
"match": "((?:{configuration|{resolver|instance):(.).(?:getRemoteConfig|getUrlDispenserServiceClient).+?;)",
"replace": "$1const experiments={enable:[],disable:[],custom:[]},setExpValue=(v,e,val)=>v&&(v.set?v.set(e,val):v[e]&&(v[e].value=val)),config=$2.getRemoteConfigResolver?.()||$2.getRemoteConfiguration?.();config&&((values=>{for(const type in experiments)experiments[type].forEach(exp=>setExpValue(values,type==='custom'?exp.name:exp,type==='custom'?exp.value:type==='enable'));(window.Spotx??={}).RemoteExp=values})(config.values||config.activeProperties));"
},
"DisableExp": {
"InAppMessaging": {
"name": "enableInAppMessaging",
"description": "Disable pop-up window for premium account purchase",
"native_description": "Enables quicksilver in-app messaging modal",
"version": {
"fr": "1.1.59",
"to": ""
}
},
"ContentInformationMessage": {
"name": "enableContentInformationMessage",
"description": "Disable covid messages between podcasts",
"native_description": "Enable showing content information messages for episodes",
"version": {
"fr": "1.1.78",
"to": "1.2.50"
}
},
"PickShuffle": {
"name": "enablePickAndShuffle",
"description": "Removes restrictions on using the queue and listening to tracks in order",
"native_description": "Enable pick and shuffle",
"version": {
"fr": "1.1.85",
"to": "1.2.42"
}
},
"MusicLeavebehinds": {
"name": "enableDesktopMusicLeavebehinds",
"description": "Disabling ad blocks in playlists",
"native_description": "Enable music leavebehinds on eligible playlists for desktop",
"version": {
"fr": "1.2.10",
"to": ""
}
},
"HptoLocationRefactor": {
"name": "enableHptoLocationRefactor",
"description": "Disabling in some cases the banner on the main page",
"native_description": "Enable new permanent location for HPTO iframe to HptoHtml.js",
"version": {
"fr": "1.2.1",
"to": "1.2.20"
}
},
"UserFraudSignals": {
"name": "enableUserFraudSignals",
"description": "presumably protection against bots (reCAPTCHA)",
"native_description": "Enable user fraud signals",
"version": {
"fr": "1.2.10",
"to": "1.2.62"
}
},
"UserFraudVerificationRequest": {
"name": "enableUserFraudVerificationRequest",
"description": "presumably protection against bots (reCAPTCHA)",
"native_description": "Enable the IAV component make api requests",
"version": {
"fr": "1.2.5",
"to": "1.2.62"
}
},
"UserFraudVerification": {
"name": "enableUserFraudVerification",
"description": "presumably protection against bots (reCAPTCHA)",
"native_description": "Enable user fraud verification",
"version": {
"fr": "1.2.3",
"to": "1.2.62"
}
},
"UserFraudCspViolation": {
"name": "enableUserFraudCspViolation",
"description": "Enable CSP violation detection",
"native_description": "Enable CSP violation detection",
"version": {
"fr": "1.2.17",
"to": "1.2.62"
}
},
"EsperantoMigration": {
"name": "enableEsperantoMigration",
"description": "presumably, the advertising management transition from Cosmos to Esperanto",
"native_description": "Enable esperanto Migration for Ad Formats",
"version": {
"fr": "1.2.6",
"to": "1.2.50"
}
},
"RightSidebarMerchFallback": {
"name": "enableRightSidebarMerchFallback",
"description": "Allow merch to fallback to artist level merch if track level does not exist",
"native_description": "Allow merch to fallback to artist level merch if track level does not exist",
"version": {
"fr": "1.2.5",
"to": "1.2.11"
}
},
"ReportAudiobooks": {
"name": "enableReportAudiobooks",
"description": "Enable Report action for audiobooks",
"native_description": "Enable Report action for audiobooks",
"version": {
"fr": "1.1.97",
"to": "1.2.50"
}
},
"ReportPodcastShows": {
"name": "enableReportPodcastShows",
"description": "Enable Report action for podcast shows",
"native_description": "Enable Report action for podcast shows",
"version": {
"fr": "1.2.12",
"to": ""
}
},
"ReportPodcastEpisodes": {
"name": "enableReportPodcastEpisodes",
"description": "Enable Report action for podcast episodes",
"native_description": "Enable Report action for podcast episodes",
"version": {
"fr": "1.2.12",
"to": ""
}
},
"ReportAudiobookChapters": {
"name": "enableReportAudiobookChapters",
"description": "Enable Report action for audiobook chapters",
"native_description": "Enable Report action for audiobook chapters",
"version": {
"fr": "1.2.12",
"to": "1.2.50"
}
},
"Dsa": {
"name": "enableDsa",
"description": "Enable showing DSA (Digital Services Act) context menu and modal for ads",
"native_description": "Enable showing DSA (Digital Services Act) context menu and modal for ads",
"version": {
"fr": "1.2.12",
"to": "1.2.19"
}
},
"Dsa2": {
"name": "enableDsaAds",
"description": "Enable showing DSA (Digital Services Act) context menu and modal for ads",
"native_description": "Enable showing DSA (Digital Services Act) context menu and modal for ads",
"version": {
"fr": "1.2.20",
"to": "1.2.52"
}
},
"Dsa3": {
"name": "enableDSASetting",
"description": "Enable DSA (Digital Service Act) features for desktop and web",
"native_description": "Enable DSA (Digital Service Act) features for desktop and web",
"version": {
"fr": "1.2.20",
"to": ""
}
},
"NewAdsNpv": {
"name": "enableNewAdsNpv",
"description": "Enable showing new ads NPV",
"native_description": "Enable showing new ads NPV",
"version": {
"fr": "1.2.18",
"to": "1.2.50"
}
},
"NewAdsNpvVideoTakeover": {
"name": "enableNewAdsNpvVideoTakeover",
"description": "Enable redesigned VideoTakeover for new ads NPV",
"native_description": "Enable redesigned VideoTakeover for new ads NPV",
"version": {
"fr": "1.2.18",
"to": "1.2.50"
}
},
"NewAdsNpvColorExtraction": {
"name": "enableNewAdsNpvColorExtraction",
"description": "Enable CTA card color extraction for new ads NPV",
"native_description": "Enable CTA card color extraction for new ads NPV",
"version": {
"fr": "1.2.18",
"to": "1.2.50"
}
},
"AudiobookAdExclusivity": {
"name": "enableAudiobookAdExclusivity",
"description": "Enable Audiobook Ad Formats Exclusivity",
"native_description": "Enable Audiobook Ad Formats Exclusivity",
"version": {
"fr": "1.2.19",
"to": ""
}
},
"NewAdsNpvNewVideoTakeoverSlot": {
"name": "enableNewAdsNpvNewVideoTakeoverSlot",
"description": "Enable new modal slot to position redesigned new ads NPV VideoTakeover above all areas except RightSidebar and NPB",
"native_description": "Enable new modal slot to position redesigned new ads NPV VideoTakeover above all areas except RightSidebar and NPB",
"version": {
"fr": "1.2.22",
"to": "1.2.50"
}
},
"FraudLoadSignals": {
"name": "enableFraudLoadSignals",
"description": "Enable user fraud signals emitted on page load",
"native_description": "Enable user fraud signals emitted on page load",
"version": {
"fr": "1.2.22",
"to": "1.2.62"
}
},
"GabitoAdEvent": {
"name": "enableGabitoAdEvent",
"description": "Use Gabito AdEvent instead of Gabo AdEvent",
"native_description": "Use Gabito AdEvent instead of Gabo AdEvent",
"version": {
"fr": "1.1.93",
"to": "1.2.25"
}
},
"YourListeningUpsell": {
"name": "enableYourListeningUpsell",
"description": "Enable Your Listening Upsell Banner for free & unauth users",
"native_description": "Enable Your Listening Upsell Banner for free & unauth users",
"version": {
"fr": "1.2.25",
"to": "1.2.63"
}
},
"podcast-ads": {
"name": "podcastads-ads_npb",
"description": "Enable the podcast ads Now Playing Bar experience, including features like the podcast ad Now Playing Bar hat",
"native_description": "Enable the podcast ads Now Playing Bar experience, including features like the podcast ad Now Playing Bar hat",
"version": {
"fr": "1.1.67",
"to": "1.2.50"
}
},
"podcast-episode": {
"name": "podcastaudioplus-episode_entity",
"description": "Enable the Sponsored By section on the Episode Page with Call to Action cards",
"native_description": "Enable the Sponsored By section on the Episode Page with Call to Action cards",
"version": {
"fr": "1.1.67",
"to": "1.2.50"
}
},
"podcast-show_page": {
"name": "podcastaudioplus-show_page",
"description": "Enable show sponsors section on the Show Page",
"native_description": "Enable show sponsors section on the Show Page",
"version": {
"fr": "1.1.77",
"to": "1.2.50"
}
},
"betamaxAutoSeekToAdPosition": {
"name": "AutoSeekToAdPosition",
"description": "If true, the player will seek to the ad position when an stop position is registered. Usefull for debugging ads.",
"native_description": "If true, the player will seek to the ad position when an stop position is registered. Usefull for debugging ads.",
"version": {
"fr": "1.2.26",
"to": ""
}
},
"PodcastSponsoredContent": {
"name": "enablePodcastSponsoredContent",
"description": "Enable sponsored content information for podcasts",
"native_description": "Enable sponsored content information for podcasts",
"version": {
"fr": "1.2.26",
"to": "1.2.50"
}
},
"HomeAds": {
"name": "enableHomeAds",
"description": "Enable Fist Impression Takeover ads on Home Page",
"native_description": "Enable Fist Impression Takeover ads on Home Page",
"version": {
"fr": "1.2.31",
"to": ""
}
},
"LearningHomeCard": {
"name": "enableLearningHomeCard",
"description": "Enable Learning Home Card",
"native_description": "Enable Learning Home Card",
"version": {
"fr": "1.2.31",
"to": "1.2.40"
}
},
"BillboardEsperantoMigration": {
"name": "enableBillboardEsperantoMigration",
"description": "Enable esperanto migration for Billboard Ad Format",
"native_description": "Enable esperanto migration for Billboard Ad Format",
"version": {
"fr": "1.2.32",
"to": "1.2.52"
}
},
"LeaderboardEsperantoMigration": {
"name": "enableEsperantoMigrationLeaderboard",
"description": "Enable esperanto Migration for Leaderboard Ad Format",
"native_description": "Enable esperanto Migration for Leaderboard Ad Format",
"version": {
"fr": "1.2.32",
"to": ""
}
},
"SponsoredPlaylistEsperantoMigration": {
"name": "enableSponsoredPlaylistEsperantoMigration",
"description": "Enable esperanto Migration for Sponsored Playlist Ad Formats",
"native_description": "Enable esperanto Migration for Sponsored Playlist Ad Formats",
"version": {
"fr": "1.2.32",
"to": "1.2.50"
}
},
"PipImpressionLogging": {
"name": "enablePipImpressionLogging",
"description": "Enables impression logging for PiP",
"native_description": "Enables impression logging for PiP",
"version": {
"fr": "1.2.32",
"to": "1.2.78"
}
},
"SwitchingBetweenHomeAdsAndHpto": {
"name": "allowSwitchingBetweenHomeAdsAndHpto",
"description": "Allow switching between the new Home Ads format and legacy HPTO format (as opposed to only showing the legacy HPTO format)",
"native_description": "Allow switching between the new Home Ads format and legacy HPTO format (as opposed to only showing the legacy HPTO format)",
"version": {
"fr": "1.2.34",
"to": ""
}
},
"LyricsUpsell": {
"name": "enableLyricsUpsell",
"description": "Enable Lyrics Upsell",
"native_description": "Enable Lyrics Upsell",
"version": {
"fr": "1.2.36",
"to": ""
}
},
"ArtistNPVImpressionsLogging": {
"name": "enableArtistNPVImpressions",
"description": "Enables impression logging for the Artist About section in NPV",
"native_description": "Enables impression logging for the Artist About section in NPV",
"version": {
"fr": "1.2.37",
"to": "1.2.50"
}
},
"SpotlightImpressionLogging": {
"name": "enableSpotlightImpressionLogging",
"description": "Enables impression logging for Spotlight",
"native_description": "Enables impression logging for Spotlight",
"version": {
"fr": "1.2.37",
"to": "1.2.50"
}
},
"EnhanceLikedSongs": {
"name": "enableEnhanceLikedSongs",
"description": "disabled on the server side",
"native_description": "Enable Enhance Liked Songs UI and functionality",
"version": {
"fr": "1.1.86",
"to": "1.2.25"
}
},
"EnhancePlaylist": {
"name": "enableEnhancePlaylistProd",
"description": "disabled on the server side",
"native_description": "Enable Enhance Playlist UI and functionality for end-users",
"version": {
"fr": "1.1.84",
"to": "1.2.25"
}
},
"SurveyAds": {
"name": "enableSurveyAds",
"description": "Enable Spotify Brand Lift (SBL) Surveys in the NPV",
"native_description": "Enable Spotify Brand Lift (SBL) Surveys in the NPV",
"version": {
"fr": "1.2.43",
"to": "1.2.63"
}
},
"EFlag": {
"name": "enableEFlag",
"description": "Enables the Employee Flag to send to Sentry",
"native_description": "Enables the Employee Flag to send to Sentry",
"version": {
"fr": "1.2.44",
"to": ""
}
},
"HomeImpressions": {
"name": "enableHomeImpressions",
"description": "Enable impressions on home for impression economy (some impressions will still be logged with this disabled)",
"native_description": "Enable impressions on home for impression economy (some impressions will still be logged with this disabled)",
"version": {
"fr": "1.2.44",
"to": "1.2.63"
}
},
"SearchImpressions": {
"name": "enableSearchImpressions",
"description": "Enable impressions on search for impression economy",
"native_description": "Enable impressions on search for impression economy",
"version": {
"fr": "1.2.44",
"to": "1.2.63"
}
},
"StageDesktopDebug": {
"name": "enableTheStageDesktopDebug",
"description": "Enable debug messages for The Stage",
"native_description": "Enable debug messages for The Stage",
"version": {
"fr": "1.2.51",
"to": ""
}
},
"NewAdsNpvCanvasAds": {
"name": "enableNewAdsNpvCanvasAds",
"description": "Enable Canvas ads for new ads NPV",
"native_description": "Enable Canvas ads for new ads NPV",
"version": {
"fr": "1.2.28",
"to": "1.2.51"
}
},
"CanvasAds": {
"name": "enableCanvasAds",
"description": "Enable Canvas for ads",
"native_description": "Enable Canvas for ads",
"version": {
"fr": "1.2.52",
"to": ""
}
},
"ConnectedStateObserver": {
"name": "enableConnectedStateObserver",
"description": "Enable observer that logs errors related to connected state and ad info",
"native_description": "Enable observer that logs errors related to connected state and ad info",
"version": {
"fr": "1.2.53",
"to": ""
}
},
"EsperantoAdStateReportManager": {
"name": "enableEsperantoAdStateReportManager",
"description": "Enables esperanto migration of the adStateReportManager",
"native_description": "Enables esperanto migration of the adStateReportManager",
"version": {
"fr": "1.2.55",
"to": "1.2.60"
}
},
"EventsInYourLibrary": {
"name": "enableEventsInYourLibrary",
"description": "Enable event chips and event items in your library",
"native_description": "Enable event chips and event items in your library",
"version": {
"fr": "1.2.55",
"to": "1.2.71"
}
},
"LeavebehindsMockData": {
"name": "enableLeavebehindsMockData",
"description": "Use the mock2 endpoint to fetch Leavebehinds from AP4P",
"native_description": "Use the mock2 endpoint to fetch Leavebehinds from AP4P",
"version": {
"fr": "1.2.30",
"to": ""
}
},
"fixColorLyricsBug": {
"name": "enableDynamicColors",
"description": "if disabled then it fixes the bug with dynamic colors in lyrics",
"native_description": "Enable dynamic colors for the app",
"version": {
"fr": "1.2.47",
"to": "1.2.56"
}
},
"EmbeddedNpvAds": {
"name": "enableEmbeddedNpvAds",
"description": "Enable embedded display ads on NPV",
"native_description": "Enable embedded display ads on NPV",
"version": {
"fr": "1.2.57",
"to": "1.2.77"
}
},
"EnhancedAdsClientDeconfliction": {
"name": "enableEnhancedAdsClientDeconfliction",
"description": "Enable refactored version of ads orchestrator middleware",
"native_description": "Enable refactored version of ads orchestrator middleware",
"version": {
"fr": "1.2.57",
"to": "1.2.61"
}
},
"AdCountUi": {
"name": "enableAdCountUi",
"description": "Enable ad count feedback in NPV",
"native_description": "Enable ad count feedback in NPV",
"version": {
"fr": "1.2.59",
"to": "1.2.82"
}
},
"SaxLeaderboardAds": {
"name": "enableSaxLeaderboardAds",
"description": "Enable SAX Leaderboard Ad Format",
"native_description": "Enable SAX Leaderboard Ad Format",
"version": {
"fr": "1.2.62",
"to": "1.2.82"
}
},
"EmbeddedAdVisibilityLogging": {
"name": "enableEmbeddedAdVisibilityLogging",
"description": "When enabled, enhanced visibility logs will be sent for embedded ads",
"native_description": "EWhen enabled, enhanced visibility logs will be sent for embedded ads",
"version": {
"fr": "1.2.63",
"to": "1.2.77"
}
},
"Hpto": {
"name": "enableHpto",
"description": "Enable Hpto announcements on Home",
"native_description": "Enable Hpto announcements on Home",
"version": {
"fr": "1.2.65",
"to": ""
}
},
"SponsoredPlaylistV2": {
"name": "enableSponsoredPlaylistV2",
"description": "Enables the new suite of interfaces for Sponsored Playlists V2",
"native_description": "Enables the new suite of interfaces for Sponsored Playlists V2",
"version": {
"fr": "1.2.66",
"to": ""
}
},
"SponsoredPlaylistV2ScrollCard": {
"name": "enableSponsoredPlaylistV2ScrollCard",
"description": "Enables the music NPV scroll card rendering during a sponsored playlist playback",
"native_description": "Enables the music NPV scroll card rendering during a sponsored playlist playback",
"version": {
"fr": "1.2.66",
"to": ""
}
},
"EmbeddedAdsCarousel": {
"name": "enableEmbeddedAdsCarousel",
"description": "Enable embedded ads carousel for the NPV",
"native_description": "Enable embedded ads carousel for the NPV",
"version": {
"fr": "1.2.73",
"to": ""
}
},
"EmbeddedAdsFetchingOverCanvas": {
"name": "enableEmbeddedAdsFetchingOverCanvas",
"description": "Enable embedded ads fetching when canvas track is playing. Defaults to true since this is currently existing behavior",
"native_description": "Enable embedded ads fetching when canvas track is playing. Defaults to true since this is currently existing behavior",
"version": {
"fr": "1.2.72",
"to": "1.2.77"
}
},
"SponsoredPlaylistMockEndpoint": {
"name": "enableSponsoredPlaylistMockEndpoint",
"description": "Enables the endpoint to fetch mock sponsorships for e2e testing",
"native_description": "Enables the endpoint to fetch mock sponsorships for e2e testing",
"version": {
"fr": "1.2.74",
"to": ""
}
},
"WatchFeedPreviewReporting": {
"name": "enableWatchFeedPreviewReporting",
"description": "Enable watch feed preview reporting (requires enableOutroPreviewReporting)",
"native_description": "Enable watch feed preview reporting (requires enableOutroPreviewReporting)",
"version": {
"fr": "1.2.70",
"to": ""
}
},
"AgeAssuranceContent": {
"name": "enableAgeAssuranceContent",
"description": "Enables the age assurance feature for content aspects (e.g., switch to video)",
"native_description": "Enables the age assurance feature for content aspects (e.g., switch to video)",
"version": {
"fr": "1.2.77",
"to": ""
}
},
"AgeAssuranceFriendActivity": {
"name": "enableAgeAssuranceFriendActivity",
"version": {
"fr": "1.2.78",
"to": ""
}
},
"AgeAssuranceComments": {
"name": "enableAgeAssuranceComments",
"version": {
"fr": "1.2.78",
"to": ""
}
},
"AgeAssuranceProfileMenu": {
"name": "enableAgeAssuranceProfileMenu",
"version": {
"fr": "1.2.78",
"to": ""
}
},
"AgeAssuranceSettings": {
"name": "enableAgeAssuranceSettings",
"version": {
"fr": "1.2.78",
"to": ""
}
},
"UnderAgeBlockingModal": {
"name": "enableUnderAgeBlockingModal",
"native_description": "Enables the underage blocking modal for accounts in blocked/pending disabled state",
"version": {
"fr": "1.2.78",
"to": ""
}
},
"AdImpressionDoesNotIgnoreVisilibility": {
"name": "embeddedAdImpressionDoesNotIgnoreVisilibility",
"native_description": "If enabled, we do consider percent visibility when logging the display ad impression",
"version": {
"fr": "1.2.78",
"to": ""
}
},
"MadeForYou": {
"name": "enableMadeForYouEntryPoint",
"description": "Show 'Made For You' entry point in the left sidebar",
"version": {
"fr": "1.1.67",
"to": "1.1.95"
}
},
"bypassApplyUpdateCheck": {
"name": "bypassApplyUpdateCheck",
"version": {
"fr": "1.2.84",
"to": ""
}
}
},
"EnableExp": {
"HomeViaGraphQLV2": {
"name": "enableHomeViaGraphQLV2",
"description": "Enable fetching Home via GraphQL",
"native_description": "Enable fetching Home via GraphQL",
"version": {
"fr": "1.1.86",
"to": "1.1.92"
}
},
"BrowseViaPathfinder": {
"name": "enableBrowseViaPathfinder",
"description": "Fixes a bug on the genres page",
"native_description": "Fetch Browse data from Pathfinder",
"version": {
"fr": "1.1.88",
"to": "1.2.24"
}
},
"IgnoreInRecommendations": {
"name": "enableIgnoreInRecommendations",
"description": "Exclude playlists from recommendations",
"native_description": "Enable Ignore In Recommendations for desktop and web",
"version": {
"fr": "1.1.87",
"to": "1.2.50"
}
},
"Equalizer": {
"name": "enableEqualizer",
"description": "Enable audio equalizer for Desktop and Web Player",
"native_description": "Enable audio equalizer for Desktop and Web Player",
"version": {
"fr": "1.1.88",
"to": ""
}
},
"CarouselsOnHome": {
"name": "enableCarouselsOnHome",
"description": "Directly related to the blocking of podcasts and sections similar to ads on the main page",
"native_description": "Use carousels on Home",
"version": {
"fr": "1.1.93",
"to": "1.2.25"
}
},
"AttackOnTitanEaster": {
"name": "enableAttackOnTitanEasterEgg",
"description": "Enable Attack on Titan Easter egg turning progress bar red when playing official soundtrack",
"native_description": "Enable Attack on Titan Easter egg turning progress bar red when playing official soundtrack",
"version": {
"fr": "1.2.6",
"to": "1.2.50"
}
},
"AlbumReleaseAnniversaries": {
"name": "enableAlbumReleaseAnniversaries",
"description": "Enable showing balloons on album release date anniversaries",
"native_description": "Enable showing balloons on album release date anniversaries",
"version": {
"fr": "1.1.89",
"to": ""
}
},
"ClearAllDownloads": {
"name": "enableClearAllDownloads",
"description": "Enable option in settings to clear all downloads",
"native_description": "Enable option in settings to clear all downloads",
"version": {
"fr": "1.1.92",
"to": "1.1.98"
}
},
"LeftSidebar": {
"name": "enableYLXSidebar",
"description": "Enable Your Library X view of the left sidebar",
"native_description": "Enable Your Library X view of the left sidebar",
"version": {
"fr": "1.2.0",
"to": "1.2.14"
}
},
"RightSidebar": {
"name": "enableRightSidebar",
"description": "Enable the view on the right sidebar",
"native_description": "Enable the view on the right sidebar",
"version": {
"fr": "1.1.98",
"to": "1.2.23"
}
},
"AddPlaylistToPlaylist": {
"name": "enableAddPlaylistToPlaylist",
"description": "Enable support for adding a playlist to another playlist",
"native_description": "Enable support for adding a playlist to another playlist",
"version": {
"fr": "1.1.98",
"to": "1.2.3"
}
},
"RightSidebarLyrics": {
"name": "enableRightSidebarLyrics",
"description": "Show lyrics in the right sidebar (disables lyrics on bottom bar)",
"native_description": "Show lyrics in the right sidebar",
"version": {
"fr": "1.2.0",
"to": "1.2.61"
}
},
"RightSidebarColors": {
"name": "enableRightSidebarExtractedColors",
"description": "Extract background color based on artwork image",
"native_description": "Extract background color based on artwork image",
"version": {
"fr": "1.2.1",
"to": "1.2.78"
}
},
"SilenceTrimmer": {
"name": "enableSilenceTrimmer",
"description": "Enable silence trimming in podcasts",
"native_description": "Enable silence trimming in podcasts",
"version": {
"fr": "1.1.99",
"to": ""
}
},
"PlaybackSpeedIncrements": {
"name": "enableSmallPlaybackSpeedIncrements",
"description": "playback speed range from 0.5-3.5 with every 0.1 increment (in podcasts)",
"native_description": "playback speed range from 0.5-3.5 with every 0.1 increment",
"version": {
"fr": "1.2.0",
"to": "1.2.14"
}
},
"ShowFollowsSetting": {
"name": "enableShowFollowsSetting",
"description": "Enable a setting to control if followers and following lists are shown on profile",
"native_description": "Enable a setting to control if followers and following lists are shown on profile",
"version": {
"fr": "1.2.1",
"to": "1.2.50"
}
},
"RightSidebarCredits": {
"name": "enableRightSidebarCredits",
"description": "Show credits in the right sidebar",
"native_description": "Show credits in the right sidebar",
"version": {
"fr": "1.2.7",
"to": "1.2.25"
}
},
"WhatsNewFeed": {
"name": "enableWhatsNewFeed",
"description": "Enable the what's new feed panel",
"native_description": "Enable the what's new feed panel",
"version": {
"fr": "1.2.12",
"to": "1.2.16"
}
},
"WhatsNewFeedMainView": {
"name": "enableWhatsNewFeedMainView",
"description": "Enable Whats new feed in the main view",
"native_description": "Enable Whats new feed in the main view",
"version": {
"fr": "1.2.17",
"to": "1.2.45"
}
},
"RightSidebarArtistEnhanced": {
"name": "enableRightSidebarArtistEnhanced",
"description": "Enable Artist about V2 section in NPV",
"native_description": "Enable Artist about V2 section in NPV",
"version": {
"fr": "1.2.16",
"to": "1.2.50"
}
},
"NewEntityHeaders": {
"name": "enableNewEntityHeaders",
"description": "Enable New Entity Headers",
"native_description": "Enable New Entity Headers",
"version": {
"fr": "1.2.15",
"to": "1.2.27"
}
},
"ReadAlongTranscripts": {
"name": "enableReadAlongTranscripts",
"description": "Enable read along transcripts in the NPV",
"native_description": "Enable read along transcripts in the NPV",
"version": {
"fr": "1.2.17",
"to": "1.2.62"
}
},
"RightSidebarTransitionAnimations": {
"name": "enableRightSidebarTransitionAnimations",
"description": "Enable the slide-in/out transition on the right sidebar",
"native_description": "Enable the slide-in/out transition on the right sidebar",
"version": {
"fr": "1.2.8",
"to": "1.2.33"
}
},
"YLXEnhancements": {
"name": "enableYLXEnhancements",
"description": "Enable Your Library X Enhancements",
"native_description": "Enable Your Library X Enhancements",
"version": {
"fr": "1.2.18",
"to": "1.2.50"
}
},
"SmallerLineHeight": {
"name": "enableSmallerLineHeight",
"description": "Enable line height 1.5 on the