Find Scripts For This Site

Find userscripts for the current website from popular script repositories

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

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

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name                 Find Scripts For This Site
// @name:zh-CN           查找适用于当前网站的脚本
// @name:zh-TW           查找適用於當前網站的腳本
// @name:ja              このサイト用のスクリプトを探す
// @name:ko              이 사이트용 스크립트 찾기
// @name:es              Buscar scripts para este sitio
// @name:fr              Trouver des scripts pour ce site
// @name:de              Skripte für diese Website finden
// @name:ru              Найти скрипты для этого сайта
// @namespace            https://github.com/utags
// @homepageURL          https://github.com/utags/userscripts#readme
// @supportURL           https://github.com/utags/userscripts/issues
// @version              0.2.4
// @description          Find userscripts for the current website from popular script repositories
// @description:zh-CN    查找适用于当前网站的用户脚本,支持多个脚本仓库
// @description:zh-TW    查找適用於當前網站的用戶腳本,支持多個腳本倉庫
// @description:ja       人気のスクリプトリポジトリから現在のウェブサイト用のユーザースクリプトを見つける
// @description:ko       인기 스크립트 저장소에서 현재 웹사이트용 사용자 스크립트 찾기
// @description:es       Encuentra userscripts para el sitio web actual desde repositorios populares
// @description:fr       Trouvez des scripts utilisateur pour le site Web actuel à partir de référentiels de scripts populaires
// @description:de       Finden Sie Benutzerskripte für die aktuelle Website aus beliebten Skript-Repositories
// @description:ru       Найдите пользовательские скрипты для текущего веб-сайта из популярных репозиториев скриптов
// @author               Pipecraft
// @license              MIT
// @match                *://*/*
// @icon                 data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2064%2064%22%20fill%3D%22none%22%3E%3Ctext%20x%3D%2232%22%20y%3D%2232%22%20text-anchor%3D%22middle%22%20dominant-baseline%3D%22middle%22%20font-family%3D%22Menlo%2C%20Monaco%2C%20Consolas%2C%20Courier%20New%2C%20monospace%22%20font-size%3D%2242%22%20font-weight%3D%22700%22%20fill%3D%22%231f2937%22%3E%7B%7D%3C/text%3E%3C/svg%3E
// @noframes
// @grant                GM_registerMenuCommand
// @grant                GM_unregisterMenuCommand
// @grant                GM_openInTab
// @grant                GM.getValue
// @grant                GM_getValue
// @grant                GM.setValue
// @grant                GM_setValue
// @grant                GM_addStyle
// @grant                GM.addValueChangeListener
// @grant                GM_addValueChangeListener
// ==/UserScript==
//
;(() => {
  'use strict'
  var __defProp = Object.defineProperty
  var __getOwnPropSymbols = Object.getOwnPropertySymbols
  var __hasOwnProp = Object.prototype.hasOwnProperty
  var __propIsEnum = Object.prototype.propertyIsEnumerable
  var __defNormalProp = (obj, key, value) =>
    key in obj
      ? __defProp(obj, key, {
          enumerable: true,
          configurable: true,
          writable: true,
          value,
        })
      : (obj[key] = value)
  var __spreadValues = (a, b) => {
    for (var prop in b || (b = {}))
      if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop])
    if (__getOwnPropSymbols)
      for (var prop of __getOwnPropSymbols(b)) {
        if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop])
      }
    return a
  }
  var style_default =
    '#find-scripts-settings-overlay{align-items:center;background:rgba(0,0,0,.5);display:flex;height:100%;justify-content:center;left:0;position:fixed;top:0;width:100%;z-index:9999}#find-scripts-settings-dialog{background:#fff;border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,.2);max-height:90%;max-width:90%;overflow-y:auto;padding:20px;width:400px}#find-scripts-settings-dialog h2{border-bottom:1px solid #eee;font-size:18px;margin-bottom:15px;margin-top:0;padding-bottom:10px}.find-scripts-setting-item{align-items:center;display:flex;margin-bottom:12px}.find-scripts-setting-item label{flex-grow:1;margin-left:8px}.find-scripts-buttons{display:flex;gap:10px;justify-content:flex-end;margin-top:15px}.find-scripts-buttons button{background:#f5f5f5;border:1px solid #ccc;border-radius:4px;cursor:pointer;padding:6px 12px}.find-scripts-buttons button:hover{background:#e5e5e5}.find-scripts-buttons button.primary{background:#4a86e8;border-color:#3a76d8;color:#fff}.find-scripts-buttons button.primary:hover{background:#3a76d8}'
  function registerMenu(caption, onClick) {
    if (typeof GM_registerMenuCommand === 'function') {
      return GM_registerMenuCommand(caption, onClick)
    }
    return 0
  }
  function unregisterMenu(menuId) {
    if (typeof GM_unregisterMenuCommand === 'function') {
      GM_unregisterMenuCommand(menuId)
    }
  }
  function openInTab(url, options) {
    if (typeof GM_openInTab === 'function') {
      GM_openInTab(url, options)
      return
    }
    globalThis.open(url, '_blank')
  }
  async function getValue(key, defaultValue) {
    if (typeof GM !== 'undefined' && typeof GM.getValue === 'function') {
      return GM.getValue(key, defaultValue)
    }
    if (typeof GM_getValue === 'function') {
      return GM_getValue(key, defaultValue)
    }
    return defaultValue
  }
  async function setValue(key, value) {
    if (typeof GM !== 'undefined' && typeof GM.setValue === 'function') {
      await GM.setValue(key, value)
      return
    }
    if (typeof GM_setValue === 'function') {
      GM_setValue(key, value)
    }
  }
  function addStyle(css) {
    if (typeof GM_addStyle === 'function') {
      GM_addStyle(css)
      return
    }
    const style = document.createElement('style')
    style.textContent = css
    document.head.append(style)
  }
  async function addValueChangeListener(key, callback) {
    if (
      typeof GM !== 'undefined' &&
      typeof GM.addValueChangeListener === 'function'
    ) {
      return GM.addValueChangeListener(key, callback)
    }
    if (typeof GM_addValueChangeListener === 'function') {
      return GM_addValueChangeListener(key, callback)
    }
    return 0
  }
  var CONFIG = {
    REPOSITORIES: [
      {
        id: 'greasy_fork',
        name: 'Greasy Fork',
        domainSearchUrl:
          'https://greasyfork.org/scripts/by-site/{domain}?filter_locale=0',
        domainSearchEnabled: true,
        keywordSearchUrl:
          'https://greasyfork.org/scripts?filter_locale=0&q={keyword}',
        keywordSearchEnabled: true,
        icon: '\u{1F374}',
      },
      {
        id: 'openuserjs',
        name: 'OpenUserJS',
        keywordSearchUrl: 'https://openuserjs.org/?q={keyword}',
        keywordSearchEnabled: true,
        icon: '\u{1F4DC}',
      },
      {
        id: 'scriptcat',
        name: 'ScriptCat',
        domainSearchUrl: 'https://scriptcat.org/search?domain={domain}',
        domainSearchEnabled: true,
        keywordSearchUrl: 'https://scriptcat.org/search?keyword={keyword}',
        keywordSearchEnabled: true,
        icon: '\u{1F431}',
      },
      {
        id: 'github',
        name: 'GitHub',
        keywordSearchUrl:
          'https://github.com/search?type=code&q=language%3AJavaScript+%22%3D%3DUserScript%3D%3D%22+{keyword}',
        keywordSearchEnabled: true,
        icon: '\u{1F419}',
      },
      {
        id: 'github_gist',
        name: 'GitHub Gist',
        keywordSearchUrl:
          'https://gist.github.com/search?l=JavaScript&q=%22%3D%3DUserScript%3D%3D%22+{keyword}',
        keywordSearchEnabled: true,
        icon: '\u{1F4DD}',
      },
      {
        id: 'sleazy_fork',
        name: 'Sleazy Fork',
        domainSearchUrl:
          'https://sleazyfork.org/scripts/by-site/{domain}?filter_locale=0',
        domainSearchEnabled: false,
        keywordSearchUrl:
          'https://sleazyfork.org/scripts?filter_locale=0&q={keyword}',
        keywordSearchEnabled: false,
        icon: '\u{1F51E}',
      },
    ],
    DEBUG: false,
    SETTINGS_KEY: 'find_scripts_settings',
  }
  var I18N = {
    en: {
      menu_domain: '{icon} Find scripts by domain on {name}',
      menu_keyword: '{icon} Find scripts by keyword on {name}',
      title_settings: 'Repository Settings',
      btn_save: 'Save',
      btn_cancel: 'Cancel',
      title_domain: 'Domain Search',
      title_keyword: 'Keyword Search',
      menu_settings: '\u2699\uFE0F Settings',
    },
    'zh-CN': {
      menu_domain:
        '{icon} \u5728 {name} \u4E0A\u6309\u57DF\u540D\u67E5\u627E\u811A\u672C',
      menu_keyword:
        '{icon} \u5728 {name} \u4E0A\u6309\u5173\u952E\u5B57\u67E5\u627E\u811A\u672C',
      title_settings: '\u4ED3\u5E93\u8BBE\u7F6E',
      btn_save: '\u4FDD\u5B58',
      btn_cancel: '\u53D6\u6D88',
      title_domain: '\u57DF\u540D\u641C\u7D22',
      title_keyword: '\u5173\u952E\u5B57\u641C\u7D22',
      menu_settings: '\u2699\uFE0F \u8BBE\u7F6E',
    },
    'zh-TW': {
      menu_domain:
        '{icon} \u5728 {name} \u4E0A\u6309\u57DF\u540D\u67E5\u627E\u8173\u672C',
      menu_keyword:
        '{icon} \u5728 {name} \u4E0A\u6309\u95DC\u9375\u5B57\u67E5\u627E\u8173\u672C',
      title_settings: '\u5009\u5EAB\u8A2D\u7F6E',
      btn_save: '\u4FDD\u5B58',
      btn_cancel: '\u53D6\u6D88',
      title_domain: '\u57DF\u540D\u641C\u7D22',
      title_keyword: '\u95DC\u9375\u5B57\u641C\u7D22',
      menu_settings: '\u2699\uFE0F \u8A2D\u7F6E',
    },
    ja: {
      menu_domain:
        '{icon} {name} \u3067\u30C9\u30E1\u30A4\u30F3\u304B\u3089\u30B9\u30AF\u30EA\u30D7\u30C8\u3092\u63A2\u3059',
      menu_keyword:
        '{icon} {name} \u3067\u30AD\u30FC\u30EF\u30FC\u30C9\u304B\u3089\u30B9\u30AF\u30EA\u30D7\u30C8\u3092\u63A2\u3059',
      title_settings: '\u30EA\u30DD\u30B8\u30C8\u30EA\u8A2D\u5B9A',
      btn_save: '\u4FDD\u5B58',
      btn_cancel: '\u30AD\u30E3\u30F3\u30BB\u30EB',
      title_domain: '\u30C9\u30E1\u30A4\u30F3\u691C\u7D22',
      title_keyword: '\u30AD\u30FC\u30EF\u30FC\u30C9\u691C\u7D22',
      menu_settings: '\u2699\uFE0F \u8A2D\u5B9A',
    },
    ko: {
      menu_domain:
        '{icon} {name}\uC5D0\uC11C \uB3C4\uBA54\uC778\uC73C\uB85C \uC2A4\uD06C\uB9BD\uD2B8 \uCC3E\uAE30',
      menu_keyword:
        '{icon} {name}\uC5D0\uC11C \uD0A4\uC6CC\uB4DC\uB85C \uC2A4\uD06C\uB9BD\uD2B8 \uCC3E\uAE30',
      title_settings: '\uC800\uC7A5\uC18C \uC124\uC815',
      btn_save: '\uC800\uC7A5',
      btn_cancel: '\uCDE8\uC18C',
      title_domain: '\uB3C4\uBA54\uC778 \uAC80\uC0C9',
      title_keyword: '\uD0A4\uC6CC\uB4DC \uAC80\uC0C9',
      menu_settings: '\u2699\uFE0F \uC124\uC815',
    },
    es: {
      menu_domain: '{icon} Buscar scripts por dominio en {name}',
      menu_keyword: '{icon} Buscar scripts por palabra clave en {name}',
      title_settings: 'Configuraci\xF3n de repositorios',
      btn_save: 'Guardar',
      btn_cancel: 'Cancelar',
      title_domain: 'B\xFAsqueda por dominio',
      title_keyword: 'B\xFAsqueda por palabra clave',
      menu_settings: '\u2699\uFE0F Configuraci\xF3n',
    },
    fr: {
      menu_domain: '{icon} Trouver des scripts par domaine sur {name}',
      menu_keyword: '{icon} Trouver des scripts par mot-cl\xE9 sur {name}',
      title_settings: 'Param\xE8tres des d\xE9p\xF4ts',
      btn_save: 'Enregistrer',
      btn_cancel: 'Annuler',
      title_domain: 'Recherche par domaine',
      title_keyword: 'Recherche par mot-cl\xE9',
      menu_settings: '\u2699\uFE0F Param\xE8tres',
    },
    de: {
      menu_domain: '{icon} Skripte nach Domain auf {name} finden',
      menu_keyword: '{icon} Skripte nach Stichwort auf {name} finden',
      title_settings: 'Repository-Einstellungen',
      btn_save: 'Speichern',
      btn_cancel: 'Abbrechen',
      title_domain: 'Domain-Suche',
      title_keyword: 'Stichwortsuche',
      menu_settings: '\u2699\uFE0F Einstellungen',
    },
    ru: {
      menu_domain:
        '{icon} \u041D\u0430\u0439\u0442\u0438 \u0441\u043A\u0440\u0438\u043F\u0442\u044B \u043F\u043E \u0434\u043E\u043C\u0435\u043D\u0443 \u043D\u0430 {name}',
      menu_keyword:
        '{icon} \u041D\u0430\u0439\u0442\u0438 \u0441\u043A\u0440\u0438\u043F\u0442\u044B \u043F\u043E \u043A\u043B\u044E\u0447\u0435\u0432\u043E\u043C\u0443 \u0441\u043B\u043E\u0432\u0443 \u043D\u0430 {name}',
      title_settings:
        '\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u0435\u0432',
      btn_save: '\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C',
      btn_cancel: '\u041E\u0442\u043C\u0435\u043D\u0430',
      title_domain:
        '\u041F\u043E\u0438\u0441\u043A \u043F\u043E \u0434\u043E\u043C\u0435\u043D\u0443',
      title_keyword:
        '\u041F\u043E\u0438\u0441\u043A \u043F\u043E \u043A\u043B\u044E\u0447\u0435\u0432\u043E\u043C\u0443 \u0441\u043B\u043E\u0432\u0443',
      menu_settings:
        '\u2699\uFE0F \u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438',
    },
  }
  var USER_LANG = detectLanguage()
  var LANG_MAP =
    USER_LANG === 'en'
      ? I18N.en
      : __spreadValues(__spreadValues({}, I18N.en), I18N[USER_LANG])
  function t(key) {
    return LANG_MAP[key]
  }
  function detectLanguage() {
    try {
      const browserLang = (
        navigator.language ||
        navigator.userLanguage ||
        'en'
      ).toLowerCase()
      const supportedLangs = Object.keys(I18N)
      if (supportedLangs.includes(browserLang)) {
        return browserLang
      }
      const langBase = browserLang.split('-')[0]
      const matchingLang = supportedLangs.find((lang) =>
        lang.startsWith(langBase + '-')
      )
      if (matchingLang) {
        return matchingLang
      }
      return 'en'
    } catch (error) {
      debugLog('Error detecting language:', error)
      return 'en'
    }
  }
  function debugLog(message, data = null) {
    if (CONFIG.DEBUG) {
      console.log('[Find Scripts] '.concat(message), data || '')
    }
  }
  function extractDomain() {
    try {
      const hostname = globalThis.location.hostname
      let domain = hostname.replace(/^www\./, '')
      const parts = domain.split('.')
      if (parts.length > 2) {
        const secondLevelDomains = [
          'co',
          'com',
          'org',
          'net',
          'edu',
          'gov',
          'mil',
        ]
        const thirdLevelDomain = parts[parts.length - 2]
        domain =
          parts.length > 3 && secondLevelDomains.includes(thirdLevelDomain)
            ? parts.slice(-3).join('.')
            : parts.slice(-2).join('.')
      }
      debugLog('Extracted domain:', domain)
      return domain
    } catch (error) {
      debugLog('Error extracting domain:', error)
      return globalThis.location.hostname
    }
  }
  function getLocalizedMenuText(repo, isKeywordSearch = false) {
    const key = isKeywordSearch ? 'menu_keyword' : 'menu_domain'
    const template = t(key)
    return template.replace('{icon}', repo.icon).replace('{name}', repo.name)
  }
  var MENU_IDS = []
  var SETTINGS_MENU_ID
  function clearMenus() {
    for (const id of MENU_IDS) {
      unregisterMenu(id)
    }
    MENU_IDS = []
    if (SETTINGS_MENU_ID) {
      unregisterMenu(SETTINGS_MENU_ID)
      SETTINGS_MENU_ID = void 0
    }
  }
  function registerAllMenus() {
    const domain = extractDomain()
    registerMenuCommands(domain)
    registerSettingsMenu()
  }
  function registerMenuCommands(domain) {
    for (const repo of CONFIG.REPOSITORIES) {
      if (repo.domainSearchUrl && repo.domainSearchEnabled) {
        const url = repo.domainSearchUrl.replace('{domain}', domain)
        const menuText = getLocalizedMenuText(repo)
        const id = registerMenu(menuText, () => {
          debugLog('Opening '.concat(repo.name, ' for domain:'), domain)
          openInTab(url, { active: true, insert: true })
        })
        MENU_IDS.push(id)
      }
      if (repo.keywordSearchUrl && repo.keywordSearchEnabled) {
        const keywordUrl = repo.keywordSearchUrl.replace('{keyword}', domain)
        const keywordMenuText = getLocalizedMenuText(repo, true)
        const id = registerMenu(keywordMenuText, () => {
          debugLog('Opening '.concat(repo.name, ' for keyword search:'), domain)
          openInTab(keywordUrl, { active: true, insert: true })
        })
        MENU_IDS.push(id)
      }
    }
  }
  async function loadSettings() {
    try {
      const savedSettings = await getValue(CONFIG.SETTINGS_KEY)
      if (savedSettings) {
        for (const repo of CONFIG.REPOSITORIES) {
          if (
            repo.domainSearchUrl &&
            savedSettings['domain_'.concat(repo.id)] !== void 0
          ) {
            repo.domainSearchEnabled = savedSettings['domain_'.concat(repo.id)]
          }
          if (
            repo.keywordSearchUrl &&
            savedSettings['keyword_'.concat(repo.id)] !== void 0
          ) {
            repo.keywordSearchEnabled =
              savedSettings['keyword_'.concat(repo.id)]
          }
        }
        debugLog('Settings loaded:', savedSettings)
      }
    } catch (error) {
      debugLog('Error loading settings:', error)
    }
  }
  async function saveSettings() {
    var _a, _b
    try {
      const settings = {}
      for (const repo of CONFIG.REPOSITORIES) {
        if (repo.domainSearchUrl) {
          settings['domain_'.concat(repo.id)] =
            (_a = repo.domainSearchEnabled) != null ? _a : false
        }
        if (repo.keywordSearchUrl) {
          settings['keyword_'.concat(repo.id)] =
            (_b = repo.keywordSearchEnabled) != null ? _b : false
        }
      }
      await setValue(CONFIG.SETTINGS_KEY, settings)
      debugLog('Settings saved:', settings)
    } catch (error) {
      debugLog('Error saving settings:', error)
    }
  }
  function showSettingsDialog() {
    var _a, _b
    addStyle(style_default)
    const overlay = document.createElement('div')
    overlay.id = 'find-scripts-settings-overlay'
    const dialog = document.createElement('div')
    dialog.id = 'find-scripts-settings-dialog'
    const titleEl = document.createElement('h2')
    titleEl.textContent = t('title_settings')
    const content = document.createElement('div')
    content.id = 'find-scripts-settings-content'
    const btns = document.createElement('div')
    btns.className = 'find-scripts-buttons'
    const cancelBtn = document.createElement('button')
    cancelBtn.id = 'find-scripts-cancel'
    cancelBtn.textContent = t('btn_cancel')
    const saveBtn = document.createElement('button')
    saveBtn.id = 'find-scripts-save'
    saveBtn.className = 'primary'
    saveBtn.textContent = t('btn_save')
    btns.append(cancelBtn, saveBtn)
    dialog.append(titleEl, content, btns)
    const contentWrap = dialog.querySelector('#find-scripts-settings-content')
    const domainSection = document.createElement('div')
    const domainTitle = document.createElement('h3')
    domainTitle.textContent = t('title_domain')
    domainSection.append(domainTitle)
    contentWrap.append(domainSection)
    for (const repo of CONFIG.REPOSITORIES) {
      if (repo.domainSearchUrl) {
        const item = document.createElement('div')
        item.className = 'find-scripts-setting-item'
        const checkbox = document.createElement('input')
        checkbox.type = 'checkbox'
        checkbox.id = 'find-scripts-domain-'.concat(repo.id)
        checkbox.checked = (_a = repo.domainSearchEnabled) != null ? _a : false
        const label = document.createElement('label')
        label.htmlFor = 'find-scripts-domain-'.concat(repo.id)
        label.textContent = ''.concat(repo.icon, ' ').concat(repo.name)
        item.append(checkbox)
        item.append(label)
        domainSection.append(item)
      }
    }
    const keywordSection = document.createElement('div')
    const keywordTitle = document.createElement('h3')
    keywordTitle.textContent = t('title_keyword')
    keywordSection.append(keywordTitle)
    contentWrap.append(keywordSection)
    for (const repo of CONFIG.REPOSITORIES) {
      if (repo.keywordSearchUrl) {
        const item = document.createElement('div')
        item.className = 'find-scripts-setting-item'
        const checkbox = document.createElement('input')
        checkbox.type = 'checkbox'
        checkbox.id = 'find-scripts-keyword-'.concat(repo.id)
        checkbox.checked = (_b = repo.keywordSearchEnabled) != null ? _b : false
        const label = document.createElement('label')
        label.htmlFor = 'find-scripts-keyword-'.concat(repo.id)
        label.textContent = ''.concat(repo.icon, ' ').concat(repo.name)
        item.append(checkbox)
        item.append(label)
        keywordSection.append(item)
      }
    }
    overlay.append(dialog)
    document.body.append(overlay)
    saveBtn.addEventListener('click', () => {
      for (const repo of CONFIG.REPOSITORIES) {
        if (repo.domainSearchUrl) {
          const domainCheckbox = document.querySelector(
            '#find-scripts-domain-'.concat(repo.id)
          )
          repo.domainSearchEnabled = Boolean(domainCheckbox.checked)
        }
        if (repo.keywordSearchUrl) {
          const keywordCheckbox = document.querySelector(
            '#find-scripts-keyword-'.concat(repo.id)
          )
          repo.keywordSearchEnabled = Boolean(keywordCheckbox.checked)
        }
      }
      void saveSettings()
      overlay.remove()
    })
    cancelBtn.addEventListener('click', () => {
      overlay.remove()
    })
    overlay.addEventListener('click', (event) => {
      const target = event.target
      if (target === overlay) overlay.remove()
    })
  }
  function registerSettingsMenu() {
    const menuText = t('menu_settings')
    SETTINGS_MENU_ID = registerMenu(menuText, showSettingsDialog)
  }
  async function initialize() {
    await loadSettings()
    registerAllMenus()
    void addValueChangeListener(CONFIG.SETTINGS_KEY, () => {
      void (async () => {
        await loadSettings()
        clearMenus()
        registerAllMenus()
      })()
    })
  }
  void initialize()
})()