哪吒探针 v2 究极美化分享:兼容 v0 版本的高性能部署方案

提示

90天以上显示是绿色
60天是橙色
30天以内显示红色

需要修改
名称direct-toad自己的名称

代码示例

(function() {
    const extraData = {
        "direct-toad": { "price": "$1254.1/年", "cycle": "2026-09-8", "review": "https://example.com", "shop": "1" }
    };
    const affLinks = { "1": "https://example1.com" };

完整代码

<style>
/* 隐藏页脚 */
.footer {
    display: none !important;
}
/* 如果上面不生效,尝试这个 */
footer {
    display: none !important;
}
</style>


<script src="//unpkg.com/[email protected]/dist/globe.gl.min.js"></script>
<style>
    /* --- 3D 地球样式 --- */
    #earth-drawer-container {
        position: fixed;
        top: 0;
        right: 0;
        width: 50vw; /* 半屏宽度 */
        max-width: 50vw;
        min-width: 400px; /* 最小宽度保护 */
        height: 100vh;
        z-index: 2147483647 !important; /* 最大层级,确保在 v0 框架之上 */
        background: linear-gradient(135deg, rgba(0, 5, 15, 0.98), rgba(0, 10, 25, 0.98));
        border-left: 2px solid rgba(0, 255, 255, 0.4);
        box-shadow: -20px 0 80px rgba(0, 10, 30, 0.95);
        transform: translateX(100%);
        transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1);
        display: flex;
        flex-direction: column;
        pointer-events: auto !important; /* 确保可交互 */
    }
    #earth-drawer-container.active {
        transform: translateX(0);
    }
    #earth-render-area {
        flex: 1;
        width: 100%;
        height: 100%;
        overflow: hidden;
        cursor: grab;
    }
   
    #earth-render-area:active {
        cursor: grabbing;
    }
    .earth-header {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        padding: 20px 30px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        z-index: 2147483647 !important; /* 极高层级,确保不被遮挡 */
        background: linear-gradient(180deg, rgba(0,0,0,0.95) 0%, transparent 100%);
        pointer-events: auto !important; /* 强制可点击 */
        backdrop-filter: blur(10px);
    }
    .earth-title {
        color: #00ffff;
        font-family: 'Microsoft YaHei', 'Segoe UI', sans-serif; /* 增加中文字体 */
        letter-spacing: 3px;
        font-weight: 700;
        font-size: 18px;
        text-shadow: 0 0 15px rgba(0, 255, 255, 0.8), 0 0 30px rgba(0, 255, 255, 0.4);
        pointer-events: auto;
        animation: titleGlow 3s ease-in-out infinite;
    }
    @keyframes titleGlow {
        0%, 100% { text-shadow: 0 0 15px rgba(0, 255, 255, 0.8), 0 0 30px rgba(0, 255, 255, 0.4); }
        50% { text-shadow: 0 0 20px rgba(0, 255, 255, 1), 0 0 40px rgba(0, 255, 255, 0.6); }
    }
    .earth-stats {
        position: absolute;
        top: 80px;
        left: 30px;
        color: rgba(255, 255, 255, 0.95);
        font-family: 'Consolas', monospace;
        font-size: 12px;
        z-index: 10;
        background: rgba(0, 20, 40, 0.85);
        padding: 12px 16px;
        border: 1px solid rgba(0, 255, 255, 0.5);
        border-radius: 6px;
        backdrop-filter: blur(10px);
        box-shadow: 0 4px 15px rgba(0, 0, 0, 0.5);
    }
    .earth-stats div { margin: 4px 0; }
    .earth-stats span {
        color: #00ffff;
        font-weight: bold;
        text-shadow: 0 0 8px rgba(0, 255, 255, 0.6);
    }
    #earth-close-btn {
        pointer-events: auto !important;
        position: relative;
        z-index: 2147483647 !important; /* 极高层级 */
        color: #fff;
        background: linear-gradient(135deg, rgba(0, 100, 150, 0.3), rgba(0, 50, 100, 0.3));
        border: 1px solid rgba(0, 255, 255, 0.6);
        padding: 10px 24px !important; /* 加大点击区域 */
        margin-right: 15px !important; /* 避免贴边被遮挡 */
        margin-top: 15px !important; /* 避免被顶部栏覆盖 */
        font-size: 12px;
        cursor: pointer;
        transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
        font-family: 'Consolas', monospace;
        font-weight: 600;
        letter-spacing: 1px;
        border-radius: 8px;
        backdrop-filter: blur(5px);
        text-transform: uppercase;
        overflow: hidden;
        box-shadow: 0 4px 20px rgba(0, 255, 255, 0.4) !important;
    }
    #earth-close-btn::before {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 0;
        height: 0;
        background: rgba(0, 255, 255, 0.3);
        border-radius: 50%;
        transform: translate(-50%, -50%);
        transition: width 0.6s, height 0.6s;
    }
    #earth-close-btn:hover::before { width: 300px; height: 300px; }
    #earth-close-btn:hover {
        background: linear-gradient(135deg, rgba(0, 255, 255, 0.4), rgba(0, 200, 255, 0.4));
        border-color: #00ffff;
        box-shadow: 0 0 20px rgba(0, 255, 255, 0.6), inset 0 0 20px rgba(0, 255, 255, 0.2);
        transform: translateY(-2px);
    }
    #earth-close-btn span { position: relative; z-index: 1; }
    /* 地图按钮样式打开全球地图 */
    #earth-toggle-btn {
        position: fixed;
        bottom: 30px;
        right: 50px;
        width: 64px;
        height: 64px;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        border: none;
        border-radius: 16px;
        cursor: pointer;
        z-index: 99998;
        box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4), 0 4px 8px rgba(0, 0, 0, 0.3);
        transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
        display: flex;
        align-items: center;
        justify-content: center;
        overflow: hidden;
    }
    #earth-toggle-btn::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
        opacity: 0;
        transition: opacity 0.4s;
    }
    #earth-toggle-btn:hover::before { opacity: 1; }
    #earth-toggle-btn:hover {
        transform: translateY(-4px) scale(1.08);
        box-shadow: 0 12px 32px rgba(102, 126, 234, 0.6), 0 8px 16px rgba(0, 0, 0, 0.4);
    }
    #earth-toggle-btn:active { transform: translateY(-2px) scale(1.05); }
   
    #earth-toggle-btn.hidden {
        transform: translateX(150px) scale(0);
        opacity: 0;
    }
    #earth-toggle-btn svg {
        width: 32px;
        height: 32px;
        position: relative;
        z-index: 1;
        filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
    }
    .pulse-ring {
        position: absolute;
        border: 2px solid #667eea;
        border-radius: 16px;
        width: 100%;
        height: 100%;
        animation: pulse-square 2s ease-out infinite;
        opacity: 0;
    }
    @keyframes pulse-square {
        0% { transform: scale(1); opacity: 1; }
        100% { transform: scale(1.3); opacity: 0; }
    }
    .earth-label-card {
        background: linear-gradient(135deg, rgba(0, 20, 40, 0.98), rgba(0, 10, 30, 0.98));
        border: 1px solid #00ffff;
        color: #fff;
        padding: 5px 10px;
        border-radius: 5px;
        font-size: 13px; /* 稍微调大字体 */
        display: flex;
        align-items: center;
        gap: 6px;
        box-shadow: 0 0 20px rgba(0, 255, 255, 0.6), 0 4px 10px rgba(0, 0, 0, 0.5);
        transform: translateY(-25px);
        white-space: nowrap;
        font-family: 'Microsoft YaHei', sans-serif; /* 适配中文 */
        backdrop-filter: blur(8px);
        font-weight: 600;
    }
    .earth-label-card .flag-emoji {
        font-size: 16px;
        filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.5));
    }
    /* Debug 面板 */
    #debug-panel {
        position: absolute;
        bottom: 25px;
        left: 25px;
        background: rgba(0, 0, 0, 0.95);
        color: #0f0;
        padding: 10px;
        font-family: monospace;
        font-size: 10px;
        max-height: 200px;
        overflow-y: auto;
        border: 1px solid #0f0;
        border-radius: 4px;
        z-index: 10;
        max-width: 300px;
        display: none;
    }
    #debug-panel.show { display: block; }
    #debug-panel div { margin: 2px 0; word-break: break-all; }
    /* 响应式优化 */
    @media (max-width: 768px) {
        #earth-drawer-container {
            width: 100vw;
            max-width: 100vw;
            height: 60vh;
            top: auto;
            bottom: 0;
            transform: translateY(100%);
            border-left: none;
            border-top: 2px solid rgba(0, 255, 255, 0.4);
            min-width: 0;
        }
       
        #earth-drawer-container.active { transform: translateY(0); }
        .earth-header { padding: 12px 15px; }
        .earth-title { font-size: 14px; letter-spacing: 2px; }
        .earth-stats { font-size: 10px; padding: 8px 12px; top: 55px; left: 15px; }
        #earth-close-btn { padding: 6px 12px; font-size: 11px; }
        #earth-toggle-btn { width: 56px; height: 56px; bottom: 10px; right: 10px; border-radius: 14px; }
        #earth-toggle-btn svg { width: 28px; height: 28px; }
        .earth-label-card { font-size: 11px; padding: 4px 8px; }
        .earth-label-card .flag-emoji { font-size: 14px; }
        #debug-panel { font-size: 9px; bottom: 15px; left: 15px; max-width: 250px; max-height: 150px; }
    }
</style>
<div id="earth-toggle-btn" title="打开全球地图">
    <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
        <circle cx="12" cy="12" r="10" stroke="white" stroke-width="1.5" fill="rgba(255,255,255,0.1)"/>
        <path d="M12 2C12 2 15 6 15 12C15 18 12 22 12 22" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
        <path d="M12 2C12 2 9 6 9 12C9 18 12 22 12 22" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
        <path d="M2 12H22" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
        <path d="M4 8H20" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
        <path d="M4 16H20" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
        <circle cx="12" cy="12" r="1.5" fill="#00ffff"/>
    </svg>
    <div class="pulse-ring"></div>
</div>
<div id="earth-drawer-container">
    <div class="earth-header">
        <div class="earth-title">NEZHA /// 已连接</div>
        <div id="earth-close-btn"><span>断开连接</span></div>
    </div>
    <div class="earth-stats" id="earth-stats">
        <div>已检测到 <span id="country-count">0</span> 个地区</div>
        <div>状态: <span id="globe-status">就绪</span></div>
        <div style="margin-top: 8px; font-size: 10px; opacity: 0.7; cursor: pointer;" id="toggle-debug">
            [显示调试信息]
        </div>
    </div>
    <div id="debug-panel"></div>
    <div id="earth-render-area"></div>
</div>
<script>
/**
 * Nezha 3D Earth V13.8 (中文名称 & 半屏显示)
 */
(function() {
    'use strict';
    // 完整坐标库
    const COORD_MAP = {
        'CN': [35.8617, 104.1954], 'HK': [22.3193, 114.1694], 'TW': [23.6978, 120.9605],
        'MO': [22.1987, 113.5439], 'JP': [36.2048, 138.2529], 'KR': [35.9078, 127.7669],
        'KP': [40.3399, 127.5101], 'SG': [1.3521, 103.8198], 'MY': [4.2105, 101.9758],
        'TH': [15.8700, 100.9925], 'VN': [14.0583, 108.2772], 'PH': [12.8797, 121.7740],
        'ID': [-0.7893, 113.9213], 'IN': [20.5937, 78.9629], 'PK': [30.3753, 69.3451],
        'BD': [23.6850, 90.3563], 'LK': [7.8731, 80.7718], 'MM': [21.9162, 95.9560],
        'KH': [12.5657, 104.9910], 'LA': [19.8563, 102.4955], 'NP': [28.3949, 84.1240],
        'BT': [27.5142, 90.4336], 'MN': [46.8625, 103.8467], 'KZ': [48.0196, 66.9237],
        'UZ': [41.3775, 64.5853], 'TM': [38.9697, 59.5563], 'KG': [41.2044, 74.7661],
        'TJ': [38.8610, 71.2761], 'AF': [33.9391, 67.7100], 'AE': [23.4241, 53.8478],
        'SA': [23.8859, 45.0792], 'IL': [31.0461, 34.8516], 'JO': [30.5852, 36.2384],
        'LB': [33.8547, 35.8623], 'SY': [34.8021, 38.9968], 'IQ': [33.2232, 43.6793],
        'IR': [32.4279, 53.6880], 'TR': [38.9637, 35.2433], 'YE': [15.5527, 48.5164],
        'OM': [21.4735, 55.9754], 'KW': [29.3117, 47.4818], 'QA': [25.3548, 51.1839],
        'BH': [26.0667, 50.5577], 'AM': [40.0691, 45.0382], 'AZ': [40.1431, 47.5769],
        'GE': [42.3154, 43.3569],
        'US': [37.0902, -95.7129], 'CA': [56.1304, -106.3468],'MX': [23.6345, -102.5528],
        'GT': [15.7835, -90.2308], 'BZ': [17.1899, -88.4976], 'SV': [13.7942, -88.8965],
        'HN': [15.2000, -86.2419], 'NI': [12.8654, -85.2072], 'CR': [9.7489, -83.7534],
        'PA': [8.5380, -80.7821], 'CU': [21.5218, -77.7812], 'JM': [18.1096, -77.2975],
        'HT': [18.9712, -72.2852], 'DO': [18.7357, -70.1627],
        'GB': [55.3781, -3.4360], 'IE': [53.4129, -8.2439], 'FR': [46.2276, 2.2137],
        'DE': [51.1657, 10.4515], 'IT': [41.8719, 12.5674], 'ES': [40.4637, -3.7492],
        'PT': [39.3999, -8.2245], 'NL': [52.1326, 5.2913], 'BE': [50.5039, 4.4699],
        'LU': [49.8153, 6.1296], 'CH': [46.8182, 8.2275], 'AT': [47.5162, 14.5501],
        'SE': [60.1282, 18.6435], 'NO': [60.4720, 8.4689], 'FI': [61.9241, 25.7482],
        'DK': [56.2639, 9.5018], 'IS': [64.9631, -19.0208], 'PL': [51.9194, 19.1451],
        'CZ': [49.8175, 15.4730], 'SK': [48.6690, 19.6990], 'HU': [47.1625, 19.5033],
        'RO': [45.9432, 24.9668], 'BG': [42.7339, 25.4858], 'GR': [39.0742, 21.8243],
        'HR': [45.1000, 15.2000], 'SI': [46.1512, 14.9955], 'RS': [44.0165, 21.0059],
        'BA': [43.9159, 17.6791], 'ME': [42.7087, 19.3744], 'MK': [41.6086, 21.7453],
        'AL': [41.1533, 20.1683], 'XK': [42.6026, 20.9030], 'UA': [48.3794, 31.1656],
        'BY': [53.7098, 27.9534], 'MD': [47.4116, 28.3699], 'RU': [61.5240, 105.3188],
        'EE': [58.5953, 25.0136], 'LV': [56.8796, 24.6032], 'LT': [55.1694, 23.8813],
        'CY': [35.1264, 33.4299], 'MT': [35.9375, 14.3754],
        'BR': [-14.2350, -51.9253],'AR': [-38.4161, -63.6167],'CL': [-35.6751, -71.5430],
        'CO': [4.5709, -74.2973], 'PE': [-9.1900, -75.0152], 'VE': [6.4238, -66.5897],
        'EC': [-1.8312, -78.1834], 'BO': [-16.2902, -63.5887],'PY': [-23.4425, -58.4438],
        'UY': [-32.5228, -55.7658],'GY': [4.8604, -58.9302], 'SR': [3.9193, -56.0278],
        'AU': [-25.2744, 133.7751],'NZ': [-40.9006, 174.8860],'FJ': [-17.7134, 178.0650],
        'PG': [-6.3150, 143.9555], 'NC': [-20.9043, 165.6180],
        'ZA': [-30.5595, 22.9375], 'EG': [26.8206, 30.8025], 'NG': [9.0820, 8.6753],
        'KE': [-0.0236, 37.9062], 'ET': [9.1450, 40.4897], 'MA': [31.7917, -7.0926],
        'DZ': [28.0339, 1.6596], 'TN': [33.8869, 9.5375], 'LY': [26.3351, 17.2283],
        'SD': [12.8628, 30.2176], 'TZ': [-6.3690, 34.8888], 'UG': [1.3733, 32.2903],
        'GH': [7.9465, -1.0232], 'CI': [7.5400, -5.5471], 'SN': [14.4974, -14.4524],
        'ZW': [-19.0154, 29.1549], 'AO': [-11.2027, 17.8739], 'MZ': [-18.6657, 35.5296]
    };
   
    const FLAG_EMOJI = {
        'CN': '🇨🇳', 'HK': '🇭🇰', 'TW': '🇹🇼', 'MO': '🇲🇴', 'JP': '🇯🇵', 'KR': '🇰🇷', 'KP': '🇰🇵', 'SG': '🇸🇬', 'MY': '🇲🇾', 'TH': '🇹🇭', 'VN': '🇻🇳', 'PH': '🇵🇭', 'ID': '🇮🇩', 'IN': '🇮🇳', 'PK': '🇵🇰', 'BD': '🇧🇩', 'LK': '🇱🇰', 'MM': '🇲🇲', 'KH': '🇰🇭', 'LA': '🇱🇦', 'NP': '🇳🇵', 'BT': '🇧🇹', 'MN': '🇲🇳', 'KZ': '🇰🇿', 'UZ': '🇺🇿', 'TM': '🇹🇲', 'KG': '🇰🇬', 'TJ': '🇹🇯', 'AF': '🇦🇫', 'AE': '🇦🇪', 'SA': '🇸🇦', 'IL': '🇮🇱', 'JO': '🇯🇴', 'LB': '🇱🇧',
        'SY': '🇸🇾', 'IQ': '🇮🇶', 'IR': '🇮🇷', 'TR': '🇹🇷', 'YE': '🇾🇪', 'OM': '🇴🇲', 'KW': '🇰🇼', 'QA': '🇶🇦', 'BH': '🇧🇭', 'AM': '🇦🇲', 'AZ': '🇦🇿', 'GE': '🇬🇪', 'US': '🇺🇸', 'CA': '🇨🇦', 'MX': '🇲🇽', 'GT': '🇬🇹', 'BZ': '🇧🇿', 'SV': '🇸🇻', 'HN': '🇭🇳', 'NI': '🇳🇮', 'CR': '🇨🇷', 'PA': '🇵🇦', 'CU': '🇨🇺', 'JM': '🇯🇲', 'HT': '🇭🇹', 'DO': '🇩🇴', 'GB': '🇬🇧', 'IE': '🇮🇪', 'FR': '🇫🇷', 'DE': '🇩🇪', 'IT': '🇮🇹', 'ES': '🇪🇸', 'PT': '🇵🇹', 'NL': '🇳🇱', 'BE': '🇧🇪', 'LU': '🇱🇺', 'CH': '🇨🇭', 'AT': '🇦🇹', 'SE': '🇸🇪', 'NO': '🇳🇴', 'FI': '🇫🇮', 'DK': '🇩🇰', 'IS': '🇮🇸', 'PL': '🇵🇱', 'CZ': '🇨🇿', 'SK': '🇸🇰', 'HU': '🇭🇺', 'RO': '🇷🇴', 'BG': '🇧🇬', 'GR': '🇬🇷', 'HR': '🇭🇷', 'SI': '🇸🇮', 'RS': '🇷🇸', 'BA': '🇧🇦', 'ME': '🇲🇪', 'MK': '������🇰', 'AL': '🇦🇱', 'XK': '🇽🇰', 'UA': '🇺🇦', 'BY': '🇧🇾', 'MD': '🇲🇩', 'RU': '🇷🇺', 'EE': '🇪🇪', 'LV': '🇱🇻', 'LT': '🇱🇹', 'CY': '🇨🇾', 'MT': '🇲🇹', 'BR': '🇧🇷', 'AR': '🇦🇷', 'CL': '🇨🇱', 'CO': '🇨🇴', 'PE': '🇵🇪', 'VE': '🇻🇪', 'EC': '🇪🇨', 'BO': '🇧🇴', 'PY': '🇵🇾', 'UY': '🇺🇾', 'GY': '🇬🇾', 'SR': '🇸🇷', 'AU': '🇦🇺', 'NZ': '🇳🇿', 'FJ': '🇫🇯', 'PG': '🇵🇬', 'NC': '🇳🇨', 'ZA': '🇿🇦', 'EG': '🇪🇬', 'NG': '🇳🇬', 'KE': '🇰🇪', 'ET': '🇪🇹', 'MA': '🇲🇦', 'DZ': '🇩🇿', 'TN': '🇹🇳', 'LY': '🇱🇾', 'SD': '🇸🇩', 'TZ': '🇹🇿', 'UG': '🇺🇬', 'GH': '🇬🇭', 'CI': '🇨🇮', 'SN': '🇸🇳', 'ZW': '🇿🇼', 'AO': '🇦🇴', 'MZ': '🇲🇿'
    };
    // --- 新增:中文名称映射表 ---
    const CODE_TO_CN = {
        'CN': '中国', 'HK': '香港', 'TW': '台湾', 'MO': '澳门', 'JP': '日本', 'KR': '韩国', 'KP': '朝鲜', 'SG': '新加坡', 'MY': '马来西亚', 'TH': '泰国', 'VN': '越南', 'PH': '菲律宾', 'ID': '印尼', 'IN': '印度', 'PK': '巴基斯坦', 'BD': '孟加拉国', 'LK': '斯里兰卡', 'MM': '缅甸', 'KH': '柬埔寨', 'LA': '老挝', 'NP': '尼泊尔', 'BT': '不丹', 'MN': '蒙古', 'KZ': '哈萨克斯坦', 'UZ': '乌兹别克斯坦', 'TM': '土库曼斯坦', 'KG': '吉尔吉斯斯坦', 'TJ': '塔吉克斯坦', 'AF': '阿富汗', 'AE': '阿联酋', 'SA': '沙特', 'IL': '以色列', 'JO': '约旦', 'LB': '黎巴嫩',
        'SY': '叙利亚', 'IQ': '伊拉克', 'IR': '伊朗', 'TR': '土耳其', 'YE': '也门', 'OM': '阿曼', 'KW': '科威特', 'QA': '卡塔尔', 'BH': '巴林', 'AM': '亚美尼亚', 'AZ': '阿塞拜疆', 'GE': '格鲁吉亚', 'US': '美国', 'CA': '加拿大', 'MX': '墨西哥', 'GT': '危地马拉', 'BZ': '伯利兹', 'SV': '萨尔瓦多', 'HN': '洪都拉斯', 'NI': '尼加拉瓜', 'CR': '哥斯达黎加', 'PA': '巴拿马', 'CU': '古巴', 'JM': '牙买加', 'HT': '海地', 'DO': '多米尼加', 'GB': '英国', 'IE': '爱尔兰', 'FR': '法国', 'DE': '德国', 'IT': '意大利', 'ES': '西班牙', 'PT': '葡萄牙', 'NL': '荷兰', 'BE': '比利时', 'LU': '卢森堡', 'CH': '瑞士', 'AT': '奥地利', 'SE': '瑞典', 'NO': '挪威', 'FI': '芬兰', 'DK': '丹麦', 'IS': '冰岛', 'PL': '波兰', 'CZ': '捷克', 'SK': '斯洛伐克', 'HU': '匈牙利', 'RO': '罗马尼亚', 'BG': '保加利亚', 'GR': '希腊', 'HR': '克罗地亚', 'SI': '斯洛文尼亚', 'RS': '塞尔维亚', 'BA': '波黑', 'ME': '黑山', 'MK': '北马其顿', 'AL': '阿尔巴尼亚', 'XK': '科索沃', 'UA': '乌克兰', 'BY': '白俄罗斯', 'MD': '摩尔多瓦', 'RU': '俄罗斯', 'EE': '爱沙尼亚', 'LV': '拉脱维亚', 'LT': '立陶宛', 'CY': '塞浦路斯', 'MT': '马耳他', 'BR': '巴西', 'AR': '阿根廷', 'CL': '智利', 'CO': '哥伦比亚', 'PE': '秘鲁', 'VE': '委内瑞拉', 'EC': '厄瓜多尔', 'BO': '玻利维亚', 'PY': '巴拉圭', 'UY': '乌拉圭', 'GY': '圭亚那', 'SR': '苏里南', 'AU': '澳大利亚', 'NZ': '新西兰', 'FJ': '斐济', 'PG': '巴新', 'NC': '新喀里多尼亚', 'ZA': '南非', 'EG': '埃及', 'NG': '尼日利亚', 'KE': '肯尼亚', 'ET': '埃塞俄比亚', 'MA': '摩洛哥', 'DZ': '阿尔及利亚', 'TN': '突尼斯', 'LY': '利比亚', 'SD': '苏丹', 'TZ': '坦桑尼亚', 'UG': '乌干达', 'GH': '加纳', 'CI': '科特迪瓦', 'SN': '塞内加尔', 'ZW': '津巴布韦', 'AO': '安哥拉', 'MZ': '莫桑比克'
    };
    const container = document.getElementById('earth-drawer-container');
    const renderArea = document.getElementById('earth-render-area');
    const toggleBtn = document.getElementById('earth-toggle-btn');
    const closeBtn = document.getElementById('earth-close-btn');
    const statsEl = document.getElementById('earth-stats');
    const countEl = document.getElementById('country-count');
    const statusEl = document.getElementById('globe-status');
    const debugPanel = document.getElementById('debug-panel');
    const toggleDebug = document.getElementById('toggle-debug');
   
    let globeInstance = null;
    let isActive = false;
    let lastDetectedFlags = [];
    let scanRetryCount = 0;
    let debugLogs = [];
    const MAX_RETRY = 3;
    const isMobile = /Mobile|Android|iPhone|iPad/i.test(navigator.userAgent);
    function addDebugLog(msg) {
        const timestamp = new Date().toLocaleTimeString();
        debugLogs.push(`[${timestamp}] ${msg}`);
        if (debugLogs.length > 100) debugLogs.shift();
        updateDebugPanel();
        console.log(msg);
    }
    function updateDebugPanel() {
        debugPanel.innerHTML = debugLogs.slice(-30).map(log => `<div>${log}</div>`).join('');
        debugPanel.scrollTop = debugPanel.scrollHeight;
    }
    toggleDebug.addEventListener('click', () => {
        debugPanel.classList.toggle('show');
        toggleDebug.textContent = debugPanel.classList.contains('show') ?
            '[隐藏调试信息]' : '[显示调试信息]';
    });
    // --- 核心扫描逻辑 ---
    function scanFlags() {
        const flags = new Set();
       
        addDebugLog('=== 开始标志扫描(增强版) ===');
        addDebugLog(`设备: ${isMobile ? '移动端' : '桌面端'}`);
        // Method 1: flag-icon-*
        document.querySelectorAll('[class*="flag-icon-"]').forEach(el => {
            el.classList.forEach(cls => {
                if (cls.startsWith('flag-icon-')) {
                    let code = cls.replace('flag-icon-', '').toUpperCase();
                    if (COORD_MAP[code]) flags.add(code);
                }
            });
        });
        // Method 2 & 3: fi-*
        document.querySelectorAll('[class*="fi-"]').forEach(el => {
            el.classList.forEach(cls => {
                const match = cls.match(/^fi-([a-z]{2})$/i);
                if (match) {
                    let code = match[1].toUpperCase();
                    if (COORD_MAP[code]) flags.add(code);
                }
            });
        });
        // Method 4: data attributes
        ['data-country-code', 'data-country'].forEach(attr => {
            document.querySelectorAll(`[${attr}]`).forEach(el => {
                let code = el.getAttribute(attr).toUpperCase();
                if (COORD_MAP[code]) flags.add(code);
            });
        });
        // Method 6: 扫描图片 src
        let m6Count = 0;
        document.querySelectorAll('img').forEach(img => {
            const src = img.src.toLowerCase();
            if (src.includes('/flag') || src.includes('assets')) {
                Object.keys(COORD_MAP).forEach(code => {
                    if (src.includes(`/${code.toLowerCase()}.`) || src.includes(`-${code.toLowerCase()}.`)) {
                        flags.add(code);
                        m6Count++;
                    }
                });
            }
        });
        if(m6Count > 0) addDebugLog(`M6 (图片路径): 发现 ${m6Count} 个`);
        // Method 7: 扫描 Emoji
        if (isMobile && flags.size === 0) {
            let m7Count = 0;
            const textContent = document.body.innerText;
            Object.keys(FLAG_EMOJI).forEach(code => {
                if (textContent.includes(FLAG_EMOJI[code])) {
                    flags.add(code);
                    m7Count++;
                }
            });
            if(m7Count > 0) addDebugLog(`M7 (Emoji): 发现 ${m7Count} 个`);
        }
        addDebugLog(`=== 总计: ${flags.size} 个唯一国家/地区 ===`);
        const sortedFlags = Array.from(flags).sort();
        return sortedFlags;
    }
    // --- 随机连线生成逻辑 ---
    function generateData() {
        const codes = scanFlags();
        const points = [];
        const arcs = [];
        if (codes.length === 0) return { points, arcs, codes };
        // 1. 先生成所有点
        codes.forEach(code => {
            const coord = COORD_MAP[code];
            if (coord) {
                const [lat, lng] = coord;
                points.push({ code, lat, lng });
            }
        });
        // 2. 在这些国家之间随机生成连线
        const maxArcs = Math.min(40, codes.length * 3);
        const usedPairs = new Set();
        let loopSafety = 0;
        while (arcs.length < maxArcs && codes.length > 1 && loopSafety < 1000) {
            loopSafety++;
            const i = Math.floor(Math.random() * codes.length);
            let j = Math.floor(Math.random() * codes.length);
            if (i === j) continue;
            const fromCode = codes[i];
            const toCode = codes[j];
            const pairKey = [fromCode, toCode].sort().join('-');
            if (usedPairs.has(pairKey)) continue;
            usedPairs.add(pairKey);
            const fromCoord = COORD_MAP[fromCode];
            const toCoord = COORD_MAP[toCode];
           
            if (fromCoord && toCoord) {
                arcs.push({
                    startLat: fromCoord[0], startLng: fromCoord[1],
                    endLat: toCoord[0], endLng: toCoord[1]
                });
            }
        }
        return { points, arcs, codes };
    }
    function initGlobe(isRetry = false) {
        if (globeInstance && !isRetry) { updateGlobe(); return; }
        statusEl.textContent = '扫描中';
        const { points, arcs, codes } = generateData();
       
        if (codes.length === 0) {
            if (scanRetryCount < MAX_RETRY - 1) {
                scanRetryCount++;
                statusEl.textContent = `重试 ${scanRetryCount}`;
                setTimeout(() => initGlobe(true), 1500);
                return;
            }
            statusEl.textContent = '无数据';
            countEl.textContent = '0';
            addDebugLog('无国家/地区标志数据。');
            return;
        }
        scanRetryCount = 0;
        countEl.textContent = codes.length;
        lastDetectedFlags = codes;
        try {
            const globe = Globe();
            globe(renderArea);
            globe.width(renderArea.clientWidth);
            globe.height(renderArea.clientHeight);
            globe.backgroundImageUrl('//unpkg.com/three-globe/example/img/night-sky.png');
            globe.globeImageUrl('//unpkg.com/three-globe/example/img/earth-night.jpg');
            globe.bumpImageUrl('//unpkg.com/three-globe/example/img/earth-topology.png');
            globe.atmosphereColor('rgba(26, 84, 144, 0.8)');
            globe.atmosphereAltitude(0.25);
            globe.ringsData(points);
            globe.ringColor(() => '#00ffff');
            globe.ringMaxRadius(5);
            globe.ringPropagationSpeed(3);
            globe.ringRepeatPeriod(800);
            globe.pointsData(points);
            globe.pointColor(() => '#00ffff');
            globe.pointAltitude(0.02);
            globe.pointRadius(0.5);
            globe.htmlElementsData(points);
           
            // --- 核心修改:使用中文名渲染 ---
            globe.htmlElement(d => {
                const el = document.createElement('div');
                const emoji = FLAG_EMOJI[d.code] || '🏁';
                const cnName = CODE_TO_CN[d.code] || d.code; // 获取中文名,没有则显示代码
                el.innerHTML = `<div class="earth-label-card"><span class="flag-emoji">${emoji}</span><b>${cnName}</b></div>`;
                return el;
            });














// --- 修改渲染逻辑:同时显示 国旗、缩写和中文 ---
globe.htmlElement(d => {
    const el = document.createElement('div');
    const cnName = CODE_TO_CN[d.code] || d.code; // 获取中文名 (如: 中国)
    const shortCode = d.code; // 获取国家缩写 (如: CN)
    
    // 使用外部图片源加载国旗
    const flagImgUrl = `https://flagcdn.com/w40/${d.code.toLowerCase()}.png`;

    el.innerHTML = `
        <div class="earth-label-card" style="display: flex; align-items: center; gap: 8px; padding: 4px 10px;">
            <img src="${flagImgUrl}" 
                 style="width: 20px; height: auto; border-radius: 2px; box-shadow: 0 0 3px rgba(0,0,0,0.5);"
                 onerror="this.style.display='none';"> 
            <span style="color: #00ffff; font-family: monospace; font-weight: bold;">${shortCode}</span>
            <span style="color: #ffffff;">${cnName}</span>
        </div>
    `;
    return el;
});










            // ---------------------------
            globe.htmlLat(d => d.lat);
            globe.htmlLng(d => d.lng);
            globe.htmlAltitude(0.01);
            globe.arcsData(arcs);
            globe.arcColor(() => ['rgba(0, 255, 255, 0.5)', 'rgba(255, 0, 255, 0.5)']);
            globe.arcDashLength(0.7);
            globe.arcDashGap(0.2);
            globe.arcDashAnimateTime(2000);
            globe.arcStroke(1.2);
            globe.arcAltitude(0.3);
            globe.pointOfView({
                lat: codes.includes('CN') ? 35 : 20,
                lng: codes.includes('CN') ? 110 : 0,
                altitude: 2.5
            });
            globe.controls().autoRotate = true;
            globe.controls().autoRotateSpeed = 0.8;
            globe.controls().enableZoom = true;
            globeInstance = globe;
            statusEl.textContent = '已激活';
        } catch (error) {
            statusEl.textContent = '错误';
            addDebugLog(`错误: ${error.message}`);
        }
    }
    function updateGlobe() {
        if (!globeInstance) return;
        const { points, arcs, codes } = generateData();
        if (JSON.stringify(codes.sort()) === JSON.stringify(lastDetectedFlags.sort())) return;
        lastDetectedFlags = codes;
        countEl.textContent = codes.length;
        globeInstance.ringsData(points);
        globeInstance.pointsData(points);
        globeInstance.htmlElementsData(points);
        globeInstance.arcsData(arcs);
    }
    function toggle() {
        isActive = !isActive;
        if (isActive) {
            container.classList.add('active');
            toggleBtn.classList.add('hidden');
            debugLogs = [];
            scanRetryCount = 0;
            setTimeout(() => initGlobe(), isMobile ? 800 : 400);
        } else {
            container.classList.remove('active');
            toggleBtn.classList.remove('hidden');
            if (globeInstance && globeInstance.controls) globeInstance.controls().autoRotate = false;
        }
    }
    toggleBtn.addEventListener('click', toggle);
    closeBtn.addEventListener('click', toggle);
    window.addEventListener('resize', () => {
        if (isActive && globeInstance) {
            globeInstance.width(renderArea.clientWidth);
            globeInstance.height(renderArea.clientHeight);
        }
    });
    setInterval(() => { if (isActive && globeInstance) updateGlobe(); }, 30000);
})();
</script>




<style>
  /* --- 1. 修复上方显示区域 --- */
  .cursor-pointer.lg\:flex-row > div.flex.flex-col { flex: 1 1 auto !important; width: 100% !important; }
  .cursor-pointer section.grid-cols-5 { 
    width: 100% !important; 
    display: grid !important; 
    grid-template-columns: repeat(5, 1fr) !important; 
    gap: 10px !important; 
  }
  .cursor-pointer section.grid-cols-5 > div.w-14 { width: auto !important; min-width: 0 !important; }
  .cursor-pointer div.shrink-0.bg-border.w-px { display: none !important; }
  .cursor-pointer.lg\:flex-row { flex-wrap: wrap !important; justify-content: space-between !important; padding-bottom: 12px !important; }

  /* --- 2. 自定义页脚样式 --- */
  .nz-custom-footer {
    width: 100% !important;
    margin-top: 10px;
    padding: 6px 10px;
    background: rgba(125, 125, 125, 0.08);
    border-radius: 8px;
    display: flex !important;
    flex-direction: row !important;
    justify-content: space-between;
    align-items: center;
    border: 1px solid rgba(150, 150, 150, 0.15);
    box-sizing: border-box;
    order: 100;
    min-height: 34px; /* 预留高度防止抖动 */
  }

  .nz-left-info { display: flex; align-items: center; gap: 8px; }

  /* 初始化为灰色,防止闪烁 */
  .nz-date-tag {
    font-size: 11px !important;
    font-weight: bold;
    padding: 2px 8px;
    border-radius: 4px;
    color: #fff !important;
    white-space: nowrap;
    background-color: #9ca3af; /* 默认灰色占位 */
    transition: background-color 0.3s ease;
  }

  .nz-days-remain {
    font-size: 11px !important;
    font-weight: 600;
    white-space: nowrap;
    transition: color 0.3s ease;
  }

  .nz-right-part { display: flex; align-items: center; gap: 8px; }
  .nz-price-val { font-size: 12px !important; font-weight: 800; color: #f59e0b; white-space: nowrap; }
  .nz-btns { display: flex; gap: 4px; }
  .nz-btns a { text-decoration: none !important; font-size: 11px !important; padding: 3px 8px !important; border-radius: 4px; white-space: nowrap; font-weight: 600; }
  
  .btn-eval { background: #3b82f6 !important; color: white !important; }
  .btn-buy { border: 1px solid #10b981 !important; color: #10b981 !important; }

  @media (max-width: 640px) {
    .nz-custom-footer { padding: 4px 6px; }
    .nz-date-text-extra { display: none; }
    .nz-days-label { display: none; }
  }
</style>

<script>
(function() {
    const extraData = {
        "direct-toad": { "price": "$1254.1/年", "cycle": "2026-09-8", "review": "https://example.com", "shop": "1" }
    };
    const affLinks = { "1": "https://example1.com" };

    // 计算逻辑保持不变
    function calculateStatus(dateStr) {
        let parts = dateStr.match(/(\d{2,4})[年\-](\d{1,2})[月\-](\d{1,2})/);
        if (!parts) return { color: '#6b7280', days: '?' };
        let year = parseInt(parts[1]);
        if (year < 100) year += 2000;
        const targetDate = new Date(year, parseInt(parts[2]) - 1, parseInt(parts[3]));
        const today = new Date();
        const diffDays = Math.ceil((targetDate - today) / (1000 * 60 * 60 * 24));
        let color = '#10b981';
        if (diffDays <= 30) color = '#ef4444';
        else if (diffDays <= 60) color = '#f59e0b';
        return { color, days: diffDays };
    }

    function doInject() {
        const cards = document.querySelectorAll('.cursor-pointer.lg\\:flex-row, .cursor-pointer.flex-col');
        
        cards.forEach(card => {
            if (card.querySelector('.nz-custom-footer')) return;
            const nameEl = card.querySelector('p.font-bold');
            if (!nameEl) return;
            const sName = nameEl.innerText.trim();

            if (extraData[sName]) {
                const data = extraData[sName];
                
                // 1. 先注入基础 HTML(静态部分)
                const footer = document.createElement('div');
                footer.className = 'nz-custom-footer';
                footer.innerHTML = `
                    <div class="nz-left-info">
                        <div class="nz-date-tag">📅 ${data.cycle}<span class="nz-date-text-extra">到期</span></div>
                        <div class="nz-days-remain"><span class="nz-days-label">剩余:</span><span class="day-val">...</span>天</div>
                    </div>
                    <div class="nz-right-part">
                        <span class="nz-price-val">💰 ${data.price}</span>
                        <div class="nz-btns">
                            ${data.review ? `<a class="btn-eval" target="_blank" href="${data.review}">评测</a>` : ''}
                            <a class="btn-buy" target="_blank" href="${affLinks[data.shop] || '#'}">购同款</a>
                        </div>
                    </div>
                `;
                card.appendChild(footer);

                // 2. 异步计算颜色和天数(不阻塞主线程)
                setTimeout(() => {
                    const status = calculateStatus(data.cycle);
                    const tag = footer.querySelector('.nz-date-tag');
                    const text = footer.querySelector('.nz-days-remain');
                    const val = footer.querySelector('.day-val');
                    
                    if(tag) tag.style.setProperty('background-color', status.color, 'important');
                    if(text) text.style.color = status.color;
                    if(val) val.innerText = status.days;
                }, 10);
            }
        });
    }

    // 提高执行频率以捕捉初次渲染,但减小 doInject 的负担
    const obs = new MutationObserver(() => {
        window.requestAnimationFrame(doInject);
    });
    obs.observe(document.body, { childList: true, subtree: true });
    
    // 初始执行一次
    doInject();
})();
</script>

针对v0版本优化
只需要对应后台id对应
示例

修改内容

                1: '',
                2: '',


                999: 'https://example.com/AFF推荐'
      "1": {
        "shop": "1",
        "price": "$89.1年付",
        "cycle": "27年3月6日到期",
        "reviewLink": ""
      },

      "2": {
        "shop": "2",
        "price": "$168三年付",
        "cycle": "28年7月3日到期",
        "reviewLink": ""
      },
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    .price-wrapper {
      position: relative;
      width: 100%;
      font-size: 1em;
      white-space: nowrap;
    }

    .date-part {
      display: inline-block;
      width: 10px; /* 控制日期和价格的间距 */
      padding-right: 220px; /* 给右边按钮预留空间 */
    }

    .price-right {
      position: absolute;
      top: 0;
      right: 0;
      display: flex;
      align-items: center;
    }

    .price-text {
      display: inline-block;
      margin-right: 8px;
    }

    .price-buttons a {
      margin-left: 6px;
    }

    /* ✅ 手机端适配样式,保持一行显示 */
    @media (max-width: 600px) {
      .date-part {
        padding-right: 280px;
      }

      .price-text {
        font-size: 0.9em;
      }

      .price-buttons a {
        margin-left: 4px;
        font-size: 0.9em;
        padding: 0.3em 0.6em;
      }

      .price-wrapper {
        font-size: 0.9em;
      }
    }
  </style>
</head>
<body>

<script>
  localStorage.setItem('showGroup', 'true');
</script>

<script>
  window.onload = function () {
    const affLinks = {

                1: '',
                2: '',


                999: 'https://example.com/AFF推荐'
    };

    const extraData = {



      "1": {
        "shop": "1",
        "price": "$89.1年付",
        "cycle": "27年3月6日到期",
        "reviewLink": ""
      },

      "2": {
        "shop": "2",
        "price": "$168三年付",
        "cycle": "28年7月3日到期",
        "reviewLink": ""
      },













      "999": {
        "shop": "999",
        "pid": "",
        "price": "$11年付",
        "cycle": "26年12月12日到期",
        "reviewLink": "https://example.com/评测"
      }
    };


    function parseCycleDate(cycleStr) {
      const match = cycleStr.match(/(\d{2})年(\d{1,2})月(\d{1,2})日/);
      if (match) {
        const year = parseInt(match[1], 10) + 2000;
        const month = parseInt(match[2], 10) - 1;
        const day = parseInt(match[3], 10);
        return new Date(year, month, day);
      }
      return null;
    }

    function getBackgroundColor(daysLeft) {
      if (daysLeft <= 10) return '#FD0101';
      if (daysLeft <= 20) return '#eea33b';
      if (daysLeft <= 30) return '#4ea84e';
      return '';
    }

    function formatCyclePrice(cycle, price, reviewLink, buyLink, usage) {
      const now = new Date();
      const cycleDate = parseCycleDate(cycle);
      let daysLeft = 9999;
      if (cycleDate) {
        daysLeft = Math.ceil((cycleDate - now) / (1000 * 60 * 60 * 24));
      }

      const bgColor = getBackgroundColor(daysLeft);
      const cycleHTML = `<span class="date-part" style="background-color: ${bgColor};">${cycle}</span>`;
      const priceHTML = `<span class="price-text">${price}</span>`;

      return `
        <div class="price-wrapper">
          ${cycleHTML}
          <span class="price-right">
            ${priceHTML}
            <span class="price-buttons">
              <a class="ui mini blue basic button" target="_blank" href="${reviewLink || '#'}">评测</a>
              <a class="ui mini green basic button" target="_blank" href="${buyLink}">购买同款</a>
            </span>
          </span>
        </div>
      `;
    }

    const servers = document.querySelectorAll('.table-condensed tr.accordion-toggle');
    servers.forEach(server => {
      const id = server.getAttribute('id')?.replace('r', '');
      if (extraData[id]) {
        const { shop, price, cycle, reviewLink, pid, usage } = extraData[id];
        const buyLink = affLinks[shop] + (pid ? '&pid=' + pid : '');
        const $infoTd = document.createElement('td');
        $infoTd.className = 'node-cell price';
        $infoTd.innerHTML = formatCyclePrice(cycle, price, reviewLink, buyLink, usage);
        server.appendChild($infoTd);
      }
    });
  };
</script>

</body>
</html>






<script src="//unpkg.com/[email protected]/dist/globe.gl.min.js"></script>
<style>
    /* --- 3D 地球样式 --- */
    #earth-drawer-container {
        position: fixed;
        top: 0;
        right: 0;
        width: 50vw; /* 半屏宽度 */
        max-width: 50vw;
        min-width: 400px; /* 最小宽度保护 */
        height: 100vh;
        z-index: 2147483647 !important; /* 最大层级,确保在 v0 框架之上 */
        background: linear-gradient(135deg, rgba(0, 5, 15, 0.98), rgba(0, 10, 25, 0.98));
        border-left: 2px solid rgba(0, 255, 255, 0.4);
        box-shadow: -20px 0 80px rgba(0, 10, 30, 0.95);
        transform: translateX(100%);
        transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1);
        display: flex;
        flex-direction: column;
        pointer-events: auto !important; /* 确保可交互 */
    }
    #earth-drawer-container.active {
        transform: translateX(0);
    }
    #earth-render-area {
        flex: 1;
        width: 100%;
        height: 100%;
        overflow: hidden;
        cursor: grab;
    }
   
    #earth-render-area:active {
        cursor: grabbing;
    }
    .earth-header {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        padding: 20px 30px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        z-index: 2147483647 !important; /* 极高层级,确保不被遮挡 */
        background: linear-gradient(180deg, rgba(0,0,0,0.95) 0%, transparent 100%);
        pointer-events: auto !important; /* 强制可点击 */
        backdrop-filter: blur(10px);
    }
    .earth-title {
        color: #00ffff;
        font-family: 'Microsoft YaHei', 'Segoe UI', sans-serif; /* 增加中文字体 */
        letter-spacing: 3px;
        font-weight: 700;
        font-size: 18px;
        text-shadow: 0 0 15px rgba(0, 255, 255, 0.8), 0 0 30px rgba(0, 255, 255, 0.4);
        pointer-events: auto;
        animation: titleGlow 3s ease-in-out infinite;
    }
    @keyframes titleGlow {
        0%, 100% { text-shadow: 0 0 15px rgba(0, 255, 255, 0.8), 0 0 30px rgba(0, 255, 255, 0.4); }
        50% { text-shadow: 0 0 20px rgba(0, 255, 255, 1), 0 0 40px rgba(0, 255, 255, 0.6); }
    }
    .earth-stats {
        position: absolute;
        top: 80px;
        left: 30px;
        color: rgba(255, 255, 255, 0.95);
        font-family: 'Consolas', monospace;
        font-size: 12px;
        z-index: 10;
        background: rgba(0, 20, 40, 0.85);
        padding: 12px 16px;
        border: 1px solid rgba(0, 255, 255, 0.5);
        border-radius: 6px;
        backdrop-filter: blur(10px);
        box-shadow: 0 4px 15px rgba(0, 0, 0, 0.5);
    }
    .earth-stats div { margin: 4px 0; }
    .earth-stats span {
        color: #00ffff;
        font-weight: bold;
        text-shadow: 0 0 8px rgba(0, 255, 255, 0.6);
    }
    #earth-close-btn {
        pointer-events: auto !important;
        position: relative;
        z-index: 2147483647 !important; /* 极高层级 */
        color: #fff;
        background: linear-gradient(135deg, rgba(0, 100, 150, 0.3), rgba(0, 50, 100, 0.3));
        border: 1px solid rgba(0, 255, 255, 0.6);
        padding: 10px 24px !important; /* 加大点击区域 */
        margin-right: 15px !important; /* 避免贴边被遮挡 */
        margin-top: 15px !important; /* 避免被顶部栏覆盖 */
        font-size: 12px;
        cursor: pointer;
        transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
        font-family: 'Consolas', monospace;
        font-weight: 600;
        letter-spacing: 1px;
        border-radius: 8px;
        backdrop-filter: blur(5px);
        text-transform: uppercase;
        overflow: hidden;
        box-shadow: 0 4px 20px rgba(0, 255, 255, 0.4) !important;
    }
    #earth-close-btn::before {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 0;
        height: 0;
        background: rgba(0, 255, 255, 0.3);
        border-radius: 50%;
        transform: translate(-50%, -50%);
        transition: width 0.6s, height 0.6s;
    }
    #earth-close-btn:hover::before { width: 300px; height: 300px; }
    #earth-close-btn:hover {
        background: linear-gradient(135deg, rgba(0, 255, 255, 0.4), rgba(0, 200, 255, 0.4));
        border-color: #00ffff;
        box-shadow: 0 0 20px rgba(0, 255, 255, 0.6), inset 0 0 20px rgba(0, 255, 255, 0.2);
        transform: translateY(-2px);
    }
    #earth-close-btn span { position: relative; z-index: 1; }
    /* 地图按钮样式打开全球地图 */
    #earth-toggle-btn {
        position: fixed;
        bottom: 30px;
        right: 50px;
        width: 64px;
        height: 64px;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        border: none;
        border-radius: 16px;
        cursor: pointer;
        z-index: 99998;
        box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4), 0 4px 8px rgba(0, 0, 0, 0.3);
        transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
        display: flex;
        align-items: center;
        justify-content: center;
        overflow: hidden;
    }
    #earth-toggle-btn::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
        opacity: 0;
        transition: opacity 0.4s;
    }
    #earth-toggle-btn:hover::before { opacity: 1; }
    #earth-toggle-btn:hover {
        transform: translateY(-4px) scale(1.08);
        box-shadow: 0 12px 32px rgba(102, 126, 234, 0.6), 0 8px 16px rgba(0, 0, 0, 0.4);
    }
    #earth-toggle-btn:active { transform: translateY(-2px) scale(1.05); }
   
    #earth-toggle-btn.hidden {
        transform: translateX(150px) scale(0);
        opacity: 0;
    }
    #earth-toggle-btn svg {
        width: 32px;
        height: 32px;
        position: relative;
        z-index: 1;
        filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
    }
    .pulse-ring {
        position: absolute;
        border: 2px solid #667eea;
        border-radius: 16px;
        width: 100%;
        height: 100%;
        animation: pulse-square 2s ease-out infinite;
        opacity: 0;
    }
    @keyframes pulse-square {
        0% { transform: scale(1); opacity: 1; }
        100% { transform: scale(1.3); opacity: 0; }
    }
    .earth-label-card {
        background: linear-gradient(135deg, rgba(0, 20, 40, 0.98), rgba(0, 10, 30, 0.98));
        border: 1px solid #00ffff;
        color: #fff;
        padding: 5px 10px;
        border-radius: 5px;
        font-size: 13px; /* 稍微调大字体 */
        display: flex;
        align-items: center;
        gap: 6px;
        box-shadow: 0 0 20px rgba(0, 255, 255, 0.6), 0 4px 10px rgba(0, 0, 0, 0.5);
        transform: translateY(-25px);
        white-space: nowrap;
        font-family: 'Microsoft YaHei', sans-serif; /* 适配中文 */
        backdrop-filter: blur(8px);
        font-weight: 600;
    }
    .earth-label-card .flag-emoji {
        font-size: 16px;
        filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.5));
    }
    /* Debug 面板 */
    #debug-panel {
        position: absolute;
        bottom: 25px;
        left: 25px;
        background: rgba(0, 0, 0, 0.95);
        color: #0f0;
        padding: 10px;
        font-family: monospace;
        font-size: 10px;
        max-height: 200px;
        overflow-y: auto;
        border: 1px solid #0f0;
        border-radius: 4px;
        z-index: 10;
        max-width: 300px;
        display: none;
    }
    #debug-panel.show { display: block; }
    #debug-panel div { margin: 2px 0; word-break: break-all; }
    /* 响应式优化 */
    @media (max-width: 768px) {
        #earth-drawer-container {
            width: 100vw;
            max-width: 100vw;
            height: 60vh;
            top: auto;
            bottom: 0;
            transform: translateY(100%);
            border-left: none;
            border-top: 2px solid rgba(0, 255, 255, 0.4);
            min-width: 0;
        }
       
        #earth-drawer-container.active { transform: translateY(0); }
        .earth-header { padding: 12px 15px; }
        .earth-title { font-size: 14px; letter-spacing: 2px; }
        .earth-stats { font-size: 10px; padding: 8px 12px; top: 55px; left: 15px; }
        #earth-close-btn { padding: 6px 12px; font-size: 11px; }
        #earth-toggle-btn { width: 56px; height: 56px; bottom: 30px; right: 60px; border-radius: 14px; }
        #earth-toggle-btn svg { width: 28px; height: 28px; }
        .earth-label-card { font-size: 11px; padding: 4px 8px; }
        .earth-label-card .flag-emoji { font-size: 14px; }
        #debug-panel { font-size: 9px; bottom: 15px; left: 15px; max-width: 250px; max-height: 150px; }
    }
</style>
<div id="earth-toggle-btn" title="打开全球地图">
    <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
        <circle cx="12" cy="12" r="10" stroke="white" stroke-width="1.5" fill="rgba(255,255,255,0.1)"/>
        <path d="M12 2C12 2 15 6 15 12C15 18 12 22 12 22" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
        <path d="M12 2C12 2 9 6 9 12C9 18 12 22 12 22" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
        <path d="M2 12H22" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
        <path d="M4 8H20" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
        <path d="M4 16H20" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
        <circle cx="12" cy="12" r="1.5" fill="#00ffff"/>
    </svg>
    <div class="pulse-ring"></div>
</div>
<div id="earth-drawer-container">
    <div class="earth-header">
        <div class="earth-title">NEZHA /// 已连接</div>
        <div id="earth-close-btn"><span>断开连接</span></div>
    </div>
    <div class="earth-stats" id="earth-stats">
        <div>已检测到 <span id="country-count">0</span> 个地区</div>
        <div>状态: <span id="globe-status">就绪</span></div>
        <div style="margin-top: 8px; font-size: 10px; opacity: 0.7; cursor: pointer;" id="toggle-debug">
            [显示调试信息]
        </div>
    </div>
    <div id="debug-panel"></div>
    <div id="earth-render-area"></div>
</div>
<script>
/**
 * Nezha 3D Earth V13.8 (中文名称 & 半屏显示)
 */
(function() {
    'use strict';
    // 完整坐标库
    const COORD_MAP = {
        'CN': [35.8617, 104.1954], 'HK': [22.3193, 114.1694], 'TW': [23.6978, 120.9605],
        'MO': [22.1987, 113.5439], 'JP': [36.2048, 138.2529], 'KR': [35.9078, 127.7669],
        'KP': [40.3399, 127.5101], 'SG': [1.3521, 103.8198], 'MY': [4.2105, 101.9758],
        'TH': [15.8700, 100.9925], 'VN': [14.0583, 108.2772], 'PH': [12.8797, 121.7740],
        'ID': [-0.7893, 113.9213], 'IN': [20.5937, 78.9629], 'PK': [30.3753, 69.3451],
        'BD': [23.6850, 90.3563], 'LK': [7.8731, 80.7718], 'MM': [21.9162, 95.9560],
        'KH': [12.5657, 104.9910], 'LA': [19.8563, 102.4955], 'NP': [28.3949, 84.1240],
        'BT': [27.5142, 90.4336], 'MN': [46.8625, 103.8467], 'KZ': [48.0196, 66.9237],
        'UZ': [41.3775, 64.5853], 'TM': [38.9697, 59.5563], 'KG': [41.2044, 74.7661],
        'TJ': [38.8610, 71.2761], 'AF': [33.9391, 67.7100], 'AE': [23.4241, 53.8478],
        'SA': [23.8859, 45.0792], 'IL': [31.0461, 34.8516], 'JO': [30.5852, 36.2384],
        'LB': [33.8547, 35.8623], 'SY': [34.8021, 38.9968], 'IQ': [33.2232, 43.6793],
        'IR': [32.4279, 53.6880], 'TR': [38.9637, 35.2433], 'YE': [15.5527, 48.5164],
        'OM': [21.4735, 55.9754], 'KW': [29.3117, 47.4818], 'QA': [25.3548, 51.1839],
        'BH': [26.0667, 50.5577], 'AM': [40.0691, 45.0382], 'AZ': [40.1431, 47.5769],
        'GE': [42.3154, 43.3569],
        'US': [37.0902, -95.7129], 'CA': [56.1304, -106.3468],'MX': [23.6345, -102.5528],
        'GT': [15.7835, -90.2308], 'BZ': [17.1899, -88.4976], 'SV': [13.7942, -88.8965],
        'HN': [15.2000, -86.2419], 'NI': [12.8654, -85.2072], 'CR': [9.7489, -83.7534],
        'PA': [8.5380, -80.7821], 'CU': [21.5218, -77.7812], 'JM': [18.1096, -77.2975],
        'HT': [18.9712, -72.2852], 'DO': [18.7357, -70.1627],
        'GB': [55.3781, -3.4360], 'IE': [53.4129, -8.2439], 'FR': [46.2276, 2.2137],
        'DE': [51.1657, 10.4515], 'IT': [41.8719, 12.5674], 'ES': [40.4637, -3.7492],
        'PT': [39.3999, -8.2245], 'NL': [52.1326, 5.2913], 'BE': [50.5039, 4.4699],
        'LU': [49.8153, 6.1296], 'CH': [46.8182, 8.2275], 'AT': [47.5162, 14.5501],
        'SE': [60.1282, 18.6435], 'NO': [60.4720, 8.4689], 'FI': [61.9241, 25.7482],
        'DK': [56.2639, 9.5018], 'IS': [64.9631, -19.0208], 'PL': [51.9194, 19.1451],
        'CZ': [49.8175, 15.4730], 'SK': [48.6690, 19.6990], 'HU': [47.1625, 19.5033],
        'RO': [45.9432, 24.9668], 'BG': [42.7339, 25.4858], 'GR': [39.0742, 21.8243],
        'HR': [45.1000, 15.2000], 'SI': [46.1512, 14.9955], 'RS': [44.0165, 21.0059],
        'BA': [43.9159, 17.6791], 'ME': [42.7087, 19.3744], 'MK': [41.6086, 21.7453],
        'AL': [41.1533, 20.1683], 'XK': [42.6026, 20.9030], 'UA': [48.3794, 31.1656],
        'BY': [53.7098, 27.9534], 'MD': [47.4116, 28.3699], 'RU': [61.5240, 105.3188],
        'EE': [58.5953, 25.0136], 'LV': [56.8796, 24.6032], 'LT': [55.1694, 23.8813],
        'CY': [35.1264, 33.4299], 'MT': [35.9375, 14.3754],
        'BR': [-14.2350, -51.9253],'AR': [-38.4161, -63.6167],'CL': [-35.6751, -71.5430],
        'CO': [4.5709, -74.2973], 'PE': [-9.1900, -75.0152], 'VE': [6.4238, -66.5897],
        'EC': [-1.8312, -78.1834], 'BO': [-16.2902, -63.5887],'PY': [-23.4425, -58.4438],
        'UY': [-32.5228, -55.7658],'GY': [4.8604, -58.9302], 'SR': [3.9193, -56.0278],
        'AU': [-25.2744, 133.7751],'NZ': [-40.9006, 174.8860],'FJ': [-17.7134, 178.0650],
        'PG': [-6.3150, 143.9555], 'NC': [-20.9043, 165.6180],
        'ZA': [-30.5595, 22.9375], 'EG': [26.8206, 30.8025], 'NG': [9.0820, 8.6753],
        'KE': [-0.0236, 37.9062], 'ET': [9.1450, 40.4897], 'MA': [31.7917, -7.0926],
        'DZ': [28.0339, 1.6596], 'TN': [33.8869, 9.5375], 'LY': [26.3351, 17.2283],
        'SD': [12.8628, 30.2176], 'TZ': [-6.3690, 34.8888], 'UG': [1.3733, 32.2903],
        'GH': [7.9465, -1.0232], 'CI': [7.5400, -5.5471], 'SN': [14.4974, -14.4524],
        'ZW': [-19.0154, 29.1549], 'AO': [-11.2027, 17.8739], 'MZ': [-18.6657, 35.5296]
    };
   
    const FLAG_EMOJI = {
        'CN': '🇨🇳', 'HK': '🇭🇰', 'TW': '🇹🇼', 'MO': '🇲🇴', 'JP': '🇯🇵', 'KR': '🇰🇷', 'KP': '🇰🇵', 'SG': '🇸🇬', 'MY': '🇲🇾', 'TH': '🇹🇭', 'VN': '🇻🇳', 'PH': '🇵🇭', 'ID': '🇮🇩', 'IN': '🇮🇳', 'PK': '🇵🇰', 'BD': '🇧🇩', 'LK': '🇱🇰', 'MM': '🇲🇲', 'KH': '🇰🇭', 'LA': '🇱🇦', 'NP': '🇳🇵', 'BT': '🇧🇹', 'MN': '🇲🇳', 'KZ': '🇰🇿', 'UZ': '🇺🇿', 'TM': '🇹🇲', 'KG': '🇰🇬', 'TJ': '🇹🇯', 'AF': '🇦🇫', 'AE': '🇦🇪', 'SA': '🇸🇦', 'IL': '🇮🇱', 'JO': '🇯🇴', 'LB': '🇱🇧',
        'SY': '🇸🇾', 'IQ': '🇮🇶', 'IR': '🇮🇷', 'TR': '🇹🇷', 'YE': '🇾🇪', 'OM': '🇴🇲', 'KW': '🇰🇼', 'QA': '🇶🇦', 'BH': '🇧🇭', 'AM': '🇦🇲', 'AZ': '🇦🇿', 'GE': '🇬🇪', 'US': '🇺🇸', 'CA': '🇨🇦', 'MX': '🇲🇽', 'GT': '🇬🇹', 'BZ': '🇧🇿', 'SV': '🇸🇻', 'HN': '🇭🇳', 'NI': '🇳🇮', 'CR': '🇨🇷', 'PA': '🇵🇦', 'CU': '🇨🇺', 'JM': '🇯🇲', 'HT': '🇭🇹', 'DO': '🇩🇴', 'GB': '🇬🇧', 'IE': '🇮🇪', 'FR': '🇫🇷', 'DE': '🇩🇪', 'IT': '🇮🇹', 'ES': '🇪🇸', 'PT': '🇵🇹', 'NL': '🇳🇱', 'BE': '🇧🇪', 'LU': '🇱🇺', 'CH': '🇨🇭', 'AT': '🇦🇹', 'SE': '🇸🇪', 'NO': '🇳🇴', 'FI': '🇫🇮', 'DK': '🇩🇰', 'IS': '🇮🇸', 'PL': '🇵🇱', 'CZ': '🇨🇿', 'SK': '🇸🇰', 'HU': '🇭🇺', 'RO': '🇷🇴', 'BG': '🇧🇬', 'GR': '🇬🇷', 'HR': '🇭🇷', 'SI': '🇸🇮', 'RS': '🇷🇸', 'BA': '🇧🇦', 'ME': '🇲🇪', 'MK': '🇲🇰', 'AL': '🇦🇱', 'XK': '🇽🇰', 'UA': '🇺🇦', 'BY': '🇧🇾', 'MD': '🇲🇩', 'RU': '🇷🇺', 'EE': '🇪🇪', 'LV': '🇱🇻', 'LT': '🇱🇹', 'CY': '🇨🇾', 'MT': '🇲🇹', 'BR': '🇧🇷', 'AR': '🇦🇷', 'CL': '🇨🇱', 'CO': '🇨🇴', 'PE': '🇵🇪', 'VE': '🇻🇪', 'EC': '🇪🇨', 'BO': '🇧🇴', 'PY': '🇵🇾', 'UY': '🇺🇾', 'GY': '🇬🇾', 'SR': '🇸🇷', 'AU': '🇦🇺', 'NZ': '🇳🇿', 'FJ': '🇫🇯', 'PG': '🇵🇬', 'NC': '🇳🇨', 'ZA': '🇿🇦', 'EG': '🇪🇬', 'NG': '🇳🇬', 'KE': '🇰🇪', 'ET': '🇪🇹', 'MA': '🇲🇦', 'DZ': '🇩🇿', 'TN': '🇹🇳', 'LY': '🇱🇾', 'SD': '🇸🇩', 'TZ': '🇹🇿', 'UG': '🇺🇬', 'GH': '🇬🇭', 'CI': '🇨🇮', 'SN': '🇸🇳', 'ZW': '🇿🇼', 'AO': '🇦🇴', 'MZ': '🇲🇿'
    };
    // --- 新增:中文名称映射表 ---
    const CODE_TO_CN = {
        'CN': '中国', 'HK': '香港', 'TW': '台湾', 'MO': '澳门', 'JP': '日本', 'KR': '韩国', 'KP': '朝鲜', 'SG': '新加坡', 'MY': '马来西亚', 'TH': '泰国', 'VN': '越南', 'PH': '菲律宾', 'ID': '印尼', 'IN': '印度', 'PK': '巴基斯坦', 'BD': '孟加拉国', 'LK': '斯里兰卡', 'MM': '缅甸', 'KH': '柬埔寨', 'LA': '老挝', 'NP': '尼泊尔', 'BT': '不丹', 'MN': '蒙古', 'KZ': '哈萨克斯坦', 'UZ': '乌兹别克斯坦', 'TM': '土库曼斯坦', 'KG': '吉尔吉斯斯坦', 'TJ': '塔吉克斯坦', 'AF': '阿富汗', 'AE': '阿联酋', 'SA': '沙特', 'IL': '以色列', 'JO': '约旦', 'LB': '黎巴嫩',
        'SY': '叙利亚', 'IQ': '伊拉克', 'IR': '伊朗', 'TR': '土耳其', 'YE': '也门', 'OM': '阿曼', 'KW': '科威特', 'QA': '卡塔尔', 'BH': '巴林', 'AM': '亚美尼亚', 'AZ': '阿塞拜疆', 'GE': '格鲁吉亚', 'US': '美国', 'CA': '加拿大', 'MX': '墨西哥', 'GT': '危地马拉', 'BZ': '伯利兹', 'SV': '萨尔瓦多', 'HN': '洪都拉斯', 'NI': '尼加拉瓜', 'CR': '哥斯达黎加', 'PA': '巴拿马', 'CU': '古巴', 'JM': '牙买加', 'HT': '海地', 'DO': '多米尼加', 'GB': '英国', 'IE': '爱尔兰', 'FR': '法国', 'DE': '德国', 'IT': '意大利', 'ES': '西班牙', 'PT': '葡萄牙', 'NL': '荷兰', 'BE': '比利时', 'LU': '卢森堡', 'CH': '瑞士', 'AT': '奥地利', 'SE': '瑞典', 'NO': '挪威', 'FI': '芬兰', 'DK': '丹麦', 'IS': '冰岛', 'PL': '波兰', 'CZ': '捷克', 'SK': '斯洛伐克', 'HU': '匈牙利', 'RO': '罗马尼亚', 'BG': '保加利亚', 'GR': '希腊', 'HR': '克罗地亚', 'SI': '斯洛文尼亚', 'RS': '塞尔维亚', 'BA': '波黑', 'ME': '黑山', 'MK': '北马其顿', 'AL': '阿尔巴尼亚', 'XK': '科索沃', 'UA': '乌克兰', 'BY': '白俄罗斯', 'MD': '摩尔多瓦', 'RU': '俄罗斯', 'EE': '爱沙尼亚', 'LV': '拉脱维亚', 'LT': '立陶宛', 'CY': '塞浦路斯', 'MT': '马耳他', 'BR': '巴西', 'AR': '阿根廷', 'CL': '智利', 'CO': '哥伦比亚', 'PE': '秘鲁', 'VE': '委内瑞拉', 'EC': '厄瓜多尔', 'BO': '玻利维亚', 'PY': '巴拉圭', 'UY': '乌拉圭', 'GY': '圭亚那', 'SR': '苏里南', 'AU': '澳大利亚', 'NZ': '新西兰', 'FJ': '斐济', 'PG': '巴新', 'NC': '新喀里多尼亚', 'ZA': '南非', 'EG': '埃及', 'NG': '尼日利亚', 'KE': '肯尼亚', 'ET': '埃塞俄比亚', 'MA': '摩洛哥', 'DZ': '阿尔及利亚', 'TN': '突尼斯', 'LY': '利比亚', 'SD': '苏丹', 'TZ': '坦桑尼亚', 'UG': '乌干达', 'GH': '加纳', 'CI': '科特迪瓦', 'SN': '塞内加尔', 'ZW': '津巴布韦', 'AO': '安哥拉', 'MZ': '莫桑比克'
    };
    const container = document.getElementById('earth-drawer-container');
    const renderArea = document.getElementById('earth-render-area');
    const toggleBtn = document.getElementById('earth-toggle-btn');
    const closeBtn = document.getElementById('earth-close-btn');
    const statsEl = document.getElementById('earth-stats');
    const countEl = document.getElementById('country-count');
    const statusEl = document.getElementById('globe-status');
    const debugPanel = document.getElementById('debug-panel');
    const toggleDebug = document.getElementById('toggle-debug');
   
    let globeInstance = null;
    let isActive = false;
    let lastDetectedFlags = [];
    let scanRetryCount = 0;
    let debugLogs = [];
    const MAX_RETRY = 3;
    const isMobile = /Mobile|Android|iPhone|iPad/i.test(navigator.userAgent);
    function addDebugLog(msg) {
        const timestamp = new Date().toLocaleTimeString();
        debugLogs.push(`[${timestamp}] ${msg}`);
        if (debugLogs.length > 100) debugLogs.shift();
        updateDebugPanel();
        console.log(msg);
    }
    function updateDebugPanel() {
        debugPanel.innerHTML = debugLogs.slice(-30).map(log => `<div>${log}</div>`).join('');
        debugPanel.scrollTop = debugPanel.scrollHeight;
    }
    toggleDebug.addEventListener('click', () => {
        debugPanel.classList.toggle('show');
        toggleDebug.textContent = debugPanel.classList.contains('show') ?
            '[隐藏调试信息]' : '[显示调试信息]';
    });
    // --- 核心扫描逻辑 ---
    function scanFlags() {
        const flags = new Set();
       
        addDebugLog('=== 开始标志扫描(增强版) ===');
        addDebugLog(`设备: ${isMobile ? '移动端' : '桌面端'}`);
        // Method 1: flag-icon-*
        document.querySelectorAll('[class*="flag-icon-"]').forEach(el => {
            el.classList.forEach(cls => {
                if (cls.startsWith('flag-icon-')) {
                    let code = cls.replace('flag-icon-', '').toUpperCase();
                    if (COORD_MAP[code]) flags.add(code);
                }
            });
        });
        // Method 2 & 3: fi-*
        document.querySelectorAll('[class*="fi-"]').forEach(el => {
            el.classList.forEach(cls => {
                const match = cls.match(/^fi-([a-z]{2})$/i);
                if (match) {
                    let code = match[1].toUpperCase();
                    if (COORD_MAP[code]) flags.add(code);
                }
            });
        });
        // Method 4: data attributes
        ['data-country-code', 'data-country'].forEach(attr => {
            document.querySelectorAll(`[${attr}]`).forEach(el => {
                let code = el.getAttribute(attr).toUpperCase();
                if (COORD_MAP[code]) flags.add(code);
            });
        });
        // Method 6: 扫描图片 src
        let m6Count = 0;
        document.querySelectorAll('img').forEach(img => {
            const src = img.src.toLowerCase();
            if (src.includes('/flag') || src.includes('assets')) {
                Object.keys(COORD_MAP).forEach(code => {
                    if (src.includes(`/${code.toLowerCase()}.`) || src.includes(`-${code.toLowerCase()}.`)) {
                        flags.add(code);
                        m6Count++;
                    }
                });
            }
        });
        if(m6Count > 0) addDebugLog(`M6 (图片路径): 发现 ${m6Count} 个`);
        // Method 7: 扫描 Emoji
        if (isMobile && flags.size === 0) {
            let m7Count = 0;
            const textContent = document.body.innerText;
            Object.keys(FLAG_EMOJI).forEach(code => {
                if (textContent.includes(FLAG_EMOJI[code])) {
                    flags.add(code);
                    m7Count++;
                }
            });
            if(m7Count > 0) addDebugLog(`M7 (Emoji): 发现 ${m7Count} 个`);
        }
        addDebugLog(`=== 总计: ${flags.size} 个唯一国家/地区 ===`);
        const sortedFlags = Array.from(flags).sort();
        return sortedFlags;
    }
    // --- 随机连线生成逻辑 ---
    function generateData() {
        const codes = scanFlags();
        const points = [];
        const arcs = [];
        if (codes.length === 0) return { points, arcs, codes };
        // 1. 先生成所有点
        codes.forEach(code => {
            const coord = COORD_MAP[code];
            if (coord) {
                const [lat, lng] = coord;
                points.push({ code, lat, lng });
            }
        });
        // 2. 在这些国家之间随机生成连线
        const maxArcs = Math.min(40, codes.length * 3);
        const usedPairs = new Set();
        let loopSafety = 0;
        while (arcs.length < maxArcs && codes.length > 1 && loopSafety < 1000) {
            loopSafety++;
            const i = Math.floor(Math.random() * codes.length);
            let j = Math.floor(Math.random() * codes.length);
            if (i === j) continue;
            const fromCode = codes[i];
            const toCode = codes[j];
            const pairKey = [fromCode, toCode].sort().join('-');
            if (usedPairs.has(pairKey)) continue;
            usedPairs.add(pairKey);
            const fromCoord = COORD_MAP[fromCode];
            const toCoord = COORD_MAP[toCode];
           
            if (fromCoord && toCoord) {
                arcs.push({
                    startLat: fromCoord[0], startLng: fromCoord[1],
                    endLat: toCoord[0], endLng: toCoord[1]
                });
            }
        }
        return { points, arcs, codes };
    }
    function initGlobe(isRetry = false) {
        if (globeInstance && !isRetry) { updateGlobe(); return; }
        statusEl.textContent = '扫描中';
        const { points, arcs, codes } = generateData();
       
        if (codes.length === 0) {
            if (scanRetryCount < MAX_RETRY - 1) {
                scanRetryCount++;
                statusEl.textContent = `重试 ${scanRetryCount}`;
                setTimeout(() => initGlobe(true), 1500);
                return;
            }
            statusEl.textContent = '无数据';
            countEl.textContent = '0';
            addDebugLog('无国家/地区标志数据。');
            return;
        }
        scanRetryCount = 0;
        countEl.textContent = codes.length;
        lastDetectedFlags = codes;
        try {
            const globe = Globe();
            globe(renderArea);
            globe.width(renderArea.clientWidth);
            globe.height(renderArea.clientHeight);
            globe.backgroundImageUrl('//unpkg.com/three-globe/example/img/night-sky.png');
            globe.globeImageUrl('//unpkg.com/three-globe/example/img/earth-night.jpg');
            globe.bumpImageUrl('//unpkg.com/three-globe/example/img/earth-topology.png');
            globe.atmosphereColor('rgba(26, 84, 144, 0.8)');
            globe.atmosphereAltitude(0.25);
            globe.ringsData(points);
            globe.ringColor(() => '#00ffff');
            globe.ringMaxRadius(5);
            globe.ringPropagationSpeed(3);
            globe.ringRepeatPeriod(800);
            globe.pointsData(points);
            globe.pointColor(() => '#00ffff');
            globe.pointAltitude(0.02);
            globe.pointRadius(0.5);
            globe.htmlElementsData(points);
           
            // --- 核心修改:使用中文名渲染 ---
            globe.htmlElement(d => {
                const el = document.createElement('div');
                const emoji = FLAG_EMOJI[d.code] || '🏁';
                const cnName = CODE_TO_CN[d.code] || d.code; // 获取中文名,没有则显示代码
                el.innerHTML = `<div class="earth-label-card"><span class="flag-emoji">${emoji}</span><b>${cnName}</b></div>`;
                return el;
            });














// --- 修改渲染逻辑:同时显示 国旗、缩写和中文 ---
globe.htmlElement(d => {
    const el = document.createElement('div');
    const cnName = CODE_TO_CN[d.code] || d.code; // 获取中文名 (如: 中国)
    const shortCode = d.code; // 获取国家缩写 (如: CN)
    
    // 使用外部图片源加载国旗
    const flagImgUrl = `https://flagcdn.com/w40/${d.code.toLowerCase()}.png`;

    el.innerHTML = `
        <div class="earth-label-card" style="display: flex; align-items: center; gap: 8px; padding: 4px 10px;">
            <img src="${flagImgUrl}" 
                 style="width: 20px; height: auto; border-radius: 2px; box-shadow: 0 0 3px rgba(0,0,0,0.5);"
                 onerror="this.style.display='none';"> 
            <span style="color: #00ffff; font-family: monospace; font-weight: bold;">${shortCode}</span>
            <span style="color: #ffffff;">${cnName}</span>
        </div>
    `;
    return el;
});










            // ---------------------------
            globe.htmlLat(d => d.lat);
            globe.htmlLng(d => d.lng);
            globe.htmlAltitude(0.01);
            globe.arcsData(arcs);
            globe.arcColor(() => ['rgba(0, 255, 255, 0.5)', 'rgba(255, 0, 255, 0.5)']);
            globe.arcDashLength(0.7);
            globe.arcDashGap(0.2);
            globe.arcDashAnimateTime(2000);
            globe.arcStroke(1.2);
            globe.arcAltitude(0.3);
            globe.pointOfView({
                lat: codes.includes('CN') ? 35 : 20,
                lng: codes.includes('CN') ? 110 : 0,
                altitude: 2.5
            });
            globe.controls().autoRotate = true;
            globe.controls().autoRotateSpeed = 0.8;
            globe.controls().enableZoom = true;
            globeInstance = globe;
            statusEl.textContent = '已激活';
        } catch (error) {
            statusEl.textContent = '错误';
            addDebugLog(`错误: ${error.message}`);
        }
    }
    function updateGlobe() {
        if (!globeInstance) return;
        const { points, arcs, codes } = generateData();
        if (JSON.stringify(codes.sort()) === JSON.stringify(lastDetectedFlags.sort())) return;
        lastDetectedFlags = codes;
        countEl.textContent = codes.length;
        globeInstance.ringsData(points);
        globeInstance.pointsData(points);
        globeInstance.htmlElementsData(points);
        globeInstance.arcsData(arcs);
    }
    function toggle() {
        isActive = !isActive;
        if (isActive) {
            container.classList.add('active');
            toggleBtn.classList.add('hidden');
            debugLogs = [];
            scanRetryCount = 0;
            setTimeout(() => initGlobe(), isMobile ? 800 : 400);
        } else {
            container.classList.remove('active');
            toggleBtn.classList.remove('hidden');
            if (globeInstance && globeInstance.controls) globeInstance.controls().autoRotate = false;
        }
    }
    toggleBtn.addEventListener('click', toggle);
    closeBtn.addEventListener('click', toggle);
    window.addEventListener('resize', () => {
        if (isActive && globeInstance) {
            globeInstance.width(renderArea.clientWidth);
            globeInstance.height(renderArea.clientHeight);
        }
    });
    setInterval(() => { if (isActive && globeInstance) updateGlobe(); }, 30000);
})();
</script>



<style>
/* 隐藏页脚 */
.footer {
    display: none !important;
}
/* 如果上面不生效,尝试这个 */
footer {
    display: none !important;
}
</style>

哪吒探针是一款广受欢迎的服务器监控工具,界面简洁、功能强大,非常适合用于监控 VPS、物理服务器和网络状态。本篇将分享一套经过深度优化的哪吒探针 v2 部署方案,在提升面板性能与稳定性的同时,兼容旧版 v0 客户端。通过合理的参数优化与部署方式调整,可以显著降低资源占用,提高监控数据的实时性和系统稳定性,适合长期稳定运行。