Browse Source

ref!: update to userutils v9

Sv443 3 months ago
parent
commit
92e3e7aa6a

+ 220 - 313
dist/BetterYTM.user.js

@@ -1,101 +1,203 @@
-// ==UserScript==
-// @name              BetterYTM
-// @namespace         https://github.com/Sv443/BetterYTM
-// @version           2.2.0
-// @description       Lots of configurable layout and user experience improvements for YouTube Music™ and YouTube™
-// @homepageURL       https://github.com/Sv443/BetterYTM#readme
-// @supportURL        https://github.com/Sv443/BetterYTM/issues
-// @license           AGPL-3.0-only
-// @author            Sv443
-// @copyright         Sv443 (https://github.com/Sv443)
-// @icon              https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/assets/images/logo/logo_dev_48.png
-// @match             https://music.youtube.com/*
-// @match             https://www.youtube.com/*
-// @run-at            document-start
-// @description:de-DE Konfigurierbare Layout- und Benutzererfahrungs-Verbesserungen für YouTube Music™ und YouTube™
-// @description:de    Konfigurierbare Layout- und Benutzererfahrungs-Verbesserungen für YouTube Music™ und YouTube™
-// @description:de-AT Konfigurierbare Layout- und Benutzererfahrungs-Verbesserungen für YouTube Music™ und YouTube™
-// @description:de-CH Konfigurierbare Layout- und Benutzererfahrungs-Verbesserungen für YouTube Music™ und YouTube™
-// @description:de-LI Konfigurierbare Layout- und Benutzererfahrungs-Verbesserungen für YouTube Music™ und YouTube™
-// @description:de-LU Konfigurierbare Layout- und Benutzererfahrungs-Verbesserungen für YouTube Music™ und YouTube™
-// @description:en-US Configurable layout and user experience improvements for YouTube Music™ and YouTube™
-// @description:en    Configurable layout and user experience improvements for YouTube Music™ and YouTube™
-// @description:en-CA Configurable layout and user experience improvements for YouTube Music™ and YouTube™
-// @description:en-GB Configurable layout and user experience improvements for YouTube Music™ and YouTube™
-// @description:en-AU Configurable layout and user experience improvements for YouTube Music™ and YouTube™
-// @description:en-IE Configurable layout and user experience improvements for YouTube Music™ and YouTube™
-// @description:en-NZ Configurable layout and user experience improvements for YouTube Music™ and YouTube™
-// @description:en-ZA Configurable layout and user experience improvements for YouTube Music™ and YouTube™
-// @description:es-ES Mejoras de diseño y experiencia de usuario configurables para YouTube Music™ y YouTube™
-// @description:es    Mejoras de diseño y experiencia de usuario configurables para YouTube Music™ y YouTube™
-// @description:es-MX Mejoras de diseño y experiencia de usuario configurables para YouTube Music™ y YouTube™
-// @description:fr-FR Améliorations de la mise en page et de l'expérience utilisateur configurables pour YouTube Music™ et YouTube™
-// @description:fr    Améliorations de la mise en page et de l'expérience utilisateur configurables pour YouTube Music™ et YouTube™
-// @description:fr-CA Améliorations de la mise en page et de l'expérience utilisateur configurables pour YouTube Music™ et YouTube™
-// @description:fr-BE Améliorations de la mise en page et de l'expérience utilisateur configurables pour YouTube Music™ et YouTube™
-// @description:fr-CH Améliorations de la mise en page et de l'expérience utilisateur configurables pour YouTube Music™ et YouTube™
-// @description:fr-LU Améliorations de la mise en page et de l'expérience utilisateur configurables pour YouTube Music™ et YouTube™
-// @description:hi-IN YouTube Music™ और YouTube™ के लिए कॉन्फ़िगर करने योग्य लेआउट और उपयोगकर्ता अनुभव में सुधार
-// @description:hi    YouTube Music™ और YouTube™ के लिए कॉन्फ़िगर करने योग्य लेआउट और उपयोगकर्ता अनुभव में सुधार
-// @description:hi-NP YouTube Music™ और YouTube™ के लिए कॉन्फ़िगर करने योग्य लेआउट और उपयोगकर्ता अनुभव में सुधार
-// @description:ja-JP YouTube Music™ と YouTube™ の構成可能なレイアウトとユーザー エクスペリエンスの向上
-// @description:ja    YouTube Music™ と YouTube™ の構成可能なレイアウトとユーザー エクスペリエンスの向上
-// @description:pt-BR Melhorias configuráveis no layout e na experiência do usuário para o YouTube Music™ e o YouTube™
-// @description:pt    Melhorias configuráveis no layout e na experiência do usuário para o YouTube Music™ e o YouTube™
-// @description:pt-PT Melhorias configuráveis no layout e na experiência do usuário para o YouTube Music™ e o YouTube™
-// @description:zh-CN YouTube Music™ 和 YouTube™ 的可配置布局和用户体验改进
-// @description:zh    YouTube Music™ 和 YouTube™ 的可配置布局和用户体验改进
-// @description:zh-TW YouTube Music™ 和 YouTube™ 的可配置布局和用户体验改进
-// @description:zh-HK YouTube Music™ 和 YouTube™ 的可配置布局和用户体验改进
-// @description:zh-SG YouTube Music™ 和 YouTube™ 的可配置布局和用户体验改进
-// @connect           api.sv443.net
-// @connect           github.com
-// @connect           raw.githubusercontent.com
-// @connect           youtube.com
-// @connect           returnyoutubedislikeapi.com
-// @noframes
-// @grant             GM.getValue
-// @grant             GM.setValue
-// @grant             GM.deleteValue
-// @grant             GM.getResourceUrl
-// @grant             GM.setClipboard
-// @grant             GM.xmlHttpRequest
-// @grant             GM.openInTab
-// @grant             unsafeWindow
-// @resource          css-above_queue_btns        https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/assets/style/aboveQueueBtns.css#sha256=S+Pkz9xm785iQ5mmX+Z0RZgaCgPvCHqVIKOTX9r/Nt8=
-// @resource          css-above_queue_btns_sticky https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/assets/style/aboveQueueBtnsSticky.css#sha256=BJX5ju+5L+4asy16iF3XOuiJUlPg5KNXkcGennJWGB0=
-// @resource          css-anchor_improvements     https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/assets/style/anchorImprovements.css#sha256=9WSAxeL1Tiv7ZCKrocNrvrQNWSbVY8/bv6wzf0lJ9pg=
-// @resource          css-auto_like               https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/assets/style/autoLike.css#sha256=A4O2rPsBXjugn0EnF5e1L68Kn3KR7Qm9nlwqe8XWMTM=
-// @resource          css-bundle                  https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/dist/BetterYTM.css#sha256=uqAnIweqbddc+SDYDXGJS1z8G3W86xvSLkKnRWedhq8=
-// @resource          css-fix_hdr                 https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/assets/style/fixHDR.css#sha256=4GeuAroKiRD1asFe6cQ1UiSg+p82Jyl/8JeWXLNTgL8=
-// @resource          css-fix_playerpage_theming  https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/assets/style/fixPlayerPageTheming.css#sha256=7xS+bvp7TJFdzyKztER8xYtsLhinTU1dAdmzuO057p0=
-// @resource          css-fix_spacing             https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/assets/style/fixSpacing.css#sha256=T57yRp87wz/ye3i4MTRh/o7cFaQsUom4yjG/Kp4eevM=
-// @resource          css-fix_sponsorblock        https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/assets/style/fixSponsorBlock.css#sha256=KY3RepJ8BaLPTM2n1+irvZUJCLlC0i2EiLzKRgz6z38=
-// @resource          css-hide_themesong_logo     https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/assets/style/hideThemeSongLogo.css#sha256=Nvr0CaLm23d5dNlJ2bOaxLw2cHfH8KBnpPCbmbXgnOE=
-// @resource          css-show_votes              https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/assets/style/showVotes.css#sha256=Zxm4eBmg6GtFMCnzWRZXW08nr4pwk6aUCMb8x8xIsJU=
-// @resource          css-vol_slider_size         https://cdn.jsdelivr.net/gh/Sv443/BetterYTM@739f1734/assets/style/volSliderSize.css#sha256=WKE/i2XjuE2HYfOkZ9N4QtEgKsWdrhMXZyb2cc+iAAk=
-// @require           https://cdn.jsdelivr.net/npm/@sv443-network/[email protected]/dist/index.global.js
-// @require           https://cdn.jsdelivr.net/npm/[email protected]/lib/marked.umd.js
-// @require           https://cdn.jsdelivr.net/npm/[email protected]/lib/umd/index.js
-// @require           https://cdn.jsdelivr.net/npm/[email protected]
-// @grant             GM.registerMenuCommand
-// @grant             GM.listValues
-// ==/UserScript==
-/*
-▄▄▄                    ▄   ▄▄▄▄▄▄   ▄
-█  █ ▄▄▄ █   █   ▄▄▄ ▄ ▄█ █  █  █▀▄▀█
-█▀▀▄ █▄█ █▀  █▀  █▄█ █▀  █   █  █   █
-█▄▄▀ ▀▄▄ ▀▄▄ ▀▄▄ ▀▄▄ █   █   █  █   █
-
-        Made with ❤️ by Sv443
-I welcome every contribution on GitHub!
-  https://github.com/Sv443/BetterYTM
-*/
-
-/* Disclaimer: I am not affiliated with or endorsed by YouTube, Google, Alphabet, Genius or anyone else */
-/* C&D this 🖕 */
-
-(function(UserUtils,DOMPurify,compareVersions,marked){'use strict';function _interopNamespaceDefault(e){var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var UserUtils__namespace=/*#__PURE__*/_interopNamespaceDefault(UserUtils);var compareVersions__namespace=/*#__PURE__*/_interopNamespaceDefault(compareVersions);// I know TS enums are impure but it doesn't really matter here, plus imo they are cooler than pure enums anyway
+(function(UserUtils,DOMPurify,compareVersions,marked){'use strict';function _interopNamespaceDefault(e){var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var UserUtils__namespace=/*#__PURE__*/_interopNamespaceDefault(UserUtils);var compareVersions__namespace=/*#__PURE__*/_interopNamespaceDefault(compareVersions);var alwaysExternalAssetPatterns = [
+	"^icon-",
+	"^img-",
+	"^font-",
+	"^doc-",
+	"^trans-"
+];
+var resources = {
+	"css-above_queue_btns": "style/aboveQueueBtns.css",
+	"css-above_queue_btns_sticky": "style/aboveQueueBtnsSticky.css",
+	"css-anchor_improvements": "style/anchorImprovements.css",
+	"css-auto_like": "style/autoLike.css",
+	"css-fix_hdr": "style/fixHDR.css",
+	"css-fix_playerpage_theming": "style/fixPlayerPageTheming.css",
+	"css-fix_spacing": "style/fixSpacing.css",
+	"css-fix_sponsorblock": "style/fixSponsorBlock.css",
+	"css-hide_themesong_logo": "style/hideThemeSongLogo.css",
+	"css-show_votes": "style/showVotes.css",
+	"css-vol_slider_size": "style/volSliderSize.css",
+	"doc-license": {
+		path: "/LICENSE.txt",
+		ref: "$BRANCH",
+		integrity: false
+	},
+	"font-cousine_ttf": "fonts/Cousine/Cousine-Regular.ttf",
+	"font-cousine_woff": "fonts/Cousine/Cousine-Regular.woff",
+	"font-cousine_woff2": "fonts/Cousine/Cousine-Regular.woff2",
+	"icon-advanced_mode": "icons/plus_circle_small.svg",
+	"icon-alert": "icons/alert.svg",
+	"icon-arrow_down": "icons/arrow_down.svg",
+	"icon-auto_like_enabled": "icons/auto_like_enabled.svg",
+	"icon-auto_like": "icons/auto_like.svg",
+	"icon-clear_list": "icons/clear_list.svg",
+	"icon-copy": "icons/copy.svg",
+	"icon-delete": "icons/delete.svg",
+	"icon-edit": "icons/edit.svg",
+	"icon-error": "icons/error.svg",
+	"icon-experimental": "icons/beaker_small.svg",
+	"icon-globe_small": "icons/globe_small.svg",
+	"icon-globe": "icons/globe.svg",
+	"icon-help": "icons/help.svg",
+	"icon-image_filled": "icons/image_filled.svg",
+	"icon-image": "icons/image.svg",
+	"icon-link": "icons/link.svg",
+	"icon-lyrics": "icons/lyrics.svg",
+	"icon-prompt": "icons/help.svg",
+	"icon-reload": "icons/refresh.svg",
+	"icon-restore_time": "icons/restore_time.svg",
+	"icon-skip_to": "icons/skip_to.svg",
+	"icon-speed": "icons/speed.svg",
+	"icon-spinner": "icons/spinner.svg",
+	"icon-upload": "icons/upload.svg",
+	"img-close": "images/close.png",
+	"img-discord": "images/external/discord.png",
+	"img-github": "images/external/github.png",
+	"img-greasyfork": "images/external/greasyfork.png",
+	"img-logo_dev": "images/logo/logo_dev_48.png",
+	"img-logo": "images/logo/logo_48.png",
+	"img-openuserjs": "images/external/openuserjs.png",
+	"trans-de-DE": "translations/de-DE.json",
+	"trans-en-US": "translations/en-US.json",
+	"trans-en-GB": "translations/en-GB.json",
+	"trans-es-ES": "translations/es-ES.json",
+	"trans-fr-FR": "translations/fr-FR.json",
+	"trans-hi-IN": "translations/hi-IN.json",
+	"trans-ja-JP": "translations/ja-JP.json",
+	"trans-pt-BR": "translations/pt-BR.json",
+	"trans-zh-CN": "translations/zh-CN.json"
+};
+var resourcesJson = {
+	alwaysExternalAssetPatterns: alwaysExternalAssetPatterns,
+	resources: resources
+};var langMapping = {
+	"de-DE": {
+	name: "Deutsch (Deutschland)",
+	nameEnglish: "German (Germany)",
+	emoji: "🇩🇪",
+	userscriptDesc: "Konfigurierbare Layout- und Benutzererfahrungs-Verbesserungen für YouTube Music™ und YouTube™",
+	authors: [
+		"Sv443"
+	],
+	altLocales: [
+		"de",
+		"de-AT",
+		"de-CH",
+		"de-LI",
+		"de-LU"
+	]
+},
+	"en-US": {
+	name: "English (United States)",
+	nameEnglish: "English (United States)",
+	emoji: "🇺🇸",
+	userscriptDesc: "Configurable layout and user experience improvements for YouTube Music™ and YouTube™",
+	authors: [
+		"Sv443"
+	],
+	altLocales: [
+		"en",
+		"en-CA"
+	]
+},
+	"en-GB": {
+	name: "English (Great Britain)",
+	nameEnglish: "English (Great Britain)",
+	emoji: "🇬🇧",
+	userscriptDesc: "Configurable layout and user experience improvements for YouTube Music™ and YouTube™",
+	authors: [
+		"Sv443"
+	],
+	altLocales: [
+		"en-AU",
+		"en-IE",
+		"en-NZ",
+		"en-ZA"
+	]
+},
+	"es-ES": {
+	name: "Español (España)",
+	nameEnglish: "Spanish (Spain)",
+	emoji: "🇪🇸",
+	userscriptDesc: "Mejoras de diseño y experiencia de usuario configurables para YouTube Music™ y YouTube™",
+	authors: [
+		"Sv443"
+	],
+	altLocales: [
+		"es",
+		"es-MX"
+	]
+},
+	"fr-FR": {
+	name: "Français (France)",
+	nameEnglish: "French (France)",
+	emoji: "🇫🇷",
+	userscriptDesc: "Améliorations de la mise en page et de l'expérience utilisateur configurables pour YouTube Music™ et YouTube™",
+	authors: [
+		"Sv443"
+	],
+	altLocales: [
+		"fr",
+		"fr-CA",
+		"fr-BE",
+		"fr-CH",
+		"fr-LU"
+	]
+},
+	"hi-IN": {
+	name: "हिंदी (भारत)",
+	nameEnglish: "Hindi (India)",
+	emoji: "🇮🇳",
+	userscriptDesc: "YouTube Music™ और YouTube™ के लिए कॉन्फ़िगर करने योग्य लेआउट और उपयोगकर्ता अनुभव में सुधार",
+	authors: [
+		"Sv443"
+	],
+	altLocales: [
+		"hi",
+		"hi-NP"
+	]
+},
+	"ja-JP": {
+	name: "日本語 (日本)",
+	nameEnglish: "Japanese (Japan)",
+	emoji: "🇯🇵",
+	userscriptDesc: "YouTube Music™ と YouTube™ の構成可能なレイアウトとユーザー エクスペリエンスの向上",
+	authors: [
+		"Sv443"
+	],
+	altLocales: [
+		"ja"
+	]
+},
+	"pt-BR": {
+	name: "Português (Brasil)",
+	nameEnglish: "Portuguese (Brazil)",
+	emoji: "🇧🇷",
+	userscriptDesc: "Melhorias configuráveis no layout e na experiência do usuário para o YouTube Music™ e o YouTube™",
+	authors: [
+		"Sv443"
+	],
+	altLocales: [
+		"pt",
+		"pt-PT"
+	]
+},
+	"zh-CN": {
+	name: "中文(简化,中国)",
+	nameEnglish: "Chinese (Simplified, China)",
+	emoji: "🇨🇳",
+	userscriptDesc: "YouTube Music™ 和 YouTube™ 的可配置布局和用户体验改进",
+	authors: [
+		"Sv443"
+	],
+	altLocales: [
+		"zh",
+		"zh-TW",
+		"zh-HK",
+		"zh-SG"
+	]
+}
+};// I know TS enums are impure but it doesn't really matter here, plus imo they are cooler than pure enums anyway
 var LogLevel;
 (function (LogLevel) {
     LogLevel[LogLevel["Debug"] = 0] = "Debug";
@@ -126,12 +228,12 @@ var PluginIntent;
     /** Plugin can write to auto-like data */
     PluginIntent[PluginIntent["WriteAutoLikeData"] = 128] = "WriteAutoLikeData";
 })(PluginIntent || (PluginIntent = {}));// these strings will have their values replaced by the post-build script:
-const modeRaw = "development";
-const branchRaw = "develop";
-const hostRaw = "github";
-const buildNumberRaw = "739f1734";
-const assetSourceRaw = "jsdelivr";
-const devServerPortRaw = "8710";
+const modeRaw = "#{{MODE}}";
+const branchRaw = "#{{BRANCH}}";
+const hostRaw = "#{{HOST}}";
+const buildNumberRaw = "#{{BUILD_NUMBER}}";
+const assetSourceRaw = "#{{ASSET_SOURCE}}";
+const devServerPortRaw = "#{{DEV_SERVER_PORT}}";
 const getRawVal = (rawVal, defaultVal) => (rawVal.match(/^#{{.+}}$/) ? defaultVal : rawVal);
 /** Path to the GitHub repo */
 const repo = "Sv443/BetterYTM";
@@ -264,138 +366,10 @@ function addLyricsCacheEntryBest(artist, song, url) {
     log("Added cache entry for best result", artist, "-", song, "\n", entry);
     emitInterface("bytm:lyricsCacheEntryAdded", { entry, type: "best" });
     return lyricsCacheMgr.setData({ cache });
-}var langMapping = {
-	"de-DE": {
-	name: "Deutsch (Deutschland)",
-	nameEnglish: "German (Germany)",
-	emoji: "🇩🇪",
-	userscriptDesc: "Konfigurierbare Layout- und Benutzererfahrungs-Verbesserungen für YouTube Music™ und YouTube™",
-	authors: [
-		"Sv443"
-	],
-	altLocales: [
-		"de",
-		"de-AT",
-		"de-CH",
-		"de-LI",
-		"de-LU"
-	]
-},
-	"en-US": {
-	name: "English (United States)",
-	nameEnglish: "English (United States)",
-	emoji: "🇺🇸",
-	userscriptDesc: "Configurable layout and user experience improvements for YouTube Music™ and YouTube™",
-	authors: [
-		"Sv443"
-	],
-	altLocales: [
-		"en",
-		"en-CA"
-	]
-},
-	"en-GB": {
-	name: "English (Great Britain)",
-	nameEnglish: "English (Great Britain)",
-	emoji: "🇬🇧",
-	userscriptDesc: "Configurable layout and user experience improvements for YouTube Music™ and YouTube™",
-	authors: [
-		"Sv443"
-	],
-	altLocales: [
-		"en-AU",
-		"en-IE",
-		"en-NZ",
-		"en-ZA"
-	]
-},
-	"es-ES": {
-	name: "Español (España)",
-	nameEnglish: "Spanish (Spain)",
-	emoji: "🇪🇸",
-	userscriptDesc: "Mejoras de diseño y experiencia de usuario configurables para YouTube Music™ y YouTube™",
-	authors: [
-		"Sv443"
-	],
-	altLocales: [
-		"es",
-		"es-MX"
-	]
-},
-	"fr-FR": {
-	name: "Français (France)",
-	nameEnglish: "French (France)",
-	emoji: "🇫🇷",
-	userscriptDesc: "Améliorations de la mise en page et de l'expérience utilisateur configurables pour YouTube Music™ et YouTube™",
-	authors: [
-		"Sv443"
-	],
-	altLocales: [
-		"fr",
-		"fr-CA",
-		"fr-BE",
-		"fr-CH",
-		"fr-LU"
-	]
-},
-	"hi-IN": {
-	name: "हिंदी (भारत)",
-	nameEnglish: "Hindi (India)",
-	emoji: "🇮🇳",
-	userscriptDesc: "YouTube Music™ और YouTube™ के लिए कॉन्फ़िगर करने योग्य लेआउट और उपयोगकर्ता अनुभव में सुधार",
-	authors: [
-		"Sv443"
-	],
-	altLocales: [
-		"hi",
-		"hi-NP"
-	]
-},
-	"ja-JP": {
-	name: "日本語 (日本)",
-	nameEnglish: "Japanese (Japan)",
-	emoji: "🇯🇵",
-	userscriptDesc: "YouTube Music™ と YouTube™ の構成可能なレイアウトとユーザー エクスペリエンスの向上",
-	authors: [
-		"Sv443"
-	],
-	altLocales: [
-		"ja"
-	]
-},
-	"pt-BR": {
-	name: "Português (Brasil)",
-	nameEnglish: "Portuguese (Brazil)",
-	emoji: "🇧🇷",
-	userscriptDesc: "Melhorias configuráveis no layout e na experiência do usuário para o YouTube Music™ e o YouTube™",
-	authors: [
-		"Sv443"
-	],
-	altLocales: [
-		"pt",
-		"pt-PT"
-	]
-},
-	"zh-CN": {
-	name: "中文(简化,中国)",
-	nameEnglish: "Chinese (Simplified, China)",
-	emoji: "🇨🇳",
-	userscriptDesc: "YouTube Music™ 和 YouTube™ 的可配置布局和用户体验改进",
-	authors: [
-		"Sv443"
-	],
-	altLocales: [
-		"zh",
-		"zh-TW",
-		"zh-HK",
-		"zh-SG"
-	]
-}
-};/** Contains the identifiers of all initialized and loaded translation locales */
+}/** Contains the identifiers of all initialized and loaded translation locales */
 const initializedLocales = new Set();
 /** Initializes the translations */
 async function initTranslations(locale) {
-    var _a, _b;
     if (initializedLocales.has(locale))
         return;
     initializedLocales.add(locale);
@@ -405,8 +379,10 @@ async function initTranslations(locale) {
         if (getFeature("localeFallback"))
             fallbackTrans = await fetchLocaleJson("en-US");
         // merge with base translations if specified
-        const baseTransFile = transFile.base ? await fetchLocaleJson(transFile.base) : undefined;
-        const translations = Object.assign(Object.assign(Object.assign({}, ((_a = fallbackTrans === null || fallbackTrans === void 0 ? void 0 : fallbackTrans.translations) !== null && _a !== void 0 ? _a : {})), ((_b = baseTransFile === null || baseTransFile === void 0 ? void 0 : baseTransFile.translations) !== null && _b !== void 0 ? _b : {})), transFile.translations);
+        const baseTransFile = typeof (transFile === null || transFile === void 0 ? void 0 : transFile.meta) === "object" && "base" in transFile.meta && typeof transFile.meta.base === "string"
+            ? await fetchLocaleJson(transFile.base)
+            : undefined;
+        const translations = Object.assign(Object.assign(Object.assign({}, (fallbackTrans !== null && fallbackTrans !== void 0 ? fallbackTrans : {})), (baseTransFile !== null && baseTransFile !== void 0 ? baseTransFile : {})), transFile);
         UserUtils.tr.addLanguage(locale, translations);
         info(`Loaded translations for locale '${locale}'`);
     }
@@ -2105,10 +2081,11 @@ var main = "./src/index.ts";
 var type = "module";
 var scripts = {
 	dev: "concurrently \"nodemon --exec pnpm run build-private-dev\" \"pnpm run serve\"",
+	"dev-local": "concurrently \"nodemon --exec pnpm run build-private-dev --config-assetSource=local\" \"pnpm run serve\"",
 	serve: "pnpm run node-ts ./src/tools/serve.ts",
 	lint: "eslint . && tsc --noEmit",
 	build: "rollup -c",
-	"build-private-dev": "rollup -c --config-mode development --config-host github --config-branch develop --config-assetSource=local",
+	"build-private-dev": "rollup -c --config-mode development --config-host github --config-branch develop",
 	"build-dev": "rollup -c --config-mode development --config-host github --config-branch develop",
 	preview: "pnpm run build-prod-gh --config-assetSource=local && pnpm run serve --auto-exit-time=6",
 	"build-prod": "pnpm run build-prod-gh && pnpm run build-prod-gf && pnpm run build-prod-oujs",
@@ -2160,7 +2137,7 @@ var updates = {
 	openuserjs: "https://openuserjs.org/scripts/Sv443/BetterYTM"
 };
 var dependencies = {
-	"@sv443-network/userutils": "^8.4.0",
+	"@sv443-network/userutils": "^9.0.2",
 	"compare-versions": "^6.1.0",
 	dompurify: "^3.1.6",
 	marked: "^12.0.2",
@@ -4101,79 +4078,7 @@ class PluginError extends Error {
         super(message);
         this.name = "PluginError";
     }
-}var alwaysExternalAssetPatterns = [
-	"^icon-",
-	"^img-",
-	"^font-",
-	"^doc-",
-	"^trans-"
-];
-var resources = {
-	"css-above_queue_btns": "style/aboveQueueBtns.css",
-	"css-above_queue_btns_sticky": "style/aboveQueueBtnsSticky.css",
-	"css-anchor_improvements": "style/anchorImprovements.css",
-	"css-auto_like": "style/autoLike.css",
-	"css-fix_hdr": "style/fixHDR.css",
-	"css-fix_playerpage_theming": "style/fixPlayerPageTheming.css",
-	"css-fix_spacing": "style/fixSpacing.css",
-	"css-fix_sponsorblock": "style/fixSponsorBlock.css",
-	"css-hide_themesong_logo": "style/hideThemeSongLogo.css",
-	"css-show_votes": "style/showVotes.css",
-	"css-vol_slider_size": "style/volSliderSize.css",
-	"doc-license": {
-		path: "/LICENSE.txt",
-		ref: "$BRANCH",
-		integrity: false
-	},
-	"font-cousine_ttf": "fonts/Cousine/Cousine-Regular.ttf",
-	"font-cousine_woff": "fonts/Cousine/Cousine-Regular.woff",
-	"font-cousine_woff2": "fonts/Cousine/Cousine-Regular.woff2",
-	"icon-advanced_mode": "icons/plus_circle_small.svg",
-	"icon-alert": "icons/alert.svg",
-	"icon-arrow_down": "icons/arrow_down.svg",
-	"icon-auto_like_enabled": "icons/auto_like_enabled.svg",
-	"icon-auto_like": "icons/auto_like.svg",
-	"icon-clear_list": "icons/clear_list.svg",
-	"icon-copy": "icons/copy.svg",
-	"icon-delete": "icons/delete.svg",
-	"icon-edit": "icons/edit.svg",
-	"icon-error": "icons/error.svg",
-	"icon-experimental": "icons/beaker_small.svg",
-	"icon-globe_small": "icons/globe_small.svg",
-	"icon-globe": "icons/globe.svg",
-	"icon-help": "icons/help.svg",
-	"icon-image_filled": "icons/image_filled.svg",
-	"icon-image": "icons/image.svg",
-	"icon-link": "icons/link.svg",
-	"icon-lyrics": "icons/lyrics.svg",
-	"icon-prompt": "icons/help.svg",
-	"icon-reload": "icons/refresh.svg",
-	"icon-restore_time": "icons/restore_time.svg",
-	"icon-skip_to": "icons/skip_to.svg",
-	"icon-speed": "icons/speed.svg",
-	"icon-spinner": "icons/spinner.svg",
-	"icon-upload": "icons/upload.svg",
-	"img-close": "images/close.png",
-	"img-discord": "images/external/discord.png",
-	"img-github": "images/external/github.png",
-	"img-greasyfork": "images/external/greasyfork.png",
-	"img-logo_dev": "images/logo/logo_dev_48.png",
-	"img-logo": "images/logo/logo_48.png",
-	"img-openuserjs": "images/external/openuserjs.png",
-	"trans-de-DE": "translations/de-DE.json",
-	"trans-en-US": "translations/en-US.json",
-	"trans-en-GB": "translations/en-GB.json",
-	"trans-es-ES": "translations/es-ES.json",
-	"trans-fr-FR": "translations/fr-FR.json",
-	"trans-hi-IN": "translations/hi-IN.json",
-	"trans-ja-JP": "translations/ja-JP.json",
-	"trans-pt-BR": "translations/pt-BR.json",
-	"trans-zh-CN": "translations/zh-CN.json"
-};
-var resourcesJson = {
-	alwaysExternalAssetPatterns: alwaysExternalAssetPatterns,
-	resources: resources
-};//#region misc
+}//#region misc
 let domain;
 /**
  * Returns the current domain as a constant string representation
@@ -5902,10 +5807,12 @@ async function checkSharedVolume() {
 async function setInitialTabVolume(sliderElem) {
     const reloadTabVol = Number(await GM.getValue("bytm-reload-tab-volume", 0));
     GM.deleteValue("bytm-reload-tab-volume").catch(() => void 0);
-    if (!getFeature("setInitialTabVolume") || reloadTabVol === 0 || isNaN(reloadTabVol))
+    if ((isNaN(reloadTabVol) || reloadTabVol === 0) && !getFeature("setInitialTabVolume"))
         return;
     await waitVideoElementReady();
-    const initialVol = reloadTabVol > 0 ? Math.round(reloadTabVol) : getFeature("initialTabVolumeLevel");
+    const initialVol = Math.round(!isNaN(reloadTabVol) && reloadTabVol > 0 ? reloadTabVol : getFeature("initialTabVolumeLevel"));
+    if (isNaN(initialVol) || initialVol < 0 || initialVol > 100)
+        return;
     if (getFeature("volumeSharedBetweenTabs")) {
         lastCheckedSharedVolume = ignoreVal = initialVol;
         if (getFeature("volumeSharedBetweenTabs"))
@@ -8075,4 +7982,4 @@ function registerDevCommands() {
     GM.registerMenuCommand("Download DataStoreSerializer file", () => downloadData());
     log("Registered dev menu commands");
 }
-preInit();})(UserUtils,DOMPurify,compareVersions,marked);//# sourceMappingURL=http://localhost:8710/BetterYTM.user.js.map
+preInit();})(UserUtils,DOMPurify,compareVersions,marked);//# sourceMappingURL=BetterYTM.user.js.map

+ 1 - 1
package.json

@@ -64,7 +64,7 @@
     "openuserjs": "https://openuserjs.org/scripts/Sv443/BetterYTM"
   },
   "dependencies": {
-    "@sv443-network/userutils": "^8.4.0",
+    "@sv443-network/userutils": "^9.0.3",
     "compare-versions": "^6.1.0",
     "dompurify": "^3.1.6",
     "marked": "^12.0.2",

+ 5 - 5
pnpm-lock.yaml

@@ -9,8 +9,8 @@ importers:
   .:
     dependencies:
       '@sv443-network/userutils':
-        specifier: ^8.4.0
-        version: 8.4.0
+        specifier: ^9.0.3
+        version: 9.0.3
       compare-versions:
         specifier: ^6.1.0
         version: 6.1.0
@@ -1828,8 +1828,8 @@ packages:
   '@storybook/[email protected]':
     resolution: {integrity: sha512-UJ97iqI+0Mk13I6ayd3TaBfSFBkWnEauwTnFMQe1dN/L3wTh8laOBaLa0Vr3utRSnt2b5hpcw/nq7azB/Gx4Yw==}
 
-  '@sv443-network/userutils@8.4.0':
-    resolution: {integrity: sha512-DgMxcpq25IIwupOl3hTLCCmjU4oXrzOyajNoApVsTg2wPI02ZxPcx1YAmpoE19awxApJS+hJQseYdKWE3hFkCA==}
+  '@sv443-network/userutils@9.0.3':
+    resolution: {integrity: sha512-bWNWgxwBDeJ1xI269FqLlVDHUKRiEMw3HzkkqiG8Ht1mQkC8DozWWOvKChNL1qWGOWtfg7ee3tGGvqCyx38qhA==}
 
   '@testing-library/[email protected]':
     resolution: {integrity: sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==}
@@ -6816,7 +6816,7 @@ snapshots:
       '@types/express': 4.17.21
       file-system-cache: 2.3.0
 
-  '@sv443-network/userutils@8.4.0':
+  '@sv443-network/userutils@9.0.3':
     dependencies:
       nanoevents: 9.1.0
 

+ 2 - 0
src/config.ts

@@ -24,6 +24,8 @@ export const defaultData = (Object.keys(featInfo) as (keyof typeof featInfo)[])
 export const migrations: DataMigrationsDict = {
   // 1 -> 2 (<=v1.0)
   2: (oldData: Record<string, unknown>) => {
+    if(typeof oldData !== "object" || oldData === null)
+      return defaultData;
     const queueBtnsEnabled = Boolean(oldData.queueButtons);
     delete oldData.queueButtons;
     return {

+ 1 - 2
src/dialogs/autoLike.ts

@@ -163,8 +163,7 @@ async function renderBody() {
           .map((ch) => ch.id === id ? { ...ch, enabled } : ch),
       });
     },
-    250,
-    "rising"
+    250
   );
 
   const sortedChannels = autoLikeStore

+ 1 - 1
src/features/layout.ts

@@ -704,7 +704,7 @@ export async function initHideCursorOnIdle() {
       };
 
       vidContainer.addEventListener("mouseenter", onMove);
-      vidContainer.addEventListener("mousemove", debounce(onMove, 200, "rising"));
+      vidContainer.addEventListener("mousemove", debounce(onMove, 200));
       vidContainer.addEventListener("mouseleave", () => {
         cursorHideTimer && clearTimeout(cursorHideTimer);
         hideTransTimer && clearTimeout(hideTransTimer);

+ 0 - 2
src/features/songLists.ts

@@ -76,8 +76,6 @@ ytmusic-section-list-renderer[main-page-type="MUSIC_PAGE_TYPE_PLAYLIST"] ytmusic
       all: true,
       continuous: true,
       debounce: 150,
-      // TODO: switch to longer debounce time and edge type "risingIdle" after UserUtils update
-      debounceEdge: "falling",
       listener: checkAddGenericBtns,
     });
 

+ 1 - 2
src/features/volume.ts

@@ -57,11 +57,10 @@ export async function initVolumeFeatures() {
 
     addSelectorListener<HTMLInputElement>("playerBarRightControls", "ytmusic-player-expanding-menu tp-yt-paper-slider#expand-volume-slider", {
       listener: (el) => listener("expand", el),
-      debounceEdge: "falling",
     });
   };
 
-  window.addEventListener("resize", debounce(onResize, 150, "falling"));
+  window.addEventListener("resize", debounce(onResize, 150));
   waitVideoElementReady().then(onResize);
   onResize();
 }

+ 6 - 3
src/menu/menu_old.ts

@@ -347,7 +347,7 @@ async function mountCfgMenu() {
   };
 
   /** Call whenever the feature config is changed */
-  const confChanged = debounce(onCfgChange, 333, "falling");
+  const confChanged = debounce(onCfgChange, 333);
 
   const featureCfg = getFeatures();
   const featureCfgWithCategories = Object.entries(featInfo)
@@ -406,7 +406,7 @@ async function mountCfgMenu() {
       const step = "step" in ftInfo ? ftInfo.step : undefined;
       const val = featureCfg[featKey as FeatureKey];
 
-      const initialVal = val ?? ftDefault ?? undefined;
+      const initialVal = val ?? ftDefault;
 
       const ftConfElem = document.createElement("div");
       ftConfElem.classList.add("bytm-ftitem");
@@ -667,6 +667,9 @@ async function mountCfgMenu() {
           // custom input element:
           let customInputEl: HTMLElement | undefined;
 
+          if(initialVal === undefined)
+            return;
+
           switch(type) {
           case "hotkey":
             customInputEl = createHotkeyInput({
@@ -850,7 +853,7 @@ async function mountCfgMenu() {
 
   (document.querySelector("#bytm-dialog-container") ?? document.body).appendChild(backgroundElem);
 
-  window.addEventListener("resize", debounce(checkToggleScrollIndicator, 250, "rising"));
+  window.addEventListener("resize", debounce(checkToggleScrollIndicator, 250));
 
   log("Added menu element");
 

+ 0 - 3
src/observers.ts

@@ -51,7 +51,6 @@ const defaultObserverOptions: SelectorObserverOptions = {
   disableOnNoListeners: false,
   enableOnAddListener: false,
   defaultDebounce: 150,
-  defaultDebounceEdge: "rising",
 };
 
 /** Global SelectorObserver instances usable throughout the script for improved performance */
@@ -105,7 +104,6 @@ export function initObservers() {
     //    enabled immediately
     globservers.body = new SelectorObserver(document.body, {
       ...defaultObserverOptions,
-      defaultDebounceEdge: "falling",
       defaultDebounce: 150,
       subtree: false,
     });
@@ -118,7 +116,6 @@ export function initObservers() {
     const bytmDialogContainerSelector = "#bytm-dialog-container";
     globservers.bytmDialogContainer = new SelectorObserver(bytmDialogContainerSelector, {
       ...defaultObserverOptions,
-      defaultDebounceEdge: "falling",
       defaultDebounce: 100,
       subtree: true,
     });

+ 8 - 5
src/utils/translations.ts

@@ -14,6 +14,9 @@ type TFuncKey = TrKey | (string & {});
 /** Contains the identifiers of all initialized and loaded translation locales */
 const initializedLocales = new Set<TrLocale>();
 
+/** The currently active locale */
+let activeLocale: TrLocale = "en-US";
+
 /** Initializes the translations */
 export async function initTranslations(locale: TrLocale) {
   if(initializedLocales.has(locale))
@@ -40,7 +43,7 @@ export async function initTranslations(locale: TrLocale) {
       ...transFile,
     };
 
-    tr.addLanguage(locale, translations);
+    tr.addTranslations(locale, translations);
 
     info(`Loaded translations for locale '${locale}'`);
   }
@@ -63,14 +66,14 @@ async function fetchLocaleJson(locale: TrLocale) {
 
 /** Sets the current language for translations */
 export function setLocale(locale: TrLocale) {
-  tr.setLanguage(locale);
+  activeLocale = locale;
   setGlobalProp("locale", locale);
   emitInterface("bytm:setLocale", { locale });
 }
 
 /** Returns the currently set language */
 export function getLocale() {
-  return tr.getLanguage() as TrLocale;
+  return activeLocale;
 }
 
 /** Returns whether the given translation key exists in the current locale */
@@ -85,7 +88,7 @@ export function hasKeyFor(locale: TrLocale, key: TFuncKey) {
 
 /** Returns the translated string for the given key, after optionally inserting values */
 export function t(key: TFuncKey, ...values: Stringifiable[]) {
-  return tr(key, ...values);
+  return tl(activeLocale, key, ...values);
 }
 
 /**
@@ -99,7 +102,7 @@ export function tp(key: TFuncKey, num: number | unknown[] | NodeList, ...values:
 
 /** Returns the translated string for the given key in the specified locale, after optionally inserting values */
 export function tl(locale: TrLocale, key: TFuncKey, ...values: Stringifiable[]) {
-  return tr.forLang(locale, key, ...values);
+  return tr.for(locale, key, ...values);
 }
 
 /**