Github Kích thước kho

hiện hữu github Thêm kích thước kho lưu trữ bên cạnh tên kho lưu trữ trên các trang tìm kiếm và kho lưu trữ

Tính đến 04-10-2024. Xem phiên bản mới nhất.

// ==UserScript==
// @name              Github Repo Size+
// @name:zh-CN        Github 仓库大小
// @description:zh-CN 在 github 搜索和存储库页面上的存储库名称旁边添加存储库大小
// @name:zh           Github 仓库大小
// @description:zh    在 github 搜索和存储库页面上的存储库名称旁边添加存储库大小
// @name:ar           Github حجم المستودع
// @description:ar    يخرج github أضف حجم المستودع بجوار اسم المستودع في صفحات البحث والمستودع
// @name:bg           Github Размер на склада
// @description:bg    съществуват github Добавете размер на хранилището до името на хранилището на страниците за търсене и хранилище
// @name:cs           Github Velikost skladu
// @description:cs    existovat github Přidejte velikost úložiště vedle názvu úložiště na stránkách vyhledávání a úložiště
// @name:da           Github Lagerstørrelse
// @description:da    eksistere github Tilføj lagerstørrelse ud for lagernavn på søge- og lagersider
// @name:de           Github Lagergröße
// @description:de    existieren github Fügen Sie auf Such- und Repository-Seiten neben dem Repository-Namen die Repository-Größe hinzu
// @name:el           Github Μέγεθος αποθήκης
// @description:el    υπάρχω github Προσθέστε μέγεθος αποθετηρίου δίπλα στο όνομα χώρου αποθήκευσης στις σελίδες αναζήτησης και αποθετηρίου
// @name:en           Github Warehouse size
// @description:en    exist github Add repository size next to repository name on search and repository pages
// @name:eo           Github Grando de magazeno
// @description:eo    ekzisti github Aldonu deponejan grandecon apud la nomo de deponejo sur serĉo kaj deponejo paĝoj
// @name:es           Github Tamaño del almacén
// @description:es    existir github Agregue el tamaño del repositorio junto al nombre del repositorio en las páginas de búsqueda y repositorio
// @name:fi           Github Varaston koko
// @description:fi    olemassa github Lisää arkiston koko arkiston nimen viereen haku- ja arkistosivuilla
// @name:fr           Github Taille de l’entrepôt
// @description:fr    exister github Ajouter la taille du référentiel à côté du nom du référentiel sur les pages de recherche et du référentiel
// @name:he           Github גודל המחסן
// @description:he    לְהִתְקַיֵם github הוסף גודל מאגר ליד שם המאגר בדפי החיפוש והמאגר
// @name:hr           Github Veličina skladišta
// @description:hr    postojati github Dodajte veličinu repozitorija pored naziva repozitorija na stranicama pretraživanja i repozitorija
// @name:hu           Github Raktár mérete
// @description:hu    létezik github Adja hozzá a lerakat méretét a lerakat neve mellett a keresési és lerakatoldalakon
// @name:id           Github Ukuran gudang
// @description:id    ada github Tambahkan ukuran repositori di sebelah nama repositori pada halaman pencarian dan repositori
// @name:it           Github Dimensioni del magazzino
// @description:it    esistere github Aggiungi la dimensione del repository accanto al nome del repository nelle pagine di ricerca e del repository
// @name:ja           Github 倉庫のサイズ
// @description:ja    存在する github 検索ページとリポジトリ ページでリポジトリ名の横にリポジトリ サイズを追加します
// @name:ka           Github საწყობის ზომა
// @description:ka    არსებობს github საძიებო და საცავის გვერდებზე საცავის სახელის გვერდით დაამატეთ საცავის ზომა
// @name:ko           Github 창고 규모
// @description:ko    존재하다 github 검색 및 저장소 페이지의 저장소 이름 옆에 저장소 크기 추가
// @name:nl           Github Grootte van magazijn
// @description:nl    bestaan github Voeg de repositorygrootte toe naast de repositorynaam op zoek- en repositorypagina’s
// @name:nb           Github Lagerstørrelse
// @description:nb    eksistere github Legg til depotstørrelse ved siden av depotnavnet på søke- og depotsidene
// @name:pl           Github Wielkość magazynu
// @description:pl    istnieć github Dodaj rozmiar repozytorium obok nazwy repozytorium na stronach wyszukiwania i repozytorium
// @name:pt-BR        Github Tamanho do armazém
// @description:pt-BR existir github Adicione o tamanho do repositório próximo ao nome do repositório nas páginas de pesquisa e do repositório
// @name:ro           Github Dimensiunea depozitului
// @description:ro    exista github Adăugați dimensiunea depozitului lângă numele depozitului pe paginile de căutare și depozit
// @name:ru           Github Размер склада
// @description:ru    существовать github Добавьте размер репозитория рядом с именем репозитория на страницах поиска и репозитория.
// @name:sk           Github Veľkosť skladu
// @description:sk    existujú github Pridajte veľkosť úložiska vedľa názvu úložiska na stránkach vyhľadávania a úložiska
// @name:sr           Github Величина магацина
// @description:sr    постоје github Додајте величину спремишта поред имена спремишта на страницама претраге и спремишта
// @name:sv           Github Lagerstorlek
// @description:sv    existera github Lägg till förvarsstorlek bredvid förvarets namn på sök- och förvarssidor
// @name:th           Github ขนาดคลังสินค้า
// @description:th    มีอยู่ github เพิ่มขนาดที่เก็บถัดจากชื่อที่เก็บในหน้าการค้นหาและที่เก็บ
// @name:tr           Github Depo boyutu
// @description:tr    var olmak github Arama ve depo sayfalarında depo adının yanına depo boyutunu ekleyin
// @name:ug           Github ئامبارنىڭ چوڭلۇقى
// @description:ug    مەۋجۇت github ئىزدەش ۋە ئامبار بېتىدىكى ئامبار نامىنىڭ يېنىغا ئامبار چوڭلۇقى قوشۇڭ
// @name:uk           Github Розмір складу
// @description:uk    існують github Додайте розмір сховища поруч із назвою сховища на сторінках пошуку та сховища
// @name:vi           Github Kích thước kho
// @description:vi    hiện hữu github Thêm kích thước kho lưu trữ bên cạnh tên kho lưu trữ trên các trang tìm kiếm và kho lưu trữ
// @name:zh-TW        Github 倉庫大小
// @description:zh-TW 在 github 搜尋和儲存庫頁面上的儲存庫名稱旁邊新增儲存庫大小
// @name:zh-HK        Github 倉庫大小
// @description:zh-HK 在 github 搜尋和儲存庫頁面上的儲存庫名稱旁邊新增儲存庫大小
// @name:fr-CA        Github Taille de l’entrepôt
// @description:fr-CA exister github Ajouter la taille du référentiel à côté du nom du référentiel sur les pages de recherche et du référentiel
// @namespace         https://github.com/ChinaGodMan/UserScripts
// @description       Adds the repo size next to the repo name on github search and repo pages
// @version           0.1.3.3
// @author            mshll & 人民的勤务员 <[email protected]>
// @match             https://github.com/*
// @grant             none
// @run-at            document-start
// @grant             GM_getValue
// @grant             GM_setValue
// @grant             GM_addStyle
// @grant             GM_registerMenuCommand
// @grant             none
// @icon              data:image/png;base64,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
// @iconbak           https://github.githubassets.com/pinned-octocat.svg
// @license           MIT
// @source            https://github.com/qinwuyuan-cn/UserScripts
// @run-at            document-start
// @supportURL        https://github.com/ChinaGodMan/UserScripts/issues
// @homepageURL       https://github.com/ChinaGodMan/UserScripts
// ==/UserScript==
"use strict"
const userLang =
    (navigator.languages && navigator.languages[0]) ||
    navigator.language ||
    "en"
const translations = {
    en: {
        save: "Save",
        cancel: "Cancel",
        modaltitle: "Set GitHub Token",
        description: 'Enter your GitHub personal access token with "repo" scope.',
        githubtokeninput: "Enter your GitHub personal access token",
        newtoken: "Click here to create a new token",
        warncheckbox: "  Inactive Development Warning",
        menu: "Set GitHub Token",
        renderWarning: "WARNING: repo has not received an update in 1+ year(s)",
        renderCaution: "Caution: repo has not received an update in 6+ months",
        confirm: "You have not entered a Token, confirm to clear the GitHub Token?",
        timediff: "Last commit was: {years} years, {months} months, {days} days ago ",
        view: "View[",
        allRepos: "]All repositories",
        newTab: "Open in a new tab when quickly viewing repositories",
    },
    "zh-CN,zh,zh-SG": {
        save: "保存",
        cancel: "取消",
        modaltitle: "设置 GitHub 令牌",
        description: '请输入您的 GitHub 个人访问令牌,需具备 "repo" 权限。',
        githubtokeninput: "请输入您的 GitHub 个人访问令牌",
        newtoken: "点击此处创建新的令牌",
        warncheckbox: " 非活跃开发警告",
        menu: "设置 GitHub 令牌",
        renderWarning: "警告:该仓库在 1 年以上未更新",
        renderCaution: "注意:该仓库在 6 个月以上未更新",
        confirm: "你没有输入Token,确认清空GitHub Token?",
        timediff: "最后一次提交距现在:{years}年{months}个月{days}天 ",
        view: "查看[",
        allRepos: "]所有仓库",
        newTab: "快速查看仓库时新窗口打开",

    },
    "zh-TW,zh-HK,zh-MO": {
        save: "保存",
        cancel: "取消",
        modaltitle: "設定 GitHub 令牌",
        description: '請輸入您的 GitHub 個人訪問令牌,需具備 "repo" 權限。',
        githubtokeninput: "請輸入您的 GitHub 個人訪問令牌",
        newtoken: "點擊此處創建新的令牌",
        warncheckbox: " 非活躍開發警告",
        menu: "設定 GitHub 令牌",
        renderWarning: "警告:該倉庫在 1 年以上未更新",
        renderCaution: "注意:該倉庫在 6 個月以上未更新",
        confirm: "你沒有輸入Token,確認清空GitHub Token?",
        timediff: "最後一次提交距現在:{years}年{months}個月{days}天 ",
    },
    vi: {
        save: "Lưu",
        cancel: "Hủy",
        modaltitle: "Đặt Token GitHub",
        description: 'Nhập token truy cập cá nhân GitHub của bạn với phạm vi "repo".',
        githubtokeninput: "Nhập token truy cập cá nhân GitHub của bạn",
        newtoken: "Nhấn vào đây để tạo token mới",
        warncheckbox: " Cảnh báo phát triển không hoạt động",
        menu: "Đặt Token GitHub",
        renderWarning: "CẢNH BÁO: kho lưu trữ đã không nhận được cập nhật trong hơn 1 năm",
        renderCaution: "Cảnh báo: kho lưu trữ đã không nhận được cập nhật trong hơn 6 tháng",
        confirm: "Bạn chưa nhập Token, xác nhận xóa GitHub Token?",
        timediff: "Lần commit cuối cách đây: {years} năm, {months} tháng, {days} ngày ",
    },
    ja: {
        save: "保存",
        cancel: "キャンセル",
        modaltitle: "GitHubトークンの設定",
        description: "「repo」スコープを持つGitHub個人アクセストークンを入力してください。",
        githubtokeninput: "GitHub個人アクセストークンを入力してください",
        newtoken: "新しいトークンを作成するにはここをクリックしてください",
        warncheckbox: " 非アクティブ開発警告",
        menu: "GitHubトークンの設定",
        renderWarning: "警告:リポジトリは1年以上更新されていません",
        renderCaution: "注意:リポジトリは6ヶ月以上更新されていません",
        confirm: "トークンが入力されていません。GitHubトークンをクリアしてもよろしいですか?",
        timediff: "最終コミットから現在まで:{years}年{months}ヶ月{days}日 ",
    },
    ko: {
        save: "저장",
        cancel: "취소",
        modaltitle: "GitHub 토큰 설정",
        description: "“repo” 범위를 가진 GitHub 개인 액세스 토큰을 입력하세요.",
        githubtokeninput: "GitHub 개인 액세스 토큰을 입력하세요",
        newtoken: "여기를 클릭하여 새 토큰을 만드세요",
        warncheckbox: " 비활성 개발 경고",
        menu: "GitHub 토큰 설정",
        renderWarning: "경고: 이 저장소는 1년 이상 업데이트되지 않았습니다",
        renderCaution: "주의: 이 저장소는 6개월 이상 업데이트되지 않았습니다",
        confirm: "토큰을 입력하지 않았습니다. GitHub 토큰을 지우시겠습니까?",
        timediff: "마지막 커밋 이후 경과: {years}년 {months}개월 {days}일 ",
    },
}
const getTranslations = (lang) => {
    for (const key in translations) {
        if (key === lang || key.split(",").includes(lang)) {
            return translations[key]
        }
    }
    return translations["en"]
}
const translate = new Proxy(
    function (key) {
        const lang = userLang
        const strings = getTranslations(lang)
        return strings[key] || translations["en"][key]
    },
    {
        get(target, prop) {
            const lang = userLang
            const strings = getTranslations(lang)
            return strings[prop] || translations["en"][prop]
        },
    }
)
//! Generate a new public access token from https://github.com/settings/tokens and insert it here
//*Note: to be able to see the size of your private repos, you need to select the `repo` scope when generating the token
let TOKEN = GM_getValue("githubToken", "")
let WARNING = GM_getValue("warn", true)
let openInNewTab = GM_getValue("openInNewTab", false)
GM_addStyle(`
    .modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);display:flex;justify-content:center;align-items:center;z-index:1000;}
    .modal-content{background:white;padding:20px;border-radius:8px;width:400px;box-shadow:0 4px 15px rgba(0,0,0,0.2);position:relative;}
    .modal-title{margin:0 0 10px 0;font-size:20px;}
    .modal-description{margin-bottom:20px;font-size:14px;color:#666;}
    .modal-description a{color:#007bff;text-decoration:underline;}
    #github-token-input{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;margin-bottom:20px;font-size:14px;}
    #save-token{background-color:#28a745;color:white;border:none;padding:10px 20px;cursor:pointer;border-radius:4px;margin-right:10px;}
    #cancel-token{background-color:#dc3545;color:white;border:none;padding:10px 20px;cursor:pointer;border-radius:4px;}
`)
function createModal() {
    const modalHTML = `
        <div class="modal-overlay">
            <div class="modal-content">
                <h2 class="modal-title">${translate.modaltitle}</h2>
                <p class="modal-description">
                    ${translate.description}
                    <a href="https://github.com/settings/tokens/new?description=GitHub%20Repo%20Size%20UserScript&scopes=repo" target="_blank" rel="noopener noreferrer">
                        ${translate.newtoken}
                    </a>
                </p>
                <input type="text" id="github-token-input" placeholder="${translate.githubtokeninput}">
                <label><input type="checkbox" id="warn">${translate.warncheckbox}</label><br>
                <label><input type="checkbox" id="openInNewTab">${translate.newTab}</label>
                <br>
                <hr>
                <button id="save-token">${translate.save}</button>
                <button id="cancel-token" class="cancel">${translate.cancel}</button>
            </div>
        </div>
    `
    const modalContainer = document.createElement("div")
    modalContainer.innerHTML = modalHTML
    document.body.appendChild(modalContainer)
    const input = document.getElementById("github-token-input")
    const warn = document.getElementById("warn")
    warn.checked = GM_getValue("warn", true)
    const newTab = document.getElementById("openInNewTab")
    newTab.checked = GM_getValue("openInNewTab", false)
    input.value = GM_getValue("githubToken", "")
    document.getElementById("save-token").addEventListener("click", () => {
        const token = input.value.trim()
        GM_setValue("warn", warn.checked)
        WARNING = warn.checked
        GM_setValue("openInNewTab", newTab.checked)
        openInNewTab = newTab.checked
        if (token) {
            GM_setValue("githubToken", token)
            modalContainer.remove()
            TOKEN = token
        } else {
            const userConfirmed = confirm(translate("confirm")) //提示是否删除
            if (userConfirmed) {
                GM_setValue("githubToken", token)
                modalContainer.remove()
                TOKEN = token
            }
        }
    })
    document
        .getElementById("cancel-token")
        .addEventListener("click", () => modalContainer.remove())
}
GM_registerMenuCommand(translate("menu"), function () {
    createModal()
})
const getPageType = () => {
    const { pathname, search } = window.location
    const params = new URLSearchParams(search)
    const [, username, repo] = pathname.split("/")
    const q = params.get("q")?.toLocaleLowerCase()
    const type = params.get("type")?.toLocaleLowerCase()
    if (window.location.pathname.split("/").pop() === "repositories")
        return "list-view-container"
    if (window.location.href.includes("?tab=repositories"))
        return "user-repositories"
    if (username && repo) return "repo"
    if (q && type === "code") return "code_search"
    if (q) return "search"
}
const addSizeToRepos = () => {
    const pageType = getPageType()
    // Get the repo selector based on the page type
    let repoSelector
    switch (pageType) {
        case "repo": //仓库详情界面
            repoSelector = "#repository-container-header strong a"
            break
        case "list-view-container": //ORG下的仓库列表
            repoSelector =
                'div[data-testid="list-view-item-title-container"] h4 a'
            break
        case "user-repositories": //用户资料页面的仓库TAB
            repoSelector = "#user-repositories-list h3 a"
            break
        case "search": //搜索
            repoSelector = 'div[data-testid="results-list"] .search-title a'
            break
        case "code_search": //代码搜索
            repoSelector = 'div[data-testid="results-list"] .search-title a'
            break
        default:
            return
    }
    function extractPath(input) {
        const thirdSlashIndex = input.indexOf(
            "/",
            input.indexOf("/", input.indexOf("/") + 1) + 1
        )
        if (thirdSlashIndex !== -1) {
            return input.substring(0, thirdSlashIndex)
        }
        return input
    }
    // Get all the repo links
    document.querySelectorAll(repoSelector).forEach(async (elem) => {
        // Get json data from github api to extract the size
        const tkn = TOKEN
        var href = elem.getAttribute("href")
        href = extractPath(href)
        //  console.log(href, elem)
        const headers = tkn ? { authorization: `token ${tkn}` } : {}
        const jsn = await (
            await fetch(`https://api.github.com/repos${href}`, {
                headers: headers,
            })
        ).json()
        if (
            repoSelector == "#repository-container-header strong a" &&
            WARNING
        ) {
            checkCommitDate(jsn.pushed_at)
        }
        // If JSON failed to load, skip
        if (jsn.message) return
        // Get parent element to append the size to
        let parent = elem.parentElement
        if (pageType === "repo") {
            const reposApi = isLoggedInUser(jsn.owner.avatar_url) ? 'https://api.github.com/user/repos' : jsn.owner.repos_url
            getUserRepos(reposApi, headers)
                .then(data => {
                    const reposArray = data.map(repo => ({
                        name: repo.name,
                        private: repo.private,
                        html_url: repo.html_url,
                        fork: repo.fork,
                        description: repo.description,
                        stargazers_count: repo.stargazers_count,
                        owner: repo.owner.login
                    }))

                    insertReposList(reposArray)


                })
                .catch(error => console.error('Error fetching data:', error))
            parent = elem.parentElement.parentElement
        }
        // Create the size container
        let sizeContainer = parent.querySelector(`#mshll-repo-size`)
        if (sizeContainer === null) {
            sizeContainer = document.createElement("span")
            sizeContainer.id = "mshll-repo-size"
            sizeContainer.classList.add(
                "Label",
                "Label--info",
                "v-align-middle",
                "ml-1"
            )
            sizeContainer.setAttribute("title", "Repository size")
            sizeContainer.innerText = "-"
            // Create the size icon
            let sizeSVG = document.createElementNS(
                "http://www.w3.org/2000/svg",
                "svg"
            )
            sizeSVG.setAttribute("aria-hidden", "true")
            sizeSVG.setAttribute("viewBox", "-4 -4 22 22")
            sizeSVG.setAttribute("width", "16")
            sizeSVG.setAttribute("height", "16")
            sizeSVG.setAttribute("fill", "currentColor")
            sizeSVG.setAttribute("data-view-component", "true")
            sizeSVG.classList.add("octicon", "octicon-file-directory", "mr-1")
            let sizeSVGPath = document.createElementNS(
                "http://www.w3.org/2000/svg",
                "path"
            )
            sizeSVGPath.setAttribute("fill-rule", "evenodd")
            sizeSVGPath.setAttribute(
                "d",
                "M1 3.5c0-.626.292-1.165.7-1.59.406-.422.956-.767 1.579-1.041C4.525.32 6.195 0 8 0c1.805 0 3.475.32 4.722.869.622.274 1.172.62 1.578 1.04.408.426.7.965.7 1.591v9c0 .626-.292 1.165-.7 1.59-.406.422-.956.767-1.579 1.041C11.476 15.68 9.806 16 8 16c-1.805 0-3.475-.32-4.721-.869-.623-.274-1.173-.62-1.579-1.04-.408-.426-.7-.965-.7-1.591Zm1.5 0c0 .133.058.318.282.551.227.237.591.483 1.101.707C4.898 5.205 6.353 5.5 8 5.5c1.646 0 3.101-.295 4.118-.742.508-.224.873-.471 1.1-.708.224-.232.282-.417.282-.55 0-.133-.058-.318-.282-.551-.227-.237-.591-.483-1.101-.707C11.102 1.795 9.647 1.5 8 1.5c-1.646 0-3.101.295-4.118.742-.508.224-.873.471-1.1.708-.224.232-.282.417-.282.55Zm0 4.5c0 .133.058.318.282.551.227.237.591.483 1.101.707C4.898 9.705 6.353 10 8 10c1.646 0 3.101-.295 4.118-.742.508-.224.873-.471 1.1-.708.224-.232.282-.417.282-.55V5.724c-.241.15-.503.286-.778.407C11.475 6.68 9.805 7 8 7c-1.805 0-3.475-.32-4.721-.869a6.15 6.15 0 0 1-.779-.407Zm0 2.225V12.5c0 .133.058.318.282.55.227.237.592.484 1.1.708 1.016.447 2.471.742 4.118.742 1.647 0 3.102-.295 4.117-.742.51-.224.874-.47 1.101-.707.224-.233.282-.418.282-.551v-2.275c-.241.15-.503.285-.778.406-1.247.549-2.917.869-4.722.869-1.805 0-3.475-.32-4.721-.869a6.327 6.327 0 0 1-.779-.406Z"
            )
            sizeSVG.appendChild(sizeSVGPath)
            // Convert the size to human readable
            const sizes = ["B", "KB", "MB", "GB", "TB"]
            const size = jsn.size * 1024 // Github API returns size in KB so convert to bytes
            let i = parseInt(Math.floor(Math.log(size) / Math.log(1024)))
            const humanReadableSize =
                (size / Math.pow(1024, i)).toFixed(1) + " " + sizes[i]
            // Insert the size into the size container
            sizeContainer.innerHTML = `${humanReadableSize}`
            sizeContainer.prepend(sizeSVG)
            // Insert the size container into the DOM
            if (pageType === "code_search") {
                parent.style.direction = "ltr"
            }
            if (!size) {
                sizeContainer.style.color = "red"
                sizeContainer.style.border = "1px solid red"
            }
            parent.appendChild(sizeContainer)
        }
    })
}
window.addSizeToRepos = addSizeToRepos
// Add the size to the repos on the page
window.onload = function () {
    //addSizeToRepos()
}
const selectors = [
    "#repository-container-header strong a", // 仓库详情界面
    'div[data-testid="list-view-item-title-container"] h4 a', // ORG下的仓库列表
    "#user-repositories-list h3 a", // 用户资料页面的仓库TAB
    'div[data-testid="results-list"] .search-title a', // 搜索
    // 'div[data-testid="results-list"] .search-title a' // 代码搜索
]
document.addEventListener('DOMContentLoaded', () => {
    main()
})
observeUrlChanges(main)
function main(delay = 0) {
    Promise.race(selectors.map((selector) => waitForElement(selector))).then(() => {
        setTimeout(() => {
            addSizeToRepos()
        }, delay)
    })
}
function observeUrlChanges(callback, delay = 10) {
    let lastUrl = location.href
    const observer = new MutationObserver(() => {
        const url = location.href
        if (url !== lastUrl) {
            lastUrl = url
            setTimeout(() => {
                console.log("链接改变,,,,,")
                callback()
            }, delay)
        }
    })
    observer.observe(document, { subtree: true, childList: true })
    return observer
}
function waitForElement(selector) {
    return new Promise((resolve) => {
        const observer = new MutationObserver(() => {
            if (document.querySelector(selector)) {
                resolve()
                observer.disconnect()
            } else {
                /*  */
            }
        })
        observer.observe(document.body, { childList: true, subtree: true })
    })
}
function displayMessage(el) {
    document
        .querySelector("#js-repo-pjax-container")
        .insertAdjacentElement("beforebegin", el)
}
function renderWarning(timediff) {
    const banner = document.createElement("div")
    banner.id = "zh-banner-warning"
    banner.setAttribute(
        "style",
        `
    background-color: red;
    height: 100px;
    margin-bottom: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    color: white;
    font-size: 36px;
    position: relative;
  `
    )
    banner.textContent = translate.renderWarning
    const smallTag = document.createElement("div")
    smallTag.setAttribute(
        "style",
        `
    position: absolute;
    bottom: 0;
    right: 0;
    padding: 5px 10px;
    font-size: 14px;
    border-top-left-radius: 5px;
  `
    )
    smallTag.textContent = timediff
    banner.appendChild(smallTag)
    displayMessage(banner)
}
function renderCaution(timediff) {
    const banner = document.createElement("div")
    banner.id = "zh-banner-warning"
    banner.setAttribute(
        "style",
        `
    background-color: yellow;
    height: 50px;
    margin-bottom: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 24px;
    position: relative;
  `
    )
    banner.textContent = translate.renderCaution
    const smallTag = document.createElement("div")
    smallTag.setAttribute(
        "style",
        `
    position: absolute;
    bottom: 0;
    right: 0;
    padding: 5px 10px;
    font-size: 14px;
    border-top-left-radius: 5px;
  `
    )
    smallTag.textContent = timediff
    banner.appendChild(smallTag)
    displayMessage(banner)
}
function checkCommitDate(datetimeString) {
    if (document.querySelector("#zh-banner-warning")) return
    const date = new Date(datetimeString)
    const now = new Date()
    const yearsDiff = now.getFullYear() - date.getFullYear()
    const monthsDiff = now.getMonth() - date.getMonth()
    const daysDiff = now.getDate() - date.getDate()
    let adjustedMonths = monthsDiff
    let adjustedDays = daysDiff
    if (adjustedDays < 0) {
        adjustedMonths--
        const lastMonth = new Date(now.getFullYear(), now.getMonth(), 0)
        adjustedDays += lastMonth.getDate()
    }
    let finalYears = yearsDiff
    if (adjustedMonths < 0) {
        finalYears--
        adjustedMonths += 12
    }
    let result = translate.timediff
    if (finalYears === 0) {
        result = result.replace(/{years}.*?(?={months})/, '')
    }
    result = result.replace('{years}', finalYears > 0 ? finalYears : '')
    result = result.replace('{months}', adjustedMonths)
    result = result.replace('{days}', adjustedDays)
    const daysSinceLastCommit = (Date.now() - date.getTime()) / 1000 / 60 / 60 / 24
    if (daysSinceLastCommit > 365) {
        renderWarning(result)
    } else if (daysSinceLastCommit > 182.5) {
        renderCaution(result)
    } else {
        /* noop */
    }
}
function insertReposList(links) {

    const gitHubStyle = `
#view-user-repos {
  order: 10;
}
#view-user-repos .dropdown-menu {
  min-width: 170px;
  width: auto;
}
#view-user-repos .dropdown-menu .dropdown-item .d-inline-flex {
  vertical-align:sub;
}`
    if (!document.head.querySelector('style[data-id="view-user-repos-css"]')) {
        const globalStyle = document.createElement('style')
        globalStyle.dataset.id = 'view-user-repos-css'
        globalStyle.innerHTML = gitHubStyle
        document.head.appendChild(globalStyle)
    }
    const existingButton = document.querySelector('button.types__StyledButton-sc-ws60qy-0.bmlmSe')
    if (existingButton) {
        const sortedLinks = links.sort((a, b) => {//!SECTION 排序
            // 首先比较 fork
            if (b.fork > 0 && a.fork <= 0) {
                return -1 // a 在前
            } else if (a.fork > 0 && b.fork <= 0) {
                return 1 // b 在前
            } else {
                // 如果 fork 相同,比较 private
                if (b.private === a.private) {
                    // 如果 private 相同,进一步判断 private 为 false 的情况
                    if (!a.private && !b.private) {
                        return b.stargazers_count - a.stargazers_count // stargazers_count 大的在前
                    }
                    return 0 // private 相同且不是 false 的情况下不排序
                }
                return (b.private ? -1 : 1) // private 为 true 的在前
            }
        })
        function getIconPath(link) {
            var fillColor = null
            if (link.private) fillColor = "green"
            if (!link.private && !link.fork) fillColor = "red"
            var svg = `<path fill="${fillColor}" fill-rule="evenodd" d="M1 3.5c0-.626.292-1.165.7-1.59.406-.422.956-.767 1.579-1.041C4.525.32 6.195 0 8 0c1.805 0 3.475.32 4.722.869.622.274 1.172.62 1.578 1.04.408.426.7.965.7 1.591v9c0 .626-.292 1.165-.7 1.59-.406.422-.956.767-1.579 1.041C11.476 15.68 9.806 16 8 16c-1.805 0-3.475-.32-4.721-.869-.623-.274-1.173-.62-1.579-1.04-.408-.426-.7-.965-.7-1.591Zm1.5 0c0 .133.058.318.282.551.227.237.591.483 1.101.707C4.898 5.205 6.353 5.5 8 5.5c1.646 0 3.101-.295 4.118-.742.508-.224.873-.471 1.1-.708.224-.232.282-.417.282-.55 0-.133-.058-.318-.282-.551-.227-.237-.591-.483-1.101-.707C11.102 1.795 9.647 1.5 8 1.5c-1.646 0-3.101.295-4.118.742-.508.224-.873.471-1.1.708-.224.232-.282.417-.282.55Zm0 4.5c0 .133.058.318.282.551.227.237.591.483 1.101.707C4.898 9.705 6.353 10 8 10c1.646 0 3.101-.295 4.118-.742.508-.224.873-.471 1.1-.708.224-.232.282-.417.282-.55V5.724c-.241.15-.503.286-.778.407C11.475 6.68 9.805 7 8 7c-1.805 0-3.475-.32-4.721-.869a6.15 6.15 0 0 1-.779-.407Zm0 2.225V12.5c0 .133.058.318.282.55.227.237.592.484 1.1.708 1.016.447 2.471.742 4.118.742 1.647 0 3.102-.295 4.117-.742.51-.224.874-.47 1.101-.707.224-.233.282-.418.282-.551v-2.275c-.241.15-.503.285-.778.406-1.247.549-2.917.869-4.722.869-1.805 0-3.475-.32-4.721-.869a6.327 6.327 0 0 1-.779-.406Z"></path>`
            if (fillColor) return svg
            if (link.fork) return `<path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path>`
        }

        let privateClassAdded = false
        let forkClassAdded = false
        const listItems = sortedLinks.map(link => {
            let liClass = ""
            if (link.private && !privateClassAdded) {
                liClass += "d-none d-md-block border-top"
                privateClassAdded = true
            }
            if (link.fork && !forkClassAdded) {
                liClass += "d-none d-md-block border-top"
                forkClassAdded = true
            }
            return `
        <li class="${liClass}">
            <a href="${link.html_url}" class="dropdown-item" ${(openInNewTab) ? 'target="_blank"' : ''} rel="noopener noreferrer">
                <span class="d-inline-flex mr-2">
                    <svg width="16" height="16" viewBox="0 0 16 16">
                        ${getIconPath(link)}
                    </svg>
                </span>
                ${link.name}
            </a>
        </li>
    `
        }).join('')

        const detailsHTML = `
<details id="view-user-repos" class="details-overlay details-reset position-relative d-flex">
    <summary role="button" type="button" class="btn text-center">
        <span class="d-none d-xl-flex flex-items-center">
             ${translate.view}<mark>${links[0].owner}</mark>${translate.allRepos}
            <span class="dropdown-caret ml-2"></span>
        </span>
        <span class="d-inline-block d-xl-none">
            ${links[0].owner} 
            <span class="dropdown-caret d-none d-sm-inline-block d-md-none d-lg-inline-block"></span>
        </span>
    </summary>
    <div>
        <ul class="dropdown-menu dropdown-menu-sw">
            ${listItems}
        </ul>
    </div>
</details>`
        existingButton.insertAdjacentHTML('beforebegin', detailsHTML)
    } else {

    }
}
function isLoggedInUser(avatar_url) {
    const imgElement = document.querySelector(".AppHeader-user button span span img")
    if (imgElement) {
        const imgSrc = imgElement.src
        return imgSrc === avatar_url
    } else {
        return false
    }
}
async function getUserRepos(href, header = {}) {
    try {
        const response = await fetch(`${href}`, {
            headers: header,
        })
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`)
        }
        return await response.json()
    } catch (error) {
        console.error('Fetch error:', error)
        throw error
    }
}
长期地址
遇到问题?请前往 GitHub 提 Issues。