GreasyFork 高級版

GreasyFork 和 SleazyFork 高級強化:現代化介面、一鍵收藏、直接安裝按鈕、腳本詳細預覽、增強編輯工具列、淺色/深色主題、最佳化導航及更多功能。

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         GreasyFork Premium
// @name:zh-CN   GreasyFork 高级版
// @name:zh-TW   GreasyFork 高級版
// @name:hi      GreasyFork प्रीमियम
// @name:es      GreasyFork Premium
// @name:ar      GreasyFork بريميوم
// @name:fr      GreasyFork Premium
// @name:bn      GreasyFork প্রিমিয়াম
// @name:pt      GreasyFork Premium
// @name:ru      GreasyFork Premium
// @name:ja      GreasyFork プレミアム
// @name:ur      GreasyFork پریمیم
// @name:ml      GreasyFork പ്രീമിയം
// @name:tr      GreasyFork Premium
// @name:it      GreasyFork Premium
// @name:th      GreasyFork Premium
// @name:de      GreasyFork Premium
// @name:ko      GreasyFork 프리미엄
// @name:pl      GreasyFork Premium
// @name:nl      GreasyFork Premium
// @name:sv      GreasyFork Premium
// @name:ro      GreasyFork Premium
// @name:vi      GreasyFork Premium
// @name:id      GreasyFork Premium
// @name:ms      GreasyFork Premium
// @name:be      GreasyFork Premium
// @name:nb      GreasyFork Premium
// @name:bg      GreasyFork Premium
// @name:ckb     GreasyFork پریمیۆم
// @name:hr      GreasyFork Premium
// @name:cs      GreasyFork Premium
// @name:da      GreasyFork Premium
// @name:eo      GreasyFork Premium
// @name:fil     GreasyFork Premium
// @name:fi      GreasyFork Premium
// @name:fr-CA   GreasyFork Premium
// @name:ka      GreasyFork Premium
// @name:el      GreasyFork Premium
// @name:he      GreasyFork Premium
// @name:hu      GreasyFork Premium
// @name:mr      GreasyFork प्रीमियम
// @name:pt-BR   GreasyFork Premium
// @name:sr      GreasyFork Premium
// @name:sk      GreasyFork Premium
// @name:es-419  GreasyFork Premium
// @name:ug      GreasyFork Premium
// @name:uk      GreasyFork Premium

// @description        Advanced GreasyFork and SleazyFork enhancement: modern UI, one-click favorites, direct install button, detailed script previews, enhanced editor toolbar, light/dark theme, optimized navigation, and much more.
// @description:zh-CN  GreasyFork 和 SleazyFork 高级增强:现代化界面、一键收藏、直接安装按钮、脚本详细预览、增强编辑工具栏、浅色/深色主题、优化导航等更多功能。
// @description:zh-TW  GreasyFork 和 SleazyFork 高級強化:現代化介面、一鍵收藏、直接安裝按鈕、腳本詳細預覽、增強編輯工具列、淺色/深色主題、最佳化導航及更多功能。
// @description:hi     GreasyFork और SleazyFork के लिए उन्नत सुधार: आधुनिक इंटरफ़ेस, एक-क्लिक पसंदीदा, सीधे इंस्टॉल बटन, विस्तृत स्क्रिप्ट पूर्वावलोकन, उन्नत संपादन टूलबार, लाइट/डार्क थीम, अनुकूलित नेविगेशन और बहुत कुछ।
// @description:es     Mejora avanzada de GreasyFork y SleazyFork: interfaz moderna, favoritos en un clic, botón de instalación directa, vista previa detallada de scripts, barra de edición mejorada, tema claro/oscuro, navegación optimizada y mucho más.
// @description:ar     تحسين متقدم لـ GreasyFork وSleazyFork: واجهة حديثة، مفضلة بنقرة واحدة، زر تثبيت مباشر، معاينة مفصلة للسكربتات، شريط تحرير محسّن، وضع فاتح/داكن، تنقل محسن وأكثر من ذلك.
// @description:fr     Amélioration avancée de GreasyFork et SleazyFork : interface modernisée, favoris en un clic, bouton d’installation direct, aperçu détaillé des scripts, barre d’édition enrichie, thème clair/sombre, navigation optimisée et bien plus encore.
// @description:bn     GreasyFork এবং SleazyFork-এর উন্নত সংস্করণ: আধুনিক ইন্টারফেস, এক-ক্লিক ফেভারিট, বিস্তারিত স্ক্রিপ্ট প্রিভিউ, উন্নত এডিটর টুলবার, সরাসরি ইনস্টল বাটন, লাইট/ডার্ক থিম, অপ্টিমাইজড নেভিগেশন এবং আরও অনেক কিছু।
// @description:pt     Melhoria avançada do GreasyFork e SleazyFork: interface moderna, favoritos com um clique, botão de instalação direta, pré-visualização detalhada de scripts, barra de edição aprimorada, tema claro/escuro, navegação otimizada e muito mais.
// @description:ru     Расширенное улучшение GreasyFork и SleazyFork: современный интерфейс, избранное в один клик, подробный просмотр скриптов, улучшенная панель редактирования, кнопка быстрой установки, светлая/тёмная тема, оптимизированная навигация и многое другое.
// @description:ja     GreasyFork と SleazyFork の高度な改善:モダンなUI、ワンクリックお気に入り、詳細なスクリプトプレビュー、強化された編集ツールバー、直接インストールボタン、ライト/ダークテーマ、最適化されたナビゲーションなど多数。
// @description:ur     GreasyFork اور SleazyFork کے لیے جدید بہتری: ماڈرن انٹرفیس، ایک کلک فیورٹس، تفصیلی اسکرپٹ پیش نظارہ، بہتر ایڈیٹر ٹول بار، ڈائریکٹ انسٹال بٹن، لائٹ/ڈارک تھیم، بہتر نیویگیشن اور بہت کچھ۔
// @description:ml     GreasyFork, SleazyFork എന്നിവയ്ക്കായുള്ള മെച്ചപ്പെട്ട പതിപ്പ്: ആധുനിക UI, ഒറ്റ ക്ലിക്ക് ഫേവറിറ്റുകൾ, വിശദമായ സ്ക്രിപ്റ്റ് പ്രിവ്യൂ, മെച്ചപ്പെടുത്തിയ എഡിറ്റർ ടൂൾബാർ, നേരിട്ടുള്ള ഇൻസ്റ്റാൾ ബട്ടൺ, ലൈറ്റ്/ഡാർക്ക് തീം, മെച്ചപ്പെടുത്തിയ നാവിഗേഷൻ എന്നിവയും കൂടുതൽ സൗകര്യങ്ങളും.
// @description:tr     GreasyFork ve SleazyFork için gelişmiş geliştirme: modern arayüz, tek tık favoriler, ayrıntılı betik önizlemeleri, geliştirilmiş düzenleme araç çubuğu, doğrudan yükleme butonu, açık/koyu tema, optimize edilmiş gezinme ve çok daha fazlası.
// @description:it     Miglioramento avanzato di GreasyFork e SleazyFork: interfaccia moderna, preferiti con un clic, anteprima dettagliata degli script, barra di modifica avanzata, pulsante di installazione diretta, tema chiaro/scuro, navigazione ottimizzata e molto altro.
// @description:th     การปรับปรุง GreasyFork และ SleazyFork ขั้นสูง: อินเทอร์เฟซทันสมัย รายการโปรดคลิกเดียว ดูตัวอย่างสคริปต์แบบละเอียด แถบเครื่องมือแก้ไขที่ปรับปรุง ปุ่มติดตั้งทันที โหมดสว่าง/มืด การนำทางที่ปรับให้เหมาะสม และอีกมากมาย
// @description:de     Erweiterte Verbesserung für GreasyFork und SleazyFork: moderne Benutzeroberfläche, Favoriten mit einem Klick, detaillierte Skriptvorschau, erweiterte Bearbeitungsleiste, direkter Installationsbutton, Hell/Dunkel-Modus, optimierte Navigation und vieles mehr.
// @description:ko     GreasyFork 및 SleazyFork 고급 개선: 현대적인 UI, 원클릭 즐겨찾기, 상세 스크립트 미리보기, 향상된 편집 도구 모음, 직접 설치 버튼, 라이트/다크 테마, 최적화된 탐색 및 다양한 추가 기능.
// @description:pl     Zaawansowane ulepszenie GreasyFork i SleazyFork: nowoczesny interfejs, ulubione jednym kliknięciem, szczegółowy podgląd skryptów, ulepszony pasek edycji, przycisk bezpośredniej instalacji, tryb jasny/ciemny, zoptymalizowana nawigacja i wiele więcej.
// @description:nl     Geavanceerde verbetering voor GreasyFork en SleazyFork: moderne interface, favorieten met één klik, gedetailleerde scriptvoorbeelden, verbeterde bewerkingsbalk, directe installatieknop, licht/donker thema, geoptimaliseerde navigatie en nog veel meer.
// @description:sv     Avancerad förbättring för GreasyFork och SleazyFork: modernt gränssnitt, favoriter med ett klick, detaljerad skriptförhandsvisning, förbättrat redigeringsverktygsfält, direkt installationsknapp, ljust/mörkt tema, optimerad navigering och mycket mer.
// @description:ro     Îmbunătățire avansată pentru GreasyFork și SleazyFork: interfață modernă, favorite cu un singur clic, previzualizare detaliată a scripturilor, bară de editare îmbunătățită, buton de instalare directă, temă deschis/închis, navigare optimizată și multe altele.
// @description:vi     Nâng cấp nâng cao cho GreasyFork và SleazyFork: giao diện hiện đại, yêu thích một lần nhấp, xem trước chi tiết tập lệnh, thanh công cụ chỉnh sửa nâng cao, nút cài đặt trực tiếp, chế độ sáng/tối, điều hướng tối ưu và nhiều hơn nữa.
// @description:id     Peningkatan lanjutan untuk GreasyFork dan SleazyFork: antarmuka modern, favorit sekali klik, pratinjau skrip terperinci, bilah alat editor yang ditingkatkan, tombol instal langsung, tema terang/gelap, navigasi yang dioptimalkan, dan banyak lagi.
// @description:ms     Penambahbaikan lanjutan untuk GreasyFork dan SleazyFork: antara muka moden, kegemaran satu klik, pratonton skrip terperinci, bar alat editor yang dipertingkatkan, butang pemasangan terus, tema terang/gelap, navigasi dioptimumkan dan banyak lagi.
// @description:be     Пашыранае паляпшэнне GreasyFork і SleazyFork: сучасны інтэрфейс, абранае ў адзін клік, прамая ўсталёўка, падрабязны прагляд скрыптоў, палепшаная панэль рэдактара, светлая/цёмная тэма, аптымізаваная навігацыя і многае іншае.
// @description:nb     Avansert forbedring for GreasyFork og SleazyFork: moderne grensesnitt, favoritter med ett klikk, direkte installasjon, detaljerte skriptforhåndsvisninger, forbedret redigeringsverktøylinje, lyst/mørkt tema, optimalisert navigasjon og mye mer.
// @description:bg     Разширено подобрение за GreasyFork и SleazyFork: модерен интерфейс, любими с едно щракване, директно инсталиране, подробен преглед на скриптове, подобрена лента на редактора, светла/тъмна тема, оптимизирана навигация и още много.
// @description:ckb    باشترکردنی پێشکەوتوو بۆ GreasyFork و SleazyFork: ڕووکارێکی مۆدێرن، دڵخوازەکان بە یەک کرتە، دامەزراندنی ڕاستەوخۆ، پێشبینینی وردی سکریپت، تووڵباری دەستکاریکەر، ڕووکاری ڕوون/تاریک و ڕێنیشاندانی باشتر.
// @description:hr     Napredno poboljšanje za GreasyFork i SleazyFork: moderno sučelje, favoriti jednim klikom, izravna instalacija, detaljni pregledi skripti, poboljšana alatna traka uređivača, svijetla/tamna tema, optimizirana navigacija i još mnogo toga.
// @description:cs     Pokročilé vylepšení GreasyFork a SleazyFork: moderní rozhraní, oblíbené jedním kliknutím, přímá instalace, podrobné náhledy skriptů, vylepšený panel editoru, světlý/tmavý motiv, optimalizovaná navigace a mnoho dalšího.
// @description:da     Avanceret forbedring til GreasyFork og SleazyFork: moderne brugerflade, favoritter med ét klik, direkte installation, detaljerede scriptvisninger, forbedret editorværktøjslinje, lyst/mørkt tema, optimeret navigation og meget mere.
// @description:eo     Altnivela plibonigo por GreasyFork kaj SleazyFork: moderna interfaco, unuklakaj ŝatatoj, rekta instalado, detalaj antaŭrigardoj de skriptoj, plibonigita redaktila ilobreto, hela/malhela etoso, optimumigita navigado kaj multe pli.
// @description:fil    Mas pinahusay na GreasyFork at SleazyFork: modernong interface, isang-click na mga paborito, direktang pag-install, detalyadong preview ng script, pinahusay na toolbar ng editor, maliwanag/madilim na tema, mas maayos na nabigasyon, at marami pang iba.
// @description:fi     Edistynyt parannus GreasyForkille ja SleazyForkille: moderni käyttöliittymä, suosikit yhdellä napsautuksella, suora asennus, yksityiskohtaiset skriptien esikatselut, parannettu editorin työkalurivi, vaalea/tumma teema, optimoitu navigointi ja paljon muuta.
// @description:fr-CA  Amélioration avancée de GreasyFork et SleazyFork : interface moderne, favoris en un clic, installation directe, aperçus détaillés des scripts, barre d’outils d’édition enrichie, thème clair/sombre, navigation optimisée et bien plus.
// @description:ka     GreasyFork-ისა და SleazyFork-ის გაფართოებული გაუმჯობესება: თანამედროვე ინტერფეისი, რჩეულები ერთი დაწკაპუნებით, პირდაპირი ინსტალაცია, სკრიპტების დეტალური გადახედვა, გაუმჯობესებული რედაქტორის პანელი, ნათელი/მუქი თემა, ოპტიმიზებული ნავიგაცია და სხვა.
// @description:el     Προηγμένη βελτίωση για GreasyFork και SleazyFork: σύγχρονο περιβάλλον, αγαπημένα με ένα κλικ, άμεση εγκατάσταση, λεπτομερείς προεπισκοπήσεις script, βελτιωμένη γραμμή επεξεργασίας, φωτεινό/σκοτεινό θέμα, βελτιστοποιημένη πλοήγηση και πολλά άλλα.
// @description:he     שיפור מתקדם ל-GreasyFork ול-SleazyFork: ממשק מודרני, מועדפים בלחיצה אחת, התקנה ישירה, תצוגות מקדימות מפורטות של סקריפטים, סרגל עריכה משופר, ערכת נושא בהירה/כהה, ניווט ממוטב ועוד.
// @description:hu     Fejlett GreasyFork- és SleazyFork-bővítés: modern felület, egykattintásos kedvencek, közvetlen telepítés, részletes szkript-előnézetek, továbbfejlesztett szerkesztőeszköztár, világos/sötét téma, optimalizált navigáció és még sok más.
// @description:mr     GreasyFork आणि SleazyFork साठी प्रगत सुधारणा: आधुनिक इंटरफेस, एका क्लिकमध्ये आवडी, थेट स्थापना, तपशीलवार स्क्रिप्ट पूर्वावलोकने, सुधारित संपादक साधनपट्टी, उजळ/गडद थीम, अनुकूलित नेव्हिगेशन आणि बरेच काही.
// @description:pt-BR  Aprimoramento avançado para GreasyFork e SleazyFork: interface moderna, favoritos com um clique, instalação direta, visualizações detalhadas de scripts, barra de edição aprimorada, tema claro/escuro, navegação otimizada e muito mais.
// @description:sr     Napredno poboljšanje za GreasyFork i SleazyFork: moderan interfejs, omiljeni jednim klikom, direktna instalacija, detaljni pregledi skripti, poboljšana traka uređivača, svetla/tamna tema, optimizovana navigacija i još mnogo toga.
// @description:sk     Pokročilé vylepšenie GreasyFork a SleazyFork: moderné rozhranie, obľúbené jedným kliknutím, priama inštalácia, podrobné náhľady skriptov, vylepšený panel editora, svetlá/tmavá téma, optimalizovaná navigácia a mnoho ďalšieho.
// @description:es-419 Mejora avanzada de GreasyFork y SleazyFork: interfaz moderna, favoritos con un clic, instalación directa, vistas detalladas de scripts, barra de edición mejorada, tema claro/oscuro, navegación optimizada y mucho más.
// @description:ug     GreasyFork ۋە SleazyFork ئۈچۈن ئىلغار ياخشىلاش: زامانىۋى كۆرۈنمە يۈز، بىر چېكىشلىك ياقتۇرغانلار، بىۋاسىتە قاچىلاش، تەپسىلىي سىكرىپت ئالدىن كۆرۈش، كۈچەيتىلگەن تەھرىرلىگۈچ قورال بالدىقى، يورۇق/قاراڭغۇ تېما ۋە ياخشىلانغان يولباشلاش.
// @description:uk     Розширене покращення GreasyFork і SleazyFork: сучасний інтерфейс, обране одним кліком, пряме встановлення, докладний перегляд скриптів, покращена панель редактора, світла/темна тема, оптимізована навігація та багато іншого.

// @icon         https://raw.githubusercontent.com/DREwX-code/greasyfork-premium/refs/heads/main/assets/icon/logo-greasyfork-premium.png
// @namespace    https://github.com/DREwX-code/greasyfork-premium
// @version      1.3.0
// @author       Dℝ∃wX
// @copyright    2026 DℝᴇwX
// @license      Apache-2.0
// @tag          Productivity
// @match        https://greasyfork.org/*
// @match        https://sleazyfork.org/*
// @run-at       document-start
// @require      https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js
// @require      https://update.greasyfork.org/scripts/593320/1915335/GreasyFork%20Premium%20-%20Classic%20Theme.js
// @require      https://update.greasyfork.org/scripts/593322/1915381/GreasyFork%20Premium%20-%20Chalkboard%20Theme.js
// @require      https://update.greasyfork.org/scripts/593323/1915385/GreasyFork%20Premium%20-%20Full%20Dark%20Theme.js
// @grant        unsafeWindow

// ==/UserScript==

/*
Copyright 2026 Dℝ∃wX

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/*
---

Third-Party Libraries:

This project uses Highlight.js for syntax highlighting.
Website: https://highlightjs.org/
Source code: https://github.com/highlightjs/highlight.js
License: BSD 3-Clause

---
*/

(function () {
    'use strict';

    const pageWindow = typeof unsafeWindow === 'undefined' ? window : unsafeWindow;

    if (window.top !== window.self) {
        return;
    }

    const STORAGE_KEY = 'gfplus-theme';
    const THEME_VARIANT_STORAGE_KEY = 'gfplus-theme-variant';
    const DENSITY_STORAGE_KEY = 'gfplus-interface-density';
    const SIDEBAR_GROUP_STATE_KEY = 'gfplus-sidebar-group-states';
    const LOADING_ATTR = 'data-gfplus-loading';
    const INTERNAL_NAV_FLAG_KEY = 'gfplus-internal-nav';
    const INTERNAL_LOADING_ATTR = 'data-gfplus-internal-loading';
    const HANDHELD_ATTR = 'data-gfplus-handheld';
    const BOOTSTRAP_THEME_SCRIPT_ID = 'gfplus-bootstrap-theme';
    const NO_TRANSITION_STYLE_ID = 'gfplus-no-transition';
    const THEME_STYLE_ID = 'gfplus-theme-style';
    const DARK_THEME_STYLE_ID = 'gfplus-theme-style-dark';
    const FULL_DARK_THEME_STYLE_ID = 'gfplus-theme-style-full-dark';
    const CHALKBOARD_THEME_STYLE_ID = 'gfplus-theme-style-chalkboard';
    const SCROLLBAR_STYLE_ID = 'gfplus-scrollbar-style';
    const DENSITY_STYLE_ID = 'gfplus-density-style';
    const THEME_MOTION_STYLE_ID = 'gfplus-theme-motion-style';
    const THEME_MOTION_ATTR = 'data-gfplus-theme-motion';
    const THEME_FALLBACK_MOTION_ATTR = 'data-gfplus-theme-fallback-motion';
    const SAFARI_ATTR = 'data-gfplus-safari';
    const LIGHTBOX_SCROLL_LOCK_CLASS = 'gfplus-lightbox-open';
    const THEME_MOTION_DURATION = 380;
    const THEME_OPTIONS = ['light', 'system', 'dark'];
    const THEME_VARIANT_OPTIONS = ['normal', 'full-dark', 'chalkboard'];
    const DENSITY_OPTIONS = ['compact', 'comfortable', 'detailed'];
    const storedTheme = localStorage.getItem(STORAGE_KEY);
    let currentTheme = THEME_OPTIONS.includes(storedTheme) ? storedTheme : 'system';
    const storedThemeVariant = localStorage.getItem(THEME_VARIANT_STORAGE_KEY);
    let currentThemeVariant = THEME_VARIANT_OPTIONS.includes(storedThemeVariant) ? storedThemeVariant : 'normal';
    const storedDensity = localStorage.getItem(DENSITY_STORAGE_KEY);
    let currentDensity = DENSITY_OPTIONS.includes(storedDensity) ? storedDensity : 'comfortable';
    let internalNavigation = false;
    let themeMotionTimer = 0;
    const root = document.documentElement;
    root?.setAttribute('data-gfplus-density', currentDensity);
    const systemThemeQuery = window.matchMedia?.('(prefers-color-scheme: dark)');
    const THEME_COLORS = {
        light: {
            background: '#f5f7fb',
            text: '#111827',
            chartBackground: '#61a5fa',
            chartBorder: '#61a5fa',
            chartGrid: '#dbe4f0',
            chartText: '#334155'
        },
        dark: {
            background: '#0b111a',
            text: '#e5e7eb',
            chartBackground: '#61a5fa',
            chartBorder: '#61a5fa',
            chartGrid: '#263449',
            chartText: '#cbd5e1'
        },
        fullDark: {
            background: '#080808',
            text: '#eeeeee',
            chartBackground: '#8ab4f8',
            chartBorder: '#aecbfa',
            chartGrid: '#303030',
            chartText: '#d0d0d0'
        },
        chalkboardLight: {
            background: '#f3f1eb',
            text: '#28332f',
            chartBackground: '#4f897b',
            chartBorder: '#367064',
            chartGrid: '#d0d8d3',
            chartText: '#3c514a'
        },
        chalkboardDark: {
            background: '#101513',
            text: '#e8e9e5',
            chartBackground: '#76bbaa',
            chartBorder: '#9bcfc2',
            chartGrid: '#394640',
            chartText: '#d1d8d4'
        }
    };

    const isSafariBrowser = () => {
        const userAgent = navigator.userAgent || '';
        return /Safari/i.test(userAgent) && !/Chrome|Chromium|CriOS|FxiOS|Edg|OPR|Opera|Android/i.test(userAgent);
    };

    if (root && isSafariBrowser()) {
        root.setAttribute(SAFARI_ATTR, 'true');
    }

    const resolveTheme = (theme = currentTheme) => theme === 'system'
        ? (systemThemeQuery?.matches ? 'dark' : 'light')
        : theme;

    const applyRootTheme = (theme, variant = currentThemeVariant) => {
        if (!root) {
            return;
        }

        const resolvedTheme = resolveTheme(theme);
        const colors = variant === 'chalkboard'
            ? THEME_COLORS[resolvedTheme === 'dark' ? 'chalkboardDark' : 'chalkboardLight']
            : (resolvedTheme === 'dark' && variant === 'full-dark'
                ? THEME_COLORS.fullDark
                : (THEME_COLORS[resolvedTheme] || THEME_COLORS.light));
        root.setAttribute('data-theme', resolvedTheme);
        root.setAttribute('data-theme-preference', theme);
        root.setAttribute('data-theme-variant', variant);
        root.style.colorScheme = resolvedTheme;
        root.style.backgroundColor = colors.background;
        root.style.color = colors.text;
        root.style.setProperty('--gfplus-preload-bg', colors.background);
        root.style.setProperty('--gfplus-preload-text', colors.text);
        root.style.setProperty('--chart-background-color', colors.chartBackground);
        root.style.setProperty('--chart-border-color', colors.chartBorder);
        root.style.setProperty('--install-stats-bar-color', colors.chartBackground);
        root.style.setProperty('--install-stats-bar-hover-color', colors.chartBorder);
        root.style.setProperty('--install-stats-grid-color', colors.chartGrid);
        root.style.setProperty('--install-stats-text-color', colors.chartText);
    };

    const isPhoneDevice = () => {
        if (navigator.userAgentData?.mobile) {
            return true;
        }

        const userAgent = navigator.userAgent || '';
        return /Android.+Mobile|iPhone|iPod|Windows Phone|webOS|BlackBerry|Opera Mini|Mobile Firefox/i.test(userAgent);
    };

    const syncHandheldMode = () => {
        if (!root) {
            return;
        }

        if (isPhoneDevice()) {
            root.setAttribute(HANDHELD_ATTR, 'true');
        } else {
            root.removeAttribute(HANDHELD_ATTR);
        }
    };

    const appendStyle = (styleEl) => {
        const target = document.head || root;
        target.appendChild(styleEl);
    };

    const prependCriticalStyle = (styleEl) => {
        if (!root) {
            appendStyle(styleEl);
            return;
        }

        root.prepend(styleEl);
    };

    const buildThemeMotionCss = () => `
    html[${THEME_MOTION_ATTR}]::view-transition-group(root) {
        animation-duration: 360ms;
        animation-timing-function: cubic-bezier(.22, 1, .36, 1);
    }

    html[${THEME_MOTION_ATTR}]::view-transition-old(root),
    html[${THEME_MOTION_ATTR}]::view-transition-new(root) {
        mix-blend-mode: normal;
    }

    html[${THEME_FALLBACK_MOTION_ATTR}],
    html[${THEME_FALLBACK_MOTION_ATTR}] body,
    html[${THEME_FALLBACK_MOTION_ATTR}] body *,
    html[${THEME_FALLBACK_MOTION_ATTR}] body *::before,
    html[${THEME_FALLBACK_MOTION_ATTR}] body *::after {
        transition-property: background, background-color, color, border-color, box-shadow, text-decoration-color, fill, stroke, outline-color !important;
        transition-duration: 340ms !important;
        transition-delay: 0ms !important;
        transition-timing-function: cubic-bezier(.22, 1, .36, 1) !important;
    }

    @media (prefers-reduced-motion: reduce) {
        html[${THEME_MOTION_ATTR}]::view-transition-group(root) {
            animation-duration: .01ms;
        }

        html[${THEME_FALLBACK_MOTION_ATTR}],
        html[${THEME_FALLBACK_MOTION_ATTR}] body,
        html[${THEME_FALLBACK_MOTION_ATTR}] body *,
        html[${THEME_FALLBACK_MOTION_ATTR}] body *::before,
        html[${THEME_FALLBACK_MOTION_ATTR}] body *::after {
            transition-duration: .01ms !important;
        }
    }
    `;

    const buildCriticalLoadingCss = () => `
    html[${LOADING_ATTR}] {
        background: var(--gfplus-preload-bg, #f5f7fb) !important;
        color: var(--gfplus-preload-text, #111827) !important;
    }
    html[${LOADING_ATTR}] body {
        background: transparent !important;
        color: inherit !important;
    }
        html[${LOADING_ATTR}] *,
        html[${LOADING_ATTR}] *::before,
        html[${LOADING_ATTR}] *::after {
        transition: none !important;
        animation: none !important;
    }
        html[${LOADING_ATTR}] body > :not(#main-header):not(script):not(style) {
        visibility: hidden !important;
        opacity: 0 !important;
    }
        html[${LOADING_ATTR}][${HANDHELD_ATTR}] body,
        html[${LOADING_ATTR}][${HANDHELD_ATTR}] body > :not(script):not(style),
        html[${LOADING_ATTR}][${HANDHELD_ATTR}][${INTERNAL_LOADING_ATTR}] body,
        html[${LOADING_ATTR}][${HANDHELD_ATTR}][${INTERNAL_LOADING_ATTR}] body > :not(script):not(style) {
        visibility: hidden !important;
        opacity: 0 !important;
    }
    `;

    applyRootTheme(currentTheme);
    syncHandheldMode();

    if (root) {
        root.setAttribute(LOADING_ATTR, 'true');
    }

    const noTransitionStyle = document.createElement('style');
    noTransitionStyle.id = NO_TRANSITION_STYLE_ID;
    noTransitionStyle.textContent = buildCriticalLoadingCss();
    prependCriticalStyle(noTransitionStyle);

    const themeMotionStyle = document.createElement('style');
    themeMotionStyle.id = THEME_MOTION_STYLE_ID;
    themeMotionStyle.textContent = buildThemeMotionCss();
    appendStyle(themeMotionStyle);

    try {
        internalNavigation = sessionStorage.getItem(INTERNAL_NAV_FLAG_KEY) === '1';
        if (internalNavigation) {
            sessionStorage.removeItem(INTERNAL_NAV_FLAG_KEY);
            root.setAttribute(INTERNAL_LOADING_ATTR, 'true');
        }
    } catch (error) {
        internalNavigation = false;
    }

    const bootstrapThemeScript = document.createElement('script');
    bootstrapThemeScript.id = BOOTSTRAP_THEME_SCRIPT_ID;
    bootstrapThemeScript.textContent = `
    (() => {
        try {
            const themeOptions = ['light', 'system', 'dark'];
            const themeVariantOptions = ['normal', 'full-dark', 'chalkboard'];
            const themeColors = ${JSON.stringify(THEME_COLORS)};
            const storedTheme = localStorage.getItem(${JSON.stringify(STORAGE_KEY)});
            const storedThemeVariant = localStorage.getItem(${JSON.stringify(THEME_VARIANT_STORAGE_KEY)});
            const theme = themeOptions.includes(storedTheme) ? storedTheme : 'system';
            const themeVariant = themeVariantOptions.includes(storedThemeVariant) ? storedThemeVariant : 'normal';
            const resolvedTheme = theme === 'system'
                ? (window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
                : theme;
            const root = document.documentElement;
            if (!root) return;
            const colorKey = themeVariant === 'chalkboard'
                ? (resolvedTheme === 'dark' ? 'chalkboardDark' : 'chalkboardLight')
                : (resolvedTheme === 'dark' && themeVariant === 'full-dark' ? 'fullDark' : resolvedTheme);
            const colors = themeColors[colorKey] || themeColors.light;
            root.setAttribute('data-theme', resolvedTheme);
            root.setAttribute('data-theme-preference', theme);
            root.setAttribute('data-theme-variant', themeVariant);
            root.style.colorScheme = resolvedTheme;
            root.style.backgroundColor = colors.background;
            root.style.color = colors.text;
            root.style.setProperty('--gfplus-preload-bg', colors.background);
            root.style.setProperty('--gfplus-preload-text', colors.text);
            root.style.setProperty('--chart-background-color', colors.chartBackground);
            root.style.setProperty('--chart-border-color', colors.chartBorder);
            root.style.setProperty('--install-stats-bar-color', colors.chartBackground);
            root.style.setProperty('--install-stats-bar-hover-color', colors.chartBorder);
            root.style.setProperty('--install-stats-grid-color', colors.chartGrid);
            root.style.setProperty('--install-stats-text-color', colors.chartText);
        } catch (error) {
            console.warn('GreasyFork Premium: early theme initialization failed.', error);
        }
    })();
    `;
    (root || document.head).prepend(bootstrapThemeScript);
    bootstrapThemeScript.remove();

    const rootThemeObserver = new MutationObserver(() => {
        if (root.getAttribute('data-theme') !== resolveTheme(currentTheme)) {
            applyRootTheme(currentTheme);
        }
    });
    rootThemeObserver.observe(root, {
        attributes: true,
        attributeFilter: ['data-theme']
    });

    window.addEventListener('resize', syncHandheldMode, { passive: true });

    const markInternalNavigation = () => {
        internalNavigation = true;
        root.setAttribute(LOADING_ATTR, 'true');
        root.setAttribute(INTERNAL_LOADING_ATTR, 'true');
        applyRootTheme(currentTheme);

        try {
            sessionStorage.setItem(INTERNAL_NAV_FLAG_KEY, '1');
        } catch (error) {
            console.warn('GreasyFork Premium: unable to persist the internal navigation state.', error);
        }
    };

    const isInternalPageNavigation = (href) => {
        try {
            const destination = new URL(href, window.location.href);
            if (!/^https?:$/.test(destination.protocol)) {
                return false;
            }

            if (destination.origin !== window.location.origin) {
                return false;
            }

            const onlyHashChange = destination.pathname === window.location.pathname
                && destination.search === window.location.search
                && destination.hash
                && destination.hash !== window.location.hash;

            return !onlyHashChange;
        } catch (error) {
            return false;
        }
    };

    document.addEventListener('click', (event) => {
        if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
            return;
        }

        const link = event.target.closest('a[href]');
        if (!link) {
            return;
        }

        const href = link.getAttribute('href');
        if (!href || href.startsWith('#') || href.startsWith('javascript:')) {
            return;
        }

        if (link.target && link.target !== '_self') {
            return;
        }

        if (isInternalPageNavigation(link.href)) {
            markInternalNavigation();
        }
    }, true);
    // ============================================================================
    // Light Theme
    // ============================================================================
    const readThemeLibrary = (themeName) => {
        const css = globalThis.GFPlusThemeLibraries?.[themeName];
        if (!css || !css.trim()) {
            throw new Error('GreasyFork Premium: missing theme library "' + themeName + '". Check the corresponding @require URL.');
        }
        return css;
    };

    const LIGHT_CSS = readThemeLibrary('light');

    // ============================================================================
    // Dark Theme
    // ============================================================================
    const DARK_CSS = readThemeLibrary('dark');

    // ============================================================================
    // Full Dark Theme Variant
    // ============================================================================
    const FULL_DARK_CSS = readThemeLibrary('fullDark');

    // ============================================================================
    // Chalkboard Theme Variant
    // ============================================================================
    const CHALKBOARD_CSS = readThemeLibrary('chalkboard');


    let loadingCleared = false;
    let phoneLoadClearScheduled = false;

    const clearNoTransition = () => {
        if (loadingCleared) {
            return;
        }

        loadingCleared = true;
        root.removeAttribute(LOADING_ATTR);
        root.removeAttribute(INTERNAL_LOADING_ATTR);
        if (noTransitionStyle.parentNode) {
            noTransitionStyle.parentNode.removeChild(noTransitionStyle);
        }
    };

    const scheduleNoTransitionClear = (frames = 2) => {
        if (loadingCleared) {
            return;
        }

        let remainingFrames = Math.max(0, frames);
        const step = () => {
            if (loadingCleared) {
                return;
            }

            if (remainingFrames === 0) {
                clearNoTransition();
                return;
            }

            remainingFrames -= 1;
            requestAnimationFrame(step);
        };

        requestAnimationFrame(step);
    };

    const schedulePhoneLoadClear = () => {
        if (phoneLoadClearScheduled || !root.hasAttribute(HANDHELD_ATTR)) {
            return;
        }

        phoneLoadClearScheduled = true;
        const unlock = () => {
            scheduleNoTransitionClear(root.hasAttribute(INTERNAL_LOADING_ATTR) ? 3 : 1);
        };

        if (document.readyState === 'complete') {
            unlock();
            return;
        }

        window.addEventListener('load', unlock, { once: true });
    };

    const lightThemeStyle = document.createElement('style');
    lightThemeStyle.id = THEME_STYLE_ID;
    lightThemeStyle.textContent = LIGHT_CSS;
    appendStyle(lightThemeStyle);

    const darkThemeStyle = document.createElement('style');
    darkThemeStyle.id = DARK_THEME_STYLE_ID;
    darkThemeStyle.textContent = DARK_CSS;
    appendStyle(darkThemeStyle);

    const fullDarkThemeStyle = document.createElement('style');
    fullDarkThemeStyle.id = FULL_DARK_THEME_STYLE_ID;
    fullDarkThemeStyle.textContent = FULL_DARK_CSS;
    appendStyle(fullDarkThemeStyle);

    const chalkboardThemeStyle = document.createElement('style');
    chalkboardThemeStyle.id = CHALKBOARD_THEME_STYLE_ID;
    chalkboardThemeStyle.textContent = CHALKBOARD_CSS;
    appendStyle(chalkboardThemeStyle);

    const SCROLLBAR_CSS = `
        :root {
            scrollbar-color: var(--gfplus-scrollbar-thumb-start) var(--gfplus-scrollbar-track-start);
        }

        ::-webkit-scrollbar {
            width: 12px;
            height: 12px;
        }

        ::-webkit-scrollbar-track {
            background: linear-gradient(
                180deg,
                var(--gfplus-scrollbar-track-start),
                var(--gfplus-scrollbar-track-end)
            );
            border-radius: 999px;
            border: 1px solid var(--gfplus-scrollbar-track-border);
        }

        ::-webkit-scrollbar-thumb {
            background: linear-gradient(
                180deg,
                var(--gfplus-scrollbar-thumb-start),
                var(--gfplus-scrollbar-thumb-end)
            );
            border-radius: 999px;
            border: 3px solid var(--gfplus-scrollbar-border);
        }

        ::-webkit-scrollbar-thumb:hover {
            background: linear-gradient(
                180deg,
                var(--gfplus-scrollbar-hover-start),
                var(--gfplus-scrollbar-hover-end)
            );
        }

        ::-webkit-scrollbar-thumb:active {
            background: var(--gfplus-scrollbar-hover-end);
        }
    `;

    const scrollbarStyle = document.createElement('style');
    scrollbarStyle.id = SCROLLBAR_STYLE_ID;
    scrollbarStyle.textContent = SCROLLBAR_CSS;
    appendStyle(scrollbarStyle);

    const DENSITY_CSS = `
    .gf-script-list-heading {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: center;
        gap: .75rem;
        min-height: 30px;
        width: 100%;
        box-sizing: border-box;
        margin: 10px 0 -8px;
        position: relative;
        z-index: 2;
    }

    .gf-script-list-heading > .script-list-description {
        min-width: 0;
        margin: 0;
    }

    .gf-script-list-heading--control-only > gf-script-density {
        grid-column: 2;
    }

    .gf-script-list-section-header {
        display: flex;
        align-items: center;
        gap: .75rem;
        width: 100%;
        box-sizing: border-box;
    }

    .gf-script-list-section-header > gf-script-density {
        margin-left: auto;
        transform: translateY(23px);
    }

    gf-script-density {
        display: inline-flex;
        justify-self: end;
        align-items: center;
    }

    html[data-gfplus-density="comfortable"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) {
        padding: clamp(.9rem, 2vw, 1.15rem);
        gap: .4rem;
    }

    html[data-gfplus-density="comfortable"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) > article {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: end;
        column-gap: .9rem;
    }

    html[data-gfplus-density="comfortable"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) > article > h2 {
        grid-column: 1 / -1;
        font-size: 1.13rem;
    }

    html[data-gfplus-density="comfortable"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) > article .description {
        margin: .38em 0;
        font-size: .91rem;
    }

    html[data-gfplus-density="comfortable"] .script-list .script-meta-block {
        grid-column: 1;
        min-width: 0;
    }

    html[data-gfplus-density="comfortable"] .script-list .gf-script-note-panel,
    html[data-gfplus-density="comfortable"] .script-list .gf-script-extra-info {
        grid-column: 1 / -1;
    }

    html[data-gfplus-density="comfortable"] .script-list .gf-script-card-actions {
        grid-column: 2;
        align-self: end;
        margin-top: .3rem;
        gap: .45rem;
    }

    html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) {
        padding: .68rem .8rem;
        gap: .2rem;
    }

    html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info):hover {
        transform: none;
    }

    html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) > article > h2 {
        font-size: 1rem;
        line-height: 1.28;
        column-gap: 6px;
        row-gap: .2em;
    }

    html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) > article {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: end;
        column-gap: .75rem;
    }

    html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) > article > h2,
    html[data-gfplus-density="compact"] .script-list .gf-script-note-panel,
    html[data-gfplus-density="compact"] .script-list .gf-script-extra-info {
        grid-column: 1 / -1;
    }

    html[data-gfplus-density="compact"] .script-list .script-meta-block {
        grid-column: 1;
        min-width: 0;
        column-count: initial;
    }

    html[data-gfplus-density="compact"] .script-list .inline-script-stats {
        display: grid;
        grid-template-columns: max-content minmax(0, 1fr) max-content max-content;
        align-items: center;
        column-gap: .75rem;
        row-gap: .16rem;
        font-size: .82rem;
        margin: .25rem 0 0;
    }

    html[data-gfplus-density="compact"] .script-list .inline-script-stats dt,
    html[data-gfplus-density="compact"] .script-list .inline-script-stats dd {
        min-width: 0;
        min-height: 1.65rem;
        margin: 0;
        display: flex;
        align-items: center;
        line-height: 1.25;
    }

    html[data-gfplus-density="compact"] .script-list .inline-script-stats dt {
        justify-content: flex-end;
    }

    html[data-gfplus-density="compact"] .script-list .inline-script-stats dt:nth-of-type(1),
    html[data-gfplus-density="compact"] .script-list .inline-script-stats dd:nth-of-type(1) {
        grid-row: 1;
    }

    html[data-gfplus-density="compact"] .script-list .inline-script-stats dt:nth-of-type(2),
    html[data-gfplus-density="compact"] .script-list .inline-script-stats dd:nth-of-type(2) {
        grid-row: 2;
    }

    html[data-gfplus-density="compact"] .script-list .inline-script-stats dt:nth-of-type(3),
    html[data-gfplus-density="compact"] .script-list .inline-script-stats dd:nth-of-type(3) {
        grid-row: 1;
    }

    html[data-gfplus-density="compact"] .script-list .inline-script-stats dt:nth-of-type(4),
    html[data-gfplus-density="compact"] .script-list .inline-script-stats dd:nth-of-type(4) {
        grid-row: 2;
    }

    html[data-gfplus-density="compact"] .script-list .inline-script-stats dt:nth-of-type(-n+2) {
        grid-column: 1;
    }

    html[data-gfplus-density="compact"] .script-list .inline-script-stats dd:nth-of-type(-n+2) {
        grid-column: 2;
    }

    html[data-gfplus-density="compact"] .script-list .inline-script-stats dt:nth-of-type(n+3):nth-of-type(-n+4) {
        grid-column: 3;
    }

    html[data-gfplus-density="compact"] .script-list .inline-script-stats dd:nth-of-type(n+3):nth-of-type(-n+4) {
        grid-column: 4;
    }

    html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) > article > h2 .gf-script-logo {
        width: 23px;
        height: 23px;
        min-width: 23px;
        min-height: 23px;
        flex: 0 0 23px;
        border-radius: 5px;
    }

    html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) > article > h2 .gf-script-title-content {
        max-width: calc(100% - 29px);
    }

    html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) > article .description,
    html[data-gfplus-density="compact"] .script-list .name-description-separator,
    html[data-gfplus-density="compact"] .script-list dt.script-list-created-date,
    html[data-gfplus-density="compact"] .script-list dd.script-list-created-date,
    html[data-gfplus-density="compact"] .script-list dt.script-list-updated-date,
    html[data-gfplus-density="compact"] .script-list dd.script-list-updated-date {
        display: none;
    }

    html[data-gfplus-density="compact"] .script-list .gf-script-card-actions {
        grid-column: 2;
        margin-top: .25rem;
        align-self: end;
        gap: .35rem;
    }

    @media (hover: hover) and (pointer: fine) {
        html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) > article > .gf-script-card-actions {
            opacity: 0;
            transform: translateX(6px);
            pointer-events: none;
            transition: opacity .16s ease, transform .16s ease;
        }

        html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info):hover > article > .gf-script-card-actions,
        html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info):focus-within > article > .gf-script-card-actions {
            opacity: 1;
            transform: translateX(0);
            pointer-events: auto;
        }
    }

    html[data-gfplus-density="compact"] .script-list .gf-script-install-button,
    html[data-gfplus-density="compact"] .script-list .gf-script-detail-button,
    html[data-gfplus-density="compact"] .script-list .gf-script-note-button {
        height: 1.9rem;
    }

    html[data-gfplus-density="compact"] .script-list .gf-script-detail-button,
    html[data-gfplus-density="compact"] .script-list .gf-script-note-button {
        width: 1.9rem;
        min-width: 1.9rem;
    }

    html[data-gfplus-density="compact"] .script-list .gf-script-install-button {
        padding: 0 .72rem;
        font-size: .84rem;
    }

    html[data-gfplus-density="detailed"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) {
        padding: clamp(1.2rem, 2.5vw, 1.6rem);
        gap: .55rem;
    }

    @media screen and (max-width: 600px) {
        .gf-script-list-heading {
            width: calc(100% - 1.5rem);
            margin: 8px .75rem -8px;
        }

        html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) {
            padding: .65rem .75rem;
        }

        html[data-gfplus-density="compact"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) > article {
            display: block;
        }

        html[data-gfplus-density="comfortable"] .script-list > li:not(.ad-entry):not(.gf-script-extra-info) > article {
            display: block;
        }

        html[data-gfplus-density="comfortable"] .script-list .gf-script-card-actions {
            margin-top: .65rem;
        }

        html[data-gfplus-density="compact"] .script-list .gf-script-card-actions {
            margin-top: .42rem;
        }

        html[data-gfplus-density="compact"] .script-list .inline-script-stats {
            grid-template-columns: minmax(6.8rem, 42%) minmax(0, 1fr);
            column-gap: .65rem;
        }

        html[data-gfplus-density="compact"] .script-list .inline-script-stats dt {
            grid-column: 1 !important;
            grid-row: auto !important;
        }

        html[data-gfplus-density="compact"] .script-list .inline-script-stats dd {
            grid-column: 2 !important;
            grid-row: auto !important;
        }
    }
    `;

    const densityStyle = document.createElement('style');
    densityStyle.id = DENSITY_STYLE_ID;
    densityStyle.textContent = DENSITY_CSS;
    appendStyle(densityStyle);

    const syncThemeStyles = (theme, variant = currentThemeVariant) => {
        const resolvedTheme = resolveTheme(theme);
        lightThemeStyle.media = resolvedTheme === 'dark' ? 'not all' : 'all';
        darkThemeStyle.media = resolvedTheme === 'dark' ? 'all' : 'not all';
        fullDarkThemeStyle.media = resolvedTheme === 'dark' && variant === 'full-dark' ? 'all' : 'not all';
        chalkboardThemeStyle.media = variant === 'chalkboard' ? 'all' : 'not all';
    };

    syncThemeStyles(currentTheme, currentThemeVariant);
    if (root.hasAttribute(HANDHELD_ATTR)) {
        schedulePhoneLoadClear();
    }

    const themeSwitchHosts = [];

    const syncThemeSwitchHosts = (theme, variant = currentThemeVariant) => {
        themeSwitchHosts.forEach((host) => {
            host.setAttribute('theme', theme);
            host.setAttribute('resolved-theme', resolveTheme(theme));
            host.setAttribute('theme-variant', variant);
            host.syncThemeButtons?.();
        });
    };

    const getThemeColor = (name) => {
        const value = getComputedStyle(root).getPropertyValue(name).trim();
        return value || '';
    };

    const INSTALL_STATS_CHART_CONTAINER_IDS = [
        'install-stats-chart-container',
        'weekly-install-stats-chart-container',
        'update-check-stats-chart-container'
    ];

    const applyInstallStatsChartTheme = () => {
        const backgroundColor = getThemeColor('--content-background-color');
        const borderColor = getThemeColor('--content-border-color');
        const barColor = getThemeColor('--install-stats-bar-color') || getThemeColor('--chart-background-color');
        const barHoverColor = getThemeColor('--install-stats-bar-hover-color') || getThemeColor('--chart-border-color');
        const textColor = getThemeColor('--install-stats-text-color') || getThemeColor('--overall-text-color');
        const gridColor = getThemeColor('--install-stats-grid-color') || getThemeColor('--content-border-color');

        root.style.setProperty('--chart-background-color', barColor);
        root.style.setProperty('--chart-border-color', barHoverColor);
        root.style.setProperty('--install-stats-bar-color', barColor);
        root.style.setProperty('--install-stats-bar-hover-color', barHoverColor);
        root.style.setProperty('--install-stats-grid-color', gridColor);
        root.style.setProperty('--install-stats-text-color', textColor);

        INSTALL_STATS_CHART_CONTAINER_IDS.forEach((containerId) => {
            const container = document.getElementById(containerId);
            if (!container) {
                return;
            }

            if (backgroundColor) {
                container.style.backgroundColor = backgroundColor;
            }
            if (borderColor) {
                container.style.border = `1px solid ${borderColor}`;
            }
        });

        const ChartCtor = pageWindow.Chart;
        if (ChartCtor?.defaults) {
            ChartCtor.defaults.color = textColor;
            ChartCtor.defaults.defaultFontColor = textColor;
            ChartCtor.defaults.backgroundColor = barColor;
            ChartCtor.defaults.borderColor = gridColor;
        }
    };

    const extractInstallStatsChartInitializers = () => Array.from(document.querySelectorAll('#script-content script'))
        .flatMap((script) => Array.from(String(script.textContent || '').matchAll(/initializeChart\(([\s\S]*?),\s*['"]([^'"]+)['"]\)/g)))
        .map((match) => ({
            dataSource: match[1],
            containerId: match[2]
        }))
        .filter(({ containerId }) => INSTALL_STATS_CHART_CONTAINER_IDS.includes(containerId));

    const destroyInstallStatsCanvasChart = (canvas) => {
        const ChartCtor = pageWindow.Chart;
        if (!ChartCtor || !canvas) {
            return;
        }

        const chart = typeof ChartCtor.getChart === 'function'
            ? (ChartCtor.getChart(canvas) || ChartCtor.getChart(canvas.id))
            : Object.values(ChartCtor.instances || {}).find((instance) => {
                const instanceCanvas = instance?.canvas || instance?.chart?.canvas || instance?.ctx?.canvas;
                return instanceCanvas === canvas;
            });
        if (chart && typeof chart.destroy === 'function') {
            chart.destroy();
        }
    };

    const rebuildInstallStatsCharts = () => {
        if (typeof pageWindow.initializeChart !== 'function') {
            return false;
        }

        const initializers = extractInstallStatsChartInitializers();
        if (!initializers.length) {
            applyInstallStatsChartTheme();
            return false;
        }

        applyInstallStatsChartTheme();
        INSTALL_STATS_CHART_CONTAINER_IDS.forEach((containerId) => {
            const container = document.getElementById(containerId);
            if (!container) {
                return;
            }

            container.querySelectorAll('canvas').forEach((canvas) => {
                destroyInstallStatsCanvasChart(canvas);
                canvas.remove();
            });
        });

        initializers.forEach(({ dataSource, containerId }) => {
            try {
                const data = Function(`return ${dataSource}`)();
                pageWindow.initializeChart(data, containerId);
            } catch (error) {
                console.warn('GreasyFork Premium: stats chart rebuild failed.', error);
            }
        });

        applyInstallStatsChartTheme();
        return true;
    };

    let installStatsChartRebuildFrame = 0;

    const initInstallStatsChartTheme = () => {
        if (installStatsChartRebuildFrame) {
            return;
        }

        installStatsChartRebuildFrame = requestAnimationFrame(() => {
            installStatsChartRebuildFrame = 0;
            window.setTimeout(rebuildInstallStatsCharts, 0);
        });
    };

    const clearThemeMotion = () => {
        if (themeMotionTimer) {
            window.clearTimeout(themeMotionTimer);
            themeMotionTimer = 0;
        }

        if (root) {
            root.removeAttribute(THEME_MOTION_ATTR);
            root.removeAttribute(THEME_FALLBACK_MOTION_ATTR);
        }
    };

    const commitTheme = (theme, variant = currentThemeVariant) => {
        currentTheme = theme;
        currentThemeVariant = variant;
        applyRootTheme(theme, variant);
        localStorage.setItem(STORAGE_KEY, theme);
        localStorage.setItem(THEME_VARIANT_STORAGE_KEY, variant);
        syncThemeStyles(theme, variant);
        syncThemeSwitchHosts(theme, variant);
        rebuildInstallStatsCharts();
    };

    const switchTheme = (theme, variant = currentThemeVariant) => {
        if (!root || (theme === currentTheme && variant === currentThemeVariant)) {
            return;
        }

        clearThemeMotion();
        const finish = () => {
            themeMotionTimer = window.setTimeout(clearThemeMotion, THEME_MOTION_DURATION);
        };

        if (typeof document.startViewTransition === 'function' && !root.hasAttribute(LOADING_ATTR)) {
            root.setAttribute(THEME_MOTION_ATTR, 'true');
            const transition = document.startViewTransition(() => {
                commitTheme(theme, variant);
            });

            Promise.resolve(transition.finished || transition.ready).finally(finish);
            return;
        }

        root.setAttribute(THEME_FALLBACK_MOTION_ATTR, 'true');
        requestAnimationFrame(() => {
            commitTheme(theme, variant);
            finish();
        });
    };

    const switchThemeVariant = (variant) => {
        if (!THEME_VARIANT_OPTIONS.includes(variant)) {
            return;
        }

        switchTheme(variant === 'full-dark' ? 'dark' : currentTheme, variant);
    };

    const syncSystemTheme = () => {
        if (currentTheme !== 'system') {
            return;
        }

        applyRootTheme(currentTheme, currentThemeVariant);
        syncThemeStyles(currentTheme, currentThemeVariant);
        syncThemeSwitchHosts(currentTheme, currentThemeVariant);
        rebuildInstallStatsCharts();
    };

    if (systemThemeQuery?.addEventListener) {
        systemThemeQuery.addEventListener('change', syncSystemTheme);
    } else {
        systemThemeQuery?.addListener?.(syncSystemTheme);
    }

    const createThemeSwitchHost = (hostId, options = {}) => {
        if (document.getElementById(hostId)) {
            return null;
        }

        const host = document.createElement('div');
        host.id = hostId;
        host.style.display = 'inline-flex';
        host.style.alignItems = 'center';
        host.style.verticalAlign = 'middle';
        host.style.marginLeft = options.marginLeft || '0';
        host.style.marginRight = options.marginRight || '0';
        host.style.marginTop = options.marginTop || '0';
        host.style.justifyContent = options.justifyContent || 'flex-start';

        const shadow = host.attachShadow({ mode: 'open' });
        const themeTranslations = getUserNavI18n(getCurrentLocale());
        const variantTranslations = themeTranslations.themeVariants || USER_NAV_I18N.en.themeVariants;

        shadow.innerHTML = `
        <style>
        :host {
            all: initial;
            display: inline-flex;
            align-items: center;
            vertical-align: middle;
            --track-bg: #e5e7eb;
            --track-border: #cbd5e1;
            --thumb-bg: #fff;
            --button-color: #475569;
            --active-color: #111827;
            --focus-color: #4f46e5;
            --menu-bg: #ffffff;
            --menu-border: #cbd5e1;
            --menu-shadow: 0 12px 30px rgba(15, 23, 42, .2);
            --menu-hover: #f1f5f9;
        }
        :host([resolved-theme="dark"]) {
            --track-bg: #1f2937;
            --track-border: #374151;
            --thumb-bg: #0f172a;
            --button-color: #94a3b8;
            --active-color: #f8fafc;
            --focus-color: #78a9ff;
            --menu-bg: #151b23;
            --menu-border: #374151;
            --menu-shadow: 0 14px 34px rgba(0, 0, 0, .46);
            --menu-hover: #202a36;
        }
        :host([resolved-theme="dark"][theme-variant="full-dark"]) {
            --track-bg: #101010;
            --track-border: #343434;
            --thumb-bg: #242424;
            --button-color: #9b9b9b;
            --active-color: #ffffff;
            --focus-color: #8ab4f8;
            --menu-bg: #121212;
            --menu-border: #343434;
            --menu-shadow: 0 16px 38px rgba(0, 0, 0, .72);
            --menu-hover: #222222;
        }
        :host([resolved-theme="light"][theme-variant="chalkboard"]) {
            --track-bg: #e8ece8;
            --track-border: #aebcb4;
            --thumb-bg: #fffefa;
            --button-color: #617069;
            --active-color: #29483f;
            --focus-color: #39796b;
            --menu-bg: #fffefa;
            --menu-border: #c8d1cb;
            --menu-shadow: 0 14px 32px rgba(37, 52, 46, .18);
            --menu-hover: #e8eee9;
        }
        :host([resolved-theme="dark"][theme-variant="chalkboard"]) {
            --track-bg: #1b2421;
            --track-border: #3b4b44;
            --thumb-bg: #2a3833;
            --button-color: #9ba8a2;
            --active-color: #e8e9e5;
            --focus-color: #82c7b6;
            --menu-bg: #181f1d;
            --menu-border: #3b4b44;
            --menu-shadow: 0 16px 38px rgba(0, 0, 0, .58);
            --menu-hover: #27332f;
        }
        :host(#gf-mobile-theme-switch) {
            flex: 0 0 120px;
            width: 120px;
            min-width: 120px;
            overflow: visible;
        }
        .theme-toggle {
            all: unset;
            display: inline-flex;
            align-items: center;
            justify-content: flex-start;
            gap: 2px;
            width: 120px;
            height: 30px;
            padding: 2px;
            border-radius: 999px;
            border: 1px solid var(--track-border);
            background: var(--track-bg);
            position: relative;
            box-sizing: border-box;
        }
        .mode-switch {
            position: relative;
            display: inline-flex;
            align-items: center;
            justify-content: space-between;
            width: 82px;
            height: 24px;
        }
        .thumb {
            position: absolute;
            top: 0;
            left: 0;
            width: 26px;
            height: 24px;
            border-radius: 999px;
            background: var(--thumb-bg);
            box-shadow: 0 2px 8px rgba(15, 23, 42, .18);
            transition: transform 0.24s ease, background 0.24s ease;
            box-sizing: border-box;
        }
        :host([theme="system"]) .thumb { transform: translateX(28px); }
        :host([theme="dark"]) .thumb { transform: translateX(56px); }
        button {
            all: unset;
            cursor: pointer;
            position: relative;
            z-index: 1;
            width: 26px;
            height: 24px;
            border-radius: 999px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            color: var(--button-color);
            box-sizing: border-box;
        }
        button[aria-pressed="true"] {
            color: var(--active-color);
            pointer-events: none;
        }
        button:focus-visible {
            outline: 2px solid var(--focus-color);
            outline-offset: 2px;
        }
        svg {
            width: 14px;
            height: 14px;
            stroke-width: 2;
            fill: none;
            stroke: currentColor;
        }
        .theme-divider {
            width: 1px;
            height: 18px;
            flex: 0 0 1px;
            background: var(--track-border);
            opacity: .9;
        }
        .variant-toggle {
            width: 26px;
            flex: 0 0 26px;
        }
        .variant-toggle svg {
            transition: transform .2s ease;
        }
        .variant-toggle[aria-expanded="true"] svg {
            transform: rotate(45deg);
        }
        .variant-menu {
            position: absolute;
            top: calc(100% + 8px);
            right: 0;
            z-index: 20;
            display: grid;
            gap: 2px;
            width: 208px;
            padding: 6px;
            border: 1px solid var(--menu-border);
            border-radius: 12px;
            background: var(--menu-bg);
            box-shadow: var(--menu-shadow);
            box-sizing: border-box;
        }
        .variant-menu[hidden] {
            display: none;
        }
        :host(#gf-mobile-theme-switch) .variant-menu {
            position: fixed;
            top: .65rem;
            right: .65rem;
            bottom: auto;
            width: min(208px, calc(100vw - 1.3rem));
            max-height: calc(100vh - 1.3rem);
            max-height: calc(100dvh - 1.3rem);
            overflow-x: hidden;
            overflow-y: auto;
            overscroll-behavior: contain;
            scrollbar-width: thin;
            scrollbar-color: var(--track-border) var(--menu-bg);
        }
        .variant-menu-heading {
            padding: 5px 8px 7px;
            margin-bottom: 3px;
            border-bottom: 1px solid var(--menu-border);
            color: var(--button-color);
            font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
            font-size: 10px;
            font-weight: 700;
            letter-spacing: .06em;
            text-align: left;
            text-transform: uppercase;
        }
        .variant-option {
            width: 100%;
            height: auto;
            min-height: 42px;
            padding: 6px 8px;
            gap: 9px;
            justify-content: flex-start;
            border-radius: 8px;
            font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
            text-align: left;
        }
        .variant-option:hover,
        .variant-option:focus-visible,
        .variant-option[aria-pressed="true"] {
            background: var(--menu-hover);
        }
        .variant-swatch {
            width: 24px;
            height: 24px;
            flex: 0 0 24px;
            border: 1px solid var(--menu-border);
            border-radius: 7px;
            box-shadow: inset 0 1px rgba(255, 255, 255, .14);
            box-sizing: border-box;
        }
        .variant-label {
            min-width: 0;
            flex: 1;
            color: var(--active-color);
            font-size: 12px;
            font-weight: 650;
            line-height: 1.2;
        }
        .variant-check {
            width: 16px;
            height: 16px;
            flex: 0 0 16px;
            padding: 2.5px;
            border-radius: 999px;
            background: var(--focus-color);
            color: var(--menu-bg);
            opacity: 0;
            transform: scale(.75);
            transition: opacity .16s ease, transform .16s ease;
            box-sizing: border-box;
        }
        .variant-option[aria-pressed="true"] .variant-check {
            opacity: 1;
            transform: scale(1);
        }
        .variant-swatch--normal {
            background: linear-gradient(135deg, #f5f7fb 0 44%, #6366f1 44% 56%, #151b23 56% 100%);
        }
        .variant-swatch--full-dark {
            background: linear-gradient(135deg, #f5f7fb 0 44%, #8ab4f8 44% 56%, #080808 56% 100%);
        }
        .variant-swatch--chalkboard {
            background: linear-gradient(135deg, #fffefa 0 44%, #4f897b 44% 56%, #181f1d 56% 100%);
        }
        </style>

        <div class="theme-toggle" role="group">
            <div class="mode-switch">
                <div class="thumb" aria-hidden="true"></div>
                <button type="button" data-theme-value="light" aria-label="Light" title="Light">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <circle cx="12" cy="12" r="5"/>
                        <line x1="12" y1="1" x2="12" y2="3"/>
                        <line x1="12" y1="21" x2="12" y2="23"/>
                        <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
                        <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
                        <line x1="1" y1="12" x2="3" y2="12"/>
                        <line x1="21" y1="12" x2="23" y2="12"/>
                        <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
                        <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
                    </svg>
                </button>
                <button type="button" data-theme-value="system" aria-label="System" title="System">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <rect x="3" y="4" width="18" height="12" rx="2"/>
                        <line x1="8" y1="20" x2="16" y2="20"/>
                        <line x1="12" y1="16" x2="12" y2="20"/>
                    </svg>
                </button>
                <button type="button" data-theme-value="dark" aria-label="Dark" title="Dark">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
                    </svg>
                </button>
            </div>
            <div class="theme-divider" aria-hidden="true"></div>
            <button class="variant-toggle" type="button" aria-label="${variantTranslations.menu}" title="${variantTranslations.menu}" aria-expanded="false">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true">
                    <line x1="12" y1="5" x2="12" y2="19"/>
                    <line x1="5" y1="12" x2="19" y2="12"/>
                </svg>
            </button>
            <div class="variant-menu" role="menu" aria-label="${variantTranslations.menu}" hidden>
                <div class="variant-menu-heading">${variantTranslations.menu}</div>
                <button class="variant-option" type="button" role="menuitemradio" data-theme-variant-value="normal">
                    <span class="variant-swatch variant-swatch--normal" aria-hidden="true"></span>
                    <span class="variant-label">${variantTranslations.normal}</span>
                    <svg class="variant-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg>
                </button>
                <button class="variant-option" type="button" role="menuitemradio" data-theme-variant-value="full-dark">
                    <span class="variant-swatch variant-swatch--full-dark" aria-hidden="true"></span>
                    <span class="variant-label">${variantTranslations.fullDark}</span>
                    <svg class="variant-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg>
                </button>
                <button class="variant-option" type="button" role="menuitemradio" data-theme-variant-value="chalkboard">
                    <span class="variant-swatch variant-swatch--chalkboard" aria-hidden="true"></span>
                    <span class="variant-label">${variantTranslations.chalkboard}</span>
                    <svg class="variant-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg>
                </button>
            </div>
        </div>
    `;

        const themeLabel = themeTranslations.themeToggle || 'Toggle theme';
        const group = shadow.querySelector('.theme-toggle');
        group.setAttribute('aria-label', themeLabel);
        const variantToggle = shadow.querySelector('.variant-toggle');
        const variantMenu = shadow.querySelector('.variant-menu');

        const positionMobileVariantMenu = () => {
            if (hostId !== 'gf-mobile-theme-switch' || variantMenu.hidden) {
                return;
            }

            const viewportPadding = 8;
            const menuGap = 8;
            const hostRect = host.getBoundingClientRect();
            const viewportWidth = window.innerWidth;
            const viewportHeight = window.innerHeight;
            const menuWidth = Math.min(208, viewportWidth - (viewportPadding * 2));
            const naturalMenuHeight = variantMenu.scrollHeight;
            const spaceAbove = hostRect.top - menuGap - viewportPadding;
            const spaceBelow = viewportHeight - hostRect.bottom - menuGap - viewportPadding;
            const placeBelow = spaceBelow >= Math.min(naturalMenuHeight, 180) || spaceBelow >= spaceAbove;
            const availableHeight = Math.max(96, placeBelow ? spaceBelow : spaceAbove);
            const menuHeight = Math.min(naturalMenuHeight, availableHeight);
            const left = Math.min(
                Math.max(viewportPadding, hostRect.right - menuWidth),
                viewportWidth - menuWidth - viewportPadding
            );
            const top = placeBelow
                ? hostRect.bottom + menuGap
                : hostRect.top - menuGap - menuHeight;

            variantMenu.style.width = `${menuWidth}px`;
            variantMenu.style.maxHeight = `${availableHeight}px`;
            variantMenu.style.left = `${left}px`;
            variantMenu.style.right = 'auto';
            variantMenu.style.top = `${Math.max(viewportPadding, top)}px`;
        };

        const closeVariantMenu = () => {
            variantMenu.hidden = true;
            variantToggle.setAttribute('aria-expanded', 'false');
        };

        const syncButtons = () => {
            shadow.querySelectorAll('button[data-theme-value]').forEach((button) => {
                const active = button.dataset.themeValue === currentTheme;
                button.setAttribute('aria-pressed', active ? 'true' : 'false');
            });
            shadow.querySelectorAll('button[data-theme-variant-value]').forEach((button) => {
                button.setAttribute('aria-checked', button.dataset.themeVariantValue === currentThemeVariant ? 'true' : 'false');
                button.setAttribute('aria-pressed', button.dataset.themeVariantValue === currentThemeVariant ? 'true' : 'false');
            });
        };

        shadow.querySelectorAll('button[data-theme-value]').forEach((button) => {
            button.addEventListener('click', () => {
                switchTheme(button.dataset.themeValue);
            });
        });

        variantToggle.addEventListener('click', () => {
            const willOpen = variantMenu.hidden;
            variantMenu.hidden = !willOpen;
            variantToggle.setAttribute('aria-expanded', willOpen ? 'true' : 'false');
            if (willOpen) {
                positionMobileVariantMenu();
            }
        });

        if (hostId === 'gf-mobile-theme-switch') {
            window.addEventListener('resize', positionMobileVariantMenu, { passive: true });
            document.addEventListener('scroll', positionMobileVariantMenu, { passive: true, capture: true });
        }

        shadow.querySelectorAll('button[data-theme-variant-value]').forEach((button) => {
            button.addEventListener('click', () => {
                switchThemeVariant(button.dataset.themeVariantValue);
                closeVariantMenu();
            });
        });

        shadow.addEventListener('keydown', (event) => {
            if (event.key === 'Escape') {
                closeVariantMenu();
                variantToggle.focus();
            }
        });

        document.addEventListener('click', (event) => {
            if (!host.contains(event.target)) {
                closeVariantMenu();
            }
        });

        themeSwitchHosts.push(host);
        host.setAttribute('theme', currentTheme);
        host.setAttribute('resolved-theme', resolveTheme(currentTheme));
        host.setAttribute('theme-variant', currentThemeVariant);
        host.syncThemeButtons = syncButtons;
        syncButtons();
        return host;
    };

    const initThemeSwitch = () => {
        if (document.getElementById('gf-theme-switch')) {
            return true;
        }

        const langForm = document.querySelector('form.language-selector');
        if (!langForm || !langForm.parentNode) {
            return false;
        }

        const host = createThemeSwitchHost('gf-theme-switch', {
            marginLeft: '8px'
        });

        if (!host) {
            return Boolean(document.getElementById('gf-theme-switch'));
        }

        langForm.parentNode.insertBefore(host, langForm.nextSibling);
        return true;
    };

    const initMobileThemeSwitch = () => {
        if (document.getElementById('gf-mobile-theme-switch')) {
            return true;
        }

        const mobileNav = document.querySelector('#mobile-nav nav');
        const languageItem = document.querySelector('#mobile-nav form.language-selector')?.closest('li');
        if (!mobileNav || !languageItem) {
            return false;
        }

        const host = createThemeSwitchHost('gf-mobile-theme-switch', {
            marginTop: '0.85rem',
            marginRight: '1.2rem'
        });

        if (!host) {
            return Boolean(document.getElementById('gf-mobile-theme-switch'));
        }

        const switchItem = document.createElement('li');
        switchItem.id = 'gf-mobile-theme-switch-item';
        switchItem.appendChild(host);
        mobileNav.insertBefore(switchItem, languageItem);
        return true;
    };

    const initMobileNavLayout = () => {
        const mobileNav = document.querySelector('#mobile-nav nav');
        if (!mobileNav) {
            return false;
        }

        if (document.getElementById('gf-mobile-primary-nav-item')) {
            return true;
        }

        const scriptsItem = mobileNav.querySelector('li.scripts-index-link');
        const forumItem = mobileNav.querySelector('li.forum-link');
        const helpItem = mobileNav.querySelector('li.help-link');
        if (!scriptsItem || !forumItem || !helpItem) {
            return false;
        }

        const primaryItem = document.createElement('li');
        primaryItem.id = 'gf-mobile-primary-nav-item';

        const primaryNav = document.createElement('div');
        primaryNav.id = 'gf-mobile-primary-nav';

        [scriptsItem, forumItem, helpItem].forEach((item) => {
            const link = item.querySelector('a');
            if (link) {
                primaryNav.appendChild(link);
            }
            item.remove();
        });

        const toggleButton = document.createElement('button');
        toggleButton.id = 'gf-mobile-primary-nav-toggle';
        toggleButton.type = 'button';
        toggleButton.textContent = '+';
        toggleButton.setAttribute('aria-expanded', 'false');
        primaryNav.appendChild(toggleButton);
        primaryItem.appendChild(primaryNav);

        const secondaryItem = document.createElement('li');
        secondaryItem.id = 'gf-mobile-secondary-nav-item';

        const secondaryNav = document.createElement('div');
        secondaryNav.id = 'gf-mobile-secondary-nav';
        secondaryNav.className = 'collapsed';

        const divider = document.createElement('div');
        divider.className = 'gf-mobile-secondary-divider';
        secondaryNav.appendChild(divider);

        [
            ...mobileNav.querySelectorAll(':scope > li')
        ].filter((item) => {
            if (item.id === 'gf-mobile-theme-switch-item') {
                return false;
            }

            if (item.classList.contains('multi-link-nav')) {
                return false;
            }

            return !item.querySelector('form.language-selector');
        }).forEach((item) => {
            secondaryNav.appendChild(item);
        });

        toggleButton.addEventListener('click', () => {
            const willExpand = secondaryNav.classList.contains('collapsed');
            secondaryNav.classList.toggle('collapsed', !willExpand);
            toggleButton.textContent = willExpand ? '-' : '+';
            toggleButton.setAttribute('aria-expanded', willExpand ? 'true' : 'false');
        });

        secondaryItem.appendChild(secondaryNav);
        mobileNav.prepend(secondaryItem);
        mobileNav.prepend(primaryItem);
        return true;
    };

    const createSidebarScrollButton = (direction) => {
        const isTop = direction === 'top';
        const label = isTop ? 'Aller en haut de la page' : 'Aller en bas de la page';
        const button = document.createElement('button');
        button.className = 'gf-sidebar-scroll-button';
        button.type = 'button';
        button.title = label;
        button.setAttribute('aria-label', label);
        button.innerHTML = isTop
            ? '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m18 15-6-6-6 6"></path></svg>'
            : '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m6 9 6 6 6-6"></path></svg>';

        button.addEventListener('click', () => {
            const reduceMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;
            const scrollingElement = document.scrollingElement || document.documentElement;
            window.scrollTo({
                top: isTop ? 0 : scrollingElement.scrollHeight,
                behavior: reduceMotion ? 'auto' : 'smooth'
            });
            button.blur();
        });

        return button;
    };

    const initSidebarScrollControls = () => {
        document.querySelectorAll('.sidebar').forEach((sidebar) => {
            if (sidebar.querySelector(':scope > .gf-sidebar-scroll-controls')) {
                return;
            }

            const controls = document.createElement('div');
            controls.className = 'gf-sidebar-scroll-controls';
            controls.appendChild(createSidebarScrollButton('top'));
            controls.appendChild(createSidebarScrollButton('bottom'));
            sidebar.appendChild(controls);
        });
    };

    const syncActiveScriptSetFilter = () => {
        const setGroup = document.getElementById('script-list-set');
        const activeSetId = new URL(window.location.href).searchParams.get('set');
        if (!setGroup || !activeSetId) {
            return false;
        }

        const activeLink = Array.from(setGroup.querySelectorAll('a[href]')).find((link) => {
            try {
                return new URL(link.href, window.location.href).searchParams.get('set') === activeSetId;
            } catch (error) {
                return false;
            }
        });
        const activeOption = activeLink?.closest('.list-option, li');
        if (!activeOption) {
            return false;
        }

        setGroup.querySelectorAll('.list-current').forEach((option) => {
            if (option !== activeOption) {
                option.classList.remove('list-current');
                option.removeAttribute('aria-current');
                option.querySelector('[aria-current]')?.removeAttribute('aria-current');
            }
        });

        activeOption.classList.add('list-current');
        activeOption.setAttribute('aria-current', 'page');
        activeLink.setAttribute('aria-current', 'page');
        return true;
    };

    const SIDEBAR_STICKY_GAP = 16;
    const MOBILE_SIDEBAR_STUCK_CLASS = 'gfplus-mobile-sidebar-stuck';
    let smartSidebarItems = [];
    let smartSidebarFrame = 0;
    let smartSidebarLastScrollY = window.scrollY;
    let smartSidebarResizeObserver = null;
    let smartSidebarInitialized = false;
    let mobileSidebarFrame = 0;
    let mobileSidebarInitialized = false;
    let mobileSidebarResizeObserver = null;

    const clampSidebarTop = (value, min, max) => Math.max(min, Math.min(max, value));

    const updateSmartSidebarPositions = () => {
        smartSidebarFrame = 0;
        const scrollY = window.scrollY;
        const scrollDelta = scrollY - smartSidebarLastScrollY;
        const desktop = window.matchMedia('(min-width: 801px)').matches;

        smartSidebarItems.forEach((item) => {
            const { sidebar } = item;
            if (!desktop) {
                sidebar.style.removeProperty('--gfplus-sidebar-sticky-top');
                item.top = SIDEBAR_STICKY_GAP;
                return;
            }

            const sidebarHeight = sidebar.offsetHeight;
            const maxTop = SIDEBAR_STICKY_GAP;
            const minTop = Math.min(maxTop, window.innerHeight - sidebarHeight - SIDEBAR_STICKY_GAP);

            if (sidebarHeight <= window.innerHeight - (SIDEBAR_STICKY_GAP * 2)) {
                item.top = maxTop;
            } else if (!Number.isFinite(item.top)) {
                item.top = clampSidebarTop(sidebar.getBoundingClientRect().top, minTop, maxTop);
            } else {
                item.top = clampSidebarTop(item.top - scrollDelta, minTop, maxTop);
            }

            sidebar.style.setProperty('--gfplus-sidebar-sticky-top', `${item.top}px`);
        });

        smartSidebarLastScrollY = scrollY;
    };

    const scheduleSmartSidebarUpdate = () => {
        if (smartSidebarFrame) {
            return;
        }
        smartSidebarFrame = requestAnimationFrame(updateSmartSidebarPositions);
    };

    const initSmartSidebar = () => {
        const sidebars = Array.from(document.querySelectorAll('.sidebar'));
        if (!sidebars.length) {
            return;
        }

        smartSidebarItems = sidebars.map((sidebar) => ({
            sidebar,
            top: Number.NaN
        }));
        smartSidebarLastScrollY = window.scrollY;

        if (!smartSidebarInitialized) {
            window.addEventListener('scroll', scheduleSmartSidebarUpdate, { passive: true });
            window.addEventListener('resize', scheduleSmartSidebarUpdate, { passive: true });
            smartSidebarInitialized = true;
        }

        if (typeof ResizeObserver === 'function') {
            if (smartSidebarResizeObserver) {
                smartSidebarResizeObserver.disconnect();
            }
            smartSidebarResizeObserver = new ResizeObserver(scheduleSmartSidebarUpdate);
            sidebars.forEach((sidebar) => smartSidebarResizeObserver.observe(sidebar));
        }

        scheduleSmartSidebarUpdate();
    };

    const updateMobileSidebarStickiness = () => {
        mobileSidebarFrame = 0;
        const mobile = window.matchMedia('(max-width: 800px)').matches;
        const anchor = document.querySelector('.sidebarred');

        if (!mobile || !anchor) {
            root.classList.remove(MOBILE_SIDEBAR_STUCK_CLASS);
            return;
        }

        const anchorTop = anchor.getBoundingClientRect().top + window.scrollY;
        root.classList.toggle(MOBILE_SIDEBAR_STUCK_CLASS, window.scrollY > 12 && window.scrollY + 12 >= anchorTop);
    };

    const scheduleMobileSidebarStickiness = () => {
        if (mobileSidebarFrame) {
            return;
        }
        mobileSidebarFrame = requestAnimationFrame(updateMobileSidebarStickiness);
    };

    const initMobileSidebarStickiness = () => {
        if (!document.querySelector('.sidebarred .sidebar, .sidebarred .open-sidebar')) {
            return;
        }

        if (!mobileSidebarInitialized) {
            window.addEventListener('scroll', scheduleMobileSidebarStickiness, { passive: true });
            window.addEventListener('resize', scheduleMobileSidebarStickiness, { passive: true });
            mobileSidebarInitialized = true;
        }

        if (typeof ResizeObserver === 'function') {
            if (mobileSidebarResizeObserver) {
                mobileSidebarResizeObserver.disconnect();
            }

            mobileSidebarResizeObserver = new ResizeObserver(scheduleMobileSidebarStickiness);
            document.querySelectorAll('.sidebarred, .sidebarred .sidebar').forEach((element) => {
                mobileSidebarResizeObserver.observe(element);
            });
        }

        scheduleMobileSidebarStickiness();
    };

    const readSidebarGroupStates = () => {
        try {
            const storedStates = JSON.parse(localStorage.getItem(SIDEBAR_GROUP_STATE_KEY) || '{}');
            return storedStates && typeof storedStates === 'object' ? storedStates : {};
        } catch (error) {
            return {};
        }
    };

    const saveSidebarGroupState = (groupKey, collapsed) => {
        try {
            const states = readSidebarGroupStates();
            states[groupKey] = collapsed;
            localStorage.setItem(SIDEBAR_GROUP_STATE_KEY, JSON.stringify(states));
        } catch (error) {
            // The controls still work when storage is unavailable.
        }
    };

    const getSidebarGroupLabel = (group) => {
        const textNode = Array.from(group.childNodes).find((node) => {
            return node.nodeType === Node.TEXT_NODE && node.textContent.trim();
        });
        return textNode?.textContent.trim().replace(/\s*:\s*$/, '') || group.id || 'ce groupe';
    };

    const updateSidebarGroupToggle = (group, button, collapsed) => {
        const label = getSidebarGroupLabel(group);
        group.setAttribute('data-gfplus-collapsed', String(collapsed));
        button.setAttribute('aria-expanded', String(!collapsed));
        button.setAttribute('aria-label', collapsed ? `Déplier ${label}` : `Replier ${label}`);
        button.title = collapsed ? `Déplier ${label}` : `Replier ${label}`;
        button.innerHTML = collapsed
            ? '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m6 9 6 6 6-6"></path></svg>'
            : '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m18 15-6-6-6 6"></path></svg>';
    };

    const initSidebarGroupToggles = () => {
        const savedStates = readSidebarGroupStates();
        document.querySelectorAll('.sidebar .list-option-group').forEach((group, index) => {
            const list = group.querySelector(':scope > ul');
            if (!list || group.querySelector(':scope > .gf-list-option-toggle-row')) {
                return;
            }

            const groupKey = group.id || `sidebar-group-${index}`;
            const row = document.createElement('div');
            row.className = 'gf-list-option-toggle-row';

            const button = document.createElement('button');
            button.className = 'gf-list-option-toggle';
            button.type = 'button';
            if (!list.id) {
                list.id = `${groupKey}-options`;
            }
            button.setAttribute('aria-controls', list.id);

            const collapsed = savedStates[groupKey] === true;
            updateSidebarGroupToggle(group, button, collapsed);

            button.addEventListener('click', () => {
                const willCollapse = group.getAttribute('data-gfplus-collapsed') !== 'true';
                updateSidebarGroupToggle(group, button, willCollapse);
                saveSidebarGroupState(groupKey, willCollapse);
                button.blur();
                scheduleSmartSidebarUpdate();
            });

            row.appendChild(button);
            list.insertAdjacentElement('afterend', row);
        });
    };

    const initCompactUserScriptSets = () => {
        const scriptSets = document.querySelector('#user-script-sets');
        if (!scriptSets) {
            return;
        }

        const container = scriptSets.closest('.text-content');
        if (container) {
            container.classList.add('text-content-compact');
        }
    };

    const MODERATOR_ACTIONS_PAGE_ATTR = 'data-gfplus-moderator-actions-page';
    const initModeratorActionsLayout = () => {
        if (window.location.pathname.includes('/moderator_actions')) {
            root.setAttribute(MODERATOR_ACTIONS_PAGE_ATTR, 'true');
        } else {
            root.removeAttribute(MODERATOR_ACTIONS_PAGE_ATTR);
        }
    };

    const SCRIPT_SET_EDITOR_ATTR = 'data-gfplus-set-editor';
    const SCRIPT_SET_EDITOR_PAGE_ATTR = 'data-gfplus-set-editor-page';

    const getScriptSetEditorI18n = (locale) => getUserNavI18n(locale);

    const collectScriptSetEntries = (form, select) => {
        const entries = new Map();

        Array.from(select?.options || []).forEach((option) => {
            const id = String(option.value || '').trim();
            if (!id) {
                return;
            }

            entries.set(id, {
                id,
                title: (option.textContent || '').trim() || `#${id}`
            });
        });

        form.querySelectorAll('input[name="scripts-included[]"]').forEach((input) => {
            const id = String(input.value || '').trim();
            if (!id || entries.has(id)) {
                return;
            }

            entries.set(id, {
                id,
                title: input.getAttribute('data-script-title') || `#${id}`
            });
        });

        return Array.from(entries.values());
    };

    const syncScriptSetHiddenInputs = (form, entries, anchor) => {
        form.querySelectorAll('input[name="scripts-included[]"]').forEach((input) => input.remove());

        entries.forEach(({ id, title }) => {
            const hiddenInput = document.createElement('input');
            hiddenInput.type = 'hidden';
            hiddenInput.name = 'scripts-included[]';
            hiddenInput.value = id;
            hiddenInput.setAttribute('data-script-title', title);
            anchor.appendChild(hiddenInput);
        });
    };

    const enhanceScriptSetEditor = (form) => {
        if (!form || form.getAttribute(SCRIPT_SET_EDITOR_ATTR) === 'done') {
            return;
        }

        const locale = getCurrentLocale();
        const i18n = getScriptSetEditorI18n(locale);
        const scriptsSection = form.querySelector('#script-set-scripts');
        const selectionBox = scriptsSection?.querySelector('.selection-box');
        const select = selectionBox?.querySelector('select[name="remove-scripts-included[]"], select[name*="remove-scripts-included"]');
        const removeSelectedButton = selectionBox?.querySelector('button[name="remove-selected-scripts"]');
        const addControl = scriptsSection?.querySelector('.form-control:not(.selection-box)');
        const includeButton = scriptsSection?.querySelector('button[name="script-action"]');
        const saveButton = form.querySelector('button[name="save"]');

        if (!scriptsSection || !selectionBox || !select) {
            return;
        }

        form.setAttribute(SCRIPT_SET_EDITOR_ATTR, 'done');
        form.classList.add('gf-set-editor-enhanced');
        root.setAttribute(SCRIPT_SET_EDITOR_PAGE_ATTR, 'true');

        const listPanel = document.createElement('div');
        listPanel.className = 'gf-set-script-list-panel';

        const listHeader = document.createElement('div');
        listHeader.className = 'gf-set-script-list-header';

        const listTitle = document.createElement('div');
        listTitle.className = 'gf-set-script-list-title';
        listTitle.textContent = i18n.currentScripts;

        const listCount = document.createElement('span');
        listCount.className = 'gf-set-script-list-count';

        const listBody = document.createElement('div');
        listBody.className = 'gf-set-script-list';

        const emptyState = document.createElement('div');
        emptyState.className = 'gf-set-script-empty';
        emptyState.textContent = i18n.emptyScripts;

        listHeader.appendChild(listTitle);
        listHeader.appendChild(listCount);
        listPanel.appendChild(listHeader);
        listPanel.appendChild(listBody);
        listPanel.appendChild(emptyState);
        selectionBox.prepend(listPanel);

        if (removeSelectedButton) {
            removeSelectedButton.hidden = true;
            removeSelectedButton.disabled = true;
        }

        if (addControl && includeButton) {
            const actions = document.createElement('div');
            actions.className = 'gf-set-editor-actions';
            includeButton.parentNode?.insertBefore(actions, includeButton);
            actions.appendChild(includeButton);
        }

        if (saveButton && !saveButton.closest('.gf-set-editor-footer')) {
            const footer = document.createElement('div');
            footer.className = 'gf-set-editor-footer';
            saveButton.textContent = i18n.save;
            saveButton.parentNode?.insertBefore(footer, saveButton);
            footer.appendChild(saveButton);
        }

        const renderEntries = () => {
            const entries = collectScriptSetEntries(form, select);
            listBody.innerHTML = '';
            listCount.textContent = String(entries.length);
            emptyState.hidden = entries.length > 0;

            entries.forEach(({ id, title }) => {
                const row = document.createElement('div');
                row.className = 'gf-set-script-row';
                row.setAttribute('data-script-id', id);

                const name = document.createElement('div');
                name.className = 'gf-set-script-name';
                name.textContent = title;

                const removeButton = document.createElement('button');
                removeButton.type = 'button';
                removeButton.className = 'gf-set-script-remove';
                removeButton.setAttribute('aria-label', `${i18n.removeScript}: ${title}`);
                removeButton.innerHTML = `
                    <svg viewBox="0 0 24 24" aria-hidden="true">
                        <path d="M18 6 6 18"></path>
                        <path d="m6 6 12 12"></path>
                    </svg>
                `;
                removeButton.addEventListener('click', () => {
                    Array.from(select.options)
                        .filter((option) => String(option.value || '').trim() === id)
                        .forEach((option) => option.remove());

                    form.querySelectorAll('input[name="scripts-included[]"]').forEach((input) => {
                        if (String(input.value || '').trim() === id) {
                            input.remove();
                        }
                    });

                    syncScriptSetHiddenInputs(form, collectScriptSetEntries(form, select), scriptsSection);
                    renderEntries();
                });

                row.appendChild(name);
                row.appendChild(removeButton);
                listBody.appendChild(row);
            });

            syncScriptSetHiddenInputs(form, entries, scriptsSection);
        };

        renderEntries();
    };

    const initScriptSetEditor = () => {
        document.querySelectorAll(FAVORITE_FORM_SELECTOR).forEach(enhanceScriptSetEditor);
    };

    const HIGHLIGHT_ATTR = 'data-gfplus-hljs';
    let wrapLinesBound = false;

    const getHighlightApi = () => typeof hljs === 'undefined' ? null : hljs;

    const getWrapLinesToggle = () => document.querySelector('#wrap-lines');

    const syncWrapLines = () => {
        const toggle = getWrapLinesToggle();
        if (!toggle) {
            return;
        }

        const shouldWrap = toggle.checked;
        document.querySelectorAll('pre.gf-hljs').forEach((pre) => {
            pre.classList.toggle('wrap', shouldWrap);
        });

        scheduleLineNumberSync();
    };

    const maybeInitWrapLinesToggle = () => {
        if (wrapLinesBound) {
            return;
        }

        const toggle = getWrapLinesToggle();
        if (!toggle) {
            return;
        }

        wrapLinesBound = true;
        toggle.addEventListener('change', syncWrapLines);
    };

    const getHighlightLanguage = (element) => {
        if (!element || !element.className) {
            return null;
        }

        const classes = element.className.split(/\s+/);
        const langClass = classes.find((cls) => cls.startsWith('language-') || cls.startsWith('lang-'));
        if (!langClass) {
            return null;
        }

        return langClass.replace(/^language-/, '').replace(/^lang-/, '');
    };

    const countCodeLines = (codeText) => {
        const normalized = String(codeText || '').replace(/\r\n?/g, '\n');
        if (!normalized) {
            return 0;
        }

        return normalized.split('\n').length;
    };

    const getCodeTextFromPre = (pre) => {
        const codeEl = pre.querySelector('code.hljs');
        if (codeEl) {
            return codeEl.textContent || '';
        }

        const sourceLines = pre.querySelectorAll('ol.linenums > li, li.L0, li.L1, li.L2, li.L3, li.L4, li.L5, li.L6, li.L7, li.L8, li.L9');
        if (sourceLines.length) {
            return Array.from(sourceLines, (line) => line.textContent || '').join('\n');
        }

        return pre.textContent || '';
    };

    const getRenderedCodeLineCount = (pre, fallbackCount) => {
        const codeEl = pre.querySelector('code.hljs');
        if (!codeEl || !pre.classList.contains('wrap')) {
            return fallbackCount;
        }

        const style = window.getComputedStyle(codeEl);
        const lineHeight = parseFloat(style.lineHeight);
        if (!Number.isFinite(lineHeight) || lineHeight <= 0) {
            return fallbackCount;
        }

        const paddingTop = parseFloat(style.paddingTop) || 0;
        const paddingBottom = parseFloat(style.paddingBottom) || 0;
        const renderedHeight = codeEl.scrollHeight - paddingTop - paddingBottom;
        const renderedLineCount = Math.round(renderedHeight / lineHeight);
        if (!Number.isFinite(renderedLineCount) || renderedLineCount <= 0) {
            return fallbackCount;
        }

        return Math.max(fallbackCount, renderedLineCount);
    };

    const ensureLineNumbers = (pre, codeText) => {
        const lineCount = getRenderedCodeLineCount(pre, countCodeLines(codeText));
        if (!lineCount) {
            return;
        }

        let numbersEl = Array.from(pre.children).find((child) => child.classList?.contains('hljs-line-numbers'));
        if (!numbersEl) {
            numbersEl = document.createElement('span');
            numbersEl.className = 'hljs-line-numbers';
            pre.insertBefore(numbersEl, pre.firstChild);
        }

        const nextLineCount = String(lineCount);
        if (numbersEl.getAttribute('data-gfplus-line-count') === nextLineCount) {
            return;
        }

        numbersEl.textContent = Array.from({ length: lineCount }, (_, index) => index + 1).join('\n');
        numbersEl.setAttribute('data-gfplus-line-count', nextLineCount);
    };

    const syncLineNumbers = () => {
        document.querySelectorAll('pre.gf-hljs').forEach((pre) => {
            ensureLineNumbers(pre, getCodeTextFromPre(pre));
        });
    };

    const scheduleLineNumberSync = () => {
        requestAnimationFrame(() => {
            syncLineNumbers();
            requestAnimationFrame(syncLineNumbers);
        });
    };

    window.addEventListener('resize', scheduleLineNumberSync, { passive: true });

    const highlightCodeBlock = (pre) => {
        const state = pre.getAttribute(HIGHLIGHT_ATTR);
        const highlightApi = getHighlightApi();
        const hasHljs = typeof highlightApi?.highlightElement === 'function';
        if (state === 'done') {
            const codeEl = pre.querySelector('code.hljs');
            if (codeEl) {
                ensureLineNumbers(pre, getCodeTextFromPre(pre));
                pre.classList.add('gf-hljs');
            }
            return;
        }

        let codeEl = pre.querySelector('code.hljs');
        if (!codeEl) {
            const codeText = getCodeTextFromPre(pre);
            if (!codeText || !codeText.trim()) {
                return;
            }

            codeEl = document.createElement('code');
            const lang = getHighlightLanguage(pre) || getHighlightLanguage(pre.querySelector('code'));
            codeEl.classList.add('hljs');
            if (lang) {
                codeEl.classList.add(`language-${lang}`);
            }
            codeEl.textContent = codeText;

            pre.innerHTML = '';
            pre.appendChild(codeEl);
            pre.classList.add('gf-hljs');
            pre.classList.remove('prettyprint', 'linenums');
            ensureLineNumbers(pre, codeText);
        } else {
            const codeText = codeEl.textContent || '';
            if (codeText) {
                ensureLineNumbers(pre, codeText);
            }
            pre.classList.add('gf-hljs');
        }

        if (hasHljs) {
            highlightApi.highlightElement(codeEl);
            pre.setAttribute(HIGHLIGHT_ATTR, 'done');
        } else {
            pre.setAttribute(HIGHLIGHT_ATTR, 'pending');
        }
    };

    const applyHighlightJs = () => {
        document
            .querySelectorAll('.code-container pre, #code-container pre, pre.prettyprint, pre.gf-hljs')
            .forEach(highlightCodeBlock);
        maybeInitWrapLinesToggle();
        syncWrapLines();
    };

    const initHighlightJs = () => {
        applyHighlightJs();

        const root = document.querySelector('#script-content') || document.body;
        const observer = new MutationObserver(applyHighlightJs);
        observer.observe(root, { childList: true, subtree: true });
    };

    // ============================================================================
    // Script Logos
    // ============================================================================
    const SCRIPT_LOGO_ATTR = 'data-gfplus-logo';
    const SCRIPT_TITLE_CONTENT_CLASS = 'gf-script-title-content';
    const scriptIconCache = new Map();
    let scriptLogoObserver = null;
    const LOGO_SIZE_LIST = 26;
    const LOGO_SIZE_TITLE = 34;

    const normalizeIconUrl = (iconUrl, baseUrl) => {
        if (!iconUrl) {
            return null;
        }

        if (iconUrl.startsWith('data:')) {
            return iconUrl;
        }

        if (iconUrl.startsWith('//')) {
            return `https:${iconUrl}`;
        }

        try {
            return new URL(iconUrl, baseUrl).href;
        } catch (error) {
            return iconUrl;
        }
    };

    const extractMetaIcon = (scriptText, baseUrl) => {
        const metaMatch = scriptText.match(/\/\/\s*==UserScript==[\s\S]*?\/\/\s*==\/UserScript==/);
        if (!metaMatch) {
            return null;
        }

        const lines = metaMatch[0].split(/\r?\n/);
        let iconValue = null;
        let icon64Value = null;

        lines.forEach((line) => {
            const cleaned = line.replace(/^\s*\/\/\s*/, '').trim();
            if (!cleaned.startsWith('@')) {
                return;
            }

            const [rawTag, ...rest] = cleaned.split(/\s+/);
            const tag = rawTag.toLowerCase();
            const value = rest.join(' ').trim();
            if (!value) {
                return;
            }

            if (tag === '@icon64' || tag === '@icon64url') {
                icon64Value = value;
            } else if (tag === '@icon' || tag === '@iconurl') {
                if (!iconValue) {
                    iconValue = value;
                }
            }
        });

        return normalizeIconUrl(icon64Value || iconValue, baseUrl);
    };

    const fetchScriptIcon = (codeUrl) => {
        if (!codeUrl) {
            return Promise.resolve(null);
        }

        if (scriptIconCache.has(codeUrl)) {
            return scriptIconCache.get(codeUrl);
        }

        const fetchPromise = (async () => {
            let scriptText = '';
            let iconUrl = null;

            try {
                const ranged = await fetch(codeUrl, { headers: { Range: 'bytes=0-8191' } });
                if (ranged.ok) {
                    scriptText = await ranged.text();
                    iconUrl = extractMetaIcon(scriptText, codeUrl);
                }
            } catch (error) {
                scriptText = '';
            }

            if (!iconUrl) {
                try {
                    const response = await fetch(codeUrl);
                    if (response.ok) {
                        scriptText = await response.text();
                        iconUrl = extractMetaIcon(scriptText, codeUrl);
                    }
                } catch (error) {
                    iconUrl = null;
                }
            }

            return iconUrl;
        })();

        scriptIconCache.set(codeUrl, fetchPromise);
        return fetchPromise;
    };

    const createScriptLogoElement = (iconUrl) => {
        if (iconUrl) {
            const img = document.createElement('img');
            img.className = 'gf-script-logo';
            img.alt = '';
            img.loading = 'lazy';
            img.decoding = 'async';
            img.referrerPolicy = 'no-referrer';
            img.width = LOGO_SIZE_LIST;
            img.height = LOGO_SIZE_LIST;
            img.src = iconUrl;
            return img;
        }

        const fallback = document.createElement('span');
        fallback.className = 'gf-script-logo gf-script-logo--fallback';
        fallback.setAttribute('aria-hidden', 'true');
        fallback.innerHTML = `
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
            <path d="M7 8L3 12L7 16"></path>
            <path d="M17 8L21 12L17 16"></path>
            <path d="M10 19L14 5"></path>
        </svg>
        `;
        return fallback;
    };

    const ensureScriptListTitleContentLayout = (link, logoEl) => {
        const title = link ? link.closest('.script-list h2') : null;
        if (!title || !logoEl || logoEl.parentNode !== title) {
            return;
        }

        let content = title.querySelector(`:scope > .${SCRIPT_TITLE_CONTENT_CLASS}`);
        if (!content) {
            content = document.createElement('span');
            content.className = SCRIPT_TITLE_CONTENT_CLASS;
            title.insertBefore(content, logoEl.nextSibling);
        }

        let insertAfterContent = content;
        Array.from(content.childNodes).forEach((child) => {
            if (
                child.nodeType === Node.ELEMENT_NODE &&
                child.matches('.name-description-separator, .script-description, .description')
            ) {
                title.insertBefore(child, insertAfterContent.nextSibling);
                insertAfterContent = child;
            }
        });

        let shouldMoveTitleNodes = true;
        Array.from(title.childNodes).forEach((child) => {
            if (child === logoEl || child === content) {
                return;
            }
            if (
                child.nodeType === Node.ELEMENT_NODE &&
                child.matches('.name-description-separator, .script-description, .description')
            ) {
                shouldMoveTitleNodes = false;
                return;
            }
            if (!shouldMoveTitleNodes) {
                return;
            }
            content.appendChild(child);
        });

        if (content.previousSibling !== logoEl) {
            title.insertBefore(content, logoEl.nextSibling);
        }
    };

    const ensureLogoForLink = (link) => {
        if (!link || link.getAttribute(SCRIPT_LOGO_ATTR)) {
            return;
        }

        const listItem = link.closest('li[data-code-url]');
        const codeUrl = listItem ? listItem.getAttribute('data-code-url') : null;
        if (!codeUrl) {
            return;
        }

        link.setAttribute(SCRIPT_LOGO_ATTR, 'pending');
        fetchScriptIcon(codeUrl)
            .then((iconUrl) => {
                const parent = link.parentNode;
                if (!parent) {
                    link.removeAttribute(SCRIPT_LOGO_ATTR);
                    return;
                }

                const existingLogo = parent.querySelector(':scope > .gf-script-logo');
                if (existingLogo) {
                    ensureScriptListTitleContentLayout(link, existingLogo);
                    link.setAttribute(SCRIPT_LOGO_ATTR, 'done');
                    return;
                }

                const logoEl = createScriptLogoElement(iconUrl);
                if (!logoEl) {
                    link.removeAttribute(SCRIPT_LOGO_ATTR);
                    return;
                }

                parent.insertBefore(logoEl, link);
                ensureScriptListTitleContentLayout(link, logoEl);
                link.setAttribute(SCRIPT_LOGO_ATTR, 'done');
            })
            .catch(() => {
                link.removeAttribute(SCRIPT_LOGO_ATTR);
            });
    };

    const ensureLogoForHeaderTitle = () => {
        const headerTitle = document.querySelector('#script-info header h2, #script-info h2');
        if (!headerTitle || headerTitle.getAttribute(SCRIPT_LOGO_ATTR)) {
            return;
        }

        const installLink = document.querySelector('a.install-link[data-install-format="js"]');
        const codeUrl = installLink ? installLink.href : null;
        if (!codeUrl) {
            return;
        }

        headerTitle.setAttribute(SCRIPT_LOGO_ATTR, 'pending');
        fetchScriptIcon(codeUrl)
            .then((iconUrl) => {
                if (headerTitle.querySelector('.gf-script-logo')) {
                    headerTitle.setAttribute(SCRIPT_LOGO_ATTR, 'done');
                    return;
                }

                const logoEl = createScriptLogoElement(iconUrl);
                if (!logoEl) {
                    headerTitle.removeAttribute(SCRIPT_LOGO_ATTR);
                    return;
                }

                logoEl.classList.add('gf-script-logo--title');
                if (logoEl.tagName === 'IMG') {
                    logoEl.width = LOGO_SIZE_TITLE;
                    logoEl.height = LOGO_SIZE_TITLE;
                }
                headerTitle.insertBefore(logoEl, headerTitle.firstChild);
                headerTitle.setAttribute(SCRIPT_LOGO_ATTR, 'done');
            })
            .catch(() => {
                headerTitle.removeAttribute(SCRIPT_LOGO_ATTR);
            });
    };

    const applyScriptLogos = () => {
        document.querySelectorAll('a.script-link').forEach(ensureLogoForLink);
        ensureLogoForHeaderTitle();
    };

    const initScriptLogos = () => {
        applyScriptLogos();
        if (scriptLogoObserver) {
            return;
        }

        scriptLogoObserver = new MutationObserver(applyScriptLogos);
        scriptLogoObserver.observe(document.body, { childList: true, subtree: true });
    };

    // ============================================================================
    // Script Cards And Detail Actions
    // ============================================================================
    const SCRIPT_CARD_ACTIONS_ATTR = 'data-gfplus-actions';
    const SCRIPT_DETAIL_ACTIONS_ATTR = 'data-gfplus-detail-actions';
    const SCRIPT_DETAIL_ACTIONS_CONTAINER_ID = 'gfplus-script-detail-actions';
    const SCRIPT_EXTRA_INFO_ATTR = 'data-gfplus-extra-info';
    const SCRIPT_EXTRA_INFO_CACHE = new Map();
    const SCRIPT_LIBRARY_NAME_PATTERN = /\b(?:library|librairie|biblioth[eè]que)\b/i;
    const SCRIPT_LIBRARY_INFO_PATTERN = /(?:ne doit pas être installé directement|should not be installed directly|not intended to be installed directly|librairie destinée à être incluse|library intended to be included)/i;
    // ============================================================================
    // Favorites
    // ============================================================================
    const FAVORITES_IDS_STORAGE_KEY = 'gfplus-favorites-ids-v1';
    const PERSONAL_NOTES_STORAGE_KEY = 'gfplus-personal-notes-v1';
    const FAVORITE_SET_NAME_PATTERN = /\bfavor(?:it(?:e|es|o|os|a|as)?|is?)\b/i;
    const FAVORITE_FORM_SELECTOR = 'form.change-script-set, form[id^="edit_script_set"], form[id^="new_script_set"]';
    let scriptCardActionsObserver = null;
    let currentPageLibraryDetailPromise = null;
    let favoriteIdsCache = null;
    let favoriteIdsPromise = null;
    let favoriteSetMetaCache = null;
    let favoriteSetMissingConfirmed = false;
    let favoriteMutationQueue = Promise.resolve();
    let favoriteSyncToken = 0;
    const pendingFavoriteOverrides = new Map();
    const favoriteBusyScriptIds = new Set();
    const reportedStorageErrors = new Set();

    const reportStorageErrorOnce = (operation, error) => {
        if (reportedStorageErrors.has(operation)) {
            return;
        }

        reportedStorageErrors.add(operation);
        console.warn(`GreasyFork Premium: unable to ${operation}.`, error);
    };

    const getCurrentLocale = () => (window.location.pathname.match(/^\/([a-z]{2,3}(?:-(?:[A-Z]{2}|[0-9]{3}))?)(?:\/|$)/) || [null, 'en'])[1];
    const buildFavoriteHtmlHeaders = () => ({
        Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
    });
    const extractUserProfilePathFromValue = (value) => {
        const match = String(value || '').match(/\/[a-z]{2,3}(?:-(?:[A-Z]{2}|[0-9]{3}))?\/users\/\d+(?:-[^/?#]+)?/);
        return match ? match[0] : null;
    };
    const extractUserIdFromProfilePath = (profilePath) => String(profilePath || '').match(/\/users\/(\d+)/)?.[1] || '';
    const isSameUserProfilePath = (leftProfilePath, rightProfilePath) => {
        const leftId = extractUserIdFromProfilePath(leftProfilePath);
        const rightId = extractUserIdFromProfilePath(rightProfilePath);
        return Boolean(leftId && rightId && leftId === rightId);
    };
    const extractCurrentUserProfilePath = () => {
        const selectors = [
            '#nav-user-info .user-profile-link a[href*="/users/"]',
            '#nav-user-info a[href*="/users/"][href*="/notification_settings"]',
            '#nav-user-info a[href*="/users/"][href*="/notifications"]',
            '#nav-user-info a[href*="/users/"][href*="/sets/"][href*="/edit"]',
            '#nav-user-info a[href*="/users/"]:not([href*="/sign_in"]):not([href*="/sign_out"])',
            '#mobile-nav .user-profile-link a[href*="/users/"]',
            '#mobile-nav a[href*="/users/"][href*="/notification_settings"]',
            '#mobile-nav a[href*="/users/"][href*="/notifications"]',
            '#mobile-nav a[href*="/users/"][href*="/sets/"][href*="/edit"]',
            '#mobile-nav a[href*="/users/"]:not([href*="/sign_in"]):not([href*="/sign_out"])',
            '.gf-user-panel a[href*="/users/"][href*="/notification_settings"]',
            '.gf-user-panel a[href*="/users/"][href*="/notifications"]'
        ];

        for (const selector of selectors) {
            const href = document.querySelector(selector)?.getAttribute('href') || '';
            const profilePath = extractUserProfilePathFromValue(href);
            if (profilePath) {
                return profilePath;
            }
        }

        return null;
    };
    const readStoredFavoriteIds = () => {
        try {
            const currentUserId = extractUserIdFromProfilePath(extractCurrentUserProfilePath());
            if (!currentUserId) {
                return new Set();
            }

            const parsed = JSON.parse(localStorage.getItem(`${FAVORITES_IDS_STORAGE_KEY}:${currentUserId}`) || '[]');
            return new Set(Array.isArray(parsed) ? parsed.map((id) => String(id).trim()).filter(Boolean) : []);
        } catch (error) {
            reportStorageErrorOnce('read stored favorites', error);
            return new Set();
        }
    };
    const writeStoredFavoriteIds = (favoriteIds) => {
        try {
            const currentUserId = extractUserIdFromProfilePath(extractCurrentUserProfilePath());
            if (!currentUserId) {
                return;
            }

            localStorage.setItem(`${FAVORITES_IDS_STORAGE_KEY}:${currentUserId}`, JSON.stringify(Array.from(favoriteIds instanceof Set ? favoriteIds : new Set())));
            localStorage.removeItem(FAVORITES_IDS_STORAGE_KEY);
        } catch (error) {
            reportStorageErrorOnce('store favorites locally', error);
        }
    };
    const getPersonalNoteStorageKey = (scriptId) => {
        const currentUserId = extractUserIdFromProfilePath(extractCurrentUserProfilePath()) || 'anonymous';
        return `${PERSONAL_NOTES_STORAGE_KEY}:${currentUserId}:${scriptId}`;
    };
    const readPersonalNote = (scriptId) => {
        try {
            return localStorage.getItem(getPersonalNoteStorageKey(scriptId)) || '';
        } catch (error) {
            reportStorageErrorOnce('read personal notes', error);
            return '';
        }
    };
    const writePersonalNote = (scriptId, note) => {
        try {
            const storageKey = getPersonalNoteStorageKey(scriptId);
            const trimmedNote = String(note || '').trim();
            if (trimmedNote) {
                localStorage.setItem(storageKey, trimmedNote);
            } else {
                localStorage.removeItem(storageKey);
            }
        } catch (error) {
            reportStorageErrorOnce('store personal notes', error);
        }
    };
    const clearStoredFavoriteIds = () => {
        favoriteIdsCache = new Set();
        favoriteSetMetaCache = null;
        try {
            const currentUserId = extractUserIdFromProfilePath(extractCurrentUserProfilePath());
            if (currentUserId) {
                localStorage.removeItem(`${FAVORITES_IDS_STORAGE_KEY}:${currentUserId}`);
            }
            localStorage.removeItem(FAVORITES_IDS_STORAGE_KEY);
        } catch (error) {
            reportStorageErrorOnce('clear stored favorites', error);
        }
    };
    const findFavoriteSetLinkInDocument = (doc, baseUrl = window.location.href) => {
        const currentUserProfilePath = extractCurrentUserProfilePath();
        if (!currentUserProfilePath) {
            return null;
        }

        const sourceUrl = new URL(baseUrl, window.location.origin);
        const sourceProfilePath = extractUserProfilePathFromValue(sourceUrl.pathname);
        const isOwnProfileDocument = isSameUserProfilePath(sourceProfilePath, currentUserProfilePath);
        const currentSetId = sourceUrl.searchParams.get('set');
        const currentHeading = doc.querySelector('.sidebarred-main-content h1, .sidebarred-main-content h2, .sidebarred-main-content h3, .text-content h1, .text-content h2, .text-content h3')?.textContent || '';
        if (currentSetId && isFavoriteSetName(currentHeading)) {
            const ownEditLink = doc.querySelector(`a[href*="/sets/${currentSetId}/edit"]`)?.getAttribute('href') || '';
            const editProfilePath = extractUserProfilePathFromValue(ownEditLink);
            if (
                favoriteSetMetaCache?.setId === currentSetId
                || isSameUserProfilePath(editProfilePath, currentUserProfilePath)
            ) {
                return sourceUrl.toString();
            }
        }

        const links = Array.from(doc.querySelectorAll([
            '#script-list-set a[href*="set="]',
            '#user-script-sets a[href*="set="]',
            '.sidebarred-main-content a[href*="set="]',
            '.text-content a[href*="set="]'
        ].join(', ')));
        const favoriteLink = links.find((link) => {
            if (!isFavoriteSetName(link.textContent || '')) {
                return false;
            }

            const href = link.getAttribute('href') || '';
            const linkUrl = new URL(href, sourceUrl);
            const linkProfilePath = extractUserProfilePathFromValue(linkUrl.pathname);
            return linkProfilePath
                ? isSameUserProfilePath(linkProfilePath, currentUserProfilePath)
                : isOwnProfileDocument;
        });
        return favoriteLink?.href ? new URL(favoriteLink.href, baseUrl).toString() : null;
    };
    const resolveFavoriteSetUrl = async () => {
        if (favoriteSetMetaCache?.viewUrl) {
            favoriteSetMissingConfirmed = false;
            return favoriteSetMetaCache.viewUrl;
        }

        const currentSetUrl = findFavoriteSetLinkInDocument(document);
        if (currentSetUrl) {
            favoriteSetMissingConfirmed = false;
            return currentSetUrl;
        }

        const profilePath = extractCurrentUserProfilePath();
        if (!profilePath) {
            return null;
        }

        const response = await fetch(new URL(profilePath, window.location.origin).toString(), {
            credentials: 'include',
            cache: 'no-store'
        });
        if (!response.ok) {
            return null;
        }

        const doc = new DOMParser().parseFromString(await response.text(), 'text/html');
        const favoriteSetUrl = findFavoriteSetLinkInDocument(doc, response.url);
        if (favoriteSetUrl) {
            favoriteSetMissingConfirmed = false;
            return favoriteSetUrl;
        }

        favoriteSetMissingConfirmed = true;
        clearStoredFavoriteIds();
        return null;
    };
    const getAllFavoritesIds = async ({ force = false } = {}) => {
        if (!force && favoriteIdsCache instanceof Set) {
            return new Set(favoriteIdsCache);
        }

        if (!force && favoriteIdsPromise) {
            return favoriteIdsPromise.then((favoriteIds) => new Set(favoriteIds));
        }

        const storedFavoriteIds = readStoredFavoriteIds();
        if (!force && storedFavoriteIds.size) {
            favoriteIdsCache = new Set(storedFavoriteIds);
        }

        const loadPromise = (async () => {
            const setUrl = await resolveFavoriteSetUrl();
            if (!setUrl) {
                if (favoriteSetMissingConfirmed) {
                    return new Set();
                }

                favoriteIdsCache = new Set(storedFavoriteIds);
                return new Set(storedFavoriteIds);
            }

            const baseUrl = new URL(setUrl, window.location.origin);
            baseUrl.searchParams.set('filter_locale', '0');

            const allIds = new Set();
            let page = 1;
            let fetchedExistingSet = false;

            while (true) {
                baseUrl.searchParams.set('page', String(page));

                const response = await fetch(baseUrl.href, {
                    credentials: 'include',
                    cache: 'no-store'
                });
                if (!response.ok) {
                    break;
                }
                if (response.url.includes('/users/sign_in')) {
                    throw new Error('Authentication required.');
                }

                fetchedExistingSet = true;
                const html = await response.text();
                const doc = new DOMParser().parseFromString(html, 'text/html');
                const ids = Array.from(doc.querySelectorAll('li[data-script-id]'))
                    .map((element) => String(element.getAttribute('data-script-id') || '').trim())
                    .filter(Boolean);

                if (!ids.length) {
                    break;
                }

                ids.forEach((id) => allIds.add(id));
                page += 1;
            }

            if (allIds.size) {
                favoriteSetMissingConfirmed = false;
                favoriteIdsCache = new Set(allIds);
                writeStoredFavoriteIds(allIds);
                return allIds;
            }

            if (fetchedExistingSet) {
                favoriteSetMissingConfirmed = false;
                favoriteIdsCache = new Set();
                writeStoredFavoriteIds([]);
                return new Set();
            }

            if (force) {
                throw new Error('Favorite set could not be loaded.');
            }

            if (favoriteSetMissingConfirmed) {
                return new Set();
            }

            favoriteIdsCache = new Set(storedFavoriteIds);
            return new Set(storedFavoriteIds);
        })().finally(() => {
            if (favoriteIdsPromise === loadPromise) {
                favoriteIdsPromise = null;
            }
        });

        favoriteIdsPromise = loadPromise;
        return loadPromise.then((favoriteIds) => new Set(favoriteIds));
    };
    const getFavoriteSetMeta = async () => {
        if (favoriteSetMetaCache?.editUrl) {
            return favoriteSetMetaCache;
        }

        const viewUrl = await resolveFavoriteSetUrl();
        if (!viewUrl) {
            return null;
        }

        const view = new URL(viewUrl, window.location.origin);
        const setId = view.searchParams.get('set');
        if (!setId) {
            return null;
        }

        const directEditLink = document.querySelector(`a[href*="/sets/${setId}/edit"]`)?.getAttribute('href') || '';
        const profilePath = extractCurrentUserProfilePath();
        const editUrl = directEditLink
            ? new URL(directEditLink, window.location.origin).toString()
            : (profilePath ? new URL(`${profilePath}/sets/${setId}/edit`, window.location.origin).toString() : null);

        if (!editUrl) {
            return null;
        }

        favoriteSetMetaCache = {
            setId: String(setId),
            viewUrl: view.toString(),
            editUrl
        };

        return favoriteSetMetaCache;
    };
    const fetchFavoriteDocument = async (url, options = {}) => {
        const response = await fetch(url, {
            credentials: 'include',
            cache: 'no-store',
            headers: {
                ...buildFavoriteHtmlHeaders(),
                ...(options.headers || {})
            },
            ...options
        });

        if (!response.ok) {
            throw new Error(`Favorite request failed (${response.status})`);
        }

        const html = await response.text();
        return {
            response,
            doc: new DOMParser().parseFromString(html, 'text/html')
        };
    };
    const formDataToUrlEncodedBody = (formData) => {
        const params = new URLSearchParams();
        for (const [key, value] of formData.entries()) {
            params.append(key, typeof value === 'string' ? value : String(value));
        }
        return params.toString();
    };
    const setFirstMatchingFormValue = (formData, candidateNames, value) => {
        const fieldName = candidateNames.find((name) => formData.has(name)) || candidateNames[0];
        formData.set(fieldName, value);
        return fieldName;
    };
    const extractFavoriteSetMetaFromDocument = (doc, fallbackUrl = '') => {
        const form = doc.querySelector(FAVORITE_FORM_SELECTOR);
        const actionUrl = form?.getAttribute('action')
            ? new URL(form.getAttribute('action'), fallbackUrl || window.location.href).toString()
            : String(fallbackUrl || '');
        const editLink = doc.querySelector('a[href*="/sets/"][href*="/edit"]')?.getAttribute('href') || '';
        const candidateUrl = actionUrl || (editLink ? new URL(editLink, fallbackUrl || window.location.href).toString() : '');
        const setId = candidateUrl.match(/\/sets\/(\d+)/)?.[1]
            || editLink.match(/\/sets\/(\d+)/)?.[1]
            || '';

        if (!setId) {
            return null;
        }

        const locale = getCurrentLocale();
        const viewUrl = new URL(`/${locale}/scripts?set=${setId}`, window.location.origin).toString();
        const editUrl = candidateUrl.includes('/edit')
            ? candidateUrl
            : new URL(`${extractCurrentUserProfilePath() || `/${locale}/users`}/sets/${setId}/edit`, window.location.origin).toString();

        return {
            setId: String(setId),
            viewUrl,
            editUrl
        };
    };
    const extractFavoriteIdsFromForm = (form) => {
        const ids = new Set();
        if (!form) {
            return ids;
        }

        form.querySelectorAll([
            'input[name="scripts-included[]"]',
            'input[name*="scripts-included"]',
            'input[name="remove-scripts-included[]"]',
            'input[name*="remove-scripts-included"]',
            'select[name="scripts-included[]"] option',
            'select[name*="scripts-included"] option',
            'select[name="remove-scripts-included[]"] option',
            'select[name*="remove-scripts-included"] option'
        ].join(', ')).forEach((element) => {
            const rawValue = ('value' in element ? element.value : element.getAttribute('value')) || '';
            const id = String(rawValue).trim().match(/^(\d+)$/)?.[1] || '';
            if (id) {
                ids.add(id);
            }
        });

        return ids;
    };
    const createFavoriteSaveFormData = (doc, form, favoriteIds) => {
        const formData = new FormData(form);
        const csrfToken = doc.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
        if (csrfToken) {
            formData.set('authenticity_token', csrfToken);
        }

        Array.from(formData.keys()).forEach((key) => {
            if (
                key === 'save'
                || key === 'add-script'
                || key === 'script-action'
                || key === 'remove-selected-scripts'
                || key.includes('scripts-included')
                || key.includes('remove-scripts-included')
            ) {
                formData.delete(key);
            }
        });

        Array.from(favoriteIds)
            .map((id) => String(id).trim())
            .filter(Boolean)
            .sort((left, right) => Number(left) - Number(right))
            .forEach((id) => {
                formData.append('scripts-included[]', id);
            });

        if (formData.has('script_set[favorite]')) {
            formData.set('script_set[favorite]', '1');
        }
        if (formData.has('favorite')) {
            formData.set('favorite', '1');
        }
        formData.set('save', '1');

        return formData;
    };
    const createFavoriteSet = async () => {
        const profilePath = extractCurrentUserProfilePath();
        if (!profilePath) {
            throw new Error('Authentication required.');
        }

        const locale = getCurrentLocale();
        const newSetUrl = new URL(`${profilePath}/sets/new?fav=1`, window.location.origin).toString();
        const { response: newSetResponse, doc: newSetDoc } = await fetchFavoriteDocument(newSetUrl);
        if (newSetResponse.url.includes('/users/sign_in')) {
            throw new Error('Authentication required.');
        }

        const form = newSetDoc.querySelector(FAVORITE_FORM_SELECTOR);
        if (!form) {
            throw new Error('Favorite creation form not found.');
        }

        const formData = new FormData(form);
        const csrfToken = newSetDoc.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
        if (csrfToken) {
            formData.set('authenticity_token', csrfToken);
        }

        setFirstMatchingFormValue(formData, ['script_set[name]', 'name'], getUserNavI18n(locale).favoriteSetName || 'Favorites');
        setFirstMatchingFormValue(formData, ['script_set[favorite]', 'favorite'], '1');
        formData.set('save', '1');

        const actionUrl = form.getAttribute('action')
            ? new URL(form.getAttribute('action'), newSetResponse.url).toString()
            : newSetResponse.url;
        const { response: createResponse, doc: createDoc } = await fetchFavoriteDocument(actionUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
            },
            body: formDataToUrlEncodedBody(formData)
        });

        if (createResponse.url.includes('/users/sign_in')) {
            throw new Error('Authentication required.');
        }

        const favoriteSetMeta = extractFavoriteSetMetaFromDocument(createDoc, createResponse.url);
        if (!favoriteSetMeta?.editUrl) {
            throw new Error('Favorite set creation failed.');
        }

        favoriteSetMissingConfirmed = false;
        favoriteSetMetaCache = favoriteSetMeta;
        return favoriteSetMeta;
    };
    const saveFavoritesToRemote = async (favoriteIds) => {
        let favoriteSetMeta = await getFavoriteSetMeta();
        if (!favoriteSetMeta?.editUrl) {
            favoriteSetMeta = await createFavoriteSet();
        }

        const { response: editResponse, doc: editDoc } = await fetchFavoriteDocument(favoriteSetMeta.editUrl);
        if (editResponse.url.includes('/users/sign_in')) {
            throw new Error('Authentication required.');
        }

        const form = editDoc.querySelector(FAVORITE_FORM_SELECTOR);
        if (!form) {
            throw new Error('Favorite edit form not found.');
        }

        const actionUrl = form.getAttribute('action')
            ? new URL(form.getAttribute('action'), editResponse.url).toString()
            : editResponse.url;
        const formData = createFavoriteSaveFormData(editDoc, form, favoriteIds);
        const { response: saveResponse, doc: saveDoc } = await fetchFavoriteDocument(actionUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
            },
            body: formDataToUrlEncodedBody(formData)
        });

        if (saveResponse.url.includes('/users/sign_in')) {
            throw new Error('Authentication required.');
        }

        const savedMeta = extractFavoriteSetMetaFromDocument(saveDoc, saveResponse.url);
        if (savedMeta?.editUrl) {
            favoriteSetMissingConfirmed = false;
            favoriteSetMetaCache = savedMeta;
        }

        const verificationUrl = favoriteSetMetaCache?.editUrl || favoriteSetMeta.editUrl;
        const verification = await fetchFavoriteDocument(verificationUrl);
        if (verification.response.url.includes('/users/sign_in')) {
            throw new Error('Authentication required.');
        }

        const verifiedForm = verification.doc.querySelector(FAVORITE_FORM_SELECTOR);
        if (!verifiedForm) {
            throw new Error('Favorite save could not be verified.');
        }

        const verifiedMeta = extractFavoriteSetMetaFromDocument(verification.doc, verification.response.url);
        if (verifiedMeta?.editUrl) {
            favoriteSetMissingConfirmed = false;
            favoriteSetMetaCache = verifiedMeta;
        }

        return extractFavoriteIdsFromForm(verifiedForm);
    };
    const enqueueFavoriteMutation = (task) => {
        const queuedTask = favoriteMutationQueue.catch(() => undefined).then(task);
        favoriteMutationQueue = queuedTask.catch(() => undefined);
        return queuedTask;
    };
    const setFavoriteButtonsBusy = (scriptId, isBusy) => {
        document.querySelectorAll(`.gf-script-star-button[data-script-id="${scriptId}"]`).forEach((starButton) => {
            starButton.disabled = isBusy;
            starButton.setAttribute('aria-busy', String(isBusy));
        });
    };
    const setStarButtonState = (starButton, isActive, locale) => {
        starButton.setAttribute('data-active', String(isActive));
        starButton.setAttribute('aria-pressed', String(isActive));
        starButton.classList.toggle('active', isActive);
        const i18n = getUserNavI18n(locale);
        starButton.setAttribute('aria-label', isActive ? i18n.removeFromFavorites : i18n.addToFavorites);
    };
    const setFavoriteStateForScript = (scriptId, isActive, locale) => {
        document.querySelectorAll(`.gf-script-star-button[data-script-id="${scriptId}"]`).forEach((starButton) => {
            setStarButtonState(starButton, isActive, locale);
        });
    };
    const syncFavoriteStarsWithSet = async ({ force = false } = {}) => {
        const syncToken = ++favoriteSyncToken;
        const locale = getCurrentLocale();
        const applyFavoriteIds = (favoriteIds) => {
            const visibleScriptIds = new Set();

            document.querySelectorAll('li[data-script-id]').forEach((scriptElement) => {
                const scriptId = String(scriptElement.getAttribute('data-script-id') || '').trim();
                if (scriptId) {
                    visibleScriptIds.add(scriptId);
                }
            });

            document.querySelectorAll('.gf-script-star-button[data-script-id]').forEach((starButton) => {
                const scriptId = String(starButton.getAttribute('data-script-id') || '').trim();
                if (scriptId) {
                    visibleScriptIds.add(scriptId);
                }
            });

            const currentPageScriptId = getCurrentPageScriptId();
            if (Number.isFinite(currentPageScriptId)) {
                visibleScriptIds.add(String(currentPageScriptId));
            }

            visibleScriptIds.forEach((scriptId) => {
                setFavoriteStateForScript(scriptId, favoriteIds.has(scriptId), locale);
            });
        };

        const storedFavoriteIds = readStoredFavoriteIds();
        if (storedFavoriteIds.size) {
            if (syncToken !== favoriteSyncToken) {
                return;
            }
            applyFavoriteIds(storedFavoriteIds);
        }

        const favoriteIds = await getAllFavoritesIds({ force });
        if (syncToken !== favoriteSyncToken) {
            return;
        }

        pendingFavoriteOverrides.forEach((isActive, scriptId) => {
            if (isActive) {
                favoriteIds.add(scriptId);
            } else {
                favoriteIds.delete(scriptId);
            }
        });

        applyFavoriteIds(favoriteIds);
    };
    const createScriptInstallButton = (codeUrl, locale) => {
        const installLabel = getUserNavI18n(locale).install || 'Install';
        const installButton = document.createElement('a');
        installButton.className = 'gf-script-install-button';
        installButton.href = codeUrl;
        installButton.textContent = installLabel;
        installButton.setAttribute('aria-label', installLabel);

        const icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
        icon.setAttribute('viewBox', '0 0 24 24');
        icon.setAttribute('aria-hidden', 'true');
        icon.innerHTML = `
            <path d="M12 3v11"></path>
            <path d="m7 11 5 5 5-5"></path>
            <path d="M5 20h14"></path>
        `;
        installButton.prepend(icon);

        return installButton;
    };
    const isSafeScriptExtraUrl = (value, baseUrl, attrName) => {
        const rawValue = String(value || '').trim();
        if (!rawValue || rawValue.startsWith('#') || rawValue.startsWith('data:')) {
            return attrName !== 'href' || !rawValue.startsWith('data:');
        }

        try {
            const url = new URL(rawValue, baseUrl);
            return /^(https?:|mailto:)$/.test(url.protocol);
        } catch {
            return false;
        }
    };
    const sanitizeScriptExtraElement = (sourceElement, baseUrl) => {
        if (!sourceElement) {
            return '';
        }

        const clone = sourceElement.cloneNode(true);
        clone.querySelectorAll('script,style,iframe,object,embed,form,input,button,textarea,select,link,meta').forEach((element) => {
            element.remove();
        });

        clone.querySelectorAll('*').forEach((element) => {
            Array.from(element.attributes).forEach((attribute) => {
                const attrName = attribute.name.toLowerCase();
                const attrValue = attribute.value || '';

                if (attrName.startsWith('on') || attrName === 'id') {
                    element.removeAttribute(attribute.name);
                    return;
                }

                if (['href', 'src', 'poster'].includes(attrName)) {
                    if (!isSafeScriptExtraUrl(attrValue, baseUrl, attrName)) {
                        element.removeAttribute(attribute.name);
                    }
                }
            });

        });

        return clone.innerHTML.trim();
    };
    const fetchScriptExtraInfo = (scriptUrl) => {
        if (SCRIPT_EXTRA_INFO_CACHE.has(scriptUrl)) {
            return SCRIPT_EXTRA_INFO_CACHE.get(scriptUrl);
        }

        const extraInfoPromise = (async () => {
            const response = await fetch(scriptUrl, {
                credentials: 'include',
                cache: 'force-cache',
                headers: buildFavoriteHtmlHeaders()
            });
            if (!response.ok) {
                throw new Error(`Script details request failed (${response.status})`);
            }

            const doc = new DOMParser().parseFromString(await response.text(), 'text/html');
            const additionalInfo = doc.querySelector('#additional-info');
            return {
                className: additionalInfo?.className || 'user-content',
                lang: additionalInfo?.getAttribute('lang') || '',
                html: sanitizeScriptExtraElement(additionalInfo, response.url)
            };
        })().catch((error) => {
            SCRIPT_EXTRA_INFO_CACHE.delete(scriptUrl);
            throw error;
        });

        SCRIPT_EXTRA_INFO_CACHE.set(scriptUrl, extraInfoPromise);
        return extraInfoPromise;
    };
    const renderScriptExtraInfoPanel = (panel, extraInfo, locale) => {
        const i18n = getUserNavI18n(locale);
        panel.textContent = '';

        if (extraInfo.html) {
            const content = document.createElement('div');
            content.className = extraInfo.className || 'user-content';
            if (extraInfo.lang) {
                content.setAttribute('lang', extraInfo.lang);
            }
            content.innerHTML = extraInfo.html;
            panel.appendChild(content);
        } else {
            const empty = document.createElement('div');
            empty.className = 'gf-script-extra-status';
            empty.textContent = i18n.noDetailedInfo;
            panel.appendChild(empty);
        }
    };
    const loadScriptExtraInfoPanel = async (panel) => {
        const scriptUrl = panel.getAttribute('data-script-url') || '';
        if (!scriptUrl || panel.getAttribute(SCRIPT_EXTRA_INFO_ATTR) === 'loaded' || panel.getAttribute(SCRIPT_EXTRA_INFO_ATTR) === 'loading') {
            return;
        }

        const locale = getCurrentLocale();
        const i18n = getUserNavI18n(locale);
        panel.setAttribute(SCRIPT_EXTRA_INFO_ATTR, 'loading');
        panel.textContent = '';

        const status = document.createElement('div');
        status.className = 'gf-script-extra-status';
        status.textContent = i18n.loadingDetails;
        panel.appendChild(status);

        try {
            const extraInfo = await fetchScriptExtraInfo(scriptUrl);
            renderScriptExtraInfoPanel(panel, extraInfo, locale);
            panel.setAttribute(SCRIPT_EXTRA_INFO_ATTR, 'loaded');
        } catch (error) {
            console.warn('GreasyFork Premium: script details failed.', error);
            panel.setAttribute(SCRIPT_EXTRA_INFO_ATTR, 'error');
            status.textContent = i18n.detailsLoadFailed;
        }
    };
    const extractGreasyForkCodeUrl = (value) => {
        const match = String(value || '').match(/https:\/\/update\.greasyfork\.org\/scripts\/\d+\/[^\s"'<>]+/);
        return match ? match[0] : null;
    };
    const getCurrentPageScriptId = () => {
        const pathnameMatch = window.location.pathname.match(/\/scripts\/(\d+)(?:-|$)/);
        const pathnameScriptId = Number.parseInt(pathnameMatch?.[1] || '', 10);
        if (Number.isFinite(pathnameScriptId)) {
            return pathnameScriptId;
        }

        const installLink = document.querySelector('a.install-link[href*="/scripts/"], a[href*="/scripts/"][data-install-format]');
        const linkMatch = installLink?.href.match(/\/scripts\/(\d+)(?:-|$)/);
        const linkScriptId = Number.parseInt(linkMatch?.[1] || '', 10);
        return Number.isFinite(linkScriptId) ? linkScriptId : null;
    };
    const getCurrentPageCodeUrl = () => {
        const installLink = document.querySelector('a.install-link[href], a[href][data-install-format]');
        if (installLink?.href) {
            return installLink.href;
        }

        const currentPageScriptId = getCurrentPageScriptId();
        const currentListItemCodeUrl = currentPageScriptId
            ? document.querySelector(`li[data-script-id="${currentPageScriptId}"][data-code-url]`)?.getAttribute('data-code-url')
            : '';
        if (currentListItemCodeUrl) {
            return currentListItemCodeUrl;
        }

        const candidateValues = Array.from(document.querySelectorAll('#script-content code, #script-info code, #script-content a[href], #script-info a[href]'))
            .flatMap((node) => [node.textContent || '', node.getAttribute?.('href') || '']);
        for (const candidateValue of candidateValues) {
            const codeUrl = extractGreasyForkCodeUrl(candidateValue);
            if (codeUrl) {
                return codeUrl;
            }
        }

        return extractGreasyForkCodeUrl(document.querySelector('#script-content')?.textContent || '');
    };
    const isInstallableScriptCodeUrl = (codeUrl) => /\.user\.(?:js|css)(?:[?#]|$)/i.test(String(codeUrl || ''));
    const isScriptLibraryListItem = (listItem) => {
        const codeUrl = listItem?.getAttribute('data-code-url') || '';
        const scriptType = String(listItem?.getAttribute('data-script-type') || '').trim().toLowerCase();
        return scriptType === 'library' || (Boolean(codeUrl) && !isInstallableScriptCodeUrl(codeUrl));
    };
    const getCurrentPageScriptInfoUrl = () => {
        const pathnameMatch = window.location.pathname.match(/^(\/[a-z]{2,3}(?:-(?:[A-Z]{2}|[0-9]{3}))?\/scripts\/\d+(?:-[^/?#]+)?)/);
        if (!pathnameMatch) {
            return '';
        }

        return new URL(pathnameMatch[1], window.location.origin).toString();
    };
    const isCurrentScriptInfoOrCodePage = () => /^\/[a-z]{2,3}(?:-(?:[A-Z]{2}|[0-9]{3}))?\/scripts\/\d+(?:-[^/?#\/]+)?(?:\/code)?\/?$/.test(window.location.pathname);
    const isLibraryInfoDocument = (doc) => {
        const nativeInstallLink = doc.querySelector('a.install-link[href][data-install-format]');
        if (nativeInstallLink) {
            return !isInstallableScriptCodeUrl(nativeInstallLink.href);
        }

        const scriptContentText = doc.querySelector('#script-content')?.textContent || '';
        if (SCRIPT_LIBRARY_INFO_PATTERN.test(scriptContentText)) {
            return true;
        }

        const codeUrl = extractGreasyForkCodeUrl(scriptContentText);
        return Boolean(codeUrl) && !isInstallableScriptCodeUrl(codeUrl);
    };
    const getCurrentPageScriptTitleText = () => [
        document.querySelector('meta[property="og:title"]')?.getAttribute('content') || '',
        document.querySelector('#script-info header h2, #script-info > h2')?.textContent || '',
        document.title || '',
        decodeURIComponent(window.location.pathname)
    ].join(' ');
    const isCurrentPageLibraryDetail = () => {
        if (!window.location.pathname.includes('/scripts/')) {
            return false;
        }

        if (document.documentElement.getAttribute('data-gfplus-library-detail') === 'true') {
            return true;
        }

        if (isLibraryInfoDocument(document)) {
            return true;
        }

        const nativeInstallLink = document.querySelector('a.install-link[href][data-install-format]');
        if (nativeInstallLink) {
            return !isInstallableScriptCodeUrl(nativeInstallLink.href);
        }

        const codeUrl = getCurrentPageCodeUrl();
        if (codeUrl) {
            return !isInstallableScriptCodeUrl(codeUrl);
        }

        return SCRIPT_LIBRARY_NAME_PATTERN.test(getCurrentPageScriptTitleText());
    };
    const removeDetailActionsIfConfirmedLibrary = async () => {
        if (!window.location.pathname.includes('/scripts/')) {
            return;
        }

        if (!currentPageLibraryDetailPromise) {
            currentPageLibraryDetailPromise = (async () => {
                const infoUrl = getCurrentPageScriptInfoUrl();
                if (!infoUrl) {
                    return false;
                }

                const response = await fetch(infoUrl, {
                    credentials: 'include',
                    cache: 'force-cache',
                    headers: buildFavoriteHtmlHeaders()
                });
                if (!response.ok) {
                    return false;
                }

                const doc = new DOMParser().parseFromString(await response.text(), 'text/html');
                return isLibraryInfoDocument(doc);
            })().catch(() => false);
        }

        if (await currentPageLibraryDetailPromise) {
            document.documentElement.setAttribute('data-gfplus-library-detail', 'true');
            document.getElementById(SCRIPT_DETAIL_ACTIONS_CONTAINER_ID)?.remove();
        }
    };
    const getScriptDetailActionsContainer = () => {
        const installArea = document.getElementById('install-area');
        if (installArea) {
            return installArea;
        }

        const existingContainer = document.getElementById(SCRIPT_DETAIL_ACTIONS_CONTAINER_ID);
        if (existingContainer) {
            return existingContainer;
        }

        const container = document.createElement('div');
        container.id = SCRIPT_DETAIL_ACTIONS_CONTAINER_ID;
        container.className = 'gf-script-card-actions gf-script-detail-actions';

        const tabs = document.getElementById('script-links');
        if (tabs) {
            tabs.insertAdjacentElement('afterend', container);
            return container;
        }

        const header = document.querySelector('#script-info header');
        if (header) {
            header.insertAdjacentElement('afterend', container);
            return container;
        }

        const content = document.getElementById('script-content');
        if (content) {
            content.insertAdjacentElement('afterbegin', container);
            return container;
        }

        return null;
    };
    const createScriptStarButton = (locale, scriptId) => {
        const starButton = document.createElement('button');
        starButton.className = 'gf-script-star-button';
        starButton.type = 'button';
        starButton.setAttribute('data-script-id', String(scriptId));
        setStarButtonState(starButton, false, locale);
        starButton.innerHTML = `
            <svg viewBox="0 0 24 24" aria-hidden="true">
                <path d="m12 3.6 2.55 5.17 5.7.83-4.12 4.01.97 5.67L12 16.6l-5.1 2.68.97-5.67L3.75 9.6l5.7-.83L12 3.6Z"></path>
            </svg>
        `;

        starButton.addEventListener('click', (event) => {
            event.preventDefault();
            event.stopPropagation();

            const currentProfilePath = extractCurrentUserProfilePath();
            if (!currentProfilePath) {
                const signInUrl = new URL(`/${locale}/users/sign_in`, window.location.origin);
                signInUrl.searchParams.set('return_to', window.location.href);
                window.location.assign(signInUrl.toString());
                return;
            }

            const scriptIdString = String(scriptId);
            if (favoriteBusyScriptIds.has(scriptIdString)) {
                return;
            }

            favoriteBusyScriptIds.add(scriptIdString);
            setFavoriteButtonsBusy(scriptIdString, true);

            let previousFavoriteIds = null;
            let desiredFavoriteState = null;

            enqueueFavoriteMutation(async () => {
                previousFavoriteIds = await getAllFavoritesIds({ force: true });
                const isActive = previousFavoriteIds.has(scriptIdString);
                desiredFavoriteState = !isActive;
                const nextFavoriteIds = new Set(previousFavoriteIds);

                if (isActive) {
                    nextFavoriteIds.delete(scriptIdString);
                } else {
                    nextFavoriteIds.add(scriptIdString);
                }

                favoriteSyncToken += 1;
                pendingFavoriteOverrides.set(scriptIdString, desiredFavoriteState);
                setFavoriteStateForScript(scriptIdString, desiredFavoriteState, locale);

                const savedFavoriteIds = await saveFavoritesToRemote(nextFavoriteIds);
                if (savedFavoriteIds.has(scriptIdString) !== desiredFavoriteState) {
                    throw new Error('Favorite save verification mismatch.');
                }

                favoriteIdsCache = new Set(savedFavoriteIds);
                writeStoredFavoriteIds(savedFavoriteIds);
                pendingFavoriteOverrides.delete(scriptIdString);
                void syncFavoriteStarsWithSet({ force: true }).catch((syncError) => {
                    console.warn('GreasyFork Premium: favorite sync after save failed.', syncError);
                });
            }).catch((error) => {
                console.warn('GreasyFork Premium: favorite update failed; reverted local state.', error);
                favoriteSyncToken += 1;
                const restoredFavoriteIds = previousFavoriteIds instanceof Set
                    ? new Set(previousFavoriteIds)
                    : (favoriteIdsCache instanceof Set ? new Set(favoriteIdsCache) : readStoredFavoriteIds());
                favoriteIdsCache = new Set(restoredFavoriteIds);
                writeStoredFavoriteIds(restoredFavoriteIds);
                setFavoriteStateForScript(scriptIdString, restoredFavoriteIds.has(scriptIdString), locale);
            }).finally(() => {
                pendingFavoriteOverrides.delete(scriptIdString);
                favoriteBusyScriptIds.delete(scriptIdString);
                setFavoriteButtonsBusy(scriptIdString, false);
                starButton.blur();
            });
        });

        return starButton;
    };
    const updateScriptNoteUi = (panel, noteButton, locale) => {
        const i18n = getUserNavI18n(locale);
        const textarea = panel.querySelector('.gf-script-note-textarea');
        const preview = panel.querySelector('.gf-script-note-preview');
        const status = panel.querySelector('.gf-script-note-status');
        const note = String(textarea?.value || '').trim();
        const hasNote = Boolean(note);

        panel.setAttribute('data-has-note', String(hasNote));
        noteButton.setAttribute('data-has-note', String(hasNote));
        noteButton.setAttribute('aria-label', hasNote ? i18n.editPersonalNote : i18n.addPersonalNote);

        if (preview) {
            preview.textContent = note;
        }
        if (status) {
            status.textContent = hasNote ? i18n.personalNoteSaved : '';
        }
    };
    const createScriptNotePanel = (locale, scriptId) => {
        const i18n = getUserNavI18n(locale);
        const panel = document.createElement('div');
        panel.className = 'gf-script-note-panel';
        panel.setAttribute('data-open', 'false');
        panel.setAttribute('data-script-id', String(scriptId));

        const preview = document.createElement('div');
        preview.className = 'gf-script-note-preview';

        const editor = document.createElement('div');
        editor.className = 'gf-script-note-editor';

        const textarea = document.createElement('textarea');
        textarea.className = 'gf-script-note-textarea';
        textarea.value = readPersonalNote(scriptId);
        textarea.placeholder = i18n.personalNotePlaceholder;
        textarea.setAttribute('aria-label', i18n.personalNoteLabel);

        const footer = document.createElement('div');
        footer.className = 'gf-script-note-footer';

        const status = document.createElement('span');
        status.className = 'gf-script-note-status';

        const footerActions = document.createElement('div');
        footerActions.className = 'gf-script-note-footer-actions';

        const deleteButton = document.createElement('button');
        deleteButton.className = 'gf-script-note-delete';
        deleteButton.type = 'button';
        deleteButton.textContent = i18n.deleteNote;

        const doneButton = document.createElement('button');
        doneButton.className = 'gf-script-note-done';
        doneButton.type = 'button';
        doneButton.textContent = i18n.done;

        footerActions.append(deleteButton, doneButton);
        footer.append(status, footerActions);
        editor.append(textarea, footer);
        panel.append(preview, editor);

        let saveTimer = 0;
        const saveNote = () => {
            if (saveTimer) {
                window.clearTimeout(saveTimer);
                saveTimer = 0;
            }
            writePersonalNote(scriptId, textarea.value);
            panel.dispatchEvent(new CustomEvent('gfplus-note-change', {
                bubbles: false,
                detail: { note: textarea.value }
            }));
        };

        textarea.addEventListener('input', () => {
            if (saveTimer) {
                window.clearTimeout(saveTimer);
            }
            saveTimer = window.setTimeout(saveNote, 220);
            panel.dispatchEvent(new CustomEvent('gfplus-note-change', {
                bubbles: false,
                detail: { note: textarea.value }
            }));
        });
        textarea.addEventListener('blur', saveNote);
        doneButton.addEventListener('click', () => {
            saveNote();
            panel.setAttribute('data-open', 'false');
            panel.dispatchEvent(new CustomEvent('gfplus-note-toggle', {
                bubbles: false,
                detail: { open: false }
            }));
        });
        deleteButton.addEventListener('click', () => {
            if (saveTimer) {
                window.clearTimeout(saveTimer);
                saveTimer = 0;
            }
            textarea.value = '';
            writePersonalNote(scriptId, '');
            panel.setAttribute('data-open', 'false');
            panel.dispatchEvent(new CustomEvent('gfplus-note-change', {
                bubbles: false,
                detail: { note: '' }
            }));
            panel.dispatchEvent(new CustomEvent('gfplus-note-toggle', {
                bubbles: false,
                detail: { open: false }
            }));
        });

        return panel;
    };
    const createScriptNoteButton = (locale, scriptId, panel) => {
        const i18n = getUserNavI18n(locale);
        const noteButton = document.createElement('button');
        noteButton.className = 'gf-script-note-button';
        noteButton.type = 'button';
        noteButton.setAttribute('aria-expanded', 'false');
        noteButton.setAttribute('data-expanded', 'false');
        noteButton.innerHTML = `
            <svg viewBox="0 0 24 24" aria-hidden="true">
                <path d="M5 4.5h14v15H5z"></path>
                <path d="M8 8h8"></path>
                <path d="M8 12h5"></path>
                <path d="M16 19.5v-4h3"></path>
            </svg>
        `;

        const sync = () => updateScriptNoteUi(panel, noteButton, locale);
        panel.addEventListener('gfplus-note-change', sync);
        panel.addEventListener('gfplus-note-toggle', (event) => {
            const open = Boolean(event.detail?.open);
            noteButton.setAttribute('aria-expanded', String(open));
            noteButton.setAttribute('data-expanded', String(open));
        });
        sync();

        noteButton.addEventListener('click', (event) => {
            event.preventDefault();
            event.stopPropagation();

            const shouldOpen = panel.getAttribute('data-open') !== 'true';
            panel.setAttribute('data-open', String(shouldOpen));
            noteButton.setAttribute('aria-expanded', String(shouldOpen));
            noteButton.setAttribute('data-expanded', String(shouldOpen));
            sync();

            if (shouldOpen) {
                window.setTimeout(() => panel.querySelector('.gf-script-note-textarea')?.focus(), 0);
            }

            noteButton.blur();
        });

        return noteButton;
    };
    const createScriptExtraInfoPanel = (scriptUrl) => {
        const panel = document.createElement('div');
        panel.className = 'gf-script-extra-info';
        panel.setAttribute(SCRIPT_EXTRA_INFO_ATTR, 'pending');
        panel.setAttribute('data-script-url', scriptUrl);
        panel.setAttribute('data-open', 'false');
        return panel;
    };
    const createScriptDetailButton = (locale, panel) => {
        const i18n = getUserNavI18n(locale);
        const detailButton = document.createElement('button');
        detailButton.className = 'gf-script-detail-button';
        detailButton.type = 'button';
        detailButton.setAttribute('aria-label', i18n.showDetails);
        detailButton.setAttribute('aria-expanded', 'false');
        detailButton.setAttribute('data-expanded', 'false');
        detailButton.innerHTML = `
            <svg viewBox="0 0 24 24" aria-hidden="true">
                <path d="M12 5v14"></path>
                <path d="M5 12h14"></path>
            </svg>
        `;

        detailButton.addEventListener('click', async (event) => {
            event.preventDefault();
            event.stopPropagation();

            const shouldOpen = panel.getAttribute('data-open') !== 'true';
            panel.setAttribute('data-open', String(shouldOpen));
            detailButton.setAttribute('aria-expanded', String(shouldOpen));
            detailButton.setAttribute('data-expanded', String(shouldOpen));
            detailButton.setAttribute('aria-label', shouldOpen ? i18n.hideDetails : i18n.showDetails);

            if (shouldOpen) {
                await loadScriptExtraInfoPanel(panel);
            }

            detailButton.blur();
        });

        return detailButton;
    };
    const applyScriptCardActions = () => {
        const locale = getCurrentLocale();

        document.querySelectorAll('li[data-script-id]:not(.ad-entry)').forEach((listItem) => {
            const isLibraryListItem = isScriptLibraryListItem(listItem);
            if (listItem.getAttribute(SCRIPT_CARD_ACTIONS_ATTR) === 'done') {
                if (isLibraryListItem) {
                    listItem.querySelectorAll('.gf-script-star-button').forEach((starButton) => {
                        starButton.remove();
                    });
                }
                return;
            }

            const article = listItem.querySelector('article');
            const codeUrl = listItem.getAttribute('data-code-url');
            const scriptLink = listItem.querySelector('a.script-link[href*="/scripts/"]');
            const scriptUrl = scriptLink?.href ? new URL(scriptLink.href, window.location.href).toString() : '';
            const scriptId = Number.parseInt(listItem.getAttribute('data-script-id') || '', 10);
            if (!article || !Number.isFinite(scriptId)) {
                return;
            }

            const actions = document.createElement('div');
            actions.className = 'gf-script-card-actions';
            let extraInfoPanel = null;
            const notePanel = createScriptNotePanel(locale, scriptId);
            if (codeUrl) {
                actions.appendChild(createScriptInstallButton(codeUrl, locale));
            }
            actions.appendChild(createScriptNoteButton(locale, scriptId, notePanel));
            if (scriptUrl) {
                extraInfoPanel = createScriptExtraInfoPanel(scriptUrl);
                actions.appendChild(createScriptDetailButton(locale, extraInfoPanel));
            }
            if (!isLibraryListItem) {
                actions.appendChild(createScriptStarButton(locale, scriptId));
            }
            article.appendChild(actions);
            article.appendChild(notePanel);
            if (extraInfoPanel) {
                article.appendChild(extraInfoPanel);
            }
            listItem.setAttribute(SCRIPT_CARD_ACTIONS_ATTR, 'done');
        });

        if (!isCurrentScriptInfoOrCodePage()) {
            document.getElementById(SCRIPT_DETAIL_ACTIONS_CONTAINER_ID)?.remove();
            void syncFavoriteStarsWithSet();
            return;
        }

        if (isCurrentPageLibraryDetail()) {
            document.getElementById(SCRIPT_DETAIL_ACTIONS_CONTAINER_ID)?.remove();
            void syncFavoriteStarsWithSet();
            return;
        }

        void removeDetailActionsIfConfirmedLibrary();

        const detailActionsTarget = getScriptDetailActionsContainer();
        if (detailActionsTarget && detailActionsTarget.getAttribute(SCRIPT_DETAIL_ACTIONS_ATTR) !== 'done') {
            const scriptId = getCurrentPageScriptId();
            const codeUrl = getCurrentPageCodeUrl();
            const hasNativeInstallArea = Boolean(document.getElementById('install-area'));
            if (Number.isFinite(scriptId) && !detailActionsTarget.querySelector(`.gf-script-star-button[data-script-id="${scriptId}"]`)) {
                const notePanel = createScriptNotePanel(locale, scriptId);
                if (!hasNativeInstallArea && codeUrl) {
                    detailActionsTarget.appendChild(createScriptInstallButton(codeUrl, locale));
                }
                detailActionsTarget.appendChild(createScriptNoteButton(locale, scriptId, notePanel));
                detailActionsTarget.appendChild(createScriptStarButton(locale, scriptId));
                detailActionsTarget.insertAdjacentElement('afterend', notePanel);
            }

            detailActionsTarget.setAttribute(SCRIPT_DETAIL_ACTIONS_ATTR, 'done');
        }

        void syncFavoriteStarsWithSet();
    };
    const initScriptCardActions = () => {
        applyScriptCardActions();
        void syncFavoriteStarsWithSet();
        if (scriptCardActionsObserver) {
            return;
        }

        scriptCardActionsObserver = new MutationObserver(applyScriptCardActions);
        scriptCardActionsObserver.observe(document.body, { childList: true, subtree: true });
    };

    // i18n dictionary for user navigation
    // ============================================================================
    // User Navigation And Translations
    // ============================================================================
    const USER_NAV_I18N = {
        'en': {
            install: 'Install',
            themeToggle: 'Toggle theme',
            themeVariants: {
                menu: 'Theme styles',
                normal: 'Classic',
                fullDark: 'Full Dark',
                chalkboard: 'Chalkboard'
            },
            density: { label: 'Density', compact: 'Compact', comfortable: 'Comfortable', detailed: 'Detailed' },
            currentScripts: 'Included scripts',
            emptyScripts: 'No scripts in this list yet.',
            removeScript: 'Remove this script',
            save: 'Save',
            favoriteSetName: 'Favorites',
            addToFavorites: 'Add to favorites',
            removeFromFavorites: 'Remove from favorites',
            addPersonalNote: 'Add personal note',
            editPersonalNote: 'Edit personal note',
            personalNoteLabel: 'Personal note',
            personalNotePlaceholder: 'Write a personal note for this script...',
            personalNoteSaved: 'Saved',
            deleteNote: 'Delete',
            done: 'Done',
            showDetails: 'Show more',
            hideDetails: 'Hide details',
            loadingDetails: 'Loading detailed info...',
            detailsLoadFailed: 'Unable to load detailed info.',
            noDetailedInfo: 'No additional details available.',
            submitScript: 'Post a script',
            submitStyle: 'Post a style',
            submitSet: 'New script set',
            webhookInfo: 'Set up a webhook',
            importScripts: 'Import scripts',
            editProfile: 'Edit profile',
            editSignIn: 'Edit sign-in methods',
            viewNotifications: 'View notifications',
            notificationSettings: 'Edit notification settings',
            deleteAccount: 'Delete account'
        },

        'fr': {
            install: 'Installer',
            themeToggle: 'Changer de thème',
            themeVariants: {
                menu: 'Styles de thème',
                normal: 'Classique',
                fullDark: 'Noir profond',
                chalkboard: 'Chalkboard'
            },
            density: { label: 'Densité', compact: 'Compact', comfortable: 'Confortable', detailed: 'Détaillé' },
            currentScripts: 'Scripts inclus',
            emptyScripts: 'Aucun script dans cette liste pour le moment.',
            removeScript: 'Retirer ce script',
            save: 'Enregistrer',
            favoriteSetName: 'Favoris',
            addToFavorites: 'Ajouter aux favoris',
            removeFromFavorites: 'Retirer des favoris',
            addPersonalNote: 'Ajouter une note personnelle',
            editPersonalNote: 'Modifier la note personnelle',
            personalNoteLabel: 'Note personnelle',
            personalNotePlaceholder: 'Écrire une note personnelle pour ce script...',
            personalNoteSaved: 'Enregistré',
            deleteNote: 'Supprimer',
            done: 'Terminé',
            showDetails: 'Voir plus',
            hideDetails: 'Réduire',
            loadingDetails: 'Chargement des détails...',
            detailsLoadFailed: 'Impossible de charger les détails.',
            noDetailedInfo: 'Aucun détail supplémentaire disponible.',
            submitScript: 'Publier un script',
            submitStyle: 'Publier un style',
            submitSet: 'Nouveau jeu de scripts',
            webhookInfo: 'Mettre en place un Webhook',
            importScripts: 'Importer des scripts',
            editProfile: 'Modifier le profil',
            editSignIn: 'Modifier mes méthodes d\'identification',
            viewNotifications: 'Afficher les notifications',
            notificationSettings: 'Modifier les paramètres de notification',
            deleteAccount: 'Supprimer mon compte'
        },

        'es': {
            install: 'Instalar',
            themeToggle: 'Cambiar tema',
            themeVariants: { menu: 'Estilos de tema', normal: 'Clásico', fullDark: 'Negro profundo', chalkboard: 'Chalkboard' },
            density: { label: 'Densidad', compact: 'Compacta', comfortable: 'Cómoda', detailed: 'Detallada' },
            currentScripts: 'Scripts incluidos',
            emptyScripts: 'No hay scripts en esta lista todavía.',
            removeScript: 'Quitar este script',
            save: 'Guardar',
            favoriteSetName: 'Favoritos',
            addToFavorites: 'Añadir a favoritos',
            removeFromFavorites: 'Quitar de favoritos',
            addPersonalNote: 'Añadir nota personal',
            editPersonalNote: 'Editar nota personal',
            personalNoteLabel: 'Nota personal',
            personalNotePlaceholder: 'Escribe una nota personal para este script...',
            personalNoteSaved: 'Guardado',
            deleteNote: 'Eliminar',
            done: 'Listo',
            showDetails: 'Ver más',
            hideDetails: 'Reducir',
            loadingDetails: 'Cargando detalles...',
            detailsLoadFailed: 'No se pudieron cargar los detalles.',
            noDetailedInfo: 'No hay detalles adicionales disponibles.',
            submitScript: 'Publicar un script',
            submitStyle: 'Publicar un estilo',
            submitSet: 'Nuevo conjunto de scripts',
            webhookInfo: 'Configurar un webhook',
            importScripts: 'Importar scripts',
            editProfile: 'Editar perfil',
            editSignIn: 'Editar métodos de inicio de sesión',
            viewNotifications: 'Ver notificaciones',
            notificationSettings: 'Editar configuración de notificaciones',
            deleteAccount: 'Eliminar cuenta'
        },

        'de': {
            install: 'Installieren',
            themeToggle: 'Design wechseln',
            themeVariants: { menu: 'Themenstile', normal: 'Klassisch', fullDark: 'Tiefschwarz', chalkboard: 'Chalkboard' },
            density: { label: 'Dichte', compact: 'Kompakt', comfortable: 'Komfortabel', detailed: 'Detailliert' },
            currentScripts: 'Enthaltene Skripte',
            emptyScripts: 'Noch keine Skripte in dieser Liste.',
            removeScript: 'Dieses Skript entfernen',
            save: 'Speichern',
            favoriteSetName: 'Favoriten',
            addToFavorites: 'Zu Favoriten hinzufügen',
            removeFromFavorites: 'Aus Favoriten entfernen',
            addPersonalNote: 'Persönliche Notiz hinzufügen',
            editPersonalNote: 'Persönliche Notiz bearbeiten',
            personalNoteLabel: 'Persönliche Notiz',
            personalNotePlaceholder: 'Schreibe eine persönliche Notiz für dieses Skript...',
            personalNoteSaved: 'Gespeichert',
            deleteNote: 'Löschen',
            done: 'Fertig',
            showDetails: 'Mehr anzeigen',
            hideDetails: 'Details ausblenden',
            loadingDetails: 'Details werden geladen...',
            detailsLoadFailed: 'Details konnten nicht geladen werden.',
            noDetailedInfo: 'Keine zusätzlichen Details verfügbar.',
            submitScript: 'Skript veröffentlichen',
            submitStyle: 'Style veröffentlichen',
            submitSet: 'Neues Skript-Set',
            webhookInfo: 'Webhook einrichten',
            importScripts: 'Skripte importieren',
            editProfile: 'Profil bearbeiten',
            editSignIn: 'Anmeldemethoden bearbeiten',
            viewNotifications: 'Benachrichtigungen anzeigen',
            notificationSettings: 'Benachrichtigungseinstellungen bearbeiten',
            deleteAccount: 'Konto löschen'
        },

        'it': {
            install: 'Installare',
            themeToggle: 'Cambia tema',
            themeVariants: { menu: 'Stili del tema', normal: 'Classico', fullDark: 'Nero profondo', chalkboard: 'Chalkboard' },
            density: { label: 'Densità', compact: 'Compatta', comfortable: 'Confortevole', detailed: 'Dettagliata' },
            currentScripts: 'Script inclusi',
            emptyScripts: 'Nessuno script in questa lista per ora.',
            removeScript: 'Rimuovi questo script',
            save: 'Salva',
            favoriteSetName: 'Preferiti',
            addToFavorites: 'Aggiungi ai preferiti',
            removeFromFavorites: 'Rimuovi dai preferiti',
            addPersonalNote: 'Aggiungi nota personale',
            editPersonalNote: 'Modifica nota personale',
            personalNoteLabel: 'Nota personale',
            personalNotePlaceholder: 'Scrivi una nota personale per questo script...',
            personalNoteSaved: 'Salvato',
            deleteNote: 'Elimina',
            done: 'Fine',
            showDetails: 'Mostra di più',
            hideDetails: 'Riduci',
            loadingDetails: 'Caricamento dettagli...',
            detailsLoadFailed: 'Impossibile caricare i dettagli.',
            noDetailedInfo: 'Nessun dettaglio aggiuntivo disponibile.',
            submitScript: 'Pubblica uno script',
            submitStyle: 'Pubblica uno stile',
            submitSet: 'Nuovo set di script',
            webhookInfo: 'Configurare un webhook',
            importScripts: 'Importa script',
            editProfile: 'Modifica profilo',
            editSignIn: 'Modifica metodi di accesso',
            viewNotifications: 'Visualizza notifiche',
            notificationSettings: 'Modifica impostazioni notifiche',
            deleteAccount: 'Elimina account'
        },

        'pt': {
            install: 'Instalar',
            themeToggle: 'Mudar tema',
            themeVariants: { menu: 'Estilos de tema', normal: 'Clássico', fullDark: 'Preto profundo', chalkboard: 'Chalkboard' },
            density: { label: 'Densidade', compact: 'Compacta', comfortable: 'Confortável', detailed: 'Detalhada' },
            currentScripts: 'Scripts incluídos',
            emptyScripts: 'Ainda não há scripts nesta lista.',
            removeScript: 'Remover este script',
            save: 'Salvar',
            favoriteSetName: 'Favoritos',
            addToFavorites: 'Adicionar aos favoritos',
            removeFromFavorites: 'Remover dos favoritos',
            addPersonalNote: 'Adicionar nota pessoal',
            editPersonalNote: 'Editar nota pessoal',
            personalNoteLabel: 'Nota pessoal',
            personalNotePlaceholder: 'Escreva uma nota pessoal para este script...',
            personalNoteSaved: 'Salvo',
            deleteNote: 'Excluir',
            done: 'Concluir',
            showDetails: 'Ver mais',
            hideDetails: 'Reduzir',
            loadingDetails: 'Carregando detalhes...',
            detailsLoadFailed: 'Não foi possível carregar os detalhes.',
            noDetailedInfo: 'Nenhum detalhe adicional disponível.',
            submitScript: 'Publicar script',
            submitStyle: 'Publicar estilo',
            submitSet: 'Novo conjunto de scripts',
            webhookInfo: 'Configurar webhook',
            importScripts: 'Importar scripts',
            editProfile: 'Editar perfil',
            editSignIn: 'Editar métodos de login',
            viewNotifications: 'Ver notificações',
            notificationSettings: 'Editar configurações de notificação',
            deleteAccount: 'Excluir conta'
        },

        'ru': {
            install: 'Установить',
            themeToggle: 'Переключить тему',
            themeVariants: { menu: 'Стили темы', normal: 'Классическая', fullDark: 'Глубокий чёрный', chalkboard: 'Chalkboard' },
            density: { label: 'Плотность', compact: 'Компактный', comfortable: 'Комфортный', detailed: 'Подробный' },
            currentScripts: 'Включённые скрипты',
            emptyScripts: 'В этом списке пока нет скриптов.',
            removeScript: 'Удалить этот скрипт',
            save: 'Сохранить',
            favoriteSetName: 'Избранное',
            addToFavorites: 'Добавить в избранное',
            removeFromFavorites: 'Удалить из избранного',
            addPersonalNote: 'Добавить личную заметку',
            editPersonalNote: 'Редактировать личную заметку',
            personalNoteLabel: 'Личная заметка',
            personalNotePlaceholder: 'Напишите личную заметку для этого скрипта...',
            personalNoteSaved: 'Сохранено',
            deleteNote: 'Удалить',
            done: 'Готово',
            showDetails: 'Показать больше',
            hideDetails: 'Свернуть',
            loadingDetails: 'Загрузка подробностей...',
            detailsLoadFailed: 'Не удалось загрузить подробности.',
            noDetailedInfo: 'Дополнительные сведения недоступны.',
            submitScript: 'Опубликовать скрипт',
            submitStyle: 'Опубликовать стиль',
            submitSet: 'Набор скриптов',
            webhookInfo: 'Настроить вебхук',
            importScripts: 'Импортировать скрипты',
            editProfile: 'Редактировать профиль',
            editSignIn: 'Редактировать способы входа',
            viewNotifications: 'Просмотр уведомлений',
            notificationSettings: 'Настройки уведомлений',
            deleteAccount: 'Удалить аккаунт'
        },

        'ja': {
            install: 'インストール',
            themeToggle: 'テーマを切り替え',
            themeVariants: { menu: 'テーマスタイル', normal: 'クラシック', fullDark: 'ディープブラック', chalkboard: 'Chalkboard' },
            density: { label: '表示密度', compact: 'コンパクト', comfortable: '標準', detailed: '詳細' },
            currentScripts: '含まれるスクリプト',
            emptyScripts: 'このリストにはまだスクリプトがありません。',
            removeScript: 'このスクリプトを削除',
            save: '保存',
            favoriteSetName: 'お気に入り',
            addToFavorites: 'お気に入りに追加',
            removeFromFavorites: 'お気に入りから削除',
            addPersonalNote: '個人メモを追加',
            editPersonalNote: '個人メモを編集',
            personalNoteLabel: '個人メモ',
            personalNotePlaceholder: 'このスクリプトの個人メモを書く...',
            personalNoteSaved: '保存済み',
            deleteNote: '削除',
            done: '完了',
            showDetails: 'もっと見る',
            hideDetails: '詳細を閉じる',
            loadingDetails: '詳細を読み込み中...',
            detailsLoadFailed: '詳細を読み込めませんでした。',
            noDetailedInfo: '追加の詳細はありません。',
            submitScript: 'スクリプトを投稿',
            submitStyle: 'スタイルを投稿',
            submitSet: '新しいスクリプトセット',
            webhookInfo: 'Webhookを設定',
            importScripts: 'スクリプトをインポート',
            editProfile: 'プロフィールを編集',
            editSignIn: 'ログイン方法を編集',
            viewNotifications: '通知を表示',
            notificationSettings: '通知設定を編集',
            deleteAccount: 'アカウントを削除'
        },

        'zh-CN': {
            install: '安装',
            themeToggle: '切换主题',
            themeVariants: { menu: '主题样式', normal: '经典', fullDark: '深黑', chalkboard: 'Chalkboard' },
            density: { label: '密度', compact: '紧凑', comfortable: '舒适', detailed: '详细' },
            currentScripts: '已包含的脚本',
            emptyScripts: '此列表中还没有脚本。',
            removeScript: '移除此脚本',
            save: '保存',
            favoriteSetName: '收藏',
            addToFavorites: '添加到收藏',
            removeFromFavorites: '从收藏中移除',
            addPersonalNote: '添加个人备注',
            editPersonalNote: '编辑个人备注',
            personalNoteLabel: '个人备注',
            personalNotePlaceholder: '为此脚本写一条个人备注...',
            personalNoteSaved: '已保存',
            deleteNote: '删除',
            done: '完成',
            showDetails: '查看更多',
            hideDetails: '收起详情',
            loadingDetails: '正在加载详细信息...',
            detailsLoadFailed: '无法加载详细信息。',
            noDetailedInfo: '没有可用的附加详细信息。',
            submitScript: '发布脚本',
            submitStyle: '发布样式',
            submitSet: '新的脚本集',
            webhookInfo: '设置 Webhook',
            importScripts: '导入脚本',
            editProfile: '编辑个人资料',
            editSignIn: '编辑登录方式',
            viewNotifications: '查看通知',
            notificationSettings: '编辑通知设置',
            deleteAccount: '删除账户'
        },

        'zh-TW': {
            install: '安裝',
            themeToggle: '切換主題',
            themeVariants: { menu: '主題樣式', normal: '經典', fullDark: '深黑', chalkboard: 'Chalkboard' },
            density: { label: '密度', compact: '緊湊', comfortable: '舒適', detailed: '詳細' },
            currentScripts: '已包含的腳本',
            emptyScripts: '此清單中還沒有腳本。',
            removeScript: '移除此腳本',
            save: '儲存',
            favoriteSetName: '收藏',
            addToFavorites: '加入收藏',
            removeFromFavorites: '從收藏移除',
            addPersonalNote: '新增個人備註',
            editPersonalNote: '編輯個人備註',
            personalNoteLabel: '個人備註',
            personalNotePlaceholder: '為此腳本寫一則個人備註...',
            personalNoteSaved: '已儲存',
            deleteNote: '刪除',
            done: '完成',
            showDetails: '查看更多',
            hideDetails: '收合詳情',
            loadingDetails: '正在載入詳細資訊...',
            detailsLoadFailed: '無法載入詳細資訊。',
            noDetailedInfo: '沒有可用的附加詳細資訊。',
            submitScript: '發佈腳本',
            submitStyle: '發佈樣式',
            submitSet: '新的腳本集',
            webhookInfo: '設定 Webhook',
            importScripts: '匯入腳本',
            editProfile: '編輯個人資料',
            editSignIn: '編輯登入方式',
            viewNotifications: '查看通知',
            notificationSettings: '編輯通知設定',
            deleteAccount: '刪除帳戶'
        },

        'ar': {
            install: 'تثبيت',
            themeToggle: 'تبديل المظهر',
            themeVariants: { menu: 'أنماط السمة', normal: 'كلاسيكي', fullDark: 'أسود عميق', chalkboard: 'Chalkboard' },
            density: { label: 'الكثافة', compact: 'مضغوط', comfortable: 'مريح', detailed: 'مفصل' },
            currentScripts: 'السكربتات المضمنة',
            emptyScripts: 'لا توجد سكربتات في هذه القائمة بعد.',
            removeScript: 'إزالة هذا السكربت',
            save: 'حفظ',
            favoriteSetName: 'المفضلة',
            addToFavorites: 'إضافة إلى المفضلة',
            removeFromFavorites: 'إزالة من المفضلة',
            addPersonalNote: 'إضافة ملاحظة شخصية',
            editPersonalNote: 'تعديل الملاحظة الشخصية',
            personalNoteLabel: 'ملاحظة شخصية',
            personalNotePlaceholder: 'اكتب ملاحظة شخصية لهذا السكربت...',
            personalNoteSaved: 'تم الحفظ',
            deleteNote: 'حذف',
            done: 'تم',
            showDetails: 'عرض المزيد',
            hideDetails: 'طي التفاصيل',
            loadingDetails: 'جارٍ تحميل التفاصيل...',
            detailsLoadFailed: 'تعذر تحميل التفاصيل.',
            noDetailedInfo: 'لا توجد تفاصيل إضافية متاحة.',
            submitScript: 'نشر سكربت',
            submitStyle: 'نشر نمط',
            submitSet: 'مجموعة سكربتات جديدة',
            webhookInfo: 'إعداد Webhook',
            importScripts: 'استيراد سكربتات',
            editProfile: 'تعديل الحساب',
            editSignIn: 'تعديل طرق تسجيل الدخول',
            viewNotifications: 'عرض الإشعارات',
            notificationSettings: 'تعديل إعدادات الإشعارات',
            deleteAccount: 'حذف الحساب'
        },

        'hi': {
            install: 'इंस्टॉल करें',
            themeToggle: 'थीम बदलें',
            themeVariants: { menu: 'थीम शैलियाँ', normal: 'क्लासिक', fullDark: 'गहरा काला', chalkboard: 'Chalkboard' },
            density: { label: 'घनत्व', compact: 'संक्षिप्त', comfortable: 'आरामदायक', detailed: 'विस्तृत' },
            currentScripts: 'शामिल स्क्रिप्ट',
            emptyScripts: 'इस सूची में अभी कोई स्क्रिप्ट नहीं है.',
            removeScript: 'इस स्क्रिप्ट को हटाएँ',
            save: 'सहेजें',
            favoriteSetName: 'पसंदीदा',
            addToFavorites: 'पसंदीदा में जोड़ें',
            removeFromFavorites: 'पसंदीदा से हटाएँ',
            addPersonalNote: 'व्यक्तिगत नोट जोड़ें',
            editPersonalNote: 'व्यक्तिगत नोट संपादित करें',
            personalNoteLabel: 'व्यक्तिगत नोट',
            personalNotePlaceholder: 'इस स्क्रिप्ट के लिए व्यक्तिगत नोट लिखें...',
            personalNoteSaved: 'सहेजा गया',
            deleteNote: 'हटाएँ',
            done: 'पूर्ण',
            showDetails: 'और देखें',
            hideDetails: 'विवरण समेटें',
            loadingDetails: 'विवरण लोड हो रहे हैं...',
            detailsLoadFailed: 'विवरण लोड नहीं हो सके.',
            noDetailedInfo: 'कोई अतिरिक्त विवरण उपलब्ध नहीं है.',
            submitScript: 'स्क्रिप्ट प्रकाशित करें',
            submitStyle: 'स्टाइल प्रकाशित करें',
            submitSet: 'नया स्क्रिप्ट सेट',
            webhookInfo: 'Webhook सेट करें',
            importScripts: 'स्क्रिप्ट आयात करें',
            editProfile: 'प्रोफ़ाइल संपादित करें',
            editSignIn: 'लॉगिन विधियाँ संपादित करें',
            viewNotifications: 'सूचनाएँ देखें',
            notificationSettings: 'सूचना सेटिंग संपादित करें',
            deleteAccount: 'खाता हटाएँ'
        },
        'bn': {
            install: 'ইনস্টল করুন',
            themeToggle: 'থিম বদলান',
            themeVariants: { menu: 'থিমের ধরন', normal: 'ক্লাসিক', fullDark: 'গভীর কালো', chalkboard: 'Chalkboard' },
            density: { label: 'ঘনত্ব', compact: 'সংক্ষিপ্ত', comfortable: 'আরামদায়ক', detailed: 'বিস্তারিত' },
            currentScripts: 'অন্তর্ভুক্ত স্ক্রিপ্ট',
            emptyScripts: 'এই তালিকায় এখনও কোনো স্ক্রিপ্ট নেই।',
            removeScript: 'এই স্ক্রিপ্ট সরান',
            save: 'সংরক্ষণ করুন',
            favoriteSetName: 'প্রিয়',
            addToFavorites: 'প্রিয়তে যোগ করুন',
            removeFromFavorites: 'প্রিয় থেকে সরান',
            addPersonalNote: 'ব্যক্তিগত নোট যোগ করুন',
            editPersonalNote: 'ব্যক্তিগত নোট সম্পাদনা করুন',
            personalNoteLabel: 'ব্যক্তিগত নোট',
            personalNotePlaceholder: 'এই স্ক্রিপ্টের জন্য ব্যক্তিগত নোট লিখুন...',
            personalNoteSaved: 'সংরক্ষিত',
            deleteNote: 'মুছুন',
            done: 'সম্পন্ন',
            showDetails: 'আরও দেখুন',
            hideDetails: 'বিস্তারিত সংকুচিত করুন',
            loadingDetails: 'বিস্তারিত লোড হচ্ছে...',
            detailsLoadFailed: 'বিস্তারিত লোড করা যায়নি।',
            noDetailedInfo: 'অতিরিক্ত কোনো বিস্তারিত নেই।',
            submitScript: 'স্ক্রিপ্ট প্রকাশ করুন',
            submitStyle: 'স্টাইল প্রকাশ করুন',
            submitSet: 'নতুন স্ক্রিপ্ট সেট',
            webhookInfo: 'Webhook সেট আপ করুন',
            importScripts: 'স্ক্রিপ্ট আমদানি করুন',
            editProfile: 'প্রোফাইল সম্পাদনা করুন',
            editSignIn: 'সাইন-ইন পদ্ধতি সম্পাদনা করুন',
            viewNotifications: 'বিজ্ঞপ্তি দেখুন',
            notificationSettings: 'বিজ্ঞপ্তি সেটিংস সম্পাদনা করুন',
            deleteAccount: 'অ্যাকাউন্ট মুছুন'
        },

        'ur': {
            install: 'انسٹال کریں',
            themeToggle: 'تھیم تبدیل کریں',
            themeVariants: { menu: 'تھیم کے انداز', normal: 'کلاسک', fullDark: 'گہرا سیاہ', chalkboard: 'Chalkboard' },
            density: { label: 'کثافت', compact: 'مختصر', comfortable: 'آرام دہ', detailed: 'تفصیلی' },
            currentScripts: 'شامل اسکرپٹس',
            emptyScripts: 'اس فہرست میں ابھی کوئی اسکرپٹ نہیں ہے۔',
            removeScript: 'یہ اسکرپٹ ہٹائیں',
            save: 'محفوظ کریں',
            favoriteSetName: 'پسندیدہ',
            addToFavorites: 'پسندیدہ میں شامل کریں',
            removeFromFavorites: 'پسندیدہ سے ہٹائیں',
            addPersonalNote: 'ذاتی نوٹ شامل کریں',
            editPersonalNote: 'ذاتی نوٹ میں ترمیم کریں',
            personalNoteLabel: 'ذاتی نوٹ',
            personalNotePlaceholder: 'اس اسکرپٹ کے لیے ذاتی نوٹ لکھیں...',
            personalNoteSaved: 'محفوظ ہو گیا',
            deleteNote: 'حذف کریں',
            done: 'مکمل',
            showDetails: 'مزید دیکھیں',
            hideDetails: 'تفصیلات سمیٹیں',
            loadingDetails: 'تفصیلات لوڈ ہو رہی ہیں...',
            detailsLoadFailed: 'تفصیلات لوڈ نہیں ہو سکیں۔',
            noDetailedInfo: 'اضافی تفصیلات دستیاب نہیں ہیں۔',
            submitScript: 'اسکرپٹ شائع کریں',
            submitStyle: 'اسٹائل شائع کریں',
            submitSet: 'نیا اسکرپٹ سیٹ',
            webhookInfo: 'Webhook سیٹ اپ کریں',
            importScripts: 'اسکرپٹس درآمد کریں',
            editProfile: 'پروفائل میں ترمیم کریں',
            editSignIn: 'سائن اِن طریقے میں ترمیم کریں',
            viewNotifications: 'اطلاعات دیکھیں',
            notificationSettings: 'اطلاع کی ترتیبات میں ترمیم کریں',
            deleteAccount: 'اکاؤنٹ حذف کریں'
        },

        'ml': {
            install: 'ഇൻസ്റ്റാൾ ചെയ്യുക',
            themeToggle: 'തീം മാറ്റുക',
            themeVariants: { menu: 'തീം ശൈലികൾ', normal: 'ക്ലാസിക്', fullDark: 'കടും കറുപ്പ്', chalkboard: 'Chalkboard' },
            density: { label: 'സാന്ദ്രത', compact: 'ഒതുക്കമുള്ള', comfortable: 'സുഖപ്രദമായ', detailed: 'വിശദമായ' },
            currentScripts: 'ഉൾപ്പെടുത്തിയ സ്ക്രിപ്റ്റുകൾ',
            emptyScripts: 'ഈ പട്ടികയിൽ ഇതുവരെ സ്ക്രിപ്റ്റുകളൊന്നുമില്ല.',
            removeScript: 'ഈ സ്ക്രിപ്റ്റ് നീക്കം ചെയ്യുക',
            save: 'സംരക്ഷിക്കുക',
            favoriteSetName: 'പ്രിയപ്പെട്ടവ',
            addToFavorites: 'പ്രിയപ്പെട്ടവയിൽ ചേർക്കുക',
            removeFromFavorites: 'പ്രിയപ്പെട്ടവയിൽ നിന്ന് നീക്കം ചെയ്യുക',
            addPersonalNote: 'വ്യക്തിഗത കുറിപ്പ് ചേർക്കുക',
            editPersonalNote: 'വ്യക്തിഗത കുറിപ്പ് തിരുത്തുക',
            personalNoteLabel: 'വ്യക്തിഗത കുറിപ്പ്',
            personalNotePlaceholder: 'ഈ സ്ക്രിപ്റ്റിന് വ്യക്തിഗത കുറിപ്പ് എഴുതുക...',
            personalNoteSaved: 'സംരക്ഷിച്ചു',
            deleteNote: 'ഇല്ലാതാക്കുക',
            done: 'പൂർത്തിയായി',
            showDetails: 'കൂടുതൽ കാണിക്കുക',
            hideDetails: 'വിശദാംശങ്ങൾ ചുരുക്കുക',
            loadingDetails: 'വിശദാംശങ്ങൾ ലോഡ് ചെയ്യുന്നു...',
            detailsLoadFailed: 'വിശദാംശങ്ങൾ ലോഡ് ചെയ്യാനായില്ല.',
            noDetailedInfo: 'കൂടുതൽ വിശദാംശങ്ങൾ ലഭ്യമല്ല.',
            submitScript: 'സ്ക്രിപ്റ്റ് പ്രസിദ്ധീകരിക്കുക',
            submitStyle: 'സ്റ്റൈൽ പ്രസിദ്ധീകരിക്കുക',
            submitSet: 'പുതിയ സ്ക്രിപ്റ്റ് സെറ്റ്',
            webhookInfo: 'Webhook സജ്ജമാക്കുക',
            importScripts: 'സ്ക്രിപ്റ്റുകൾ ഇറക്കുമതി ചെയ്യുക',
            editProfile: 'പ്രൊഫൈൽ തിരുത്തുക',
            editSignIn: 'സൈൻ-ഇൻ രീതികൾ തിരുത്തുക',
            viewNotifications: 'അറിയിപ്പുകൾ കാണുക',
            notificationSettings: 'അറിയിപ്പ് ക്രമീകരണങ്ങൾ തിരുത്തുക',
            deleteAccount: 'അക്കൗണ്ട് ഇല്ലാതാക്കുക'
        },

        'ko': {
            install: '설치',
            themeToggle: '테마 전환',
            themeVariants: { menu: '테마 스타일', normal: '클래식', fullDark: '딥 블랙', chalkboard: 'Chalkboard' },
            density: { label: '밀도', compact: '좁게', comfortable: '보통', detailed: '자세히' },
            currentScripts: '포함된 스크립트',
            emptyScripts: '이 목록에는 아직 스크립트가 없습니다.',
            removeScript: '이 스크립트 제거',
            save: '저장',
            favoriteSetName: '즐겨찾기',
            addToFavorites: '즐겨찾기에 추가',
            removeFromFavorites: '즐겨찾기에서 제거',
            addPersonalNote: '개인 메모 추가',
            editPersonalNote: '개인 메모 편집',
            personalNoteLabel: '개인 메모',
            personalNotePlaceholder: '이 스크립트에 대한 개인 메모를 작성하세요...',
            personalNoteSaved: '저장됨',
            deleteNote: '삭제',
            done: '완료',
            showDetails: '더 보기',
            hideDetails: '상세 정보 접기',
            loadingDetails: '상세 정보를 불러오는 중...',
            detailsLoadFailed: '상세 정보를 불러올 수 없습니다.',
            noDetailedInfo: '추가 상세 정보가 없습니다.',
            submitScript: '스크립트 게시',
            submitStyle: '스타일 게시',
            submitSet: '새 스크립트 세트',
            webhookInfo: 'Webhook 설정',
            importScripts: '스크립트 가져오기',
            editProfile: '프로필 수정',
            editSignIn: '로그인 방법 수정',
            viewNotifications: '알림 보기',
            notificationSettings: '알림 설정 수정',
            deleteAccount: '계정 삭제'
        },

        'tr': {
            install: 'Yükle',
            themeToggle: 'Tema değiştir',
            themeVariants: { menu: 'Tema stilleri', normal: 'Klasik', fullDark: 'Derin siyah', chalkboard: 'Chalkboard' },
            density: { label: 'Yoğunluk', compact: 'Kompakt', comfortable: 'Rahat', detailed: 'Ayrıntılı' },
            currentScripts: 'Dahil edilen scriptler',
            emptyScripts: 'Bu listede henüz script yok.',
            removeScript: 'Bu scripti kaldır',
            save: 'Kaydet',
            favoriteSetName: 'Favoriler',
            addToFavorites: 'Favorilere ekle',
            removeFromFavorites: 'Favorilerden kaldır',
            addPersonalNote: 'Kişisel not ekle',
            editPersonalNote: 'Kişisel notu düzenle',
            personalNoteLabel: 'Kişisel not',
            personalNotePlaceholder: 'Bu script için kişisel not yaz...',
            personalNoteSaved: 'Kaydedildi',
            deleteNote: 'Sil',
            done: 'Bitti',
            showDetails: 'Daha fazla göster',
            hideDetails: 'Ayrıntıları daralt',
            loadingDetails: 'Ayrıntılar yükleniyor...',
            detailsLoadFailed: 'Ayrıntılar yüklenemedi.',
            noDetailedInfo: 'Ek ayrıntı yok.',
            submitScript: 'Script yayınla',
            submitStyle: 'Stil yayınla',
            submitSet: 'Yeni script seti',
            webhookInfo: 'Webhook ayarla',
            importScripts: 'Script içe aktar',
            editProfile: 'Profili düzenle',
            editSignIn: 'Giriş yöntemlerini düzenle',
            viewNotifications: 'Bildirimleri görüntüle',
            notificationSettings: 'Bildirim ayarlarını düzenle',
            deleteAccount: 'Hesabı sil'
        },

        'pl': {
            install: 'Zainstaluj',
            themeToggle: 'Przełącz motyw',
            themeVariants: { menu: 'Style motywu', normal: 'Klasyczny', fullDark: 'Głęboka czerń', chalkboard: 'Chalkboard' },
            density: { label: 'Gęstość', compact: 'Kompaktowy', comfortable: 'Wygodny', detailed: 'Szczegółowy' },
            currentScripts: 'Dołączone skrypty',
            emptyScripts: 'Na tej liście nie ma jeszcze skryptów.',
            removeScript: 'Usuń ten skrypt',
            save: 'Zapisz',
            favoriteSetName: 'Ulubione',
            addToFavorites: 'Dodaj do ulubionych',
            removeFromFavorites: 'Usuń z ulubionych',
            addPersonalNote: 'Dodaj osobistą notatkę',
            editPersonalNote: 'Edytuj osobistą notatkę',
            personalNoteLabel: 'Osobista notatka',
            personalNotePlaceholder: 'Napisz osobistą notatkę do tego skryptu...',
            personalNoteSaved: 'Zapisano',
            deleteNote: 'Usuń',
            done: 'Gotowe',
            showDetails: 'Pokaż więcej',
            hideDetails: 'Zwiń szczegóły',
            loadingDetails: 'Ładowanie szczegółów...',
            detailsLoadFailed: 'Nie udało się załadować szczegółów.',
            noDetailedInfo: 'Brak dodatkowych szczegółów.',
            submitScript: 'Opublikuj skrypt',
            submitStyle: 'Opublikuj styl',
            submitSet: 'Nowy zestaw skryptów',
            webhookInfo: 'Skonfiguruj webhook',
            importScripts: 'Importuj skrypty',
            editProfile: 'Edytuj profil',
            editSignIn: 'Edytuj metody logowania',
            viewNotifications: 'Zobacz powiadomienia',
            notificationSettings: 'Edytuj ustawienia powiadomień',
            deleteAccount: 'Usuń konto'
        },

        'nl': {
            install: 'Installeren',
            themeToggle: 'Thema wisselen',
            themeVariants: { menu: 'Themastijlen', normal: 'Klassiek', fullDark: 'Diepzwart', chalkboard: 'Chalkboard' },
            density: { label: 'Dichtheid', compact: 'Compact', comfortable: 'Comfortabel', detailed: 'Gedetailleerd' },
            currentScripts: 'Opgenomen scripts',
            emptyScripts: 'Er staan nog geen scripts in deze lijst.',
            removeScript: 'Dit script verwijderen',
            save: 'Opslaan',
            favoriteSetName: 'Favorieten',
            addToFavorites: 'Aan favorieten toevoegen',
            removeFromFavorites: 'Uit favorieten verwijderen',
            addPersonalNote: 'Persoonlijke notitie toevoegen',
            editPersonalNote: 'Persoonlijke notitie bewerken',
            personalNoteLabel: 'Persoonlijke notitie',
            personalNotePlaceholder: 'Schrijf een persoonlijke notitie voor dit script...',
            personalNoteSaved: 'Opgeslagen',
            deleteNote: 'Verwijderen',
            done: 'Klaar',
            showDetails: 'Meer weergeven',
            hideDetails: 'Details inklappen',
            loadingDetails: 'Details laden...',
            detailsLoadFailed: 'Details konden niet worden geladen.',
            noDetailedInfo: 'Geen extra details beschikbaar.',
            submitScript: 'Script publiceren',
            submitStyle: 'Stijl publiceren',
            submitSet: 'Nieuwe scriptset',
            webhookInfo: 'Webhook instellen',
            importScripts: 'Scripts importeren',
            editProfile: 'Profiel bewerken',
            editSignIn: 'Aanmeldmethoden bewerken',
            viewNotifications: 'Meldingen bekijken',
            notificationSettings: 'Meldingsinstellingen bewerken',
            deleteAccount: 'Account verwijderen'
        },

        'sv': {
            install: 'Installera',
            themeToggle: 'Växla tema',
            themeVariants: { menu: 'Temastilar', normal: 'Klassisk', fullDark: 'Djupsvart', chalkboard: 'Chalkboard' },
            density: { label: 'Täthet', compact: 'Kompakt', comfortable: 'Bekväm', detailed: 'Detaljerad' },
            currentScripts: 'Inkluderade skript',
            emptyScripts: 'Det finns inga skript i den här listan ännu.',
            removeScript: 'Ta bort det här skriptet',
            save: 'Spara',
            favoriteSetName: 'Favoriter',
            addToFavorites: 'Lägg till i favoriter',
            removeFromFavorites: 'Ta bort från favoriter',
            addPersonalNote: 'Lägg till personlig anteckning',
            editPersonalNote: 'Redigera personlig anteckning',
            personalNoteLabel: 'Personlig anteckning',
            personalNotePlaceholder: 'Skriv en personlig anteckning för det här skriptet...',
            personalNoteSaved: 'Sparat',
            deleteNote: 'Ta bort',
            done: 'Klart',
            showDetails: 'Visa mer',
            hideDetails: 'Dölj detaljer',
            loadingDetails: 'Läser in detaljer...',
            detailsLoadFailed: 'Det gick inte att läsa in detaljer.',
            noDetailedInfo: 'Inga ytterligare detaljer tillgängliga.',
            submitScript: 'Publicera skript',
            submitStyle: 'Publicera stil',
            submitSet: 'Ny skriptsamling',
            webhookInfo: 'Konfigurera webhook',
            importScripts: 'Importera skript',
            editProfile: 'Redigera profil',
            editSignIn: 'Redigera inloggningsmetoder',
            viewNotifications: 'Visa notiser',
            notificationSettings: 'Redigera notisinställningar',
            deleteAccount: 'Ta bort konto'
        },

        'ro': {
            install: 'Instalează',
            themeToggle: 'Comută tema',
            themeVariants: { menu: 'Stiluri de temă', normal: 'Clasic', fullDark: 'Negru profund', chalkboard: 'Chalkboard' },
            density: { label: 'Densitate', compact: 'Compact', comfortable: 'Confortabil', detailed: 'Detaliat' },
            currentScripts: 'Scripturi incluse',
            emptyScripts: 'Nu există încă scripturi în această listă.',
            removeScript: 'Elimină acest script',
            save: 'Salvează',
            favoriteSetName: 'Favorite',
            addToFavorites: 'Adaugă la favorite',
            removeFromFavorites: 'Elimină din favorite',
            addPersonalNote: 'Adaugă notă personală',
            editPersonalNote: 'Editează nota personală',
            personalNoteLabel: 'Notă personală',
            personalNotePlaceholder: 'Scrie o notă personală pentru acest script...',
            personalNoteSaved: 'Salvat',
            deleteNote: 'Șterge',
            done: 'Gata',
            showDetails: 'Vezi mai mult',
            hideDetails: 'Restrânge detaliile',
            loadingDetails: 'Se încarcă detaliile...',
            detailsLoadFailed: 'Detaliile nu au putut fi încărcate.',
            noDetailedInfo: 'Nu există detalii suplimentare disponibile.',
            submitScript: 'Publică script',
            submitStyle: 'Publică stil',
            submitSet: 'Set nou de scripturi',
            webhookInfo: 'Configurează webhook',
            importScripts: 'Importă scripturi',
            editProfile: 'Editează profil',
            editSignIn: 'Editează metodele de autentificare',
            viewNotifications: 'Vezi notificări',
            notificationSettings: 'Editează setările notificărilor',
            deleteAccount: 'Șterge contul'
        },

        'vi': {
            install: 'Cài đặt',
            themeToggle: 'Chuyển giao diện',
            themeVariants: { menu: 'Kiểu giao diện', normal: 'Cổ điển', fullDark: 'Đen sâu', chalkboard: 'Chalkboard' },
            density: { label: 'Mật độ', compact: 'Thu gọn', comfortable: 'Thoải mái', detailed: 'Chi tiết' },
            currentScripts: 'Script đã thêm',
            emptyScripts: 'Chưa có script nào trong danh sách này.',
            removeScript: 'Xóa script này',
            save: 'Lưu',
            favoriteSetName: 'Yêu thích',
            addToFavorites: 'Thêm vào yêu thích',
            removeFromFavorites: 'Xóa khỏi yêu thích',
            addPersonalNote: 'Thêm ghi chú cá nhân',
            editPersonalNote: 'Chỉnh sửa ghi chú cá nhân',
            personalNoteLabel: 'Ghi chú cá nhân',
            personalNotePlaceholder: 'Viết ghi chú cá nhân cho script này...',
            personalNoteSaved: 'Đã lưu',
            deleteNote: 'Xóa',
            done: 'Xong',
            showDetails: 'Xem thêm',
            hideDetails: 'Thu gọn chi tiết',
            loadingDetails: 'Đang tải chi tiết...',
            detailsLoadFailed: 'Không thể tải chi tiết.',
            noDetailedInfo: 'Không có chi tiết bổ sung.',
            submitScript: 'Đăng script',
            submitStyle: 'Đăng kiểu',
            submitSet: 'Bộ script mới',
            webhookInfo: 'Thiết lập webhook',
            importScripts: 'Nhập script',
            editProfile: 'Chỉnh sửa hồ sơ',
            editSignIn: 'Chỉnh sửa phương thức đăng nhập',
            viewNotifications: 'Xem thông báo',
            notificationSettings: 'Chỉnh sửa cài đặt thông báo',
            deleteAccount: 'Xóa tài khoản'
        },

        'id': {
            install: 'Pasang',
            themeToggle: 'Ganti tema',
            themeVariants: { menu: 'Gaya tema', normal: 'Klasik', fullDark: 'Hitam pekat', chalkboard: 'Chalkboard' },
            density: { label: 'Kepadatan', compact: 'Ringkas', comfortable: 'Nyaman', detailed: 'Terperinci' },
            currentScripts: 'Skrip yang disertakan',
            emptyScripts: 'Belum ada skrip dalam daftar ini.',
            removeScript: 'Hapus skrip ini',
            save: 'Simpan',
            favoriteSetName: 'Favorit',
            addToFavorites: 'Tambahkan ke favorit',
            removeFromFavorites: 'Hapus dari favorit',
            addPersonalNote: 'Tambahkan catatan pribadi',
            editPersonalNote: 'Edit catatan pribadi',
            personalNoteLabel: 'Catatan pribadi',
            personalNotePlaceholder: 'Tulis catatan pribadi untuk skrip ini...',
            personalNoteSaved: 'Tersimpan',
            deleteNote: 'Hapus',
            done: 'Selesai',
            showDetails: 'Lihat selengkapnya',
            hideDetails: 'Sembunyikan detail',
            loadingDetails: 'Memuat detail...',
            detailsLoadFailed: 'Tidak dapat memuat detail.',
            noDetailedInfo: 'Tidak ada detail tambahan.',
            submitScript: 'Publikasikan skrip',
            submitStyle: 'Publikasikan gaya',
            submitSet: 'Set skrip baru',
            webhookInfo: 'Atur webhook',
            importScripts: 'Impor skrip',
            editProfile: 'Edit profil',
            editSignIn: 'Edit metode masuk',
            viewNotifications: 'Lihat notifikasi',
            notificationSettings: 'Edit pengaturan notifikasi',
            deleteAccount: 'Hapus akun'
        },

        'ms': {
            install: 'Pasang',
            themeToggle: 'Tukar tema',
            themeVariants: { menu: 'Gaya tema', normal: 'Klasik', fullDark: 'Hitam pekat', chalkboard: 'Chalkboard' },
            density: { label: 'Kepadatan', compact: 'Padat', comfortable: 'Selesa', detailed: 'Terperinci' },
            currentScripts: 'Skrip disertakan',
            emptyScripts: 'Tiada skrip dalam senarai ini lagi.',
            removeScript: 'Alih keluar skrip ini',
            save: 'Simpan',
            favoriteSetName: 'Kegemaran',
            addToFavorites: 'Tambah ke kegemaran',
            removeFromFavorites: 'Alih keluar daripada kegemaran',
            addPersonalNote: 'Tambah nota peribadi',
            editPersonalNote: 'Edit nota peribadi',
            personalNoteLabel: 'Nota peribadi',
            personalNotePlaceholder: 'Tulis nota peribadi untuk skrip ini...',
            personalNoteSaved: 'Disimpan',
            deleteNote: 'Padam',
            done: 'Selesai',
            showDetails: 'Lihat lagi',
            hideDetails: 'Sembunyikan butiran',
            loadingDetails: 'Memuatkan butiran...',
            detailsLoadFailed: 'Tidak dapat memuatkan butiran.',
            noDetailedInfo: 'Tiada butiran tambahan tersedia.',
            submitScript: 'Terbitkan skrip',
            submitStyle: 'Terbitkan gaya',
            submitSet: 'Set skrip baharu',
            webhookInfo: 'Sediakan webhook',
            importScripts: 'Import skrip',
            editProfile: 'Edit profil',
            editSignIn: 'Edit kaedah log masuk',
            viewNotifications: 'Lihat notifikasi',
            notificationSettings: 'Edit tetapan notifikasi',
            deleteAccount: 'Padam akaun'
        },

        'be': {
            install: 'Усталяваць',
            themeToggle: 'Пераключыць тэму',
            themeVariants: { menu: 'Стылі тэмы', normal: 'Класічная', fullDark: 'Глыбокі чорны', chalkboard: 'Chalkboard' },
            density: { label: 'Шчыльнасць', compact: 'Кампактна', comfortable: 'Зручна', detailed: 'Падрабязна' },
            currentScripts: 'Уключаныя скрыпты',
            emptyScripts: 'У гэтым спісе пакуль няма скрыптоў.',
            removeScript: 'Выдаліць гэты скрыпт',
            save: 'Захаваць',
            favoriteSetName: 'Абранае',
            addToFavorites: 'Дадаць у абранае',
            removeFromFavorites: 'Выдаліць з абранага',
            addPersonalNote: 'Дадаць асабістую нататку',
            editPersonalNote: 'Рэдагаваць асабістую нататку',
            personalNoteLabel: 'Асабістая нататка',
            personalNotePlaceholder: 'Напішыце асабістую нататку для гэтага скрыпта...',
            personalNoteSaved: 'Захавана',
            deleteNote: 'Выдаліць',
            done: 'Гатова',
            showDetails: 'Паказаць больш',
            hideDetails: 'Згарнуць падрабязнасці',
            loadingDetails: 'Загрузка падрабязнасцей...',
            detailsLoadFailed: 'Не ўдалося загрузіць падрабязнасці.',
            noDetailedInfo: 'Дадатковых звестак няма.',
            submitScript: 'Апублікаваць скрыпт',
            submitStyle: 'Апублікаваць стыль',
            submitSet: 'Новы набор скрыптоў',
            webhookInfo: 'Наладзіць webhook',
            importScripts: 'Імпартаваць скрыпты',
            editProfile: 'Рэдагаваць профіль',
            editSignIn: 'Рэдагаваць спосабы ўваходу',
            viewNotifications: 'Праглядзець апавяшчэнні',
            notificationSettings: 'Рэдагаваць налады апавяшчэнняў',
            deleteAccount: 'Выдаліць уліковы запіс'
        },

        'nb': {
            install: 'Installer',
            themeToggle: 'Bytt tema',
            themeVariants: { menu: 'Temastiler', normal: 'Klassisk', fullDark: 'Dypsvart', chalkboard: 'Chalkboard' },
            density: { label: 'Tetthet', compact: 'Kompakt', comfortable: 'Komfortabel', detailed: 'Detaljert' },
            currentScripts: 'Inkluderte skript',
            emptyScripts: 'Det er ingen skript i denne listen ennå.',
            removeScript: 'Fjern dette skriptet',
            save: 'Lagre',
            favoriteSetName: 'Favoritter',
            addToFavorites: 'Legg til i favoritter',
            removeFromFavorites: 'Fjern fra favoritter',
            addPersonalNote: 'Legg til personlig notat',
            editPersonalNote: 'Rediger personlig notat',
            personalNoteLabel: 'Personlig notat',
            personalNotePlaceholder: 'Skriv et personlig notat for dette skriptet...',
            personalNoteSaved: 'Lagret',
            deleteNote: 'Slett',
            done: 'Ferdig',
            showDetails: 'Vis mer',
            hideDetails: 'Skjul detaljer',
            loadingDetails: 'Laster inn detaljer...',
            detailsLoadFailed: 'Kunne ikke laste inn detaljer.',
            noDetailedInfo: 'Ingen flere detaljer er tilgjengelige.',
            submitScript: 'Publiser skript',
            submitStyle: 'Publiser stil',
            submitSet: 'Nytt skriptsett',
            webhookInfo: 'Konfigurer webhook',
            importScripts: 'Importer skript',
            editProfile: 'Rediger profil',
            editSignIn: 'Rediger innloggingsmetoder',
            viewNotifications: 'Vis varsler',
            notificationSettings: 'Rediger varslingsinnstillinger',
            deleteAccount: 'Slett konto'
        },

        'bg': {
            install: 'Инсталиране',
            themeToggle: 'Смяна на темата',
            themeVariants: { menu: 'Стилове на темата', normal: 'Класическа', fullDark: 'Дълбоко черно', chalkboard: 'Chalkboard' },
            density: { label: 'Плътност', compact: 'Компактна', comfortable: 'Удобна', detailed: 'Подробна' },
            currentScripts: 'Включени скриптове',
            emptyScripts: 'Все още няма скриптове в този списък.',
            removeScript: 'Премахване на този скрипт',
            save: 'Запазване',
            favoriteSetName: 'Любими',
            addToFavorites: 'Добавяне към любими',
            removeFromFavorites: 'Премахване от любими',
            addPersonalNote: 'Добавяне на лична бележка',
            editPersonalNote: 'Редактиране на личната бележка',
            personalNoteLabel: 'Лична бележка',
            personalNotePlaceholder: 'Напишете лична бележка за този скрипт...',
            personalNoteSaved: 'Запазено',
            deleteNote: 'Изтриване',
            done: 'Готово',
            showDetails: 'Показване на още',
            hideDetails: 'Скриване на подробностите',
            loadingDetails: 'Зареждане на подробности...',
            detailsLoadFailed: 'Подробностите не можаха да се заредят.',
            noDetailedInfo: 'Няма допълнителни подробности.',
            submitScript: 'Публикуване на скрипт',
            submitStyle: 'Публикуване на стил',
            submitSet: 'Нов набор от скриптове',
            webhookInfo: 'Настройване на webhook',
            importScripts: 'Импортиране на скриптове',
            editProfile: 'Редактиране на профила',
            editSignIn: 'Редактиране на методите за вход',
            viewNotifications: 'Преглед на известията',
            notificationSettings: 'Редактиране на настройките за известия',
            deleteAccount: 'Изтриване на акаунта'
        },

        'hr': {
            install: 'Instaliraj',
            themeToggle: 'Promijeni temu',
            themeVariants: { menu: 'Stilovi teme', normal: 'Klasična', fullDark: 'Duboka crna', chalkboard: 'Chalkboard' },
            density: { label: 'Gustoća', compact: 'Kompaktno', comfortable: 'Udobno', detailed: 'Detaljno' },
            currentScripts: 'Uključene skripte',
            emptyScripts: 'Na ovom popisu još nema skripti.',
            removeScript: 'Ukloni ovu skriptu',
            save: 'Spremi',
            favoriteSetName: 'Favoriti',
            addToFavorites: 'Dodaj u favorite',
            removeFromFavorites: 'Ukloni iz favorita',
            addPersonalNote: 'Dodaj osobnu bilješku',
            editPersonalNote: 'Uredi osobnu bilješku',
            personalNoteLabel: 'Osobna bilješka',
            personalNotePlaceholder: 'Napišite osobnu bilješku za ovu skriptu...',
            personalNoteSaved: 'Spremljeno',
            deleteNote: 'Izbriši',
            done: 'Gotovo',
            showDetails: 'Prikaži više',
            hideDetails: 'Sakrij pojedinosti',
            loadingDetails: 'Učitavanje pojedinosti...',
            detailsLoadFailed: 'Pojedinosti se nisu mogle učitati.',
            noDetailedInfo: 'Nema dodatnih pojedinosti.',
            submitScript: 'Objavi skriptu',
            submitStyle: 'Objavi stil',
            submitSet: 'Novi skup skripti',
            webhookInfo: 'Postavi webhook',
            importScripts: 'Uvezi skripte',
            editProfile: 'Uredi profil',
            editSignIn: 'Uredi načine prijave',
            viewNotifications: 'Prikaži obavijesti',
            notificationSettings: 'Uredi postavke obavijesti',
            deleteAccount: 'Izbriši račun'
        },

        'cs': {
            install: 'Nainstalovat',
            themeToggle: 'Přepnout motiv',
            themeVariants: { menu: 'Styly motivu', normal: 'Klasický', fullDark: 'Hluboká černá', chalkboard: 'Chalkboard' },
            density: { label: 'Hustota', compact: 'Kompaktní', comfortable: 'Pohodlná', detailed: 'Podrobná' },
            currentScripts: 'Zahrnuté skripty',
            emptyScripts: 'V tomto seznamu zatím nejsou žádné skripty.',
            removeScript: 'Odebrat tento skript',
            save: 'Uložit',
            favoriteSetName: 'Oblíbené',
            addToFavorites: 'Přidat do oblíbených',
            removeFromFavorites: 'Odebrat z oblíbených',
            addPersonalNote: 'Přidat osobní poznámku',
            editPersonalNote: 'Upravit osobní poznámku',
            personalNoteLabel: 'Osobní poznámka',
            personalNotePlaceholder: 'Napište osobní poznámku k tomuto skriptu...',
            personalNoteSaved: 'Uloženo',
            deleteNote: 'Smazat',
            done: 'Hotovo',
            showDetails: 'Zobrazit více',
            hideDetails: 'Skrýt podrobnosti',
            loadingDetails: 'Načítání podrobností...',
            detailsLoadFailed: 'Podrobnosti se nepodařilo načíst.',
            noDetailedInfo: 'Nejsou k dispozici žádné další podrobnosti.',
            submitScript: 'Publikovat skript',
            submitStyle: 'Publikovat styl',
            submitSet: 'Nová sada skriptů',
            webhookInfo: 'Nastavit webhook',
            importScripts: 'Importovat skripty',
            editProfile: 'Upravit profil',
            editSignIn: 'Upravit způsoby přihlášení',
            viewNotifications: 'Zobrazit oznámení',
            notificationSettings: 'Upravit nastavení oznámení',
            deleteAccount: 'Smazat účet'
        },

        'da': {
            install: 'Installer',
            themeToggle: 'Skift tema',
            themeVariants: { menu: 'Temastile', normal: 'Klassisk', fullDark: 'Dyb sort', chalkboard: 'Chalkboard' },
            density: { label: 'Tæthed', compact: 'Kompakt', comfortable: 'Behagelig', detailed: 'Detaljeret' },
            currentScripts: 'Inkluderede scripts',
            emptyScripts: 'Der er endnu ingen scripts på denne liste.',
            removeScript: 'Fjern dette script',
            save: 'Gem',
            favoriteSetName: 'Favoritter',
            addToFavorites: 'Føj til favoritter',
            removeFromFavorites: 'Fjern fra favoritter',
            addPersonalNote: 'Tilføj personlig note',
            editPersonalNote: 'Rediger personlig note',
            personalNoteLabel: 'Personlig note',
            personalNotePlaceholder: 'Skriv en personlig note til dette script...',
            personalNoteSaved: 'Gemt',
            deleteNote: 'Slet',
            done: 'Færdig',
            showDetails: 'Vis mere',
            hideDetails: 'Skjul detaljer',
            loadingDetails: 'Indlæser detaljer...',
            detailsLoadFailed: 'Detaljerne kunne ikke indlæses.',
            noDetailedInfo: 'Ingen yderligere detaljer er tilgængelige.',
            submitScript: 'Udgiv script',
            submitStyle: 'Udgiv stil',
            submitSet: 'Nyt scriptsæt',
            webhookInfo: 'Opsæt webhook',
            importScripts: 'Importer scripts',
            editProfile: 'Rediger profil',
            editSignIn: 'Rediger loginmetoder',
            viewNotifications: 'Vis notifikationer',
            notificationSettings: 'Rediger notifikationsindstillinger',
            deleteAccount: 'Slet konto'
        },

        'eo': {
            install: 'Instali',
            themeToggle: 'Ŝanĝi etoson',
            themeVariants: { menu: 'Etosaj stiloj', normal: 'Klasika', fullDark: 'Profunde nigra', chalkboard: 'Chalkboard' },
            density: { label: 'Denseco', compact: 'Kompakta', comfortable: 'Komforta', detailed: 'Detala' },
            currentScripts: 'Inkluzivitaj skriptoj',
            emptyScripts: 'Ankoraŭ ne estas skriptoj en ĉi tiu listo.',
            removeScript: 'Forigi ĉi tiun skripton',
            save: 'Konservi',
            favoriteSetName: 'Ŝatatoj',
            addToFavorites: 'Aldoni al ŝatatoj',
            removeFromFavorites: 'Forigi el ŝatatoj',
            addPersonalNote: 'Aldoni personan noton',
            editPersonalNote: 'Redakti personan noton',
            personalNoteLabel: 'Persona noto',
            personalNotePlaceholder: 'Skribu personan noton por ĉi tiu skripto...',
            personalNoteSaved: 'Konservita',
            deleteNote: 'Forigi',
            done: 'Farita',
            showDetails: 'Montri pli',
            hideDetails: 'Kaŝi detalojn',
            loadingDetails: 'Ŝargante detalojn...',
            detailsLoadFailed: 'Ne eblis ŝargi la detalojn.',
            noDetailedInfo: 'Neniuj pliaj detaloj disponeblas.',
            submitScript: 'Publikigi skripton',
            submitStyle: 'Publikigi stilon',
            submitSet: 'Nova skriptaro',
            webhookInfo: 'Agordi webhook',
            importScripts: 'Importi skriptojn',
            editProfile: 'Redakti profilon',
            editSignIn: 'Redakti ensalutmetodojn',
            viewNotifications: 'Vidi sciigojn',
            notificationSettings: 'Redakti sciigajn agordojn',
            deleteAccount: 'Forigi konton'
        },

        'fil': {
            install: 'I-install',
            themeToggle: 'Palitan ang tema',
            themeVariants: { menu: 'Mga estilo ng tema', normal: 'Klasiko', fullDark: 'Napakaitim', chalkboard: 'Chalkboard' },
            density: { label: 'Densidad', compact: 'Siksik', comfortable: 'Komportable', detailed: 'Detalyado' },
            currentScripts: 'Mga kasamang script',
            emptyScripts: 'Wala pang script sa listahang ito.',
            removeScript: 'Alisin ang script na ito',
            save: 'I-save',
            favoriteSetName: 'Mga Paborito',
            addToFavorites: 'Idagdag sa mga paborito',
            removeFromFavorites: 'Alisin sa mga paborito',
            addPersonalNote: 'Magdagdag ng personal na tala',
            editPersonalNote: 'I-edit ang personal na tala',
            personalNoteLabel: 'Personal na tala',
            personalNotePlaceholder: 'Sumulat ng personal na tala para sa script na ito...',
            personalNoteSaved: 'Nai-save',
            deleteNote: 'Tanggalin',
            done: 'Tapos na',
            showDetails: 'Magpakita pa',
            hideDetails: 'Itago ang mga detalye',
            loadingDetails: 'Nilo-load ang mga detalye...',
            detailsLoadFailed: 'Hindi ma-load ang mga detalye.',
            noDetailedInfo: 'Walang karagdagang detalye.',
            submitScript: 'Mag-publish ng script',
            submitStyle: 'Mag-publish ng estilo',
            submitSet: 'Bagong set ng script',
            webhookInfo: 'Mag-set up ng webhook',
            importScripts: 'Mag-import ng mga script',
            editProfile: 'I-edit ang profile',
            editSignIn: 'I-edit ang mga paraan ng pag-sign in',
            viewNotifications: 'Tingnan ang mga notification',
            notificationSettings: 'I-edit ang mga setting ng notification',
            deleteAccount: 'Tanggalin ang account'
        },

        'fi': {
            install: 'Asenna',
            themeToggle: 'Vaihda teemaa',
            themeVariants: { menu: 'Teematyylit', normal: 'Klassinen', fullDark: 'Syvänmusta', chalkboard: 'Chalkboard' },
            density: { label: 'Tiheys', compact: 'Tiivis', comfortable: 'Mukava', detailed: 'Yksityiskohtainen' },
            currentScripts: 'Sisällytetyt skriptit',
            emptyScripts: 'Tässä luettelossa ei ole vielä skriptejä.',
            removeScript: 'Poista tämä skripti',
            save: 'Tallenna',
            favoriteSetName: 'Suosikit',
            addToFavorites: 'Lisää suosikkeihin',
            removeFromFavorites: 'Poista suosikeista',
            addPersonalNote: 'Lisää henkilökohtainen muistiinpano',
            editPersonalNote: 'Muokkaa henkilökohtaista muistiinpanoa',
            personalNoteLabel: 'Henkilökohtainen muistiinpano',
            personalNotePlaceholder: 'Kirjoita henkilökohtainen muistiinpano tästä skriptistä...',
            personalNoteSaved: 'Tallennettu',
            deleteNote: 'Poista',
            done: 'Valmis',
            showDetails: 'Näytä lisää',
            hideDetails: 'Piilota tiedot',
            loadingDetails: 'Ladataan tietoja...',
            detailsLoadFailed: 'Tietoja ei voitu ladata.',
            noDetailedInfo: 'Lisätietoja ei ole saatavilla.',
            submitScript: 'Julkaise skripti',
            submitStyle: 'Julkaise tyyli',
            submitSet: 'Uusi skriptijoukko',
            webhookInfo: 'Määritä webhook',
            importScripts: 'Tuo skriptejä',
            editProfile: 'Muokkaa profiilia',
            editSignIn: 'Muokkaa kirjautumistapoja',
            viewNotifications: 'Näytä ilmoitukset',
            notificationSettings: 'Muokkaa ilmoitusasetuksia',
            deleteAccount: 'Poista tili'
        },

        'ckb': {
            install: 'دامەزراندن',
            themeToggle: 'گۆڕینی ڕووکار',
            themeVariants: { menu: 'شێوازەکانی ڕووکار', normal: 'کلاسیک', fullDark: 'ڕەشی قووڵ', chalkboard: 'Chalkboard' },
            density: { label: 'چڕی', compact: 'پڕ', comfortable: 'ئاسوودە', detailed: 'ورد' },
            currentScripts: 'سکریپتە لەخۆگیراوەکان',
            emptyScripts: 'هێشتا هیچ سکریپتێک لەم لیستەدا نییە.',
            removeScript: 'ئەم سکریپتە بسڕەوە',
            save: 'پاشەکەوتکردن',
            favoriteSetName: 'دڵخوازەکان',
            addToFavorites: 'زیادکردن بۆ دڵخوازەکان',
            removeFromFavorites: 'لابردن لە دڵخوازەکان',
            addPersonalNote: 'تێبینی کەسی زیاد بکە',
            editPersonalNote: 'تێبینی کەسی دەستکاری بکە',
            personalNoteLabel: 'تێبینی کەسی',
            personalNotePlaceholder: 'تێبینییەکی کەسی بۆ ئەم سکریپتە بنووسە...',
            personalNoteSaved: 'پاشەکەوت کرا',
            deleteNote: 'سڕینەوە',
            done: 'تەواو',
            showDetails: 'زیاتر پیشان بدە',
            hideDetails: 'وردەکارییەکان بشارەوە',
            loadingDetails: 'بارکردنی وردەکارییەکان...',
            detailsLoadFailed: 'بارکردنی وردەکارییەکان سەرکەوتوو نەبوو.',
            noDetailedInfo: 'هیچ وردەکارییەکی زیادە بەردەست نییە.',
            submitScript: 'سکریپت بڵاو بکەرەوە',
            submitStyle: 'شێواز بڵاو بکەرەوە',
            submitSet: 'کۆمەڵە سکریپتی نوێ',
            webhookInfo: 'Webhook ڕێک بخە',
            importScripts: 'سکریپتەکان هاوردە بکە',
            editProfile: 'پرۆفایل دەستکاری بکە',
            editSignIn: 'شێوازەکانی چوونەژوورەوە دەستکاری بکە',
            viewNotifications: 'ئاگادارکردنەوەکان ببینە',
            notificationSettings: 'ڕێکخستنەکانی ئاگادارکردنەوە دەستکاری بکە',
            deleteAccount: 'هەژمار بسڕەوە'
        },

        'ka': {
            install: 'დაყენება',
            themeToggle: 'თემის შეცვლა',
            themeVariants: { menu: 'თემის სტილები', normal: 'კლასიკური', fullDark: 'ღრმა შავი', chalkboard: 'Chalkboard' },
            density: { label: 'სიმჭიდროვე', compact: 'კომპაქტური', comfortable: 'კომფორტული', detailed: 'დეტალური' },
            currentScripts: 'ჩართული სკრიპტები',
            emptyScripts: 'ამ სიაში ჯერ სკრიპტები არ არის.',
            removeScript: 'ამ სკრიპტის წაშლა',
            save: 'შენახვა',
            favoriteSetName: 'რჩეულები',
            addToFavorites: 'რჩეულებში დამატება',
            removeFromFavorites: 'რჩეულებიდან წაშლა',
            addPersonalNote: 'პირადი შენიშვნის დამატება',
            editPersonalNote: 'პირადი შენიშვნის რედაქტირება',
            personalNoteLabel: 'პირადი შენიშვნა',
            personalNotePlaceholder: 'დაწერეთ პირადი შენიშვნა ამ სკრიპტისთვის...',
            personalNoteSaved: 'შენახულია',
            deleteNote: 'წაშლა',
            done: 'მზადაა',
            showDetails: 'მეტის ჩვენება',
            hideDetails: 'დეტალების დამალვა',
            loadingDetails: 'დეტალები იტვირთება...',
            detailsLoadFailed: 'დეტალების ჩატვირთვა ვერ მოხერხდა.',
            noDetailedInfo: 'დამატებითი დეტალები არ არის.',
            submitScript: 'სკრიპტის გამოქვეყნება',
            submitStyle: 'სტილის გამოქვეყნება',
            submitSet: 'სკრიპტების ახალი ნაკრები',
            webhookInfo: 'Webhook-ის დაყენება',
            importScripts: 'სკრიპტების იმპორტი',
            editProfile: 'პროფილის რედაქტირება',
            editSignIn: 'შესვლის მეთოდების რედაქტირება',
            viewNotifications: 'შეტყობინებების ნახვა',
            notificationSettings: 'შეტყობინებების პარამეტრების რედაქტირება',
            deleteAccount: 'ანგარიშის წაშლა'
        },

        'el': {
            install: 'Εγκατάσταση',
            themeToggle: 'Εναλλαγή θέματος',
            themeVariants: { menu: 'Στυλ θέματος', normal: 'Κλασικό', fullDark: 'Βαθύ μαύρο', chalkboard: 'Chalkboard' },
            density: { label: 'Πυκνότητα', compact: 'Συμπαγής', comfortable: 'Άνετη', detailed: 'Λεπτομερής' },
            currentScripts: 'Συμπεριλαμβανόμενα script',
            emptyScripts: 'Δεν υπάρχουν ακόμη script σε αυτή τη λίστα.',
            removeScript: 'Αφαίρεση αυτού του script',
            save: 'Αποθήκευση',
            favoriteSetName: 'Αγαπημένα',
            addToFavorites: 'Προσθήκη στα αγαπημένα',
            removeFromFavorites: 'Αφαίρεση από τα αγαπημένα',
            addPersonalNote: 'Προσθήκη προσωπικής σημείωσης',
            editPersonalNote: 'Επεξεργασία προσωπικής σημείωσης',
            personalNoteLabel: 'Προσωπική σημείωση',
            personalNotePlaceholder: 'Γράψτε μια προσωπική σημείωση για αυτό το script...',
            personalNoteSaved: 'Αποθηκεύτηκε',
            deleteNote: 'Διαγραφή',
            done: 'Τέλος',
            showDetails: 'Εμφάνιση περισσότερων',
            hideDetails: 'Απόκρυψη λεπτομερειών',
            loadingDetails: 'Φόρτωση λεπτομερειών...',
            detailsLoadFailed: 'Δεν ήταν δυνατή η φόρτωση των λεπτομερειών.',
            noDetailedInfo: 'Δεν υπάρχουν πρόσθετες λεπτομέρειες.',
            submitScript: 'Δημοσίευση script',
            submitStyle: 'Δημοσίευση στυλ',
            submitSet: 'Νέο σύνολο script',
            webhookInfo: 'Ρύθμιση webhook',
            importScripts: 'Εισαγωγή script',
            editProfile: 'Επεξεργασία προφίλ',
            editSignIn: 'Επεξεργασία μεθόδων σύνδεσης',
            viewNotifications: 'Προβολή ειδοποιήσεων',
            notificationSettings: 'Επεξεργασία ρυθμίσεων ειδοποιήσεων',
            deleteAccount: 'Διαγραφή λογαριασμού'
        },

        'he': {
            install: 'התקנה',
            themeToggle: 'החלפת ערכת נושא',
            themeVariants: { menu: 'סגנונות ערכת נושא', normal: 'קלאסי', fullDark: 'שחור עמוק', chalkboard: 'Chalkboard' },
            density: { label: 'צפיפות', compact: 'קומפקטית', comfortable: 'נוחה', detailed: 'מפורטת' },
            currentScripts: 'סקריפטים כלולים',
            emptyScripts: 'עדיין אין סקריפטים ברשימה זו.',
            removeScript: 'הסרת הסקריפט הזה',
            save: 'שמירה',
            favoriteSetName: 'מועדפים',
            addToFavorites: 'הוספה למועדפים',
            removeFromFavorites: 'הסרה מהמועדפים',
            addPersonalNote: 'הוספת הערה אישית',
            editPersonalNote: 'עריכת ההערה האישית',
            personalNoteLabel: 'הערה אישית',
            personalNotePlaceholder: 'כתיבת הערה אישית עבור סקריפט זה...',
            personalNoteSaved: 'נשמר',
            deleteNote: 'מחיקה',
            done: 'סיום',
            showDetails: 'הצגת עוד',
            hideDetails: 'הסתרת פרטים',
            loadingDetails: 'הפרטים נטענים...',
            detailsLoadFailed: 'לא ניתן לטעון את הפרטים.',
            noDetailedInfo: 'אין פרטים נוספים זמינים.',
            submitScript: 'פרסום סקריפט',
            submitStyle: 'פרסום סגנון',
            submitSet: 'ערכת סקריפטים חדשה',
            webhookInfo: 'הגדרת webhook',
            importScripts: 'ייבוא סקריפטים',
            editProfile: 'עריכת פרופיל',
            editSignIn: 'עריכת שיטות התחברות',
            viewNotifications: 'הצגת התראות',
            notificationSettings: 'עריכת הגדרות התראות',
            deleteAccount: 'מחיקת חשבון'
        },

        'hu': {
            install: 'Telepítés',
            themeToggle: 'Téma váltása',
            themeVariants: { menu: 'Témastílusok', normal: 'Klasszikus', fullDark: 'Mélyfekete', chalkboard: 'Chalkboard' },
            density: { label: 'Sűrűség', compact: 'Kompakt', comfortable: 'Kényelmes', detailed: 'Részletes' },
            currentScripts: 'Tartalmazott szkriptek',
            emptyScripts: 'Még nincs szkript ebben a listában.',
            removeScript: 'Szkript eltávolítása',
            save: 'Mentés',
            favoriteSetName: 'Kedvencek',
            addToFavorites: 'Hozzáadás a kedvencekhez',
            removeFromFavorites: 'Eltávolítás a kedvencek közül',
            addPersonalNote: 'Személyes jegyzet hozzáadása',
            editPersonalNote: 'Személyes jegyzet szerkesztése',
            personalNoteLabel: 'Személyes jegyzet',
            personalNotePlaceholder: 'Írjon személyes jegyzetet ehhez a szkripthez...',
            personalNoteSaved: 'Mentve',
            deleteNote: 'Törlés',
            done: 'Kész',
            showDetails: 'Továbbiak megjelenítése',
            hideDetails: 'Részletek elrejtése',
            loadingDetails: 'Részletek betöltése...',
            detailsLoadFailed: 'A részletek nem tölthetők be.',
            noDetailedInfo: 'Nincsenek további részletek.',
            submitScript: 'Szkript közzététele',
            submitStyle: 'Stílus közzététele',
            submitSet: 'Új szkriptkészlet',
            webhookInfo: 'Webhook beállítása',
            importScripts: 'Szkriptek importálása',
            editProfile: 'Profil szerkesztése',
            editSignIn: 'Bejelentkezési módok szerkesztése',
            viewNotifications: 'Értesítések megtekintése',
            notificationSettings: 'Értesítési beállítások szerkesztése',
            deleteAccount: 'Fiók törlése'
        },

        'mr': {
            install: 'स्थापित करा',
            themeToggle: 'थीम बदला',
            themeVariants: { menu: 'थीम शैली', normal: 'क्लासिक', fullDark: 'गडद काळा', chalkboard: 'Chalkboard' },
            density: { label: 'घनता', compact: 'संक्षिप्त', comfortable: 'आरामदायी', detailed: 'तपशीलवार' },
            currentScripts: 'समाविष्ट स्क्रिप्ट',
            emptyScripts: 'या यादीत अजून कोणतीही स्क्रिप्ट नाही.',
            removeScript: 'ही स्क्रिप्ट काढा',
            save: 'जतन करा',
            favoriteSetName: 'आवडी',
            addToFavorites: 'आवडींमध्ये जोडा',
            removeFromFavorites: 'आवडींमधून काढा',
            addPersonalNote: 'वैयक्तिक नोंद जोडा',
            editPersonalNote: 'वैयक्तिक नोंद संपादित करा',
            personalNoteLabel: 'वैयक्तिक नोंद',
            personalNotePlaceholder: 'या स्क्रिप्टसाठी वैयक्तिक नोंद लिहा...',
            personalNoteSaved: 'जतन केले',
            deleteNote: 'हटवा',
            done: 'पूर्ण',
            showDetails: 'अधिक दाखवा',
            hideDetails: 'तपशील लपवा',
            loadingDetails: 'तपशील लोड होत आहेत...',
            detailsLoadFailed: 'तपशील लोड करता आले नाहीत.',
            noDetailedInfo: 'अतिरिक्त तपशील उपलब्ध नाहीत.',
            submitScript: 'स्क्रिप्ट प्रकाशित करा',
            submitStyle: 'शैली प्रकाशित करा',
            submitSet: 'नवीन स्क्रिप्ट संच',
            webhookInfo: 'Webhook सेट करा',
            importScripts: 'स्क्रिप्ट आयात करा',
            editProfile: 'प्रोफाइल संपादित करा',
            editSignIn: 'साइन-इन पद्धती संपादित करा',
            viewNotifications: 'सूचना पहा',
            notificationSettings: 'सूचना सेटिंग्ज संपादित करा',
            deleteAccount: 'खाते हटवा'
        },

        'sr': {
            install: 'Instaliraj',
            themeToggle: 'Promeni temu',
            themeVariants: { menu: 'Stilovi teme', normal: 'Klasična', fullDark: 'Duboka crna', chalkboard: 'Chalkboard' },
            density: { label: 'Gustina', compact: 'Kompaktno', comfortable: 'Udobno', detailed: 'Detaljno' },
            currentScripts: 'Uključene skripte',
            emptyScripts: 'Na ovoj listi još nema skripti.',
            removeScript: 'Ukloni ovu skriptu',
            save: 'Sačuvaj',
            favoriteSetName: 'Omiljeno',
            addToFavorites: 'Dodaj u omiljeno',
            removeFromFavorites: 'Ukloni iz omiljenog',
            addPersonalNote: 'Dodaj ličnu belešku',
            editPersonalNote: 'Uredi ličnu belešku',
            personalNoteLabel: 'Lična beleška',
            personalNotePlaceholder: 'Napišite ličnu belešku za ovu skriptu...',
            personalNoteSaved: 'Sačuvano',
            deleteNote: 'Obriši',
            done: 'Gotovo',
            showDetails: 'Prikaži više',
            hideDetails: 'Sakrij detalje',
            loadingDetails: 'Učitavanje detalja...',
            detailsLoadFailed: 'Detalji nisu mogli da se učitaju.',
            noDetailedInfo: 'Nema dodatnih detalja.',
            submitScript: 'Objavi skriptu',
            submitStyle: 'Objavi stil',
            submitSet: 'Novi skup skripti',
            webhookInfo: 'Podesi webhook',
            importScripts: 'Uvezi skripte',
            editProfile: 'Uredi profil',
            editSignIn: 'Uredi načine prijave',
            viewNotifications: 'Prikaži obaveštenja',
            notificationSettings: 'Uredi podešavanja obaveštenja',
            deleteAccount: 'Obriši nalog'
        },

        'sk': {
            install: 'Nainštalovať',
            themeToggle: 'Prepnúť tému',
            themeVariants: { menu: 'Štýly témy', normal: 'Klasický', fullDark: 'Hlboká čierna', chalkboard: 'Chalkboard' },
            density: { label: 'Hustota', compact: 'Kompaktná', comfortable: 'Pohodlná', detailed: 'Podrobná' },
            currentScripts: 'Zahrnuté skripty',
            emptyScripts: 'V tomto zozname zatiaľ nie sú žiadne skripty.',
            removeScript: 'Odstrániť tento skript',
            save: 'Uložiť',
            favoriteSetName: 'Obľúbené',
            addToFavorites: 'Pridať medzi obľúbené',
            removeFromFavorites: 'Odstrániť z obľúbených',
            addPersonalNote: 'Pridať osobnú poznámku',
            editPersonalNote: 'Upraviť osobnú poznámku',
            personalNoteLabel: 'Osobná poznámka',
            personalNotePlaceholder: 'Napíšte osobnú poznámku k tomuto skriptu...',
            personalNoteSaved: 'Uložené',
            deleteNote: 'Odstrániť',
            done: 'Hotovo',
            showDetails: 'Zobraziť viac',
            hideDetails: 'Skryť podrobnosti',
            loadingDetails: 'Načítavajú sa podrobnosti...',
            detailsLoadFailed: 'Podrobnosti sa nepodarilo načítať.',
            noDetailedInfo: 'Nie sú dostupné žiadne ďalšie podrobnosti.',
            submitScript: 'Publikovať skript',
            submitStyle: 'Publikovať štýl',
            submitSet: 'Nová sada skriptov',
            webhookInfo: 'Nastaviť webhook',
            importScripts: 'Importovať skripty',
            editProfile: 'Upraviť profil',
            editSignIn: 'Upraviť spôsoby prihlásenia',
            viewNotifications: 'Zobraziť upozornenia',
            notificationSettings: 'Upraviť nastavenia upozornení',
            deleteAccount: 'Odstrániť účet'
        },

        'ug': {
            install: 'قاچىلاش',
            themeToggle: 'تېمىنى ئالماشتۇرۇش',
            themeVariants: { menu: 'تېما ئۇسلۇبلىرى', normal: 'كلاسسىك', fullDark: 'قېنىق قارا', chalkboard: 'Chalkboard' },
            density: { label: 'زىچلىق', compact: 'ئىخچام', comfortable: 'راھەت', detailed: 'تەپسىلىي' },
            currentScripts: 'قوشۇلغان سىكرىپتلار',
            emptyScripts: 'بۇ تىزىملىكتە تېخى سىكرىپت يوق.',
            removeScript: 'بۇ سىكرىپتنى چىقىرىۋېتىش',
            save: 'ساقلاش',
            favoriteSetName: 'ياقتۇرغانلار',
            addToFavorites: 'ياقتۇرغانلارغا قوشۇش',
            removeFromFavorites: 'ياقتۇرغانلاردىن چىقىرىش',
            addPersonalNote: 'شەخسىي ئىزاھ قوشۇش',
            editPersonalNote: 'شەخسىي ئىزاھنى تەھرىرلەش',
            personalNoteLabel: 'شەخسىي ئىزاھ',
            personalNotePlaceholder: 'بۇ سىكرىپت ئۈچۈن شەخسىي ئىزاھ يېزىڭ...',
            personalNoteSaved: 'ساقلاندى',
            deleteNote: 'ئۆچۈرۈش',
            done: 'تامام',
            showDetails: 'تېخىمۇ كۆپ كۆرسىتىش',
            hideDetails: 'تەپسىلاتلارنى يوشۇرۇش',
            loadingDetails: 'تەپسىلاتلار يۈكلىنىۋاتىدۇ...',
            detailsLoadFailed: 'تەپسىلاتلارنى يۈكلىگىلى بولمىدى.',
            noDetailedInfo: 'قوشۇمچە تەپسىلات يوق.',
            submitScript: 'سىكرىپت ئېلان قىلىش',
            submitStyle: 'ئۇسلۇب ئېلان قىلىش',
            submitSet: 'يېڭى سىكرىپت توپلىمى',
            webhookInfo: 'Webhook تەڭشەش',
            importScripts: 'سىكرىپتلارنى ئەكىرىش',
            editProfile: 'ئارخىپنى تەھرىرلەش',
            editSignIn: 'كىرىش ئۇسۇللىرىنى تەھرىرلەش',
            viewNotifications: 'ئۇقتۇرۇشلارنى كۆرۈش',
            notificationSettings: 'ئۇقتۇرۇش تەڭشەكلىرىنى تەھرىرلەش',
            deleteAccount: 'ھېساباتنى ئۆچۈرۈش'
        },

        'uk': {
            install: 'Встановити',
            themeToggle: 'Перемкнути тему',
            themeVariants: { menu: 'Стилі теми', normal: 'Класична', fullDark: 'Глибокий чорний', chalkboard: 'Chalkboard' },
            density: { label: 'Щільність', compact: 'Компактна', comfortable: 'Зручна', detailed: 'Докладна' },
            currentScripts: 'Включені скрипти',
            emptyScripts: 'У цьому списку ще немає скриптів.',
            removeScript: 'Видалити цей скрипт',
            save: 'Зберегти',
            favoriteSetName: 'Обране',
            addToFavorites: 'Додати до обраного',
            removeFromFavorites: 'Видалити з обраного',
            addPersonalNote: 'Додати особисту нотатку',
            editPersonalNote: 'Редагувати особисту нотатку',
            personalNoteLabel: 'Особиста нотатка',
            personalNotePlaceholder: 'Напишіть особисту нотатку для цього скрипта...',
            personalNoteSaved: 'Збережено',
            deleteNote: 'Видалити',
            done: 'Готово',
            showDetails: 'Показати більше',
            hideDetails: 'Сховати подробиці',
            loadingDetails: 'Завантаження подробиць...',
            detailsLoadFailed: 'Не вдалося завантажити подробиці.',
            noDetailedInfo: 'Додаткові подробиці відсутні.',
            submitScript: 'Опублікувати скрипт',
            submitStyle: 'Опублікувати стиль',
            submitSet: 'Новий набір скриптів',
            webhookInfo: 'Налаштувати webhook',
            importScripts: 'Імпортувати скрипти',
            editProfile: 'Редагувати профіль',
            editSignIn: 'Редагувати способи входу',
            viewNotifications: 'Переглянути сповіщення',
            notificationSettings: 'Редагувати налаштування сповіщень',
            deleteAccount: 'Видалити обліковий запис'
        },

        'th': {
            install: 'ติดตั้ง',
            themeToggle: 'สลับธีม',
            themeVariants: { menu: 'รูปแบบธีม', normal: 'คลาสสิก', fullDark: 'ดำสนิท', chalkboard: 'Chalkboard' },
            density: { label: 'ความหนาแน่น', compact: 'กะทัดรัด', comfortable: 'สบาย', detailed: 'ละเอียด' },
            currentScripts: 'สคริปต์ที่รวมอยู่',
            emptyScripts: 'ยังไม่มีสคริปต์ในรายการนี้',
            removeScript: 'ลบสคริปต์นี้',
            save: 'บันทึก',
            favoriteSetName: 'รายการโปรด',
            addToFavorites: 'เพิ่มในรายการโปรด',
            removeFromFavorites: 'ลบออกจากรายการโปรด',
            addPersonalNote: 'เพิ่มบันทึกส่วนตัว',
            editPersonalNote: 'แก้ไขบันทึกส่วนตัว',
            personalNoteLabel: 'บันทึกส่วนตัว',
            personalNotePlaceholder: 'เขียนบันทึกส่วนตัวสำหรับสคริปต์นี้...',
            personalNoteSaved: 'บันทึกแล้ว',
            deleteNote: 'ลบ',
            done: 'เสร็จสิ้น',
            showDetails: 'ดูเพิ่มเติม',
            hideDetails: 'ย่อรายละเอียด',
            loadingDetails: 'กำลังโหลดรายละเอียด...',
            detailsLoadFailed: 'ไม่สามารถโหลดรายละเอียดได้',
            noDetailedInfo: 'ไม่มีรายละเอียดเพิ่มเติม',
            submitScript: 'เผยแพร่สคริปต์',
            submitStyle: 'เผยแพร่สไตล์',
            submitSet: 'ชุดสคริปต์ใหม่',
            webhookInfo: 'ตั้งค่า Webhook',
            importScripts: 'นำเข้าสคริปต์',
            editProfile: 'แก้ไขโปรไฟล์',
            editSignIn: 'แก้ไขวิธีเข้าสู่ระบบ',
            viewNotifications: 'ดูการแจ้งเตือน',
            notificationSettings: 'แก้ไขการตั้งค่าการแจ้งเตือน',
            deleteAccount: 'ลบบัญชี'
        }
    };

    USER_NAV_I18N['fr-CA'] = { ...USER_NAV_I18N.fr };
    USER_NAV_I18N['pt-BR'] = { ...USER_NAV_I18N.pt };
    USER_NAV_I18N['es-419'] = { ...USER_NAV_I18N.es };

    const getUserNavI18n = (locale) => {
        const exactLocale = USER_NAV_I18N[locale] || {};
        const primaryLocale = USER_NAV_I18N[String(locale || '').split('-')[0]] || {};
        return {
            ...USER_NAV_I18N.en,
            ...primaryLocale,
            ...exactLocale
        };
    };

    const normalizeFavoriteSetName = (value) => String(value || '').trim().toLocaleLowerCase();
    const isFavoriteSetName = (value) => {
        const normalizedValue = normalizeFavoriteSetName(value);
        if (!normalizedValue) {
            return false;
        }

        return FAVORITE_SET_NAME_PATTERN.test(normalizedValue)
            || Object.values(USER_NAV_I18N).some((i18n) => {
                const favoriteSetName = normalizeFavoriteSetName(i18n.favoriteSetName);
                return favoriteSetName && (normalizedValue === favoriteSetName || normalizedValue.includes(favoriteSetName));
            });
    };

    const FAVORITES_NAV_SHORTCUT_ATTR = 'data-gfplus-favorites-shortcut';
    const initFavoritesNavShortcut = () => {
        if (!extractCurrentUserProfilePath()) {
            return false;
        }

        const targets = [
            {
                menu: document.querySelector('#site-nav > nav > li.with-submenu > nav'),
                className: 'gf-favorites-nav-shortcut',
                insert: (menu, item) => menu.prepend(item)
            },
            {
                menu: document.getElementById('gf-mobile-secondary-nav'),
                className: 'gf-favorites-nav-shortcut gf-mobile-favorites-nav-shortcut',
                insert: (menu, item) => {
                    const divider = menu.querySelector(':scope > .gf-mobile-secondary-divider');
                    divider ? divider.after(item) : menu.prepend(item);
                }
            }
        ].filter(({ menu }) => menu && !menu.hasAttribute(FAVORITES_NAV_SHORTCUT_ATTR));

        if (!targets.length) {
            return true;
        }

        targets.forEach(({ menu }) => menu.setAttribute(FAVORITES_NAV_SHORTCUT_ATTR, 'loading'));
        void resolveFavoriteSetUrl()
            .then((favoriteSetUrl) => {
                const profileLocale = extractCurrentUserProfilePath()?.match(/^\/([^/]+)\//)?.[1];
                const locale = profileLocale || getCurrentLocale();
                targets.forEach(({ menu, className, insert }) => {
                    if (!favoriteSetUrl || !menu.isConnected) {
                        menu.setAttribute(FAVORITES_NAV_SHORTCUT_ATTR, 'unavailable');
                        return;
                    }

                    const shortcutItem = document.createElement('li');
                    shortcutItem.className = className;

                    const shortcutLink = document.createElement('a');
                    shortcutLink.href = favoriteSetUrl;
                    shortcutLink.textContent = getUserNavI18n(locale).favoriteSetName;

                    shortcutItem.appendChild(shortcutLink);
                    insert(menu, shortcutItem);
                    menu.setAttribute(FAVORITES_NAV_SHORTCUT_ATTR, 'ready');
                });
            })
            .catch(() => {
                targets.forEach(({ menu }) => menu.setAttribute(FAVORITES_NAV_SHORTCUT_ATTR, 'unavailable'));
            });

        return true;
    };

    const USER_NAV_ICONS = {
        edit: `
            <svg viewBox="0 0 24 24" aria-hidden="true">
                <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path>
                <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path>
            </svg>
        `,
        settings: `
            <svg viewBox="0 0 512 512" fill="currentColor" aria-hidden="true">
                <path d="M217.6,499.2v-55.279c-23.97-4.89-46.908-14.387-67.328-27.887l-39.091,39.083l-54.298-54.298
                    l39.083-39.091c-13.5-20.429-22.997-43.366-27.887-67.328H12.8v-76.8h55.279
                    c4.89-23.97,14.387-46.908,27.887-67.328l-39.083-39.091l54.298-54.306
                    l39.091,39.091c20.42-13.5,43.358-22.997,67.328-27.887V12.8h76.8v55.279
                    c23.97,4.89,46.908,14.387,67.328,27.887l39.091-39.091l54.298,54.306
                    l-39.083,39.091c13.5,20.429,22.997,43.366,27.887,67.328H499.2v76.8h-55.279
                    c-4.89,23.97-14.387,46.908-27.887,67.328l39.083,39.091l-54.298,54.298
                    l-39.091-39.083c-20.429,13.5-43.366,22.997-67.328,27.887V499.2H217.6z
                    M256,140.8c-63.522,0-115.2,51.678-115.2,115.2S192.478,371.2,256,371.2
                    S371.2,319.522,371.2,256S319.522,140.8,256,140.8z"/>
            </svg>
        `,
        signOut: `
            <svg viewBox="0 0 24 24" aria-hidden="true">
                <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path>
                <polyline points="16 17 21 12 16 7"></polyline>
                <line x1="21" y1="12" x2="9" y2="12"></line>
            </svg>
        `
    };

    const parseUserProfileHref = (href) => {
        const match = String(href || '').match(/\/([a-z]{2,3}(?:-(?:[A-Z]{2}|[0-9]{3}))?)\/users\/(\d+)-/);
        return match ? { locale: match[1], userId: match[2] } : null;
    };

    const buildUserPanelHtml = (type, locale, userId, i18n) => type === 'edit'
        ? `
            <a href="/${locale}/script_versions/new">${i18n.submitScript}</a>
            <a href="/${locale}/script_versions/new?language=css">${i18n.submitStyle}</a>
            <div class="gf-user-panel-separator"></div>
            <a href="/${locale}/users/${userId}/sets/new">${i18n.submitSet}</a>
            <a href="/${locale}/users/webhook-info">${i18n.webhookInfo}</a>
            <div class="gf-user-panel-separator"></div>
            <a href="/${locale}/import">${i18n.importScripts}</a>
        `
        : `
            <a href="/${locale}/users/edit">${i18n.editProfile}</a>
            <a href="/${locale}/users/edit_sign_in">${i18n.editSignIn}</a>
            <div class="gf-user-panel-separator"></div>
            <a href="/${locale}/users/${userId}/notifications">${i18n.viewNotifications}</a>
            <a href="/${locale}/users/${userId}/notification_settings">${i18n.notificationSettings}</a>
            <div class="gf-user-panel-separator"></div>
            <a href="/${locale}/users/edit_account_deletion">${i18n.deleteAccount}</a>
        `;

    const createUserPanelControl = (type, locale, userId, i18n, mobile = false) => {
        const icon = document.createElement('span');
        icon.className = type === 'settings'
            ? 'gf-user-icon gf-user-icon--settings gf-user-icon--settings--hover'
            : `gf-user-icon${mobile ? ' gf-mobile-edit-icon' : ''}`;
        icon.setAttribute('data-panel', type);
        icon.innerHTML = USER_NAV_ICONS[type];

        const panel = document.createElement('div');
        panel.className = `gf-user-panel${mobile ? ' gf-mobile-user-panel' : ''}`;
        panel.setAttribute('data-panel-type', type);
        panel.innerHTML = buildUserPanelHtml(type, locale, userId, i18n);

        if (!mobile) {
            icon.appendChild(panel);
        }

        return { icon, panel };
    };

    const createSignOutControl = (source, mobile = false) => {
        const link = document.createElement('a');
        link.className = `gf-user-icon${mobile ? ' gf-mobile-sign-out-icon' : ''}`;
        link.href = source.href;
        link.rel = source.rel || 'nofollow';
        if (source.method) {
            link.setAttribute('data-method', source.method);
        }
        link.innerHTML = USER_NAV_ICONS.signOut;
        return link;
    };

    const bindUserPanelControls = (controls) => {
        let activeControl = null;

        const closePanels = () => {
            controls.forEach(({ icon, panel }) => {
                icon.classList.remove('active');
                panel.classList.remove('active');
            });
            activeControl = null;
        };

        controls.forEach((control) => {
            control.icon.addEventListener('click', (event) => {
                event.stopPropagation();
                const shouldOpen = !control.panel.classList.contains('active');
                closePanels();
                if (shouldOpen) {
                    control.icon.classList.add('active');
                    control.panel.classList.add('active');
                    activeControl = control;
                }
            });
        });

        document.addEventListener('click', (event) => {
            if (activeControl && !controls.some(({ icon, panel }) => icon.contains(event.target) || panel.contains(event.target))) {
                closePanels();
            }
        });

        document.addEventListener('keydown', (event) => {
            if (event.key === 'Escape' && activeControl) {
                closePanels();
            }
        });
    };


    const initUserNavigation = () => {
        const navUserInfo = document.getElementById('nav-user-info');
        if (!navUserInfo) {
            return false;
        }

        if (navUserInfo.querySelector('.gf-user-nav-icons')) {
            return true;
        }

        const profileLink = navUserInfo.querySelector('.user-profile-link a');
        if (!profileLink) {
            return false;
        }

        const userIdentity = parseUserProfileHref(profileLink.getAttribute('href'));
        if (!userIdentity) {
            return false;
        }

        const { locale, userId } = userIdentity;
        const i18n = getUserNavI18n(locale);

        const signOutLink = navUserInfo.querySelector('.sign-out-link');
        if (signOutLink) {
            signOutLink.remove();
        }

        const iconsContainer = document.createElement('span');
        iconsContainer.className = 'gf-user-nav-icons';

        const editControl = createUserPanelControl('edit', locale, userId, i18n);
        const settingsControl = createUserPanelControl('settings', locale, userId, i18n);
        const signOutControl = createSignOutControl({
            href: `/${locale}/users/sign_out`,
            rel: 'nofollow',
            method: 'delete'
        });
        iconsContainer.append(editControl.icon, settingsControl.icon, signOutControl);

        const profileLinkSpan = navUserInfo.querySelector('.user-profile-link');
        if (profileLinkSpan.nextSibling) {
            navUserInfo.insertBefore(iconsContainer, profileLinkSpan.nextSibling);
        } else {
            navUserInfo.appendChild(iconsContainer);
        }

        bindUserPanelControls([editControl, settingsControl]);

        return true;
    };

    const initMobileUserNavigation = () => {
        const mobileUserItem = document.querySelector('#mobile-nav li.multi-link-nav');
        if (!mobileUserItem) {
            return false;
        }

        if (mobileUserItem.querySelector('#gf-mobile-user-actions')) {
            return true;
        }

        const profileLinkSpan = mobileUserItem.querySelector('.user-profile-link');
        const profileLink = profileLinkSpan?.querySelector('a');
        const signOutContainer = mobileUserItem.querySelector('.sign-out-link');
        if (!profileLink || !signOutContainer) {
            return false;
        }

        const userIdentity = parseUserProfileHref(profileLink.getAttribute('href'));
        if (!userIdentity) {
            return false;
        }

        const { locale, userId } = userIdentity;
        const i18n = getUserNavI18n(locale);
        const signOutAnchor = signOutContainer.querySelector('a');
        if (!signOutAnchor) {
            return false;
        }

        const userRow = document.createElement('div');
        userRow.id = 'gf-mobile-user-row';

        const actions = document.createElement('span');
        actions.id = 'gf-mobile-user-actions';

        const editControl = createUserPanelControl('edit', locale, userId, i18n, true);
        const settingsControl = createUserPanelControl('settings', locale, userId, i18n, true);
        const signOutControl = createSignOutControl({
            href: signOutAnchor.href,
            rel: signOutAnchor.getAttribute('rel'),
            method: signOutAnchor.getAttribute('data-method')
        }, true);
        actions.append(editControl.icon, settingsControl.icon, signOutControl);

        const userMeta = document.createElement('div');
        userMeta.id = 'gf-mobile-user-meta';
        userMeta.appendChild(profileLinkSpan);

        const mobileThemeSwitch = document.getElementById('gf-mobile-theme-switch');
        const mobileThemeSwitchItem = document.getElementById('gf-mobile-theme-switch-item');
        if (mobileThemeSwitch) {
            mobileThemeSwitch.style.marginTop = '0';
            mobileThemeSwitch.style.marginRight = '0';
            mobileThemeSwitch.style.marginLeft = '0';
            userMeta.appendChild(mobileThemeSwitch);
        }

        if (mobileThemeSwitchItem) {
            mobileThemeSwitchItem.remove();
        }

        userRow.appendChild(userMeta);
        userRow.appendChild(actions);

        signOutContainer.remove();
        mobileUserItem.prepend(userRow);
        mobileUserItem.append(editControl.panel, settingsControl.panel);
        bindUserPanelControls([editControl, settingsControl]);

        return true;
    };

    // ============================================================================
    // Lightbox And Image Zoom
    // ============================================================================
    const STANDALONE_LIGHTBOX_IMAGE_ATTR = 'data-gfplus-standalone-lightbox';
    let lightboxScrollLockObserver = null;
    let lightboxScrollPreventInitialized = false;
    let standaloneLightboxObserver = null;
    let lightboxZoomImage = null;
    let lightboxZoomImageSource = '';
    let lightboxZoomState = {
        scale: 1,
        x: 0,
        y: 0
    };
    let lightboxDragState = null;
    let lightboxPinchState = null;

    const clampLightboxZoomValue = (value, min, max) => Math.max(min, Math.min(max, value));

    const constrainLightboxPan = () => {
        if (!lightboxZoomImage || lightboxZoomState.scale <= 1) {
            lightboxZoomState.x = 0;
            lightboxZoomState.y = 0;
            return;
        }

        const maxX = (lightboxZoomImage.clientWidth * (lightboxZoomState.scale - 1)) / 2;
        const maxY = (lightboxZoomImage.clientHeight * (lightboxZoomState.scale - 1)) / 2;
        lightboxZoomState.x = clampLightboxZoomValue(lightboxZoomState.x, -maxX, maxX);
        lightboxZoomState.y = clampLightboxZoomValue(lightboxZoomState.y, -maxY, maxY);
    };

    const applyLightboxImageZoom = () => {
        if (!lightboxZoomImage) {
            return;
        }

        constrainLightboxPan();
        const zoomed = lightboxZoomState.scale > 1.01;
        lightboxZoomImage.classList.toggle('gfplus-lightbox-zoomed', zoomed);
        lightboxZoomImage.style.transform = zoomed
            ? `translate3d(${lightboxZoomState.x}px, ${lightboxZoomState.y}px, 0) scale(${lightboxZoomState.scale})`
            : '';
    };

    const resetLightboxImageZoom = () => {
        if (!lightboxZoomImage) {
            return;
        }

        lightboxZoomState = { scale: 1, x: 0, y: 0 };
        lightboxDragState = null;
        lightboxPinchState = null;
        lightboxZoomImage.classList.remove('gfplus-lightbox-zoomed', 'gfplus-lightbox-dragging');
        lightboxZoomImage.style.transform = '';
    };

    const setLightboxImageZoom = (scale, focalPoint = null) => {
        const previousScale = lightboxZoomState.scale;
        const nextScale = clampLightboxZoomValue(scale, 1, 4);

        if (lightboxZoomImage && focalPoint && previousScale > 0) {
            const rect = lightboxZoomImage.getBoundingClientRect();
            const imageCenterX = rect.left + rect.width / 2;
            const imageCenterY = rect.top + rect.height / 2;
            const scaleRatio = nextScale / previousScale;
            lightboxZoomState.x += (focalPoint.x - imageCenterX) * (1 - scaleRatio);
            lightboxZoomState.y += (focalPoint.y - imageCenterY) * (1 - scaleRatio);
        }

        lightboxZoomState.scale = nextScale;
        if (lightboxZoomState.scale <= 1.01) {
            lightboxZoomState = { scale: 1, x: 0, y: 0 };
        }
        applyLightboxImageZoom();
    };

    const getTouchDistance = (touches) => {
        const dx = touches[0].clientX - touches[1].clientX;
        const dy = touches[0].clientY - touches[1].clientY;
        return Math.hypot(dx, dy);
    };

    const getTouchCenter = (touches) => ({
        x: (touches[0].clientX + touches[1].clientX) / 2,
        y: (touches[0].clientY + touches[1].clientY) / 2
    });

    const handleLightboxImageWheel = (event) => {
        if (!root.classList.contains(LIGHTBOX_SCROLL_LOCK_CLASS)) {
            return;
        }

        event.preventDefault();
        event.stopPropagation();
        const factor = event.deltaY < 0 ? 1.14 : 0.88;
        setLightboxImageZoom(lightboxZoomState.scale * factor, {
            x: event.clientX,
            y: event.clientY
        });
    };

    const handleLightboxImageDoubleClick = (event) => {
        event.preventDefault();
        event.stopPropagation();
        setLightboxImageZoom(lightboxZoomState.scale > 1.01 ? 1 : 2.4, {
            x: event.clientX,
            y: event.clientY
        });
    };

    const stopLightboxImageClickClose = (event) => {
        event.stopPropagation();
    };

    const handleLightboxImagePointerDown = (event) => {
        if (event.pointerType === 'touch' || lightboxZoomState.scale <= 1.01) {
            return;
        }

        event.preventDefault();
        lightboxDragState = {
            pointerId: event.pointerId,
            startX: event.clientX,
            startY: event.clientY,
            x: lightboxZoomState.x,
            y: lightboxZoomState.y
        };
        lightboxZoomImage?.classList.add('gfplus-lightbox-dragging');
        lightboxZoomImage?.setPointerCapture?.(event.pointerId);
    };

    const handleLightboxImagePointerMove = (event) => {
        if (!lightboxDragState || lightboxDragState.pointerId !== event.pointerId) {
            return;
        }

        event.preventDefault();
        lightboxZoomState.x = lightboxDragState.x + event.clientX - lightboxDragState.startX;
        lightboxZoomState.y = lightboxDragState.y + event.clientY - lightboxDragState.startY;
        applyLightboxImageZoom();
    };

    const endLightboxImagePointerDrag = (event) => {
        if (!lightboxDragState || lightboxDragState.pointerId !== event.pointerId) {
            return;
        }

        lightboxZoomImage?.releasePointerCapture?.(event.pointerId);
        lightboxZoomImage?.classList.remove('gfplus-lightbox-dragging');
        lightboxDragState = null;
    };

    const handleLightboxImageTouchStart = (event) => {
        if (event.touches.length === 2) {
            lightboxPinchState = {
                distance: getTouchDistance(event.touches),
                scale: lightboxZoomState.scale
            };
            return;
        }

        if (event.touches.length === 1 && lightboxZoomState.scale > 1.01) {
            lightboxDragState = {
                startX: event.touches[0].clientX,
                startY: event.touches[0].clientY,
                x: lightboxZoomState.x,
                y: lightboxZoomState.y
            };
        }
    };

    const handleLightboxImageTouchMove = (event) => {
        if (event.touches.length === 2 && lightboxPinchState) {
            event.preventDefault();
            event.stopPropagation();
            const nextScale = lightboxPinchState.scale * (getTouchDistance(event.touches) / lightboxPinchState.distance);
            setLightboxImageZoom(nextScale, getTouchCenter(event.touches));
            return;
        }

        if (event.touches.length === 1 && lightboxDragState && lightboxZoomState.scale > 1.01) {
            event.preventDefault();
            event.stopPropagation();
            lightboxZoomState.x = lightboxDragState.x + event.touches[0].clientX - lightboxDragState.startX;
            lightboxZoomState.y = lightboxDragState.y + event.touches[0].clientY - lightboxDragState.startY;
            applyLightboxImageZoom();
        }
    };

    const handleLightboxImageTouchEnd = () => {
        lightboxDragState = null;
        lightboxPinchState = null;
        lightboxZoomImage?.classList.remove('gfplus-lightbox-dragging');
    };

    const bindLightboxImageZoom = () => {
        const openLightbox = document.querySelector('.lum-lightbox.lum-open');
        const image = openLightbox?.querySelector('.lum-img, .lum-lightbox-inner img, img');
        const imageSource = image?.currentSrc || image?.src || '';
        if (!image) {
            return;
        }

        if (image === lightboxZoomImage && imageSource === lightboxZoomImageSource) {
            return;
        }

        resetLightboxImageZoom();
        lightboxZoomImage = image;
        lightboxZoomImageSource = imageSource;
        lightboxZoomImage.classList.add('gfplus-lightbox-zoomable');
        if (lightboxZoomImage.dataset.gfplusZoomBound !== 'true') {
            lightboxZoomImage.dataset.gfplusZoomBound = 'true';
            lightboxZoomImage.addEventListener('click', stopLightboxImageClickClose);
            lightboxZoomImage.addEventListener('wheel', handleLightboxImageWheel, { passive: false });
            lightboxZoomImage.addEventListener('dblclick', handleLightboxImageDoubleClick);
            lightboxZoomImage.addEventListener('pointerdown', handleLightboxImagePointerDown);
            lightboxZoomImage.addEventListener('pointermove', handleLightboxImagePointerMove);
            lightboxZoomImage.addEventListener('pointerup', endLightboxImagePointerDrag);
            lightboxZoomImage.addEventListener('pointercancel', endLightboxImagePointerDrag);
            lightboxZoomImage.addEventListener('touchstart', handleLightboxImageTouchStart, { passive: false });
            lightboxZoomImage.addEventListener('touchmove', handleLightboxImageTouchMove, { passive: false });
            lightboxZoomImage.addEventListener('touchend', handleLightboxImageTouchEnd);
            lightboxZoomImage.addEventListener('touchcancel', handleLightboxImageTouchEnd);
        }
    };

    const updateLightboxScrollLock = () => {
        const lightboxOpen = Boolean(document.querySelector('.lum-lightbox.lum-open'));
        root.classList.toggle(LIGHTBOX_SCROLL_LOCK_CLASS, lightboxOpen);
        if (lightboxOpen) {
            bindLightboxImageZoom();
        } else {
            resetLightboxImageZoom();
            lightboxZoomImage = null;
            lightboxZoomImageSource = '';
        }
    };

    const preventLightboxBackgroundScroll = (event) => {
        if (root.classList.contains(LIGHTBOX_SCROLL_LOCK_CLASS)) {
            event.preventDefault();
        }
    };

    const initLightboxScrollLock = () => {
        updateLightboxScrollLock();

        if (!lightboxScrollPreventInitialized) {
            document.addEventListener('wheel', preventLightboxBackgroundScroll, { passive: false, capture: true });
            document.addEventListener('touchmove', preventLightboxBackgroundScroll, { passive: false, capture: true });
            lightboxScrollPreventInitialized = true;
        }

        if (lightboxScrollLockObserver || !document.body) {
            return;
        }

        lightboxScrollLockObserver = new MutationObserver(updateLightboxScrollLock);
        lightboxScrollLockObserver.observe(document.body, {
            attributes: true,
            attributeFilter: ['class'],
            childList: true,
            subtree: true
        });
    };

    const closeStandaloneImageLightbox = (lightbox) => {
        resetLightboxImageZoom();
        lightbox?.__gfplusEscapeHandler && document.removeEventListener('keydown', lightbox.__gfplusEscapeHandler);
        lightbox?.remove();
        updateLightboxScrollLock();
    };

    const openStandaloneImageLightbox = (sourceImage) => {
        const source = sourceImage.currentSrc || sourceImage.src;
        if (!source) {
            return;
        }

        const lightbox = document.createElement('div');
        lightbox.className = 'lum-lightbox lum-open gfplus-standalone-lightbox';
        lightbox.innerHTML = `
            <div class="lum-lightbox-inner">
                <div class="lum-lightbox-image-wrapper">
                    <span class="lum-lightbox-position-helper">
                        <img class="lum-img" alt="">
                        <p class="lum-lightbox-caption"></p>
                    </span>
                </div>
                <div class="lum-close-button"></div>
            </div>
        `;

        const image = lightbox.querySelector('.lum-img');
        const caption = lightbox.querySelector('.lum-lightbox-caption');
        image.src = source;
        image.alt = sourceImage.alt || '';

        const captionText = sourceImage.alt || sourceImage.title || '';
        if (captionText) {
            caption.textContent = captionText;
        } else {
            caption.remove();
        }

        lightbox.addEventListener('click', (event) => {
            if (!event.target.closest('.lum-img, .lum-close-button')) {
                closeStandaloneImageLightbox(lightbox);
            }
        });

        lightbox.querySelector('.lum-close-button')?.addEventListener('click', (event) => {
            event.preventDefault();
            event.stopPropagation();
            closeStandaloneImageLightbox(lightbox);
        });

        const handleEscape = (event) => {
            if (event.key === 'Escape' && lightbox.isConnected) {
                closeStandaloneImageLightbox(lightbox);
            }
        };
        lightbox.__gfplusEscapeHandler = handleEscape;
        document.addEventListener('keydown', handleEscape);

        document.body.appendChild(lightbox);
        updateLightboxScrollLock();
    };

    const shouldBindStandaloneImageLightbox = (image) => {
        if (!image?.src || image.closest('.lum-lightbox')) {
            return false;
        }

        if (!image.closest('.user-content, #additional-info, #script-content, .gf-script-extra-info')) {
            return false;
        }

        if (image.closest('a[href]') || image.classList.contains('gf-script-logo')) {
            return false;
        }

        return true;
    };

    const bindStandaloneImageLightboxes = () => {
        document.querySelectorAll('img[src]').forEach((image) => {
            if (image.getAttribute(STANDALONE_LIGHTBOX_IMAGE_ATTR) === 'done' || !shouldBindStandaloneImageLightbox(image)) {
                return;
            }

            image.setAttribute(STANDALONE_LIGHTBOX_IMAGE_ATTR, 'done');
            image.classList.add('gfplus-standalone-lightbox-trigger');
            image.addEventListener('click', (event) => {
                event.preventDefault();
                event.stopPropagation();
                openStandaloneImageLightbox(image);
            });
        });
    };

    const initStandaloneImageLightboxes = () => {
        bindStandaloneImageLightboxes();

        if (standaloneLightboxObserver || !document.body) {
            return;
        }

        standaloneLightboxObserver = new MutationObserver(bindStandaloneImageLightboxes);
        standaloneLightboxObserver.observe(document.body, {
            childList: true,
            subtree: true
        });
    };

    // ============================================================================
    // Editor Toolbar
    // ============================================================================
    const EDITOR_TOOLBAR_ATTR = 'data-gfplus-editor-toolbar';
    const EDITOR_TOOLBAR_BUTTONS = [
        {
            id: 'heading',
            label: 'Heading',
            icon: 'H',
            headingLevel: 2
        },
        {
            id: 'bold',
            label: 'Bold',
            icon: '<path d="M7 5h6a3 3 0 0 1 0 6H7z"></path><path d="M7 11h7a3 3 0 0 1 0 6H7z"></path>',
            markdown: (text) => `**${text || 'texte'}**`,
            html: (text) => `<strong>${text || 'texte'}</strong>`
        },
        {
            id: 'italic',
            label: 'Italic',
            icon: '<path d="M10 5h8"></path><path d="M6 19h8"></path><path d="M14 5 10 19"></path>',
            markdown: (text) => `*${text || 'texte'}*`,
            html: (text) => `<em>${text || 'texte'}</em>`
        },
        {
            id: 'link',
            label: 'Link',
            icon: '<path d="M10 13a5 5 0 0 0 7.07 0l2-2a5 5 0 0 0-7.07-7.07l-1.15 1.15"></path><path d="M14 11a5 5 0 0 0-7.07 0l-2 2A5 5 0 0 0 12 20.07l1.15-1.15"></path>',
            markdown: (text) => `[${text || 'texte'}](https://example.com)`,
            html: (text) => `<a href="https://example.com">${text || 'texte'}</a>`
        },
        {
            id: 'image',
            label: 'Image',
            icon: '<rect x="4" y="5" width="16" height="14" rx="2"></rect><circle cx="9" cy="10" r="1.5"></circle><path d="m4 16 4-4 3 3 2-2 7 6"></path>',
            markdown: (text) => `![${text || 'description'}](https://example.com/image.png)`,
            html: (text) => `<img src="https://example.com/image.png" alt="${text || 'description'}">`
        },
        {
            id: 'code',
            label: 'Code',
            icon: '<path d="m9 18 6-12"></path><path d="m7 8-4 4 4 4"></path><path d="m17 8 4 4-4 4"></path>',
            markdown: (text) => text.includes('\n') ? `\`\`\`\n${text || 'code'}\n\`\`\`` : `\`${text || 'code'}\``,
            html: (text) => text.includes('\n') ? `<pre><code>${text || 'code'}</code></pre>` : `<code>${text || 'code'}</code>`
        },
        {
            id: 'quote',
            label: 'Blockquote',
            icon: '<path d="M8 8H5a4 4 0 0 0-4 4v5h7v-7H4"></path><path d="M20 8h-3a4 4 0 0 0-4 4v5h7v-7h-4"></path>',
            markdown: (text) => `> ${text || 'citation'}`,
            html: (text) => `<blockquote>${text || 'citation'}</blockquote>`
        },
        {
            id: 'list',
            label: 'List',
            icon: '<path d="M8 6h13"></path><path d="M8 12h13"></path><path d="M8 18h13"></path><path d="M3 6h.01"></path><path d="M3 12h.01"></path><path d="M3 18h.01"></path>',
            markdown: (text) => (text || 'élément').split('\n').map((line) => `- ${line || 'élément'}`).join('\n'),
            html: (text) => `<ul>\n${(text || 'élément').split('\n').map((line) => `  <li>${line || 'élément'}</li>`).join('\n')}\n</ul>`
        },
        {
            id: 'details',
            label: 'Details',
            icon: '<path d="m9 18 6-6-6-6"></path><path d="M4 5h16"></path><path d="M4 19h16"></path>',
            markdown: (text) => `<details open>\n<summary>Titre</summary>\n\n${text || 'Contenu'}\n</details>`,
            html: (text) => `<details open>\n<summary>Titre</summary>\n<p>${text || 'Contenu'}</p>\n</details>`
        },
        {
            id: 'mark',
            label: 'Highlight',
            icon: '<path d="m4 20 4-1 10-10a2.8 2.8 0 0 0-4-4L4 15l-1 4z"></path><path d="M13 6l5 5"></path>',
            markdown: (text) => `<mark>${text || 'texte'}</mark>`,
            html: (text) => `<mark>${text || 'texte'}</mark>`
        },
        {
            id: 'textColor',
            label: 'Text Color',
            icon: '<path d="M4 19h16"></path><path d="M8 15 12 5l4 10"></path><path d="M9.5 11h5"></path>',
            colorProperty: 'color',
            defaultColor: '#4f46e5'
        },
        {
            id: 'backgroundColor',
            label: 'Background Color',
            icon: '<path d="m4 14 7-7 6 6-7 7z"></path><path d="M14 4 20 10"></path><path d="M4 20h16"></path>',
            colorProperty: 'background-color',
            defaultColor: '#fef3c7'
        }
    ];

    const getPreviewableMarkupMode = (previewable) => {
        const markupName = previewable.getAttribute('data-markup-option-name') || '';
        const escapedMarkupName = window.CSS?.escape ? window.CSS.escape(markupName) : markupName.replace(/"/g, '\\"');
        const checkedControl = markupName
            ? document.querySelector(`input[name="${escapedMarkupName}"]:checked, select[name="${escapedMarkupName}"]`)
            : null;
        const mode = String(checkedControl?.value || '').toLowerCase();
        return mode.includes('html') ? 'html' : 'markdown';
    };

    const insertEditorSnippet = (textarea, snippetFactory) => {
        const start = textarea.selectionStart ?? textarea.value.length;
        const end = textarea.selectionEnd ?? start;
        const selectedText = textarea.value.slice(start, end);
        const snippet = snippetFactory(selectedText);
        textarea.setRangeText(snippet, start, end, 'end');
        textarea.dispatchEvent(new Event('input', { bubbles: true }));
        textarea.dispatchEvent(new Event('change', { bubbles: true }));
        textarea.focus();
    };

    const createEditorToolbarButton = (buttonConfig, previewable, textarea) => {
        const fragment = document.createDocumentFragment();
        const button = document.createElement('button');
        button.className = `gf-editor-toolbar-button${buttonConfig.icon.startsWith('<') ? '' : ' gf-editor-toolbar-button--text'}`;
        button.type = 'button';
        button.title = buttonConfig.label;
        button.setAttribute('aria-label', buttonConfig.label);
        button.innerHTML = buttonConfig.icon.startsWith('<')
            ? `<svg viewBox="0 0 24 24" aria-hidden="true">${buttonConfig.icon}</svg>`
            : buttonConfig.icon;

        if (buttonConfig.headingLevel) {
            const tool = document.createElement('span');
            tool.className = 'gf-editor-toolbar-heading-tool';

            const headingSelect = document.createElement('select');
            headingSelect.className = 'gf-editor-toolbar-heading-select';
            headingSelect.title = 'Heading Level';
            headingSelect.setAttribute('aria-label', 'Heading Level');
            [1, 2, 3, 4, 5, 6].forEach((level) => {
                const option = document.createElement('option');
                option.value = String(level);
                option.textContent = `H${level}`;
                headingSelect.appendChild(option);
            });
            headingSelect.value = String(buttonConfig.headingLevel);

            button.addEventListener('click', (event) => {
                event.preventDefault();
                const level = Number.parseInt(headingSelect.value || String(buttonConfig.headingLevel), 10);
                const safeLevel = Math.min(6, Math.max(1, Number.isFinite(level) ? level : 2));
                const mode = getPreviewableMarkupMode(previewable);
                insertEditorSnippet(textarea, (text) => (
                    mode === 'html'
                        ? `<h${safeLevel}>${text || 'Titre'}</h${safeLevel}>`
                        : `${'#'.repeat(safeLevel)} ${text || 'Titre'}`
                ));
                button.blur();
            });

            tool.appendChild(button);
            tool.appendChild(headingSelect);
            fragment.appendChild(tool);
            return fragment;
        }

        if (buttonConfig.colorProperty) {
            const tool = document.createElement('span');
            tool.className = 'gf-editor-toolbar-color-tool';

            const colorInput = document.createElement('input');
            colorInput.className = 'gf-editor-toolbar-color-input';
            colorInput.type = 'color';
            colorInput.value = buttonConfig.defaultColor;
            colorInput.setAttribute('aria-label', buttonConfig.label);

            const swatchButton = document.createElement('button');
            swatchButton.className = 'gf-editor-toolbar-color-swatch-button';
            swatchButton.type = 'button';
            swatchButton.title = `Change ${buttonConfig.label.toLowerCase()}`;
            swatchButton.setAttribute('aria-label', `Change ${buttonConfig.label.toLowerCase()}`);

            const colorSwatch = document.createElement('span');
            colorSwatch.className = 'gf-editor-toolbar-color-swatch';
            colorSwatch.style.backgroundColor = colorInput.value;
            swatchButton.appendChild(colorSwatch);

            button.addEventListener('click', (event) => {
                event.preventDefault();
                insertEditorSnippet(textarea, (text) => `<span style="${buttonConfig.colorProperty}:${colorInput.value}">${text || 'texte'}</span>`);
                button.blur();
            });

            swatchButton.addEventListener('click', (event) => {
                event.preventDefault();
                colorInput.focus({ preventScroll: true });
                if (typeof colorInput.showPicker === 'function') {
                    colorInput.showPicker();
                } else {
                    colorInput.click();
                }
            });

            colorInput.addEventListener('input', () => {
                colorSwatch.style.backgroundColor = colorInput.value;
            });

            colorInput.addEventListener('change', () => {
                colorSwatch.style.backgroundColor = colorInput.value;
            });

            tool.appendChild(button);
            tool.appendChild(swatchButton);
            tool.appendChild(colorInput);
            fragment.appendChild(tool);
            return fragment;
        }

        button.addEventListener('click', (event) => {
            event.preventDefault();
            const mode = getPreviewableMarkupMode(previewable);
            insertEditorSnippet(textarea, buttonConfig[mode] || buttonConfig.markdown);
            button.blur();
        });

        fragment.appendChild(button);
        return fragment;
    };

    const enhancePreviewableEditor = (previewable) => {
        if (previewable.getAttribute(EDITOR_TOOLBAR_ATTR) === 'done') {
            return;
        }

        const textarea = previewable.querySelector('textarea.comment-entry, textarea');
        if (!textarea) {
            return;
        }

        const toolbar = document.createElement('div');
        toolbar.className = 'gf-editor-toolbar';
        toolbar.setAttribute('role', 'toolbar');
        toolbar.setAttribute('aria-label', 'Outils de mise en forme');
        EDITOR_TOOLBAR_BUTTONS.forEach((buttonConfig) => {
            toolbar.appendChild(createEditorToolbarButton(buttonConfig, previewable, textarea));
        });

        const tabs = previewable.querySelector(':scope > .tabs');
        if (tabs) {
            tabs.insertAdjacentElement('afterend', toolbar);
        } else {
            textarea.insertAdjacentElement('beforebegin', toolbar);
        }

        previewable.setAttribute(EDITOR_TOOLBAR_ATTR, 'done');
    };

    let editorToolbarObserver = null;
    const initPreviewableEditorToolbars = () => {
        document.querySelectorAll('.previewable').forEach(enhancePreviewableEditor);
        if (editorToolbarObserver || !document.body) {
            return;
        }

        editorToolbarObserver = new MutationObserver(() => {
            document.querySelectorAll('.previewable:not([data-gfplus-editor-toolbar="done"])').forEach(enhancePreviewableEditor);
        });
        editorToolbarObserver.observe(document.body, { childList: true, subtree: true });
    };

    // ============================================================================
    // Script List Density
    // ============================================================================
    const setInterfaceDensity = (density) => {
        if (!DENSITY_OPTIONS.includes(density)) {
            return;
        }

        currentDensity = density;
        root.setAttribute('data-gfplus-density', density);
        localStorage.setItem(DENSITY_STORAGE_KEY, density);

        document.querySelectorAll('gf-script-density').forEach((host) => {
            host.syncDensityButtons?.();
        });
    };

    const createDensityControl = () => {
        const i18n = getUserNavI18n(getCurrentLocale()).density;
        const host = document.createElement('gf-script-density');
        const shadow = host.attachShadow({ mode: 'open' });
        shadow.innerHTML = `
            <style>
                :host {
                    --density-border: color-mix(in srgb, var(--content-border-color) 78%, var(--link-color) 22%);
                    --density-muted: color-mix(in srgb, var(--overall-text-color) 62%, transparent);
                    --density-surface: color-mix(in srgb, var(--content-background-color) 96%, var(--overall-text-color) 4%);
                    display: inline-flex;
                    color: var(--overall-text-color);
                    font-family: var(--font-family-base);
                }
                .density-control {
                    display: inline-flex;
                    align-items: center;
                    gap: 2px;
                    padding: 3px 4px;
                    border: 1px solid var(--density-border);
                    border-radius: 10px;
                    background: linear-gradient(180deg, var(--content-background-color), var(--density-surface));
                }
                .label {
                    align-self: stretch;
                    display: inline-flex;
                    align-items: center;
                    padding: 0 9px 0 7px;
                    margin-right: 2px;
                    border-right: 1px solid var(--density-border);
                    color: var(--density-muted);
                    font-size: 10.5px;
                    font-weight: 700;
                    letter-spacing: .025em;
                    user-select: none;
                }
                button {
                    all: unset;
                    width: 29px;
                    height: 27px;
                    display: inline-flex;
                    align-items: center;
                    justify-content: center;
                    border-radius: 7px;
                    color: var(--density-muted);
                    cursor: pointer;
                    box-sizing: border-box;
                    transition: color .16s ease, background-color .16s ease;
                }
                button:hover {
                    color: var(--overall-text-color);
                    background: color-mix(in srgb, var(--link-color) 10%, transparent);
                }
                button[aria-pressed="true"] {
                    color: var(--link-color);
                    background: color-mix(in srgb, var(--content-background-color) 86%, var(--link-color) 14%);
                    outline: 1px solid color-mix(in srgb, var(--link-color) 30%, transparent);
                    outline-offset: -1px;
                    cursor: default;
                }
                button:focus-visible {
                    outline: 2px solid var(--link-color);
                    outline-offset: 1px;
                }
                svg {
                    width: 15.5px;
                    height: 15.5px;
                    fill: none;
                    stroke: currentColor;
                    stroke-width: 1.7;
                    stroke-linecap: round;
                    stroke-linejoin: round;
                }
                @media (max-width: 430px) {
                    .label { display: none; }
                }
            </style>
            <div class="density-control" role="group" aria-label="${i18n.label}">
                <span class="label">${i18n.label}</span>
                <button type="button" data-density="compact" aria-label="${i18n.compact}" title="${i18n.compact}">
                    <svg viewBox="0 0 18 18" aria-hidden="true">
                        <line x1="3" y1="6" x2="15" y2="6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></line>
                        <line x1="3" y1="9" x2="15" y2="9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></line>
                        <line x1="3" y1="12" x2="15" y2="12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></line>
                    </svg>
                </button>
                <button type="button" data-density="comfortable" aria-label="${i18n.comfortable}" title="${i18n.comfortable}">
                    <svg viewBox="0 0 18 18" aria-hidden="true">
                        <line x1="3" y1="5" x2="15" y2="5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></line>
                        <line x1="3" y1="9" x2="15" y2="9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></line>
                        <line x1="3" y1="13" x2="15" y2="13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></line>
                    </svg>
                </button>
                <button type="button" data-density="detailed" aria-label="${i18n.detailed}" title="${i18n.detailed}">
                    <svg viewBox="0 0 18 18" aria-hidden="true">
                        <line x1="3" y1="4" x2="15" y2="4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></line>
                        <line x1="3" y1="7" x2="15" y2="7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></line>
                        <line x1="3" y1="10" x2="15" y2="10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></line>
                        <line x1="3" y1="13" x2="15" y2="13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></line>
                    </svg>
                </button>
            </div>
        `;

        const buttons = Array.from(shadow.querySelectorAll('button[data-density]'));
        const syncButtons = () => {
            buttons.forEach((button) => {
                const isActive = button.dataset.density === currentDensity;
                button.setAttribute('aria-pressed', String(isActive));
                button.tabIndex = isActive ? 0 : -1;
            });
        };

        buttons.forEach((button) => {
            button.addEventListener('click', () => setInterfaceDensity(button.dataset.density));
            button.addEventListener('keydown', (event) => {
                if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) {
                    return;
                }

                event.preventDefault();
                const currentIndex = DENSITY_OPTIONS.indexOf(currentDensity);
                const nextIndex = event.key === 'Home'
                    ? 0
                    : event.key === 'End'
                        ? DENSITY_OPTIONS.length - 1
                        : (currentIndex + (event.key === 'ArrowRight' ? 1 : -1) + DENSITY_OPTIONS.length) % DENSITY_OPTIONS.length;
                const nextDensity = DENSITY_OPTIONS[nextIndex];
                setInterfaceDensity(nextDensity);
                buttons[nextIndex]?.focus();
            });
        });

        host.syncDensityButtons = syncButtons;
        syncButtons();
        return host;
    };

    const applyScriptDensityControls = () => {
        document.querySelectorAll('.script-list').forEach((scriptList) => {
            if (
                scriptList.getAttribute('data-gfplus-density-control') === 'done'
                || scriptList.id === 'user-library-script-list'
                || !scriptList.querySelector(':scope > li[data-script-id]')
            ) {
                return;
            }

            const precedingDescription = scriptList.previousElementSibling?.matches('p.script-list-description')
                ? scriptList.previousElementSibling
                : null;
            const densityControl = createDensityControl();
            const profileScriptsHeader = scriptList.id === 'user-script-list'
                ? scriptList.closest('#user-script-list-section')?.querySelector(':scope > header')
                : null;

            if (profileScriptsHeader) {
                profileScriptsHeader.classList.add('gf-script-list-section-header');
                profileScriptsHeader.appendChild(densityControl);
            } else {
                const heading = document.createElement('div');
                heading.className = `gf-script-list-heading${precedingDescription ? '' : ' gf-script-list-heading--control-only'}`;

                if (precedingDescription) {
                    precedingDescription.insertAdjacentElement('beforebegin', heading);
                    heading.append(precedingDescription, densityControl);
                } else {
                    scriptList.insertAdjacentElement('beforebegin', heading);
                    heading.appendChild(densityControl);
                }
            }

            scriptList.setAttribute('data-gfplus-density-control', 'done');
        });
    };

    let densityControlObserver = null;
    const initScriptDensityControls = () => {
        applyScriptDensityControls();

        if (densityControlObserver || !document.body) {
            return;
        }

        densityControlObserver = new MutationObserver(applyScriptDensityControls);
        densityControlObserver.observe(document.body, {
            childList: true,
            subtree: true
        });
    };

    let fastMenuObserver = null;
    let fastMenuFrame = 0;

    const applyFastMenuEnhancements = () => {
        initThemeSwitch();
        initMobileNavLayout();
        initMobileThemeSwitch();
        syncActiveScriptSetFilter();
        initUserNavigation();
        initMobileUserNavigation();
        initFavoritesNavShortcut();
    };

    const scheduleFastMenuEnhancements = () => {
        if (fastMenuFrame) {
            return;
        }

        fastMenuFrame = requestAnimationFrame(() => {
            fastMenuFrame = 0;
            applyFastMenuEnhancements();
        });
    };

    const initFastMenuEnhancements = () => {
        applyFastMenuEnhancements();

        if (document.readyState !== 'loading' || fastMenuObserver) {
            return;
        }

        fastMenuObserver = new MutationObserver(scheduleFastMenuEnhancements);
        fastMenuObserver.observe(root, {
            childList: true,
            subtree: true
        });

        document.addEventListener('DOMContentLoaded', () => {
            scheduleFastMenuEnhancements();

            if (fastMenuObserver) {
                fastMenuObserver.disconnect();
                fastMenuObserver = null;
            }
        }, { once: true });
    };

    let uiInitialized = false;
    const initUi = () => {
        if (uiInitialized) {
            return;
        }

        uiInitialized = true;
        initThemeSwitch();
        initMobileNavLayout();
        initMobileThemeSwitch();
        initSidebarScrollControls();
        syncActiveScriptSetFilter();
        initSidebarGroupToggles();
        initSmartSidebar();
        initMobileSidebarStickiness();
        initModeratorActionsLayout();
        initCompactUserScriptSets();
        initScriptSetEditor();
        initHighlightJs();
        initInstallStatsChartTheme();
        initLightboxScrollLock();
        initStandaloneImageLightboxes();
        initPreviewableEditorToolbars();
        initScriptDensityControls();
        initScriptLogos();
        initScriptCardActions();
        initUserNavigation();
        initMobileUserNavigation();
        initFavoritesNavShortcut();

        if (root.hasAttribute(HANDHELD_ATTR)) {
            schedulePhoneLoadClear();
            return;
        }

        scheduleNoTransitionClear();
    };

    initFastMenuEnhancements();

    if (document.readyState === 'loading') {
        window.addEventListener('DOMContentLoaded', initUi, { once: true });
    } else {
        initUi();
    }
})();