GiteeTree

Gitee目录树生成与卡片化分享

Du musst eine Erweiterung wie Tampermonkey, Greasemonkey oder Violentmonkey installieren, um dieses Skript zu installieren.

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

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

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

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

Sie müssten eine Skript Manager Erweiterung installieren damit sie dieses Skript installieren können

(Ich habe schon ein Skript Manager, Lass mich es installieren!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         GiteeTree
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Gitee目录树生成与卡片化分享
// @author       Azad-sl
// @match        https://gitee.com/*
// @grant        GM_addStyle
// @grant        GM_xmlhttpRequest
// @grant        GM_setClipboard
// @grant        unsafeWindow
// @connect      gitee.com
// @require      https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js
// @resource     fontAwesome https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css
// @license      MIT
// @homepageURL  https://gitee.com/azad-sl/GiteeTree
// @supportURL  https://gitee.com/azad-sl/GiteeTree/issues
// ==/UserScript==

(function() {
    'use strict';
    GM_addStyle(`
        @import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css");

        .gitee-tree-btn {
            background-color: #4CAF50 !important;
            color: white !important;
            border: none !important;
            padding: 6px 12px !important;
            border-radius: 4px !important;
            cursor: pointer !important;
            font-weight: 500 !important;
            display: inline-flex !important;
            align-items: center !important;
            transition: background-color 0.2s !important;
            font-size: 14px !important;
            height: 32px !important;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2) !important;
        }
        .gitee-tree-btn:hover {
            background-color: #3d8b40 !important;
            transform: translateY(-1px) !important;
            box-shadow: 0 4px 8px rgba(0,0,0,0.2) !important;
        }
        .gitee-tree-btn-fixed {
            position: fixed !important;
            top: 70px !important;
            right: 20px !important;
            z-index: 9999 !important;
        }
        .gitee-tree-modal {
            display: none;
            position: fixed;
            z-index: 10000;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            backdrop-filter: blur(5px);
        }
        .gitee-tree-modal-content {
            background-color: white;
            margin: 5% auto;
            padding: 20px;
            border-radius: 16px;
            width: 90%;
            max-width: 900px;
            max-height: 85vh;
            overflow-y: auto;
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3);
        }
        @media (max-width: 768px) {
            .gitee-tree-modal-content {
                width: 95%;
                max-width: 95%;
                margin: 10% auto;
                padding: 15px;
            }
        }
        @media (max-width: 480px) {
            .gitee-tree-modal-content {
                width: 98%;
                max-width: 98%;
                margin: 15% auto;
                padding: 10px;
            }
        }
        .gitee-tree-modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 1px solid #eee;
        }
        .gitee-tree-modal-title {
            font-size: 1.5rem;
            font-weight: 600;
            color: #1a202c;
            display: flex;
            align-items: center;
        }
        .gitee-tree-close {
            color: #aaa;
            font-size: 28px;
            font-weight: bold;
            cursor: pointer;
            transition: color 0.3s ease;
        }
        .gitee-tree-close:hover {
            color: #667eea;
        }
        .gitee-tree-logo {
            width: 28px;
            height: 28px;
            margin-right: 10px;
            fill: #c71d23;
            display: inline-block;
            vertical-align: middle;
        }
        .gitee-tree-input-field {
            background: rgba(255, 255, 255, 0.9);
            border: 1px solid rgba(0, 0, 0, 0.1);
            border-radius: 8px;
            padding: 0.75rem 1rem;
            font-size: 1rem;
            transition: all 0.3s ease;
            width: 100%;
            margin-bottom: 10px;
        }
        .gitee-tree-input-field:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
        }
        .gitee-tree-btn-primary {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 8px;
            padding: 0.75rem 1.5rem;
            font-weight: 500;
            transition: all 0.3s ease;
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
            cursor: pointer;
        }
        .gitee-tree-btn-primary:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
        }
        .gitee-tree-btn-secondary {
            background: rgba(255, 255, 255, 0.9);
            color: #4b5563;
            border: 1px solid rgba(0, 0, 0, 0.1);
            border-radius: 8px;
            padding: 0.5rem 1rem;
            font-weight: 500;
            transition: all 0.3s ease;
            cursor: pointer;
            margin-right: 8px;
            margin-bottom: 8px;
        }
        .gitee-tree-btn-secondary:hover {
            background: rgba(255, 255, 255, 1);
            transform: translateY(-1px);
        }
        .gitee-tree-section-title {
            font-size: 1.2rem;
            font-weight: 600;
            color: #1a202c;
            margin-bottom: 1rem;
            display: flex;
            align-items: center;
        }
        .gitee-tree-result-container {
            background: rgba(255, 255, 255, 0.9);
            border-radius: 12px;
            padding: 1.5rem;
            margin-top: 1.5rem;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
        }
        .gitee-tree-directory-tree-container {
            background: rgba(249, 250, 251, 0.8);
            border-radius: 8px;
            padding: 1rem;
            max-height: 400px;
            overflow-y: auto;
            font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
            line-height: 1.6;
        }
        .gitee-tree-advanced-options {
            background-color: #f9fafb;
            border-radius: 12px;
            padding: 16px;
            margin-top: 16px;
            margin-bottom: 16px;
        }
        .gitee-tree-advanced-options-title {
            font-weight: 600;
            margin-bottom: 12px;
            color: #4b5563;
            display: flex;
            align-items: center;
        }
        .gitee-tree-advanced-options-content {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 16px;
        }
        .gitee-tree-option-group {
            display: flex;
            flex-direction: column;
        }
        .gitee-tree-option-label {
            font-size: 0.875rem;
            font-weight: 500;
            color: #4b5563;
            margin-bottom: 6px;
        }
        .gitee-tree-loader-container {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 2rem;
        }
        .gitee-tree-loader {
            width: 40px;
            height: 40px;
            position: relative;
        }
        .gitee-tree-loader-circle {
            position: absolute;
            width: 100%;
            height: 100%;
            border-radius: 50%;
            border: 3px solid transparent;
            border-top-color: #667eea;
            animation: spin 1.5s cubic-bezier(0.68, -0.55, 0.265, 1.55) infinite;
        }
        .gitee-tree-loader-circle:nth-child(2) {
            width: 80%;
            height: 80%;
            top: 10%;
            left: 10%;
            border-top-color: #764ba2;
            animation-delay: 0.2s;
        }
        .gitee-tree-loader-circle:nth-child(3) {
            width: 60%;
            height: 60%;
            top: 20%;
            left: 20%;
            border-top-color: #9f7aea;
            animation-delay: 0.4s;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        .gitee-tree-loader-text {
            margin-top: 1rem;
            color: #6b7280;
            font-size: 0.875rem;
        }
        .gitee-tree-loader-dots {
            display: inline-flex;
            gap: 4px;
        }
        .gitee-tree-loader-dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background-color: #667eea;
            animation: bounce 1.4s infinite ease-in-out both;
        }
        .gitee-tree-loader-dot:nth-child(1) { animation-delay: -0.32s; }
        .gitee-tree-loader-dot:nth-child(2) { animation-delay: -0.16s; }
        @keyframes bounce {
            0%, 80%, 100% { transform: scale(0); }
            40% { transform: scale(1); }
        }
        .gitee-tree-error-section {
            margin-top: 1rem;
            background: #fee;
            border: 1px solid #fcc;
            border-radius: 8px;
            padding: 1rem;
            color: #c33;
        }
        .gitee-tree-flex {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            margin-bottom: 16px;
        }
        .gitee-tree-dropdown {
            position: relative;
            display: inline-block;
        }
        .gitee-tree-dropdown-content {
            display: none;
            position: absolute;
            background-color: #f9f9f9;
            min-width: 120px;
            box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
            z-index: 1;
            border-radius: 8px;
            overflow: hidden;
        }
        .gitee-tree-dropdown-content a {
            color: #333;
            padding: 8px 12px;
            text-decoration: none;
            display: block;
        }
        .gitee-tree-dropdown-content a:hover {
            background-color: #f1f1f1;
        }
        .gitee-tree-dropdown:hover .gitee-tree-dropdown-content {
            display: block;
        }

        .gitee-tree-mac-button-red {
            background-color: #ff5f57 !important;
        }
        .gitee-tree-mac-button-yellow {
            background-color: #ffbd2e !important;
        }
        .gitee-tree-mac-button-green {
            background-color: #28ca42 !important;
        }

        .gitee-tree-mac-card {
            background: linear-gradient(145deg, #2d3748, #1a202c);
            border-radius: 16px;
            overflow: hidden;
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3);
            backdrop-filter: blur(10px);
            width: 400px;
            max-width: 90%;
            margin: 0 auto;
        }
        .gitee-tree-mac-header {
            background: linear-gradient(145deg, #4a5568, #2d3748);
            padding: 10px 16px; 
            display: flex;
            align-items: center;
            gap: 8px;
        }
        .gitee-tree-mac-button {
            width: 12px;
            height: 12px;
            border-radius: 50%;
        }
        .gitee-tree-mac-content {
            padding: 20px; 
            display: flex;
            gap: 20px;
            align-items: flex-start;
        }
        .gitee-tree-mac-info {
            flex: 1;
            color: #e2e8f0;
        }
        .gitee-tree-mac-title {
            font-size: 1.25rem;
            font-weight: 600;
            color: #f7fafc;
            margin-bottom: 8px;
            display: flex;
            align-items: center;
        }
        .gitee-tree-mac-desc {
            font-size: 0.875rem;
            color: #cbd5e0;
            margin-bottom: 16px;
            overflow: hidden;
            text-overflow: ellipsis;
            display: -webkit-box;
            -webkit-line-clamp: 3;
            -webkit-box-orient: vertical;
        }
        .gitee-tree-mac-stats {
            display: flex;
            gap: 16px;
            font-size: 0.875rem;
        }

        .gitee-tree-gitee-card {
            background: #ffffff;
            border: 1px solid #d0d7de;
            border-radius: 12px;
            overflow: hidden;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
            width: 400px;
            max-width: 90%;
            margin: 0 auto;
        }
        .gitee-tree-gitee-header {
            background: #f6f8fa;
            padding: 10px 16px; 
            border-bottom: 1px solid #d0d7de;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        .gitee-tree-gitee-title {
            font-size: 1.25rem;
            font-weight: 600;
            color: #0969da;
            display: flex;
            align-items: center;
        }
        .gitee-tree-gitee-badge {
            background: #ddf4ff;
            color: #0969da;
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 0.75rem;
            font-weight: 500;
            margin-left: auto;
        }
        .gitee-tree-gitee-content {
            padding: 16px;
            display: flex;
            gap: 20px;
        }
        .gitee-tree-gitee-info {
            flex: 1;
        }
        .gitee-tree-gitee-desc {
            color: #656d76;
            margin-bottom: 16px;
            overflow: hidden;
            text-overflow: ellipsis;
            display: -webkit-box;
            -webkit-line-clamp: 3;
            -webkit-box-orient: vertical;
        }
        .gitee-tree-gitee-stats {
            display: flex;
            gap: 16px;
            font-size: 0.875rem;
            color: #656d76;
        }

        .gitee-tree-material-card {
            background: #ffffff;
            border-radius: 12px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.08);
            overflow: hidden;
            width: 400px;
            max-width: 90%;
            margin: 0 auto;
        }
        .gitee-tree-material-content {
            padding: 20px; 
        }
        .gitee-tree-material-top {
            display: flex;
            gap: 20px;
            align-items: flex-start;
            margin-bottom: 16px; 
        }
        .gitee-tree-material-info {
            flex: 1;
        }
        .gitee-tree-material-title {
            font-size: 1.5rem;
            font-weight: 400;
            color: #202124;
            margin-bottom: 8px;
            display: flex;
            align-items: center;
        }
        .gitee-tree-material-desc {
            color: #5f6368;
            line-height: 1.5;
            overflow: hidden;
            text-overflow: ellipsis;
            display: -webkit-box;
            -webkit-line-clamp: 3;
            -webkit-box-orient: vertical;
        }
        .gitee-tree-material-divider {
            height: 1px;
            background: #e8eaed;
            margin: 16px 0; 
        }
        .gitee-tree-material-stats {
            display: flex;
            justify-content: space-between;
            align-items: center;
            color: #5f6368;
        }
        .gitee-tree-material-stats-left {
            display: flex;
            gap: 20px;
        }

        .gitee-tree-modern-card {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-radius: 16px;
            color: white;
            overflow: hidden;
            box-shadow: 0 10px 30px rgba(102, 126, 234, 0.3);
            width: 400px;
            max-width: 90%;
            margin: 0 auto;
        }
        .gitee-tree-modern-content {
            padding: 20px 28px; 
        }
        .gitee-tree-modern-title {
            font-size: 1.5rem;
            font-weight: 600;
            margin-bottom: 8px;
            display: flex;
            align-items: center;
        }
        .gitee-tree-modern-desc {
            opacity: 0.9;
            margin-bottom: 20px; 
            line-height: 1.5;
            overflow: hidden;
            text-overflow: ellipsis;
            display: -webkit-box;
            -webkit-line-clamp: 3;
            -webkit-box-orient: vertical;
        }
        .gitee-tree-modern-footer {
            display: flex;
            justify-content: space-between;
            align-items: flex-end;
        }
        .gitee-tree-modern-stats {
            display: flex;
            flex-direction: column;
            gap: 8px;
        }
        .gitee-tree-modern-stat {
            opacity: 0.9;
            font-size: 0.9rem;
        }

        .gitee-tree-qr-container {
            background: white;
            padding: 8px;
            border-radius: 8px;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-shrink: 0;
        }
        .gitee-tree-mac-tree-container {
            background: linear-gradient(145deg, #2d3748, #1a202c);
            border-radius: 16px;
            overflow: hidden;
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3);
            width: 900px;
            color: #e2e8f0;
        }
        .gitee-tree-mac-tree-header {
            background: linear-gradient(145deg, #4a5568, #2d3748);
            padding: 12px 16px;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        .gitee-tree-mac-tree-content {
            padding: 20px;
            font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
            line-height: 1.6;
            white-space: pre;
            overflow: visible;
            font-size: 14px;
        }
        .gitee-tree-token-status {
            margin-top: 8px;
            color: #28a745;
            font-size: 0.875rem;
            display: none;
        }
        .gitee-tree-token-status.active {
            display: block;
        }
        .fas, .far, .fab {
            display: inline-block;
            font-style: normal;
            font-variant: normal;
            text-rendering: auto;
            line-height: 1;
        }
    `);
    
    function createTreeButton() {
        const treeButton = document.createElement('button');
        treeButton.className = 'gitee-tree-btn gitee-tree-btn-fixed';
        treeButton.innerHTML = '<i class="fas fa-tree"></i> GiteeTree';
        treeButton.title = '生成Gitee项目目录树';
        document.body.appendChild(treeButton);
        treeButton.addEventListener('click', openTreeModal);
    }
    function createTreeModal() {
        const modal = document.createElement('div');
        modal.className = 'gitee-tree-modal';
        modal.id = 'giteeTreeModal';
        const modalContent = document.createElement('div');
        modalContent.className = 'gitee-tree-modal-content';
        const modalHeader = document.createElement('div');
        modalHeader.className = 'gitee-tree-modal-header';
        const modalTitle = document.createElement('h2');
        modalTitle.className = 'gitee-tree-modal-title';
        modalTitle.innerHTML = `
            <svg class="gitee-tree-logo" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
                <path d="M512 1024C229.2224 1024 0 794.7776 0 512S229.2224 0 512 0s512 229.2224 512 512-229.2224 512-512 512z m259.1488-568.8832H480.4096a25.2928 25.2928 0 0 0-25.2928 25.2928l-0.0256 63.2064c0 13.952 11.3152 25.2928 25.2672 25.2928h177.024c13.9776 0 25.2928 11.3152 25.2928 25.2672v12.6464a75.8528 75.8528 0 0 1-75.8528 75.8528H366.592a25.2928 25.2928 0 0 1-25.2672-25.2928v-240.1792a75.8528 75.8528 0 0 1 75.8272-75.8528h353.9456a25.2928 25.2928 0 0 0 25.2672-25.2928l0.0768-63.2064a25.2928 25.2928 0 0 0-25.2672-25.2928H417.152a189.6192 189.6192 0 0 0-189.6192 189.6448v353.9456c0 13.9776 11.3152 25.2928 25.2928 25.2928h372.9408a170.6496 170.6496 0 0 0 170.6496-170.6496v-145.408a25.2928 25.2928 0 0 0-25.2928-25.2672z" fill="currentColor"></path>
            </svg>
            GiteeTree - Gitee目录树生成与卡片化分享
        `;
        const closeButton = document.createElement('span');
        closeButton.className = 'gitee-tree-close';
        closeButton.innerHTML = '&times;';
        closeButton.addEventListener('click', closeTreeModal);
        modalHeader.appendChild(modalTitle);
        modalHeader.appendChild(closeButton);
        const modalBody = document.createElement('div');
        modalBody.className = 'gitee-tree-modal-body';
        modalBody.innerHTML = `
            <div class="gitee-tree-section">
                <details>
                    <summary class="cursor-pointer flex justify-between items-center text-lg font-semibold text-gray-700 hover:text-gray-900 transition duration-200">
                        <span><i class="fas fa-key mr-2"></i>API 访问令牌设置</span>
                        <i class="fas fa-chevron-down transform transition-transform duration-200"></i>
                    </summary>
                    <div class="mt-4 space-y-4 pt-4 border-t border-gray-100">
                        <div>
                            <label class="block text-sm font-medium text-gray-700 mb-2">Gitee 个人访问令牌</label>
                            <div class="flex space-x-2">
                                <input type="password" id="giteeTreeTokenInput" placeholder="输入你的 Gitee 个人访问令牌" class="flex-1 gitee-tree-input-field">
                                <button id="giteeTreeSaveTokenBtn" class="gitee-tree-btn-secondary">保存</button>
                            </div>
                        </div>
                        <div class="bg-blue-50 border border-blue-200 rounded-lg p-4">
                            <p class="text-sm text-blue-700">
                                <i class="fas fa-info-circle mr-2"></i>
                                <strong>如何获取访问令牌:</strong><br>
                                请访问 <a href="https://gitee.com/profile/personal_access_tokens" target="_blank" class="font-semibold underline hover:text-blue-800">Gitee 个人访问令牌页面 <i class="fas fa-external-link-alt text-xs"></i></a> 生成新令牌,确保勾选 <code class="bg-blue-100 px-1 rounded">user_info</code> 和 <code class="bg-blue-100 px-1 rounded">projects</code> 权限。
                            </p>
                        </div>
                        <div id="giteeTreeTokenStatus" class="gitee-tree-token-status">
                            <div class="flex items-center space-x-2 text-green-600">
                                <i class="fas fa-check-circle"></i>
                                <span class="text-sm">访问令牌已保存</span>
                            </div>
                        </div>
                    </div>
                </details>
            </div>
            <div class="gitee-tree-section">
                <h2 class="gitee-tree-section-title">
                    <i class="fas fa-tools mr-2"></i>项目地址
                </h2>
                <div class="space-y-4">
                    <input type="text" id="giteeTreeProjectInput" placeholder="例如:gitee.com/owner/repo 或 owner/repo" class="gitee-tree-input-field">
                    <div class="gitee-tree-advanced-options">
                        <div class="gitee-tree-advanced-options-title">
                            <i class="fas fa-cog mr-2"></i>高级选项
                        </div>
                        <div class="gitee-tree-advanced-options-content">
                            <div class="gitee-tree-option-group">
                                <label class="gitee-tree-option-label">目录深度</label>
                                <select id="giteeTreeDepthSelect" class="gitee-tree-input-field">
                                    <option value="1">1层(仅根目录)</option>
                                    <option value="2">2层</option>
                                    <option value="3">3层</option>
                                    <option value="4">4层</option>
                                    <option value="5">5层</option>
                                    <option value="0">全部(无限制)</option>
                                </select>
                            </div>
                            <div class="gitee-tree-option-group">
                                <label class="gitee-tree-option-label">显示内容</label>
                                <select id="giteeTreeViewTypeSelect" class="gitee-tree-input-field">
                                    <option value="all">完整视图(文件和文件夹)</option>
                                    <option value="folders">仅文件夹</option>
                                </select>
                            </div>
                        </div>
                    </div>
                    <div class="gitee-tree-flex">
                        <button id="giteeTreeGenerateDirBtn" class="gitee-tree-btn-primary flex items-center justify-center space-x-2 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
                            <i class="fas fa-folder-tree"></i>
                            <span>生成目录树</span>
                        </button>
                        <button id="giteeTreeGenerateCardBtn" class="gitee-tree-btn-primary flex items-center justify-center space-x-2 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
                            <i class="fas fa-id-card"></i>
                            <span>生成分享卡片</span>
                        </button>
                    </div>
                </div>
                <div id="giteeTreeDirLoadingSection" class="gitee-tree-loader-container" style="display: none;">
                    <div class="gitee-tree-loader">
                        <div class="gitee-tree-loader-circle"></div>
                        <div class="gitee-tree-loader-circle"></div>
                        <div class="gitee-tree-loader-circle"></div>
                    </div>
                    <div class="gitee-tree-loader-text">
                        正在获取项目目录结构
                        <div class="gitee-tree-loader-dots">
                            <div class="gitee-tree-loader-dot"></div>
                            <div class="gitee-tree-loader-dot"></div>
                            <div class="gitee-tree-loader-dot"></div>
                        </div>
                    </div>
                </div>
                <div id="giteeTreeDirResultSection" style="display: none;">
                    <div class="gitee-tree-result-container">
                        <div class="gitee-tree-flex justify-between items-start mb-4 gap-4">
                            <h3 class="text-lg font-semibold text-gray-700">
                                <i class="fas fa-folder-tree mr-2"></i>项目目录树
                            </h3>
                            <div class="gitee-tree-flex">
                                <button id="giteeTreeCopyTextBtn" class="gitee-tree-btn-secondary">
                                    <i class="fas fa-copy mr-1"></i>复制文本
                                </button>
                                <button id="giteeTreeCopyMarkdownBtn" class="gitee-tree-btn-secondary">
                                    <i class="fas fa-code mr-1"></i>复制Markdown
                                </button>
                                <button id="giteeTreeDownloadImageBtn" class="gitee-tree-btn-secondary">
                                    <i class="fas fa-image mr-1"></i>导出图片
                                </button>
                                <div class="gitee-tree-dropdown">
                                    <button id="giteeTreeDownloadScriptBtn" class="gitee-tree-btn-secondary">
                                        <i class="fas fa-file-code mr-1"></i>下载脚本 <i class="fas fa-caret-down ml-1"></i>
                                    </button>
                                    <div class="gitee-tree-dropdown-content">
                                        <a id="giteeTreeDownloadBatBtn" href="#">Windows (.bat)</a>
                                        <a id="giteeTreeDownloadShBtn" href="#">Linux/Mac (.sh)</a>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div id="giteeTreeDirectoryTreeContainer" class="gitee-tree-directory-tree-container"></div>
                    </div>
                </div>
                <div id="giteeTreeCardLoadingSection" class="gitee-tree-loader-container" style="display: none;">
                    <div class="gitee-tree-loader">
                        <div class="gitee-tree-loader-circle"></div>
                        <div class="gitee-tree-loader-circle"></div>
                        <div class="gitee-tree-loader-circle"></div>
                    </div>
                    <div class="gitee-tree-loader-text">
                        正在生成项目分享卡片
                        <div class="gitee-tree-loader-dots">
                            <div class="gitee-tree-loader-dot"></div>
                            <div class="gitee-tree-loader-dot"></div>
                            <div class="gitee-tree-loader-dot"></div>
                        </div>
                    </div>
                </div>
                <div id="giteeTreeCardResultSection" style="display: none;">
                    <div class="gitee-tree-result-container">
                        <div class="gitee-tree-flex justify-between items-start mb-4 gap-4">
                            <h3 class="text-lg font-semibold text-gray-700">
                                <i class="fas fa-id-card mr-2"></i>项目分享卡片
                            </h3>
                            <div class="gitee-tree-flex">
                                <div>
                                    <label class="block text-sm font-medium text-gray-700 mb-1">卡片风格</label>
                                    <select id="giteeTreeCardStyleSelect" class="gitee-tree-input-field text-sm">
                                        <option value="mac">macOS 风格</option>
                                        <option value="gitee">Gitee 风格</option>
                                        <option value="material">Material 风格</option>
                                        <option value="modern">现代风格</option>
                                    </select>
                                </div>
                                <button id="giteeTreeDownloadCardBtn" class="gitee-tree-btn-secondary self-end">
                                    <i class="fas fa-download mr-1"></i>下载卡片
                                </button>
                            </div>
                        </div>
                        <div class="flex justify-center">
                            <div id="giteeTreeShareCardContainer" class="w-full max-w-md"></div>
                        </div>
                    </div>
                </div>
                <div id="giteeTreeErrorSection" class="gitee-tree-error-section" style="display: none;">
                    <div class="flex items-center">
                        <i class="fas fa-exclamation-circle text-red-600 text-xl mr-3"></i>
                        <div>
                            <h3 class="text-lg font-semibold text-red-800">获取失败</h3>
                            <p class="text-red-600 mt-1" id="giteeTreeErrorMessage"></p>
                        </div>
                    </div>
                </div>
            </div>
        `;
        modalContent.appendChild(modalHeader);
        modalContent.appendChild(modalBody);
        modal.appendChild(modalContent);
        document.body.appendChild(modal);
        initializeEventListeners();
    }
    function initializeEventListeners() {
        document.getElementById('giteeTreeSaveTokenBtn').addEventListener('click', () => {
            const token = document.getElementById('giteeTreeTokenInput').value.trim();
            if (token) {
                localStorage.setItem('gitee_token', token);
                document.getElementById('giteeTreeTokenStatus').classList.add('active');
                document.getElementById('giteeTreeGenerateDirBtn').disabled = false;
                document.getElementById('giteeTreeGenerateCardBtn').disabled = false;
            }
        });
        document.getElementById('giteeTreeGenerateDirBtn').addEventListener('click', async () => {
            const input = document.getElementById('giteeTreeProjectInput').value.trim();
            if (!input) {
                showError('请输入项目地址或路径');
                return;
            }
            const depth = parseInt(document.getElementById('giteeTreeDepthSelect').value);
            const viewType = document.getElementById('giteeTreeViewTypeSelect').value;
            try {
                const { owner, repo } = parseProjectPath(input);
                document.getElementById('giteeTreeDirLoadingSection').style.display = 'flex';
                document.getElementById('giteeTreeDirResultSection').style.display = 'none';
                document.getElementById('giteeTreeErrorSection').style.display = 'none';
                const [projectInfo, directory] = await Promise.all([
                    getProjectInfo(owner, repo),
                    getProjectDirectoryRecursive(owner, repo, '', 0, depth)
                ]);
                currentProjectInfo = projectInfo;
                currentDirectoryItems = directory;
                fullDirectoryTree = `${projectInfo.name}\n${generateDirectoryTreeText(directory, '', 'all')}`;
                currentDirectoryTree = `${projectInfo.name}\n${generateDirectoryTreeText(directory, '', viewType)}`;
                document.getElementById('giteeTreeDirectoryTreeContainer').innerHTML = `<pre>${currentDirectoryTree}</pre>`;
                document.getElementById('giteeTreeDirLoadingSection').style.display = 'none';
                document.getElementById('giteeTreeDirResultSection').style.display = 'block';
            } catch (error) {
                showError(error.message);
            }
        });
        document.getElementById('giteeTreeGenerateCardBtn').addEventListener('click', async () => {
            const input = document.getElementById('giteeTreeProjectInput').value.trim();
            if (!input) {
                showError('请输入项目地址或路径');
                return;
            }
            try {
                const { owner, repo } = parseProjectPath(input);
                document.getElementById('giteeTreeCardLoadingSection').style.display = 'flex';
                document.getElementById('giteeTreeCardResultSection').style.display = 'none';
                document.getElementById('giteeTreeErrorSection').style.display = 'none';
                currentProjectInfo = await getProjectInfo(owner, repo);
                const container = document.getElementById('giteeTreeShareCardContainer');
                container.innerHTML = '';
                const card = generateShareCard(currentProjectInfo, selectedCardStyle);
                container.appendChild(card);
                document.getElementById('giteeTreeCardLoadingSection').style.display = 'none';
                document.getElementById('giteeTreeCardResultSection').style.display = 'block';
            } catch (error) {
                showError(error.message);
            }
        });
        document.getElementById('giteeTreeCopyTextBtn').addEventListener('click', () => {
            if (currentDirectoryTree) {
                GM_setClipboard(currentDirectoryTree);
                showButtonFeedback(document.getElementById('giteeTreeCopyTextBtn'));
            }
        });
        document.getElementById('giteeTreeCopyMarkdownBtn').addEventListener('click', () => {
            if (currentDirectoryTree) {
                const markdown = `\`\`\`\n${currentDirectoryTree}\`\`\``;
                GM_setClipboard(markdown);
                showButtonFeedback(document.getElementById('giteeTreeCopyMarkdownBtn'));
            }
        });
        document.getElementById('giteeTreeDownloadImageBtn').addEventListener('click', async () => {
            if (!fullDirectoryTree || !currentProjectInfo) return;
            const tempContainer = document.createElement('div');
            tempContainer.style.position = 'absolute';
            tempContainer.style.left = '-9999px';
            const macTreeContainer = document.createElement('div');
            macTreeContainer.className = 'gitee-tree-mac-tree-container';
            const macHeader = document.createElement('div');
            macHeader.className = 'gitee-tree-mac-tree-header';
            macHeader.innerHTML = `
                <div class="gitee-tree-mac-button gitee-tree-mac-button-red"></div>
                <div class="gitee-tree-mac-button gitee-tree-mac-button-yellow"></div>
                <div class="gitee-tree-mac-button gitee-tree-mac-button-green"></div>
                <div style="margin-left: 10px; display: flex; align-items: center;">
                    <svg class="gitee-tree-logo" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
                        <path d="M512 1024C229.2224 1024 0 794.7776 0 512S229.2224 0 512 0s512 229.2224 512 512-229.2224 512-512 512z m259.1488-568.8832H480.4096a25.2928 25.2928 0 0 0-25.2928 25.2928l-0.0256 63.2064c0 13.952 11.3152 25.2928 25.2672 25.2928h177.024c13.9776 0 25.2928 11.3152 25.2928 25.2672v12.6464a75.8528 75.8528 0 0 1-75.8528 75.8528H366.592a25.2928 25.2928 0 0 1-25.2672-25.2928v-240.1792a75.8528 75.8528 0 0 1 75.8272-75.8528h353.9456a25.2928 25.2928 0 0 0 25.2672-25.2928l0.0768-63.2064a25.2928 25.2928 0 0 0-25.2672-25.2928H417.152a189.6192 189.6192 0 0 0-189.6192 189.6448v353.9456c0 13.9776 11.3152 25.2928 25.2928 25.2928h372.9408a170.6496 170.6496 0 0 0 170.6496-170.6496v-145.408a25.2928 25.2928 0 0 0-25.2928-25.2672z" fill="currentColor"></path>
                    </svg>
                    <span style="color: #f7fafc; font-weight: 600;">${currentProjectInfo.full_name}</span>
                </div>
            `;
            const macContent = document.createElement('div');
            macContent.className = 'gitee-tree-mac-tree-content';
            macContent.textContent = fullDirectoryTree;
            macTreeContainer.appendChild(macHeader);
            macTreeContainer.appendChild(macContent);
            tempContainer.appendChild(macTreeContainer);
            document.body.appendChild(tempContainer);
            try {
                const contentHeight = macContent.scrollHeight;
                macTreeContainer.style.height = (contentHeight + 80) + 'px'; // 80px是头部高度
                const canvas = await html2canvas(macTreeContainer, {
                    backgroundColor: null,
                    scale: 2,
                    height: contentHeight + 80,
                    windowHeight: contentHeight + 80
                });
                const link = document.createElement('a');
                link.download = `${currentProjectInfo.full_name.replace('/', '-')}-directory.png`;
                link.href = canvas.toDataURL('image/png');
                link.click();
                showButtonFeedback(document.getElementById('giteeTreeDownloadImageBtn'), '已下载!');
            } catch (error) {
                console.error('生成图片失败:', error);
            } finally {
                document.body.removeChild(tempContainer);
            }
        });
        document.getElementById('giteeTreeDownloadBatBtn').addEventListener('click', (e) => {
            e.preventDefault();
            if (!currentDirectoryItems || !currentProjectInfo) return;
            let scriptContent = `@echo off\necho Creating directory structure for ${currentProjectInfo.full_name}\necho.\n`;
            function generateBatScript(items, path = '') {
                items.forEach(item => {
                    const itemPath = path ? `${path}\\${item.name}` : item.name;
                    if (item.type === 'dir') {
                        scriptContent += `mkdir "${itemPath}"\n`;
                        if (item.children && item.children.length > 0) {
                            generateBatScript(item.children, itemPath);
                        }
                    } else {
                        scriptContent += `echo. > "${itemPath}"\n`;
                    }
                });
            }
            generateBatScript(currentDirectoryItems);
            scriptContent += `\necho Directory structure created successfully!\npause`;
            const blob = new Blob([scriptContent], { type: 'text/plain' });
            const url = URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.download = `${currentProjectInfo.full_name.replace('/', '-')}-structure.bat`;
            link.href = url;
            link.click();
            URL.revokeObjectURL(url);
        });
        document.getElementById('giteeTreeDownloadShBtn').addEventListener('click', (e) => {
            e.preventDefault();
            if (!currentDirectoryItems || !currentProjectInfo) return;
            let scriptContent = `#!/bin/bash\necho "Creating directory structure for ${currentProjectInfo.full_name}"\necho\n`;
            function generateShScript(items, path = '') {
                items.forEach(item => {
                    const itemPath = path ? `${path}/${item.name}` : item.name;
                    if (item.type === 'dir') {
                        scriptContent += `mkdir -p "${itemPath}"\n`;
                        if (item.children && item.children.length > 0) {
                            generateShScript(item.children, itemPath);
                        }
                    } else {
                        scriptContent += `touch "${itemPath}"\n`;
                    }
                });
            }
            generateShScript(currentDirectoryItems);
            scriptContent += `\necho "Directory structure created successfully!"`;
            const blob = new Blob([scriptContent], { type: 'text/plain' });
            const url = URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.download = `${currentProjectInfo.full_name.replace('/', '-')}-structure.sh`;
            link.href = url;
            link.click();
            URL.revokeObjectURL(url);
        });
        document.getElementById('giteeTreeDownloadCardBtn').addEventListener('click', async () => {
            if (!currentProjectInfo) return;
            try {
                const cardElement = document.querySelector('#giteeTreeShareCardContainer > div');
                const canvas = await html2canvas(cardElement, {
                    backgroundColor: null,
                    scale: 2
                });
                const link = document.createElement('a');
                link.download = `${currentProjectInfo.full_name.replace('/', '-')}-card.png`;
                link.href = canvas.toDataURL('image/png');
                link.click();
            } catch (error) {
                console.error('生成卡片图片失败:', error);
            }
        });
        document.getElementById('giteeTreeCardStyleSelect').addEventListener('change', (e) => {
            selectedCardStyle = e.target.value;
            if (currentProjectInfo) {
                const container = document.getElementById('giteeTreeShareCardContainer');
                container.innerHTML = '';
                const card = generateShareCard(currentProjectInfo, selectedCardStyle);
                container.appendChild(card);
            }
        });
        document.getElementById('giteeTreeProjectInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                document.getElementById('giteeTreeGenerateDirBtn').click();
            }
        });
        document.querySelector('details').addEventListener('toggle', function() {
            const icon = this.querySelector('i.fa-chevron-down');
            if (this.open) {
                icon.style.transform = 'rotate(180deg)';
            } else {
                icon.style.transform = 'rotate(0deg)';
            }
        });
    }
    function openTreeModal() {
        const modal = document.getElementById('giteeTreeModal');
        if (!modal) {
            createTreeModal();
            setTimeout(() => {
                document.getElementById('giteeTreeModal').style.display = 'block';
                const savedToken = localStorage.getItem('gitee_token');
                if (savedToken) {
                    document.getElementById('giteeTreeTokenInput').value = savedToken;
                    document.getElementById('giteeTreeTokenStatus').classList.add('active');
                    document.getElementById('giteeTreeGenerateDirBtn').disabled = false;
                    document.getElementById('giteeTreeGenerateCardBtn').disabled = false;
                }
                const pathParts = window.location.pathname.split('/').filter(part => part);
                if (pathParts.length >= 2) {
                    const owner = pathParts[0];
                    const repo = pathParts[1];
                    document.getElementById('giteeTreeProjectInput').value = `${owner}/${repo}`;
                }
            }, 100);
        } else {
            modal.style.display = 'block';
        }
    }
    function closeTreeModal() {
        document.getElementById('giteeTreeModal').style.display = 'none';
    }
    function showError(message) {
        document.getElementById('giteeTreeErrorMessage').textContent = message;
        document.getElementById('giteeTreeDirLoadingSection').style.display = 'none';
        document.getElementById('giteeTreeCardLoadingSection').style.display = 'none';
        document.getElementById('giteeTreeDirResultSection').style.display = 'none';
        document.getElementById('giteeTreeCardResultSection').style.display = 'none';
        document.getElementById('giteeTreeErrorSection').style.display = 'block';
    }
    function showButtonFeedback(button, text = '已复制!') {
        const originalContent = button.innerHTML;
        button.innerHTML = `<i class="fas fa-check mr-1"></i>${text}`;
        button.disabled = true;
        setTimeout(() => {
            button.innerHTML = originalContent;
            button.disabled = false;
        }, 1500);
    }
    function parseProjectPath(input) {
        input = input.replace(/^https?:\/\//, '');
        input = input.replace(/^gitee\.com\//, '');
        input = input.replace(/\/$/, '');
        const parts = input.split('/');
        if (parts.length !== 2) {
            throw new Error('请输入正确的项目路径,格式:owner/repo');
        }
        return { owner: parts[0], repo: parts[1] };
    }
    async function getProjectInfo(owner, repo) {
        const savedToken = localStorage.getItem('gitee_token');
        if (!savedToken) {
            throw new Error('请先设置 Gitee 访问令牌');
        }
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: 'GET',
                url: `https://gitee.com/api/v5/repos/${owner}/${repo}`,
                headers: {
                    'Authorization': `token ${savedToken}`,
                    'Accept': 'application/json'
                },
                onload: function(response) {
                    if (response.status === 200) {
                        resolve(JSON.parse(response.responseText));
                    } else {
                        if (response.status === 401) {
                            reject(new Error('访问令牌无效或已过期,请重新设置'));
                        } else if (response.status === 403) {
                            reject(new Error('访问令牌权限不足,请确保已勾选相应权限'));
                        } else if (response.status === 404) {
                            reject(new Error('项目不存在或无权访问'));
                        } else {
                            reject(new Error(`获取项目信息失败 (${response.status})`));
                        }
                    }
                },
                onerror: function(error) {
                    reject(new Error('网络请求失败'));
                }
            });
        });
    }
    async function getProjectDirectoryRecursive(owner, repo, path = '', depth = 0, maxDepth = 0) {
        if (maxDepth > 0 && depth >= maxDepth) {
            return [];
        }
        const savedToken = localStorage.getItem('gitee_token');
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: 'GET',
                url: `https://gitee.com/api/v5/repos/${owner}/${repo}/contents/${path}`,
                headers: {
                    'Authorization': `token ${savedToken}`,
                    'Accept': 'application/json'
                },
                onload: async function(response) {
                    if (response.status === 200) {
                        const items = JSON.parse(response.responseText);
                        for (const item of items) {
                            if (item.type === 'dir') {
                                item.children = await getProjectDirectoryRecursive(owner, repo, item.path, depth + 1, maxDepth);
                            }
                        }
                        resolve(items);
                    } else {
                        resolve([]);
                    }
                },
                onerror: function(error) {
                    reject(new Error('网络请求失败'));
                }
            });
        });
    }
    function generateDirectoryTreeText(items, prefix = '', viewType = 'all') {
        let text = '';
        items.forEach((item, index) => {
            if (viewType === 'folders' && item.type !== 'dir') {
                return;
            }
            const isLast = index === items.length - 1;
            const connector = isLast ? '└── ' : '├── ';
            const icon = item.type === 'dir' ? '📁' : '📄';
            text += `${prefix}${connector}${icon} ${item.name}\n`;
            if (item.type === 'dir' && item.children && item.children.length > 0) {
                const newPrefix = prefix + (isLast ? '    ' : '│   ');
                text += generateDirectoryTreeText(item.children, newPrefix, viewType);
            }
        });
        return text;
    }
    function generateShareCard(projectInfo, style) {
        const cardDiv = document.createElement('div');
        const giteeIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
        giteeIcon.setAttribute('viewBox', '0 0 1024 1024');
        giteeIcon.setAttribute('width', '16');
        giteeIcon.setAttribute('height', '16');
        giteeIcon.classList.add('gitee-tree-logo');
        const giteePath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
        giteePath.setAttribute('d', 'M512 1024C229.2224 1024 0 794.7776 0 512S229.2224 0 512 0s512 229.2224 512 512-229.2224 512-512 512z m259.1488-568.8832H480.4096a25.2928 25.2928 0 0 0-25.2928 25.2928l-0.0256 63.2064c0 13.952 11.3152 25.2928 25.2672 25.2928h177.024c13.9776 0 25.2928 11.3152 25.2928 25.2672v12.6464a75.8528 75.8528 0 0 1-75.8528 75.8528H366.592a25.2928 25.2928 0 0 1-25.2672-25.2928v-240.1792a75.8528 75.8528 0 0 1 75.8272-75.8528h353.9456a25.2928 25.2928 0 0 0 25.2672-25.2928l0.0768-63.2064a25.2928 25.2928 0 0 0-25.2672-25.2928H417.152a189.6192 189.6192 0 0 0-189.6192 189.6448v353.9456c0 13.9776 11.3152 25.2928 25.2928 25.2928h372.9408a170.6496 170.6496 0 0 0 170.6496-170.6496v-145.408a25.2928 25.2928 0 0 0-25.2928-25.2672z');
        giteePath.setAttribute('fill', 'currentColor');
        giteeIcon.appendChild(giteePath);

        switch(style) {
            case 'mac':
                cardDiv.className = 'gitee-tree-mac-card';
                cardDiv.innerHTML = `
                    <div class="gitee-tree-mac-header">
                        <div class="gitee-tree-mac-button gitee-tree-mac-button-red"></div>
                        <div class="gitee-tree-mac-button gitee-tree-mac-button-yellow"></div>
                        <div class="gitee-tree-mac-button gitee-tree-mac-button-green"></div>
                    </div>
                    <div class="gitee-tree-mac-content">
                        <div class="gitee-tree-mac-info">
                            <h3 class="gitee-tree-mac-title"></h3>
                            <p class="gitee-tree-mac-desc">${projectInfo.description || '暂无描述'}</p>
                            <div class="gitee-tree-mac-stats">
                                <span><i class="fas fa-star text-yellow-400 mr-1"></i>${projectInfo.stargazers_count || 0}</span>
                                <span><i class="fas fa-code-branch text-green-400 mr-1"></i>${projectInfo.forks_count || 0}</span>
                                <span><i class="fas fa-circle text-blue-400 mr-1 text-xs"></i>${projectInfo.language || '未知'}</span>
                            </div>
                        </div>
                        <div class="gitee-tree-qr-container">
                            <div id="giteeTreeQrcode"></div>
                        </div>
                    </div>
                `;
                const macTitle = cardDiv.querySelector('.gitee-tree-mac-title');
                macTitle.appendChild(giteeIcon.cloneNode(true));
                macTitle.appendChild(document.createTextNode(projectInfo.full_name));
                break;

            case 'gitee':
                cardDiv.className = 'gitee-tree-gitee-card';
                cardDiv.innerHTML = `
                    <div class="gitee-tree-gitee-header">
                        <h3 class="gitee-tree-gitee-title"></h3>
                        <span class="gitee-tree-gitee-badge">Public</span>
                    </div>
                    <div class="gitee-tree-gitee-content">
                        <div class="gitee-tree-gitee-info">
                            <p class="gitee-tree-gitee-desc">${projectInfo.description || '暂无描述'}</p>
                            <div class="gitee-tree-gitee-stats">
                                <span><i class="fas fa-star mr-1"></i>${projectInfo.stargazers_count || 0}</span>
                                <span><i class="fas fa-code-branch mr-1"></i>${projectInfo.forks_count || 0}</span>
                                <span><i class="fas fa-circle mr-1 text-xs"></i>${projectInfo.language || '未知'}</span>
                            </div>
                        </div>
                        <div class="gitee-tree-qr-container">
                            <div id="giteeTreeQrcode"></div>
                        </div>
                    </div>
                `;
                const giteeTitle = cardDiv.querySelector('.gitee-tree-gitee-title');
                giteeTitle.appendChild(giteeIcon.cloneNode(true));
                giteeTitle.appendChild(document.createTextNode(projectInfo.full_name));
                break;

            case 'material':
                cardDiv.className = 'gitee-tree-material-card';
                cardDiv.innerHTML = `
                    <div class="gitee-tree-material-content">
                        <div class="gitee-tree-material-top">
                            <div class="gitee-tree-material-info">
                                <h3 class="gitee-tree-material-title"></h3>
                                <p class="gitee-tree-material-desc">${projectInfo.description || '暂无描述'}</p>
                            </div>
                            <div class="gitee-tree-qr-container">
                                <div id="giteeTreeQrcode"></div>
                            </div>
                        </div>
                        <div class="gitee-tree-material-divider"></div>
                        <div class="gitee-tree-material-stats">
                            <div class="gitee-tree-material-stats-left">
                                <span><i class="fas fa-star mr-2"></i>${projectInfo.stargazers_count || 0}</span>
                                <span><i class="fas fa-code-branch mr-2"></i>${projectInfo.forks_count || 0}</span>
                            </div>
                            <span><i class="fas fa-circle mr-2 text-xs"></i>${projectInfo.language || '未知'}</span>
                        </div>
                    </div>
                `;
                const materialTitle = cardDiv.querySelector('.gitee-tree-material-title');
                materialTitle.appendChild(giteeIcon.cloneNode(true));
                materialTitle.appendChild(document.createTextNode(projectInfo.full_name));
                break;

            case 'modern':
                cardDiv.className = 'gitee-tree-modern-card';
                cardDiv.innerHTML = `
                    <div class="gitee-tree-modern-content">
                        <div>
                            <h3 class="gitee-tree-modern-title"></h3>
                            <p class="gitee-tree-modern-desc">${projectInfo.description || '暂无描述'}</p>
                        </div>
                        <div class="gitee-tree-modern-footer">
                            <div class="gitee-tree-modern-stats">
                                <div class="gitee-tree-modern-stat"><i class="fas fa-star mr-2"></i>${projectInfo.stargazers_count || 0} Stars</div>
                                <div class="gitee-tree-modern-stat"><i class="fas fa-code-branch mr-2"></i>${projectInfo.forks_count || 0} Forks</div>
                                <div class="gitee-tree-modern-stat"><i class="fas fa-circle mr-2 text-xs"></i>${projectInfo.language || '未知'}</div>
                            </div>
                            <div class="gitee-tree-qr-container">
                                <div id="giteeTreeQrcode"></div>
                            </div>
                        </div>
                    </div>
                `;
                const modernTitle = cardDiv.querySelector('.gitee-tree-modern-title');
                modernTitle.appendChild(giteeIcon.cloneNode(true));
                modernTitle.appendChild(document.createTextNode(projectInfo.full_name));
                break;
        }

        setTimeout(() => {
            const qrcodeDiv = cardDiv.querySelector('#giteeTreeQrcode');
            if (qrcodeDiv) {
                new QRCode(qrcodeDiv, {
                    text: projectInfo.html_url,
                    width: 96,
                    height: 96,
                    colorDark: "#000000",
                    colorLight: "#ffffff",
                    correctLevel: QRCode.CorrectLevel.H
                });
            }
        }, 100);

        return cardDiv;
    }
    let savedToken = localStorage.getItem('gitee_token') || '';
    let selectedCardStyle = 'mac';
    let currentDirectoryTree = '';
    let currentProjectInfo = null;
    let currentDirectoryItems = [];
    let fullDirectoryTree = '';
    window.addEventListener('load', () => {
        setTimeout(() => {
            createTreeButton();
            window.addEventListener('click', (e) => {
                const modal = document.getElementById('giteeTreeModal');
                if (e.target === modal) {
                    closeTreeModal();
                }
            });
        }, 1000);
    });
    let lastUrl = location.href;
    new MutationObserver(() => {
        const url = location.href;
        if (url !== lastUrl) {
            lastUrl = url;
            setTimeout(createTreeButton, 1000);
        }
    }).observe(document, { subtree: true, childList: true });
})();