github-codewiki-jumper

One click jump from GitHub to CodeWiki, DeepWiki and Zread

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name               github-codewiki-jumper
// @name:zh-CN         GitHub 代码百科跳转助手
// @namespace          https://github.com/qixing-jk/github-codewiki-jumper
// @version            1.2.6
// @author             qixing-jk
// @description        One click jump from GitHub to CodeWiki, DeepWiki and Zread
// @description:zh-CN  一键从 GitHub仓库 跳转到 CodeWiki, DeepWiki 和 Zread
// @match              *://github.com/*
// ==/UserScript==

(function () {
  'use strict';

  const JUMPER_CONTAINER_ID = "jumper-buttons-container";
  const INJECTION_SELECTOR = '[class*="SidebarSection-module__sidebarSection"].hide-sm.hide-md';
  const SIDEBAR_SELECTOR = 'div[class*="CodeViewSidebar-module__borderGrid"]';
  const normalizeRepositoryName = (value) => {
    const parts = value == null ? void 0 : value.trim().split("/").map((part) => part.trim());
    if (!parts || parts.length !== 2 || parts.some((part) => !part)) {
      return null;
    }
    return parts.join("/");
  };
  const getRepositoryNameFromPath = () => {
    const [owner, repository] = window.location.pathname.split("/").filter(Boolean);
    if (!owner || !repository) {
      return null;
    }
    try {
      return normalizeRepositoryName(`${decodeURIComponent(owner)}/${decodeURIComponent(repository)}`);
    } catch {
      return null;
    }
  };
  const getRepositoryName = () => {
    var _a, _b;
    const candidates = [
      (_a = document.querySelector('meta[name="current-repo-nwo"]')) == null ? void 0 : _a.getAttribute("content"),
      (_b = document.querySelector('meta[name="octolytics-dimension-repository_nwo"]')) == null ? void 0 : _b.getAttribute("content"),
      getRepositoryNameFromPath()
    ];
    for (const candidate of candidates) {
      const repositoryName = normalizeRepositoryName(candidate);
      if (repositoryName) {
        return repositoryName;
      }
    }
    return null;
  };
  const buildRepositoryPath = (repositoryName) => {
    const normalizedRepositoryName = normalizeRepositoryName(repositoryName);
    if (!normalizedRepositoryName) {
      return null;
    }
    return `/${normalizedRepositoryName.split("/").map((part) => encodeURIComponent(part)).join("/")}`;
  };
  const buildDeepWikiUrl = (pathname) => {
    return `https://deepwiki.com${pathname}`;
  };
  const buildCodeWikiUrl = (hostname, pathname) => {
    return `https://codewiki.google/${hostname}${pathname}`;
  };
  const buildZReadUrl = (pathname) => {
    return `https://zread.ai${pathname}`;
  };
  const deepWikiIconUrl = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='110%20110%20460%20500'%3e%3cpath%20style='fill:%2321c19a'%20class=''%20d='M418.73,332.37c9.84-5.68,22.07-5.68,31.91,0l25.49,14.71c.82.48,1.69.8,2.58,1.06.19.06.37.11.55.16.87.21,1.76.34,2.65.35.04,0,.08.02.13.02.1,0,.19-.03.29-.04.83-.02,1.64-.13,2.45-.32.14-.03.28-.05.42-.09.87-.24,1.7-.59,2.5-1.03.08-.04.17-.06.25-.1l50.97-29.43c3.65-2.11,5.9-6.01,5.9-10.22v-58.86c0-4.22-2.25-8.11-5.9-10.22l-50.97-29.43c-3.65-2.11-8.15-2.11-11.81,0l-50.97,29.43c-.08.04-.13.11-.2.16-.78.48-1.51,1.02-2.15,1.66-.1.1-.18.21-.28.31-.57.6-1.08,1.26-1.51,1.97-.07.12-.15.22-.22.34-.44.77-.77,1.6-1.03,2.47-.05.19-.1.37-.14.56-.22.89-.37,1.81-.37,2.76v29.43c0,11.36-6.11,21.95-15.95,27.63-9.84,5.68-22.06,5.68-31.91,0l-25.49-14.71c-.82-.48-1.69-.8-2.57-1.06-.19-.06-.37-.11-.56-.16-.88-.21-1.76-.34-2.65-.34-.13,0-.26.02-.4.02-.84.02-1.66.13-2.47.32-.13.03-.27.05-.4.09-.87.24-1.71.6-2.51,1.04-.08.04-.16.06-.24.1l-50.97,29.43c-3.65,2.11-5.9,6.01-5.9,10.22v58.86c0,4.22,2.25,8.11,5.9,10.22l50.97,29.43c.08.04.17.06.24.1.8.44,1.64.79,2.5,1.03.14.04.28.06.42.09.81.19,1.62.3,2.45.32.1,0,.19.04.29.04.04,0,.08-.02.13-.02.89,0,1.77-.13,2.65-.35.19-.04.37-.1.56-.16.88-.26,1.75-.59,2.58-1.06l25.49-14.71c9.84-5.68,22.06-5.68,31.91,0,9.84,5.68,15.95,16.27,15.95,27.63v29.43c0,.95.15,1.87.37,2.76.05.19.09.37.14.56.25.86.59,1.69,1.03,2.47.07.12.15.22.22.34.43.71.94,1.37,1.51,1.97.1.1.18.21.28.31.65.63,1.37,1.18,2.15,1.66.07.04.13.11.2.16l50.97,29.43c1.83,1.05,3.86,1.58,5.9,1.58s4.08-.53,5.9-1.58l50.97-29.43c3.65-2.11,5.9-6.01,5.9-10.22v-58.86c0-4.22-2.25-8.11-5.9-10.22l-50.97-29.43c-.08-.04-.16-.06-.24-.1-.8-.44-1.64-.8-2.51-1.04-.13-.04-.26-.05-.39-.09-.82-.2-1.65-.31-2.49-.33-.13,0-.25-.02-.38-.02-.89,0-1.78.13-2.66.35-.18.04-.36.1-.54.15-.88.26-1.75.59-2.58,1.07l-25.49,14.72c-9.84,5.68-22.07,5.68-31.9,0-9.84-5.68-15.95-16.27-15.95-27.63s6.11-21.95,15.95-27.63Z'%3e%3c/path%3e%3cpath%20style='fill:%233969ca'%20d='M141.09,317.65l50.97,29.43c1.83,1.05,3.86,1.58,5.9,1.58s4.08-.53,5.9-1.58l50.97-29.43c.08-.04.13-.11.2-.16.78-.48,1.51-1.02,2.15-1.66.1-.1.18-.21.28-.31.57-.6,1.08-1.26,1.51-1.97.07-.12.15-.22.22-.34.44-.77.77-1.6,1.03-2.47.05-.19.1-.37.14-.56.22-.89.37-1.81.37-2.76v-29.43c0-11.36,6.11-21.95,15.96-27.63s22.06-5.68,31.91,0l25.49,14.71c.82.48,1.69.8,2.57,1.06.19.06.37.11.56.16.87.21,1.76.34,2.64.35.04,0,.09.02.13.02.1,0,.19-.04.29-.04.83-.02,1.65-.13,2.45-.32.14-.03.28-.05.41-.09.87-.24,1.71-.6,2.51-1.04.08-.04.16-.06.24-.1l50.97-29.43c3.65-2.11,5.9-6.01,5.9-10.22v-58.86c0-4.22-2.25-8.11-5.9-10.22l-50.97-29.43c-3.65-2.11-8.15-2.11-11.81,0l-50.97,29.43c-.08.04-.13.11-.2.16-.78.48-1.51,1.02-2.15,1.66-.1.1-.18.21-.28.31-.57.6-1.08,1.26-1.51,1.97-.07.12-.15.22-.22.34-.44.77-.77,1.6-1.03,2.47-.05.19-.1.37-.14.56-.22.89-.37,1.81-.37,2.76v29.43c0,11.36-6.11,21.95-15.95,27.63-9.84,5.68-22.07,5.68-31.91,0l-25.49-14.71c-.82-.48-1.69-.8-2.58-1.06-.19-.06-.37-.11-.55-.16-.88-.21-1.76-.34-2.65-.35-.13,0-.26.02-.4.02-.83.02-1.66.13-2.47.32-.13.03-.27.05-.4.09-.87.24-1.71.6-2.51,1.04-.08.04-.16.06-.24.1l-50.97,29.43c-3.65,2.11-5.9,6.01-5.9,10.22v58.86c0,4.22,2.25,8.11,5.9,10.22Z'%3e%3c/path%3e%3cpath%20style='fill:%230294de'%20class=''%20d='M396.88,484.35l-50.97-29.43c-.08-.04-.17-.06-.24-.1-.8-.44-1.64-.79-2.51-1.03-.14-.04-.27-.06-.41-.09-.81-.19-1.64-.3-2.47-.32-.13,0-.26-.02-.39-.02-.89,0-1.78.13-2.66.35-.18.04-.36.1-.54.15-.88.26-1.76.59-2.58,1.07l-25.49,14.72c-9.84,5.68-22.06,5.68-31.9,0-9.84-5.68-15.96-16.27-15.96-27.63v-29.43c0-.95-.15-1.87-.37-2.76-.05-.19-.09-.37-.14-.56-.25-.86-.59-1.69-1.03-2.47-.07-.12-.15-.22-.22-.34-.43-.71-.94-1.37-1.51-1.97-.1-.1-.18-.21-.28-.31-.65-.63-1.37-1.18-2.15-1.66-.07-.04-.13-.11-.2-.16l-50.97-29.43c-3.65-2.11-8.15-2.11-11.81,0l-50.97,29.43c-3.65,2.11-5.9,6.01-5.9,10.22v58.86c0,4.22,2.25,8.11,5.9,10.22l50.97,29.43c.08.04.17.06.25.1.8.44,1.63.79,2.5,1.03.14.04.29.06.43.09.8.19,1.61.3,2.43.32.1,0,.2.04.3.04.04,0,.09-.02.13-.02.88,0,1.77-.13,2.64-.34.19-.04.37-.1.56-.16.88-.26,1.75-.59,2.57-1.06l25.49-14.71c9.84-5.68,22.06-5.68,31.91,0,9.84,5.68,15.95,16.27,15.95,27.63v29.43c0,.95.15,1.87.37,2.76.05.19.09.37.14.56.25.86.59,1.69,1.03,2.47.07.12.15.22.22.34.43.71.94,1.37,1.51,1.97.1.1.18.21.28.31.65.63,1.37,1.18,2.15,1.66.07.04.13.11.2.16l50.97,29.43c1.83,1.05,3.86,1.58,5.9,1.58s4.08-.53,5.9-1.58l50.97-29.43c3.65-2.11,5.9-6.01,5.9-10.22v-58.86c0-4.22-2.25-8.11-5.9-10.22Z'%3e%3c/path%3e%3c/svg%3e";
  const codeWikiIconUrl = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20fill='none'%20viewBox='-20%20-20%20320%20320'%3e%3cpath%20fill='%23007af4'%20d='M119.166%204.013a56.1%2056.1%200%200%201%2041.668%200l113.289%2045.316c7.836%203.135%207.836%2014.228%200%2017.363L206.34%2093.805c-4.694%201.877-4.694%208.521%200%2010.399l67.782%2027.114c7.837%203.134%207.836%2014.227%200%2017.362l-67.781%2027.113c-4.694%201.877-4.694%208.522%200%2010.399l67.781%2027.113c7.837%203.134%207.836%2014.228%200%2017.362l-113.289%2045.317a56.1%2056.1%200%200%201-41.667%200L5.877%20230.667c-7.836-3.134-7.836-14.227%200-17.362l67.78-27.113c4.695-1.877%204.695-8.522%200-10.399L5.878%20148.68c-7.836-3.135-7.836-14.228%200-17.362l67.782-27.114c4.694-1.878%204.694-8.522%200-10.4L5.879%2066.693c-7.837-3.135-7.837-14.228%200-17.363z'/%3e%3cpath%20fill='url(%23a)'%20d='M119.166%204.013a56.1%2056.1%200%200%201%2041.668%200l113.289%2045.316c7.836%203.135%207.836%2014.228%200%2017.363L206.34%2093.805c-4.694%201.877-4.694%208.521%200%2010.399l67.782%2027.114c7.837%203.134%207.836%2014.227%200%2017.362l-67.781%2027.113c-4.694%201.877-4.694%208.522%200%2010.399l67.781%2027.113c7.837%203.134%207.836%2014.228%200%2017.362l-113.289%2045.317a56.1%2056.1%200%200%201-41.667%200L5.877%20230.667c-7.836-3.134-7.836-14.227%200-17.362l67.78-27.113c4.695-1.877%204.695-8.522%200-10.399L5.878%20148.68c-7.836-3.135-7.836-14.228%200-17.362l67.782-27.114c4.694-1.878%204.694-8.522%200-10.4L5.879%2066.693c-7.837-3.135-7.837-14.228%200-17.363z'/%3e%3cpath%20fill='url(%23b)'%20d='M119.166%204.013a56.1%2056.1%200%200%201%2041.668%200l113.289%2045.316c7.836%203.135%207.836%2014.228%200%2017.363L206.34%2093.805c-4.694%201.877-4.694%208.521%200%2010.399l67.782%2027.114c7.837%203.134%207.836%2014.227%200%2017.362l-67.781%2027.113c-4.694%201.877-4.694%208.522%200%2010.399l67.781%2027.113c7.837%203.134%207.836%2014.228%200%2017.362l-113.289%2045.317a56.1%2056.1%200%200%201-41.667%200L5.877%20230.667c-7.836-3.134-7.836-14.227%200-17.362l67.78-27.113c4.695-1.877%204.695-8.522%200-10.399L5.878%20148.68c-7.836-3.135-7.836-14.228%200-17.362l67.782-27.114c4.694-1.878%204.694-8.522%200-10.4L5.879%2066.693c-7.837-3.135-7.837-14.228%200-17.363z'/%3e%3cpath%20fill='url(%23c)'%20d='M119.167%204.012a56.1%2056.1%200%200%201%2041.667%200L274.123%2049.33c7.836%203.134%207.836%2014.226%200%2017.36L206.34%2093.806c-4.694%201.877-4.694%208.521%200%2010.399l67.782%2027.114c7.836%203.134%207.836%2014.228%200%2017.362l-67.781%2027.113c-4.693%201.878-4.693%208.522%200%2010.399l67.781%2027.113c7.836%203.135%207.836%2014.228%200%2017.362l-113.288%2045.317a56.1%2056.1%200%200%201-41.668%200L5.877%20230.667c-7.836-3.134-7.836-14.227%200-17.362l67.78-27.113c4.694-1.877%204.694-8.521%200-10.399L5.877%20148.68c-7.836-3.134-7.836-14.227%200-17.362l67.783-27.114c4.693-1.878%204.693-8.522%200-10.4L5.878%2066.692c-7.836-3.135-7.836-14.227%200-17.361z'/%3e%3cdefs%3e%3clinearGradient%20id='a'%20x1='82.447'%20x2='127.557'%20y1='259.773'%20y2='161.773'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20offset='.206'%20stop-color='%2308b962'/%3e%3cstop%20offset='.987'%20stop-color='%2308b962'%20stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient%20id='b'%20x1='99.558'%20x2='150.891'%20y1='43.553'%20y2='139.996'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20stop-color='%23f94543'/%3e%3cstop%20offset='1'%20stop-color='%23f94543'%20stop-opacity='0'/%3e%3c/linearGradient%3e%3cradialGradient%20id='c'%20cx='0'%20cy='0'%20r='1'%20gradientTransform='matrix(438.114%200%200%20438.11%2011.9%20139.972)'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20stop-color='%23fabc12'/%3e%3cstop%20offset='.423'%20stop-color='%23fabc12'%20stop-opacity='0'/%3e%3c/radialGradient%3e%3c/defs%3e%3c/svg%3e";
  const zreadIconUrl = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20aria-hidden='true'%20viewBox='0%200%2032%2032'%20version='1.1'%20width='24'%20height='24'%20data-view-component='true'%3e%3cpath%20d='M9.91922%203.2002H4.47922C3.77229%203.2002%203.19922%203.77327%203.19922%204.4802V9.9202C3.19922%2010.6271%203.77229%2011.2002%204.47922%2011.2002H9.91922C10.6261%2011.2002%2011.1992%2010.6271%2011.1992%209.9202V4.4802C11.1992%203.77327%2010.6261%203.2002%209.91922%203.2002Z'%20fill='%23000000'%3e%3c/path%3e%3cpath%20d='M9.91922%2020.7998H4.47922C3.77229%2020.7998%203.19922%2021.3729%203.19922%2022.0798V27.5198C3.19922%2028.2267%203.77229%2028.7998%204.47922%2028.7998H9.91922C10.6261%2028.7998%2011.1992%2028.2267%2011.1992%2027.5198V22.0798C11.1992%2021.3729%2010.6261%2020.7998%209.91922%2020.7998Z'%20fill='%23000000'%3e%3c/path%3e%3cpath%20d='M27.5208%203.2002H22.0808C21.3739%203.2002%2020.8008%203.77327%2020.8008%204.4802V9.9202C20.8008%2010.6271%2021.3739%2011.2002%2022.0808%2011.2002H27.5208C28.2277%2011.2002%2028.8008%2010.6271%2028.8008%209.9202V4.4802C28.8008%203.77327%2028.2277%203.2002%2027.5208%203.2002Z'%20fill='%23000000'%3e%3c/path%3e%3cpath%20d='M8%2024L24%208L8%2024Z'%20fill='%23000000'%3e%3c/path%3e%3cpath%20d='M8%2024L24%208'%20stroke='%23000000'%20stroke-width='2'%20stroke-linecap='round'%3e%3c/path%3e%3c/svg%3e";
  const zreadIconDarkUrl = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20aria-hidden='true'%20viewBox='0%200%2032%2032'%20version='1.1'%20width='24'%20height='24'%20data-view-component='true'%3e%3cpath%20d='M9.91922%203.2002H4.47922C3.77229%203.2002%203.19922%203.77327%203.19922%204.4802V9.9202C3.19922%2010.6271%203.77229%2011.2002%204.47922%2011.2002H9.91922C10.6261%2011.2002%2011.1992%2010.6271%2011.1992%209.9202V4.4802C11.1992%203.77327%2010.6261%203.2002%209.91922%203.2002Z'%20fill='%23b8b8b8'%3e%3c/path%3e%3cpath%20d='M9.91922%2020.7998H4.47922C3.77229%2020.7998%203.19922%2021.3729%203.19922%2022.0798V27.5198C3.19922%2028.2267%203.77229%2028.7998%204.47922%2028.7998H9.91922C10.6261%2028.7998%2011.1992%2028.2267%2011.1992%2027.5198V22.0798C11.1992%2021.3729%2010.6261%2020.7998%209.91922%2020.7998Z'%20fill='%23b8b8b8'%3e%3c/path%3e%3cpath%20d='M27.5208%203.2002H22.0808C21.3739%203.2002%2020.8008%203.77327%2020.8008%204.4802V9.9202C20.8008%2010.6271%2021.3739%2011.2002%2022.0808%2011.2002H27.5208C28.2277%2011.2002%2028.8008%2010.6271%2028.8008%209.9202V4.4802C28.8008%203.77327%2028.2277%203.2002%2027.5208%203.2002Z'%20fill='%23b8b8b8'%3e%3c/path%3e%3cpath%20d='M8%2024L24%208L8%2024Z'%20fill='%23b8b8b8'%3e%3c/path%3e%3cpath%20d='M8%2024L24%208'%20stroke='%23b8b8b8'%20stroke-width='2'%20stroke-linecap='round'%3e%3c/path%3e%3c/svg%3e";
  const isDarkMode = () => {
    var _a;
    const html = document.documentElement;
    if ((html == null ? void 0 : html.getAttribute("data-color-mode")) === "dark") {
      return true;
    }
    if ((html == null ? void 0 : html.classList.contains("dark")) || (html == null ? void 0 : html.classList.contains("color-mode-dark"))) {
      return true;
    }
    const media = (_a = window.matchMedia) == null ? void 0 : _a.call(window, "(prefers-color-scheme: dark)");
    return !!(media == null ? void 0 : media.matches);
  };
  const getZreadIcon = () => isDarkMode() ? zreadIconDarkUrl : zreadIconUrl;
  const createButtonsContainer = () => {
    const container = document.createElement("div");
    container.id = JUMPER_CONTAINER_ID;
    container.setAttribute("translate", "no");
    container.classList.add("notranslate");
    return container;
  };
  const createLink = (url, text, iconUrl) => {
    const link = document.createElement("a");
    link.href = url;
    link.target = "_blank";
    link.classList.add("Link", "Link--muted");
    link.style.display = "inline-flex";
    link.style.alignItems = "center";
    link.style.whiteSpace = "nowrap";
    link.style.gap = "8px";
    const img = document.createElement("img");
    img.src = iconUrl;
    img.style.width = "16px";
    img.style.height = "16px";
    img.style.flexShrink = "0";
    img.style.display = "block";
    link.appendChild(img);
    link.appendChild(document.createTextNode(text));
    return link;
  };
  const addButtons = () => {
    var _a;
    const repositoryName = getRepositoryName();
    if (!repositoryName) {
      return;
    }
    const repositoryPath = buildRepositoryPath(repositoryName);
    if (!repositoryPath) {
      return;
    }
    const targetElement = document.querySelector(INJECTION_SELECTOR);
    if (!targetElement || document.getElementById(JUMPER_CONTAINER_ID)) {
      return;
    }
    const urlx = new URL(window.location.href);
    const buttonsContainer = createButtonsContainer();
    for (const link of [
      createLink(buildDeepWikiUrl(repositoryPath), "DeepWiki", deepWikiIconUrl),
      createLink(buildCodeWikiUrl(urlx.hostname, repositoryPath), "CodeWiki", codeWikiIconUrl),
      createLink(buildZReadUrl(repositoryPath), "Zread", getZreadIcon())
    ]) {
      const div = document.createElement("div");
      div.classList.add("mt-2");
      div.appendChild(link);
      buttonsContainer.appendChild(div);
    }
    const sidebar = document.querySelector(SIDEBAR_SELECTOR);
    const reportRow = (_a = sidebar == null ? void 0 : sidebar.querySelector('a[href*="/contact/report-content"]')) == null ? void 0 : _a.closest(".mt-2");
    if (reportRow) {
      reportRow.insertAdjacentElement("afterend", buttonsContainer);
      return;
    }
    targetElement.appendChild(buttonsContainer);
  };
  let injectTimer;
  const shouldInjectButtons = () => {
    return !!document.querySelector(INJECTION_SELECTOR) && !document.getElementById(JUMPER_CONTAINER_ID);
  };
  const scheduleInjection = (delay = 200) => {
    if (injectTimer) {
      clearTimeout(injectTimer);
    }
    injectTimer = setTimeout(() => {
      injectTimer = void 0;
      if (shouldInjectButtons()) {
        addButtons();
      }
    }, delay);
  };
  const observeSidebar = () => {
    const observer = new MutationObserver(() => {
      if (shouldInjectButtons()) {
        scheduleInjection(0);
      }
    });
    observer.observe(document.documentElement, {
      childList: true,
      subtree: true
    });
  };
  const setupNavigationListeners = () => {
    const handleNavigation = () => {
      scheduleInjection();
    };
    document.addEventListener("turbo:load", handleNavigation);
    document.addEventListener("turbo:render", handleNavigation);
    document.addEventListener("pjax:end", handleNavigation);
    window.addEventListener("popstate", handleNavigation);
    observeSidebar();
    scheduleInjection(0);
  };
  setupNavigationListeners();
  addButtons();

})();