2025国家智慧教育平台寒假研修,可秒刷视频!适合中小学(基础教育) | 职业教育 | 高等教育

适用2025国家智慧教育平台寒假研修.中小学课程,可快速通过视频学习。即秒刷!| 职业教育/高等教育 可自动挂机。欢迎加入QQ交流群,及时获取最新消息!请勿随意二次发布代码,尊重原创!

当前为 2025-01-30 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         2025国家智慧教育平台寒假研修,可秒刷视频!适合中小学(基础教育) | 职业教育  | 高等教育
// @namespace    http://tampermonkey.net/zzzzzzys_国家中小学
// @version      1.0.3
// @description  适用2025国家智慧教育平台寒假研修.中小学课程,可快速通过视频学习。即秒刷!| 职业教育/高等教育 可自动挂机。欢迎加入QQ交流群,及时获取最新消息!请勿随意二次发布代码,尊重原创!
// @author       zzzzzzys
// @match        https://basic.smartedu.cn/*
// @match        https://core.teacher.vocational.smartedu.cn/*
// @icon         https://basic.smartedu.cn/favicon.ico
// @require      https://fastly.jsdelivr.net/npm/[email protected]/crypto-js.min.js
// @resource     https://cdn.staticfile.org/limonte-sweetalert2/11.7.1/sweetalert2.min.css
// @require      https://fastly.jsdelivr.net/npm/[email protected]/dist/sweetalert2.all.min.js
// @connect      basic.smartedu.cn
// @connect      x-study-record-api.ykt.eduyun.cn
// @grant        unsafeWindow
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @grant        GM_info
// @grant        GM_addStyle
// @run-at       document-end
// @license      GPL-3.0-or-later
// ==/UserScript==
/*****************************
 * 盗版可耻
 * 请尊重原创劳动成果!
 * 作者:zzzzzzys
 * https://greasyfork.org/zh-CN/users/1176747-zzzzzzys
 * 搬运可耻
 ****************************/
(function () {
    'use strict';
    const qqGroup = [
        {customName:"群1",id: "570337037", link: "https://qm.qq.com/q/rDCbvTiV9K", isFull: true,priority:0},
        {customName:"群2",id: "618010974", link: "https://qm.qq.com/q/h854sxDvKa", isFull: false,priority:2},
        {customName:"群3",id: "1003884618", link: "https://qm.qq.com/q/kRcyAunAic", isFull: false,priority:1},
        {customName:"群4",id: "821240605", link: "https://qm.qq.com/q/z1ogtdhyGA", isFull: false,priority:2},
        {customName:"群5",id: "1013973135", link: "https://qm.qq.com/q/EpXA5Ar3vG", isFull: false,priority:2},
    ]

    let qqUrl = "https://qm.qq.com/q/rDCbvTiV9K"
    let qqNum = "570337037"
    let qqNum2 = "618010974"
    let qqUrl2 = "https://qm.qq.com/q/h854sxDvKa"
    let biliUrl = "https://b23.tv/x5pFcB0"
    // 预处理群组数据
    const renderQQGroups = () => {
        try {
            const activeGroups = qqGroup
                .filter(group => {
                    // 添加数据校验
                    if (!group.customName || !group.id) {
                        console.warn('Invalid group:', group);
                        return false;
                    }
                    return !group.isFull;
                })
                .sort((a, b) => a.priority - b.priority);

            // 添加空状态提示
            if (activeGroups.length === 0) {
                return `<div style="color: #ff9999; text-align:center; margin:12px 0">
              所有群组已开放,欢迎直接加入
            </div>`;
            }
            const title=`<div style="background: linear-gradient(135deg, #FF4DAF 0%, #FF6B6B 100%);display: flex; align-items: center; gap:15px;">
                            <img src="https://qzonestyle.gtimg.cn/qzone/qzact/act/external/tiqq/logo.png" 
                                 style="height:36px; border-radius:6px;">
                            <div>
                                <div style="font-size:16px; font-weight:bold; margin-bottom:4px;">教师交流群(请优先选择未满群加入)</div>
                                <div style="font-size:12px; opacity:0.9;">获取实时支持 | 最新功能优先体验</div>
                            </div>
                        </div>`
            let content= title + activeGroups.map(group => `
                      <a href="${group.link}" 
                         target="_blank"
                         style="display: block; margin-top: 12px; padding: 10px;
                                background: rgba(255,255,255,0.2);
                                border-radius: 6px; text-align: center;
                                text-decoration: none; color: white !important;
                                transition: 0.3s; font-weight: 500;
                                cursor: pointer;"
                         aria-label="加入QQ群${group.customName}(群号:${group.id})">
                        🎯 点击加入${group.customName}:${group.id} <!-- 移除群号显示 -->
                      </a>
                    `).join('');
            return `<div style="background: linear-gradient(135deg, #FF4DAF 0%, #FF6B6B 100%); padding:15px; border-radius:8px; color:white;">
                                    ${content}
                                </div>`
        } catch (error) {
            console.error('QQ群渲染错误:', error);
            return ''; // 静默失败
        }
    };
    const groupHtml = `<!-- 社群入口 -->
                    <div style="background: linear-gradient(135deg, #FF4DAF 0%, #FF6B6B 100%); padding:15px; border-radius:8px; color:white;">
                        <div style="display: flex; align-items: center; gap:15px;">
                            <img src="https://qzonestyle.gtimg.cn/qzone/qzact/act/external/tiqq/logo.png" 
                                 style="height:36px; border-radius:6px;">
                            <div>
                                <div style="font-size:16px; font-weight:bold; margin-bottom:4px;">教师交流群(请优先选择未满群加入)</div>
                                <div style="font-size:12px; opacity:0.9;">获取实时支持 | 最新功能优先体验</div>
                            </div>
                        </div>
                        
                        <!-- QQ群 -->
                        <a href="${qqGroup[2].isFull ? 'javascript:void(0);' : qqGroup[2].link}" 
                           ${qqGroup[2].isFull ? '' : 'target="_blank"'} 
                           style="display: block; margin-top:12px; padding:10px; 
                                  background: ${qqGroup[2].isFull ? '#999' : 'rgba(255,255,255,0.2)'}; 
                                  border-radius:6px; text-align:center; 
                                  text-decoration:none; color:white !important;
                                  transition:0.3s; font-weight:500;
                                  cursor: ${qqGroup[2].isFull ? 'not-allowed' : 'pointer'};">
                            ${qqGroup[2].isFull ? '⛔ 群已满' : '🎯 点击加入QQ群3:' + qqGroup[2].id}
                        </a>
                        <!-- QQ群2 -->
                        <a href="${qqGroup[1].isFull ? 'javascript:void(0);' : qqGroup[1].link}" 
                           ${qqGroup[1].isFull ? '' : 'target="_blank"'} 
                           style="display: block; margin-top:12px; padding:10px; 
                                  background: ${qqGroup[1].isFull ? '#999' : 'rgba(255,255,255,0.2)'}; 
                                  border-radius:6px; text-align:center; 
                                  text-decoration:none; color:white !important;
                                  transition:0.3s; font-weight:500;
                                  cursor: ${qqGroup[1].isFull ? 'not-allowed' : 'pointer'};">
                            ${qqGroup[1].isFull ? '⛔ 群已满' : '🎯 点击加入QQ群2:' + qqGroup[1].id}
                        </a>
                        <!-- QQ群 -->
                        <a href="${qqGroup[3].isFull ? 'javascript:void(0);' : qqGroup[3].link}" 
                           ${qqGroup[3].isFull ? '' : 'target="_blank"'} 
                           style="display: block; margin-top:12px; padding:10px; 
                                  background: ${qqGroup[3].isFull ? '#999' : 'rgba(255,255,255,0.2)'}; 
                                  border-radius:6px; text-align:center; 
                                  text-decoration:none; color:white !important;
                                  transition:0.3s; font-weight:500;
                                  cursor: ${qqGroup[3].isFull ? 'not-allowed' : 'pointer'};">
                            ${qqGroup[3].isFull ? '⛔ 群已满' : '🎯 点击加入QQ群4:' + qqGroup[3].id}
                        </a>
                        <!-- QQ群 -->
                        <a href="${qqGroup[4].isFull ? 'javascript:void(0);' : qqGroup[4].link}" 
                           ${qqGroup[4].isFull ? '' : 'target="_blank"'} 
                           style="display: block; margin-top:12px; padding:10px; 
                                  background: ${qqGroup[4].isFull ? '#999' : 'rgba(255,255,255,0.2)'}; 
                                  border-radius:6px; text-align:center; 
                                  text-decoration:none; color:white !important;
                                  transition:0.3s; font-weight:500;
                                  cursor: ${qqGroup[4].isFull ? 'not-allowed' : 'pointer'};">
                            ${qqGroup[4].isFull ? '⛔ 群已满' : '🎯 点击加入QQ群5:' + qqGroup[4].id}
                        </a>

                        <!-- QQ群 -->
                        <a href="${qqGroup[0].isFull ? 'javascript:void(0);' : qqGroup[0].link}" 
                           ${qqGroup[0].isFull ? '' : 'target="_blank"'} 
                           style="display: block; margin-top:12px; padding:10px; 
                                  background: ${qqGroup[0].isFull ? '#999' : 'rgba(255,255,255,0.2)'}; 
                                  border-radius:6px; text-align:center; 
                                  text-decoration:none; color:white !important;
                                  transition:0.3s; font-weight:500;
                                  cursor: ${qqGroup[0].isFull ? 'not-allowed' : 'pointer'};">
                            ${qqGroup[0].isFull ? '⛔ 群已满' : '🎯 点击加入QQ群:' + qqGroup[0].id}
                        </a>
                        <a href="${biliUrl}" 
                           target="_blank" 
                           style="display: block; margin-top:12px; padding:10px; 
                                  background: rgba(255,255,255,0.2); border-radius:6px; 
                                  text-align:center; text-decoration:none; color:white !important;
                                  transition:0.3s; font-weight:500;">
                            📽️ 点击观看使用教程,哔哩哔哩:${biliUrl}
                        </a>
                    </div>`
    let requestObj = {
        fullsData: {
            url: "https://s-file-2.ykt.cbern.com.cn/teach/s_course/v2/activity_sets/3efdb592-138e-4854-8964-5e10f6011f33/fulls.json",
            method: "GET",
        },
        resourceLearningPositions: {
            url: "https://x-study-record-api.ykt.eduyun.cn/v1/resource_learning_positions/",
            method: "PUT"
        },
        /* 职业教育 | 高等教育  */
        progress: {
            url: "https://core.teacher.vocational.smartedu.cn/p/course/services/member/study/progress",
            method: "POST",
        }
    }

    /********************************************************
     * 职业教育/高等教育
     *******************************************************/
    const SWAL_CONFIG = {
        title: '课程进度控制',
        html: `
            <div style="margin-bottom: 5px">
                <label>v${GM_info.script.version}</label>
            </div>
            <div style="
                padding: 12px;
                background: #e8f4ff;
                border-radius: 8px;
                margin-bottom: 15px;
                border: 1px solid #b3d4fc;
                text-align: center;
            ">
                <span style="
                    font-size: 14px;    
                    color: #ff4daf;
                    display: inline-flex;
                    align-items: center;
                    gap: 6px;
                ">
                    <span style="font-size: 16px">🎯</span>
                    老师您好,点击开始按钮,开始减负之旅<br>
                    脚本会自动学习当前页所有视频,您可安心休息片刻
                </span>
            </div>
             <div style="margin-bottom: 15px">
                <label>当前视频:</label>
                <div id="currentVideo" style="
                    font-size: 16px;
                    color: #3498db;
                    font-weight: 500;
                    margin: 8px 0;
                    white-space: nowrap;
                    overflow: hidden;
                    text-overflow: ellipsis;
                ">尚未开始</div>
            </div>
            <div class="progress-container" style="
                background: #f0f0f0;
                height: 20px;
                border-radius: 10px;
                margin: 15px 0;
                overflow: hidden;
            ">
                <div id="swalProgressBar" style="
                    height: 100%;
                    background: linear-gradient(90deg, #4CAF50 0%, #8BC34A 100%);
                    width: 0;
                    transition: width 0.3s ease;
                "></div>
            </div>
            <div style="
                display: grid;
                grid-template-columns: 1fr 1fr;
                gap: 10px;
                margin-bottom: 15px;
            ">
                <div>
                    <label>当前进度</label>
                    <div id="currentProgress" style="
                        font-size: 18px;
                        font-weight: bold;
                        color: #2c3e50;
                    ">0:00</div>
                </div>
                <div>
                    <label>大概需要时间</label>
                    <div id="needTime" style="
                        font-size: 14px;
                        color: #2efd00;
                    ">还未开始</div>
                </div>
                <div>
                    <label>总时长</label>
                    <div id="totalTime" style="
                        font-size: 14px;
                        color: #7f8c8d;
                    ">还未开始</div>
                </div>
            </div>
            <div id="statusMessage" style="
                padding: 10px;
                border-radius: 5px;
                margin: 10px 0;
                background: #f8f9fa;
                text-align: center;
            ">准备就绪</div>
            <div style="
            padding: 12px;
            background: #f5f7fa;
            border-radius: 8px;
            margin: 12px 0;
            border: 1px solid #e4e7ed;
        ">
           ${renderQQGroups()}
        </div>
            <div id="author" style="
                padding: 8px 16px; /* 适当的上下左右内边距 */
                border-radius: 10px;
                margin: 10px 0;
                background: #f8f9fa;
                text-align: center;
                font-size: 12px; /* 稍微增大字体 */
                font-weight: bold; /* 加粗字体 */
                color: #495057; /* 更深的字体颜色,增强可读性 */
                border: 1px solid #dee2e6; /* 添加边框 */
                box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* 轻微阴影效果 */
                letter-spacing: 1px; /* 增加字母间距 */
            ">
                By YoungthZou. 盗码可耻! zzzzzzys
            </div>
        `,
        showConfirmButton: false,
        allowOutsideClick: false,
        allowEscapeKey: false,
        width: 600,
        willOpen: () => {
            document.querySelector('.swal2-close').remove();
        }
    };

    // 状态管理
    let currentProgress = 60;
    let isRunning = false;
    let timerId = null;
    let swalInstance = null;
    let totalTime = 1000;
    let checkInterval = null
    // 工具函数
    const formatTime = (seconds) => {
        const mins = Math.floor(seconds / 60);
        const secs = seconds % 60;
        return `${mins}:${secs.toString().padStart(2, '0')}`;
    };

    const updateUI = (progress, status) => {
        if (!swalInstance) return;

        // 更新进度条
        const progressBar = swalInstance.querySelector('#swalProgressBar');
        const percent = (progress / totalTime * 100).toFixed(1);
        progressBar.style.width = `${Math.min(parseFloat(percent), 100)}%`;

        // 更新文本显示
        swalInstance.querySelector('#currentProgress').textContent = formatTime(progress);
        swalInstance.querySelector('#totalTime').textContent = formatTime(totalTime);
        swalInstance.querySelector('#needTime').textContent = formatTime(parseInt(((totalTime - progress) / 3).toFixed(0)));

        // 更新状态消息
        const statusEl = swalInstance.querySelector('#statusMessage');
        statusEl.textContent = {
            loading: '🔄 正在同步进度...',
            success: '✅ 同步成功,stand by...',
            error: '❌ 同步失败(长时间失败,请反馈)',
            idle: '⏸ 已暂停',
            finished: '✅已学完,跳过...',
            finishAll: '已全部学完,请手动刷新,给个好评吧~',
            next: "🔄 此视频已学完,准备学习下一个..."
        }[status] || '准备就绪';

        statusEl.style.color = {
            loading: '#f39c12',
            success: '#2ecc71',
            error: '#e74c3c',
            idle: '#7f8c8d',
            finished: '#0022fd',
            finishAll: '#ff4daf',
            next: '#f39c12',
        }[status];
    };

    // 发送请求
    const sendProgress = async (videoId) => {
        updateUI(currentProgress, 'loading');
        let oriData = {
            courseId: unsafeWindow.courseId,
            itemId: unsafeWindow.p.itemId,
            videoId: videoId,
            playProgress: currentProgress,
            segId: unsafeWindow.p.segId,
            type: unsafeWindow.p.type,
            tjzj: 1,
            clockInDot: currentProgress,//后台要求此参数为视频播放的位置
            sourceId: unsafeWindow.p.projectId,
            timeLimit: unsafeWindow.timilistParam.timeLimit || -1,
            originP: unsafeWindow.p.originP === 1 ? 2 : 1,  // 硬编码,等待修改
        }
        try {
            const response = await fetch(
                `${requestObj.progress.url}?orgId=${unsafeWindow.p.orgId}`,
                {
                    method: "POST",
                    headers: {
                        "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
                        "x-requested-with": "XMLHttpRequest",
                        "u-platformId": unsafeWindow.platformInfo.id
                    },
                    credentials: "include",
                    body: new URLSearchParams(oriData)
                }
            );

            const data = await response.json();
            console.log(data)
            if (data.data?.videoProgress > 0) {
                currentProgress = parseInt(data.data.videoProgress);
                updateUI(currentProgress, 'success');
                return data.data.progress;
            } else {
                throw new Error('无效的服务器响应');
            }
        } catch (error) {
            console.error('请求失败:', error);
            updateUI(currentProgress, 'error');
        }
    };

    // 创建控制界面
    function createControlPanel() {
        Swal.fire({
            ...SWAL_CONFIG,
            didOpen: (modal) => {
                swalInstance = modal;

                // 添加控制按钮
                const actions = document.createElement('div');
                actions.style = `
                    display: grid;
                    grid-template-columns: 1fr 1fr;
                    gap: 10px;
                    margin-top: 15px;
                `;

                const startBtn = createButton('▶ 开始', '#2ecc71', async () => {
                    if (!isRunning) {
                        try {
                            try {
                                document.querySelector('video').pause()
                            }catch (e) {

                            }
                            isRunning = true;
                            startBtn.textContent = '⏸ 暂停';
                            startBtn.style.background = '#e74c3c';
                            let courseData = getCourseData();
                            for (const courseDatum of courseData) {
                                if (!isRunning) {
                                    return
                                }
                                await sleep(2000)
                                console.log(courseDatum.name)
                                swalInstance.querySelector('#currentVideo').textContent = courseDatum.name
                                currentProgress = 0;
                                totalTime = parseInt(courseDatum.duration);
                                if (parseInt(courseDatum.progress) === 1) {
                                    console.log(" 已学完,跳过...")
                                    updateUI(currentProgress, 'finished');
                                    continue;
                                }
                                do {
                                    const progress = await sendProgress(courseDatum.videoId, currentProgress); // 立即执行
                                    if (progress === "1.0") {
                                        // currentProgress=0;
                                        break;
                                    }

                                    // currentProgress += 60
                                    // 可中断的等待
                                    await interruptibleWait(21000);
                                } while (currentProgress < totalTime && isRunning)
                                updateUI(currentProgress, 'next');
                                await sleep(20000);
                            }
                            // 非暂停结束
                            if(isRunning){
                                currentProgress = 1;
                                totalTime = 1;
                                updateUI(currentProgress, 'finishAll');
                                startBtn.textContent = '▶ 开始';
                                startBtn.style.background = '#2ecc71';
                            }
                        } catch (e) {
                            console.error(e)
                            if (Swal) {
                                Swal.fire({
                                    title: "失败!",
                                    text: e.toString() + "请在视频播放页面使用!!!",
                                    icon: 'error',
                                    // showCancelButton: true,
                                    confirmButtonColor: "#FF4DAFFF",
                                    // cancelButtonText: "取消,等会刷新",
                                    confirmButtonText: "点击去反馈",

                                }).then((result) => {
                                    if (result.isConfirmed) {
                                        window.open("https://greasyfork.org/zh-CN/scripts/525037/feedback")
                                    }
                                });
                            }
                        }finally {
                            isRunning = false;
                        }

                    } else {
                        isRunning = false;
                        startBtn.textContent = '▶ 继续';
                        startBtn.style.background = '#2ecc71';
                        // clearInterval(timerId);
                        if (checkInterval) {
                            clearTimeout(checkInterval.timer);
                            checkInterval.resolve(); // 立即结束等待
                        }
                        updateUI(currentProgress, 'idle');
                        setTimeout(() => {
                            updateUI(currentProgress, 'idle');
                        }, 2000)
                    }
                });

                const resetBtn = createButton('→去好评', '#dbba34', () => {
                    window.open("https://greasyfork.org/zh-CN/scripts/525037/feedback")
                });

                actions.append(startBtn, resetBtn);
                modal.querySelector('.swal2-html-container').append(actions);
            }
        });
    }

    /**
     * 睡眠
     * @param time
     * @returns {Promise<unknown>}
     */
    const sleep = function (time) {
        return new Promise(resolve => setTimeout(resolve, time));
    }

    function interruptibleWait(ms) {
        return new Promise(resolve => {
            const timer = setTimeout(resolve, ms);
            // 暴露清除方法以便立即暂停
            checkInterval = {timer, resolve};
        });
    }

    function createButton(text, color, onClick) {
        const btn = document.createElement('button');
        btn.textContent = text;
        btn.style = `
            padding: 10px 15px;
            border: none;
            border-radius: 5px;
            background: ${color};
            color: white;
            cursor: pointer;
            transition: opacity 0.3s;
        `;
        btn.addEventListener('click', onClick);
        btn.addEventListener('mouseenter', () => btn.style.opacity = 0.8);
        btn.addEventListener('mouseleave', () => btn.style.opacity = 1);
        return btn;
    }

    function getCourseData() {
        let courseData = unsafeWindow.initlessons
        console.log(courseData)
        if (!courseData) {
            updateUI(currentProgress, 'error');
            console.error("no course data!");
            return
        }
        courseData = courseData.filter(item => {
            return item?.type !== "1";
        });
        return [...courseData];
    }


    /********************************************************
     * 打赏
     *******************************************************/
    GM_addStyle(`
.donate-panel {
    position: fixed;
    left: 30%;
    top:50%;
    background: linear-gradient(135deg, #fff5f5 0%, #fff0f7 100%);
    border-radius: 16px;
    box-shadow: 0 8px 32px rgba(255, 77, 175, 0.2);
    padding: 24px;
    width: 520px;
    
    z-index: 2147483647;
    transform: translateY(-100); /* 初始隐藏位置 */
    opacity: 1; /* 确保初始可见性 */
    border: 1px solid #ffe6f0;
    backdrop-filter: blur(8px);
    transition: none; /* 禁用transition改用animation */
}

.donate-header {
    position: relative;
    font-size: 18px;
    color: #ff4daf;
    margin-bottom: 20px;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 12px;
    padding-bottom: 12px;
    border-bottom: 2px solid rgba(255, 77, 175, 0.1);
}

.donate-header::after {
    content: "✨";
    position: absolute;
    right: 0;
    top: -8px;
    font-size: 24px;
    animation: sparkle 2s infinite;
}

.motivation-text {
    font-size: 13px;
    color: #666;
    line-height: 1.6;
    margin: 12px 0;
    background: rgba(255, 255, 255, 0.9);
    padding: 12px;
    border-radius: 8px;
    border: 1px solid #ffebf3;
}

@keyframes heartbeat {
    0% { transform: scale(1); }
    50% { transform: scale(1.05); }
    100% { transform: scale(1); }
}

@keyframes sparkle {
    0% { opacity: 0.3; }
    50% { opacity: 1; }
    100% { opacity: 0.3; }
}
@keyframes panelSlideIn {
    from { transform: translateY(100%); opacity: 0; }
    to { transform: translateY(-50%); opacity: 1; }
}

@keyframes panelSlideOut {
    from { transform: translateY(0); opacity: 1; }
    to { transform: translateY(100%); opacity: 0; }
}

@keyframes heartbeat {
    0% { transform: scale(1); }
    50% { transform: scale(1.1); }
    100% { transform: scale(1); }
}

.qr-grid {
    display: grid;
    grid-template-columns: 1fr; /* 改为单列布局 */
    gap: 24px;
    margin: 24px auto;
    max-width: 300px; /* 增大容器宽度 */
}

.qr-item {
    position: relative;
    overflow: hidden;
    border-radius: 12px;
    transition: 0.3s;
    padding: 12px; /* 增加内边距 */
    background: #fff;
    box-shadow: 0 4px 12px rgba(255, 77, 175, 0.1);
}

.qr-item:hover {
    transform: translateY(-4px);
    box-shadow: 0 6px 16px rgba(255, 77, 175, 0.2);
}

.qr-item img {
    width: 100%;
    height: auto; /* 保持比例 */
    border-radius: 8px;
    border: 1px solid #ffe5f0;
    min-height: 280px; /* 最小高度保证 */
}

.qr-item p {
    text-align: center;
    margin: 16px 0 8px;
    font-size: 16px; /* 增大文字 */
    color: #ff4daf;
    font-weight: 600;
}
/* 新增文字样式 */
.qr-tips {
    text-align: center;
    margin: 8px 0;
    font-size: 14px;
    color: #ff7ab8; /* 更柔和的粉色 */
}

.qr-proverb {
    font-style: italic;
    color: #ff9ec7; /* 更浅的粉色 */
    font-size: 13px;
    margin-top: 4px;
}

/* 修改原有.qr-item p样式 */
.qr-item p {
    margin: 12px 0 4px; /* 减小下边距 */
    /* 其他样式保持不变 */
}

/* 手机横屏/平板适配 */
@media (min-width: 600px) {
    .qr-grid {
        grid-template-columns: 1fr 1fr; /* 大屏幕恢复双列 */
        max-width: 600px;
    }
    .qr-item img {
        min-height: 240px;
    }
}

.third-party {
    margin-top: 20px;
}

.platform-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px;
    background: linear-gradient(135deg, #fff0f5 0%, #fff8fb 100%);
    border-radius: 8px;
    text-decoration: none;
    color: #ff6699 !important;
    font-size: 14px;
    margin: 8px 0;
    transition: 0.3s;
    border: 1px solid #ffe6ee;
}
.donate-panel.active {
    animation: panelSlideIn 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}

.donate-panel.exit {
    animation: panelSlideOut 0.3s ease forwards;
}

/* 触发按钮动画 */
#donate-trigger {
    animation: heartbeat 1.8s ease-in-out infinite;
}
.platform-btn:hover {
    background: linear-gradient(135deg, #ffe6ee 0%, #fff1f7 100%);
    box-shadow: 0 4px 12px rgba(255, 77, 175, 0.1);
}

.close-btn {
    /* 保持原有样式 */
}
`);

    // 激励文案库
    const motivationTexts = [
        "您的每一份支持都将转化为:",
        "❤️ 服务器续费 ",
        "🛠️ 持续开发维护 ",
        "☕ 深夜码农的咖啡燃料",
        "🐈 小猫最爱的水煮鸡胸肉",
    ];

    // 动态生成激励文案
    function generateMotivation() {
        const fragments = [
            '<div class="motivation-text">',
            '🌟 <strong>感谢使用本脚本!</strong>',
            ...motivationTexts.map(t => `• ${t}`),
            '</div>'
        ].join('<br>');

        return fragments
            .replace('${donateCount}', '1,234')
            .replace('${updateDays}', '365');
    }
    // 打赏面板HTML结构
    const donateHTML = `
<div  id="donate-panel">
    ${generateMotivation()}
    <div class="donate-header">
        <svg viewBox="0 0 24 24" width="20" height="20" fill="#1e62ec">
            <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
        </svg>
        支持开发者
    </div>
    <div class="qr-grid">
        <div class="qr-item">
            <p>微信扫码支持</p>
            <img style="width: 200px;height: 266px" src="https://mp-8ba0e2a3-d9c9-45a0-a902-d3bde09f5afd.cdn.bspapp.com/monkey-pic/WeChat.jpg" alt="微信赞赏码">
            <div class="qr-tips">
            <p>❤️持续创作需要您的支持</p>
            <p class="qr-proverb">星火相聚,终成光芒</p>
             </div>
            
        </div>
        <div class="qr-item">
            <p>支付宝扫码支持</p>
            <img style="width: 200px;height: 266px" src="https://mp-8ba0e2a3-d9c9-45a0-a902-d3bde09f5afd.cdn.bspapp.com/monkey-pic/alipay.jpg" alt="支付宝收款码">
            <div class="qr-tips">
            <p>🌸每一份心意都值得珍惜</p>
            <p class="qr-proverb">不啻微芒,造矩成阳</p>
        </div>
            
        </div>
    </div>
    <div class="donate-header">
        <svg viewBox="0 0 24 24" width="20" height="20" fill="#1e62ec">
            <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
        </svg>
        感谢您的支持!
    </div>
    <div class="third-party">
        <!--<a href="https://afdian.net/@yourid" class="platform-btn" target="_blank">
            <svg viewBox="0 0 1024 1024" width="14" height="14" style="vertical-align:-2px;">
                <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372zm218-572.1h-50.4c-4.4 0-8 3.6-8 8v384.2c0 4.4 3.6 8 8 8h145.7c4.4 0 8-3.6 8-8V319.9c0-4.4-3.6-8-8-8h-50.4c-4.4 0-8 3.6-8 8v151.7H730V319.9c0-4.4-3.6-8-8-8zM328.1 703.9c-4.4 0-8-3.6-8-8v-384c0-4.4 3.6-8 8-8h50.4c4.4 0 8 3.6 8 8v151.7h116.7V319.9c0-4.4 3.6-8 8-8h50.4c4.4 0 8 3.6 8 8v384.2c0 4.4-3.6 8-8 8h-145c-4.4 0-8-3.6-8-8v-151H344v151c0 4.4-3.6 8-8 8H328.1z"/>
            </svg>
            爱发电支持
        </a>-->

        <div class="platform-btn" id="donate-panel-close">感谢开发者,已支持~</div>
    </div>
</div>
`;

    // 初始化打赏面板
    function initDonate() {
        if (document.getElementById('donate-panel')) return;

        const panel = document.createElement('div');
        panel.innerHTML = donateHTML;
        panel.className = 'donate-panel';
        document.body.appendChild(panel);

        // 强制重排触发动画
        void panel.offsetWidth; // 触发CSS重绘
        panel.classList.add('active');

        // 关闭按钮事件
        panel.querySelector('#donate-panel-close').addEventListener('click', () => {
            panel.classList.remove('active');
            panel.classList.add('exit');
            panel.addEventListener('animationend', () => {
                panel.remove();
            }, {once: true});
        });

        // 点击外部关闭
        const clickHandler = (e) => {
            if (!panel.contains(e.target) && e.target.id !== 'donate-trigger') {
                panel.classList.add('exit');
                panel.addEventListener('animationend', () => {
                    panel.remove();
                }, {once: true});
                document.removeEventListener('click', clickHandler);
            }
        };
        setTimeout(() => document.addEventListener('click', clickHandler), 100);
    }

    // 显示触发按钮
    const trigger = document.createElement('div');
    trigger.innerHTML = '❤️ 打赏支持';
    Object.assign(trigger.style, {
        position: 'fixed',
        left: '10px',
        top: '415px',
        background: '#ff6b6b',
        color: 'white',
        padding: '8px 16px',
        borderRadius: '20px',
        cursor: 'pointer',
        zIndex: '999999999999999',
        boxShadow: '0 2px 8px rgba(0,0,0,0.2)',
        fontSize: '14px'
    });
    // 触发按钮增强
    Object.assign(trigger.style, {
        background: 'linear-gradient(135deg, #ff4daf 0%, #ff6b6b 100%)',
        fontWeight: '600',
        padding: '12px 24px',
        boxShadow: '0 4px 24px rgba(255, 77, 175, 0.3)',
        animation: 'heartbeat 1.5s ease-in-out infinite',
        border: '1px solid #ffb3d9'
    });
    trigger.addEventListener('click', initDonate);
    document.body.appendChild(trigger);

    /********************************************************
     * 中小学智慧教育平台 * 寒假研修
     *******************************************************/
        //样式
    let style = `.button-3 {
              position: fixed;  
              appearance: none;
              background-color: #ed5822;
              border: 1px solid rgba(27, 31, 35, .15);
              border-radius: 6px;
              box-shadow: rgba(27, 31, 35, .1) 0 1px 0;
              box-sizing: border-box;
              color: #ffffff;
              cursor: pointer;
              display: inline-block;
              font-family: -apple-system,system-ui,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";
              font-size: 14px;
              font-weight: 600;
              line-height: 20px;
              padding: 6px 16px;
              left: 20px;
              top: 300px;
              text-align: center;
              text-decoration: none;
              user-select: none;
              -webkit-user-select: none;
              touch-action: manipulation;
              vertical-align: middle;
              white-space: nowrap;
              z-index: 2147483647;
            }
  
            .button-3:focus:not(:focus-visible):not(.focus-visible) {
              box-shadow: none;
              outline: none;
            }
  
            .button-3:hover {
              background-color: #2c974b;
            }
  
            .button-3:focus {
              box-shadow: rgba(46, 164, 79, .4) 0 0 0 3px;
              outline: none;
            }
  
            .button-3:disabled {
              background-color: #94d3a2;
              border-color: rgba(27, 31, 35, .1);
              color: rgba(255, 255, 255, .8);
              cursor: default;
            }
  
            .button-3:active {
              background-color: #298e46;
              box-shadow: rgba(20, 70, 32, .2) 0 1px 0 inset;
            }`
    const showQQGroup = () => {

    }
    const createFloatingButton = () => {
        // 如果按钮已存在则先移除旧实例
        const existingBtn = document.getElementById('zs-helper-btn');
        if (existingBtn) existingBtn.remove();

        // 直接创建按钮元素(去掉外层div嵌套)
        const btn = document.createElement('div');
        btn.id = 'zs-helper-btn'; // 确保唯一ID直接设置在元素上
        btn.style.cssText = `
        position: fixed;
        left: 10px;
        top: 250px;
        transform: translateY(-50%);
        background: #ed5822;
        color: white;
        padding: 12px 24px;
        border-radius: 30px;
        cursor: pointer;
        box-shadow: 0 4px 12px rgba(255,77,175,0.3);
        z-index: 2147483647; /* 使用最大z-index值 */
        transition: 0.3s;
        font-family: 'Microsoft Yahei', sans-serif;
        white-space: nowrap;
        display: flex;
        align-items: center;
        gap: 8px;
    `;

        // 添加内部HTML内容
        btn.innerHTML = `
        <svg style="width:18px;height:18px;fill:white;" viewBox="0 0 24 24">
            <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"/>
        </svg>
        <span>使用指南</span>
    `;

        // 使用更可靠的事件监听方式
        const handleHover = () => {
            btn.style.transform = 'translateY(-50%) scale(1.05)';
            btn.style.boxShadow = '0 6px 16px rgba(255,77,175,0.4)';
        };

        const handleLeave = () => {
            btn.style.transform = 'translateY(-50%) scale(1)';
            btn.style.boxShadow = '0 4px 12px rgba(255,77,175,0.3)';
        };

        btn.addEventListener('mouseenter', handleHover);
        btn.addEventListener('mouseleave', handleLeave);
        btn.addEventListener('click', showGuideDialog);

        document.body.appendChild(btn);
        return btn;
    };
    // 显示操作指南弹窗
    const showGuideDialog = () => {
        if (Swal) {
            Swal.fire({
                title: `<span style="color: #FF4DAF; font-size:26px; display: flex; align-items: center; gap:8px;">📚 智能刷课指南 <div style="font-size:12px; color:#95a5a6; margin-left:auto;">v${GM_info.script.version}</div></span>`,
                html: `
                <div style="text-align: left; max-width: 720px; line-height: 1.8;">
                    <!-- 操作步骤 -->
                    <div style="background: #f8f9fa; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
                        <div style="color: red; font-weight:500; margin-bottom:10px;">
                            播放页面未正常生效请刷新页面!播放页面左侧无红色按钮请刷新页面!
                        </div>
                        <div style="color: #2c3e50; font-weight:500; margin-bottom:10px;">
                            🚀 极速操作流程<br>
                        </div>
                        
                        <div style="display: grid; grid-template-columns: 32px 1fr; gap: 10px; align-items: center;">
                            <div style="background: #FF4DAF; color: white; width:24px; height:24px; border-radius:50%; text-align:center; line-height:24px;">1</div>
                            <div>进入2025研修课程播放页面</div>
                            
                            <div style="background: #FF4DAF; color: white; width:24px; height:24px; border-radius:50%; text-align:center; line-height:24px;">2</div>
                            <div>等待视频加载完成(<span style="color:#e74c3c">未自动播放时</span>)</div>
                            
                            <div style="background: #FF4DAF; color: white; width:24px; height:24px; border-radius:50%; text-align:center; line-height:24px;">3</div>
                            <div>点击左侧<span style="color:#FF4DAF; font-weight:bold">「即刻开刷」</span>按钮</div>
                        </div>
                    </div>

                    <!-- 注意事项 -->
                    <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-bottom:20px;">
                        <div style="border-left: 3px solid #FF4DAF; padding-left:12px;">
                            <div style="color: #e74c3c; font-weight:500; margin-bottom:8px;">⚠️ 重要提醒</div>
                            <ul style="margin:0; padding-left:18px; color:#7f8c8d; font-size:14px;">
                                <li>视频最后剩下5秒需要看完</li>
                                <li>请勿主动点击播放</li>
                                <li>建议刷完全部视频再刷新,观看最后的几秒</li>
                            </ul>
                        </div>

                        <div style="border-left: 3px solid #27ae60; padding-left:12px;">
                            <div style="color: #27ae60; font-weight:500; margin-bottom:8px;">💡 高效技巧</div>
                            <ul style="margin:0; padding-left:18px; color:#7f8c8d; font-size:14px;">
                                <li>先刷一个视频</li>
                                <li>点击另外一个视频</li>
                                <li>再点击回刚刷的视频,播放完最后5s</li>
                            </ul>
                        </div>
                    </div>
                    ${renderQQGroups()}
                    
                </div>
            `,
                confirmButtonText: "已了解,开始减负之旅 →",
                confirmButtonColor: "#FF4DAF",
                showCancelButton: true,
                cancelButtonText: "不在显示此窗口",
                cancelButtonColor: "#95a5a6",
                width: 760,
                customClass: {
                    popup: 'animated pulse',
                    title: 'swal-title-custom'
                },
                footer: '<div style="color:#bdc3c7; font-size:12px;">请合理使用本工具</div>'
            }).then((result) => {
                // console.log(result);
                // console.log(Swal.DismissReason.cancel);
                if (result.dismiss === Swal.DismissReason.cancel) {
                    // 跳转到课程列表页或其他操作
                    localStorage.setItem('noMoreDialog', "ture")
                }
            });
        }
    }
    // 初始化逻辑
    // 初始化逻辑优化
    const init = () => {
        // 创建悬浮按钮
        const floatBtn = createFloatingButton();

        // 添加防DOM清理监听(优化版)
        const observer = new MutationObserver(mutations => {
            if (!document.body.contains(floatBtn)) {
                createFloatingButton();
            }
        });
        observer.observe(document.body, {childList: true});

        // 添加CSS保护
        const style = document.createElement('style');
        style.textContent = `
        #zs-helper-btn {
            pointer-events: auto !important;
            opacity: 1 !important;
            visibility: visible !important;
        }
        #zs-helper-btn:hover {
            transform: translateY(-50%) scale(1.05) !important;
        }
    `;
        document.head.appendChild(style);
    };

    function getVideoTime() {
        return Math.round(document.querySelector('video').duration)
    }

    function getResourceId() {
        // 获取目标元素
        const divElement = document.querySelector('div.vjs-poster');
        if (divElement) {

            const bgImage = divElement.style.backgroundImage;

            const uuidPattern = /assets\/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/;
            const match = bgImage.match(uuidPattern);
            if (match) {
                const resId = match[1];
                console.log(resId);
                return resId
            }
        }
        throw Error("can not get ResourceId!")
    }

    function getDynamicToken() {
        try {
            const pattern = /^ND_UC_AUTH-([0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12})&ncet-xedu&token$/;
            for (let key of Object.keys(localStorage)) {
                if (pattern.test(key)) {
                    return {
                        key: key,
                        appId: key.match(pattern)[1],
                        token: JSON.parse(JSON.parse(localStorage.getItem(key)).value)
                    };
                }
            }
            throw Error("Invalid token! can not get loginInfo!");
        } catch (err) {
            throw Error("At:getDynamicToken>>" + err);
        }
    }


    // const tokenData = getDynamicToken();
    // if (tokenData) {
    //     console.log("完整键名:", tokenData.key);
    //     console.log("用户UUID:", tokenData.uuid);
    //     console.log("Token值:", tokenData.token);
    // }
    // 作者:zzzzzzys
    // https://greasyfork.org/zh-CN/users/1176747-zzzzzzys
    // 搬运可耻
    const getMACAuthorizationHeaders = function (url, method) {
        let n = getDynamicToken().token
        return He(url, method, {
            accessToken: n.access_token,
            macKey: n.mac_key,
            diff: n.diff
        });
    }

    function Ze(e) {
        for (var t = "0123456789ABCDEFGHIJKLMNOPQRTUVWXZYS".split(""), n = "", r = 0; r < e; r++)
            n += t[Math.ceil(35 * Math.random())];
        return n
    }

    function Fe(e) {
        return (new Date).getTime() + parseInt(e, 10) + ":" + Ze(8)
    }

    function ze(e, t, n, r) {
        let o = {
            relative: new URL(e).pathname,
            authority: new URL(e).hostname
        }
        let i = t + "\n" + n.toUpperCase() + "\n" + o.relative + "\n" + o.authority + "\n";
        return CryptoJS.HmacSHA256(i, r).toString(CryptoJS.enc.Base64)
    }

    function He(e) {
        // 作者:zzzzzzys
        // https://greasyfork.org/zh-CN/users/1176747-zzzzzzys
        // 搬运可耻
        let t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "GET"
            , n = arguments.length > 2 ? arguments[2] : void 0
            , r = n.accessToken
            , o = n.macKey
            , i = n.diff
            , s = Fe(i)
            , a = ze(e, s, t, o);
        return 'MAC id="'.concat(r, '",nonce="').concat(s, '",mac="').concat(a, '"')
    }

    const setProgress = function (url, duration) {
        const info = getDynamicToken()
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                'url': url,
                method: 'PUT',
                "headers": {
                    "accept": "application/json, text/plain, */*",
                    "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
                    "authorization": getMACAuthorizationHeaders(url, 'PUT'),
                    "cache-control": "no-cache",
                    "pragma": "no-cache",
                    "content-type": "application/json",
                    "sdp-app-id": info.appId,
                    "sec-ch-ua": "\"Not A(Brand\";v=\"8\", \"Chromium\";v=\"132\", \"Microsoft Edge\";v=\"132\"",
                    "sec-ch-ua-mobile": "?0",
                    "sec-ch-ua-platform": "\"Windows\"",
                    "sec-fetch-dest": "empty",
                    "sec-fetch-mode": "cors",
                    "sec-fetch-site": "cross-site",
                    "host": "x-study-record-api.ykt.eduyun.cn",
                    "origin": "https://basic.smartedu.cn",
                    "referer": "https://basic.smartedu.cn/",
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0"
                },
                data: JSON.stringify({position: duration - 3}),
                // fetch:true,
                onload: function (res) {
                    console.log('请求成功')
                    console.log(res)
                    if (res.status === 200) {
                        console.log("刷课成功!")
                        resolve(res)
                    }else {
                        reject('服务器拒绝:'+res.toString())
                    }
                },
                onerror: function (err) {
                    reject('请求错误!' + err.toString())
                }
            })
        })
    }

    function main () {
        init()
        if (!localStorage.getItem("noMoreDialog")) {
            showGuideDialog()
            // return
        }
        let myStyle = document.createElement('style')
        myStyle.innerHTML = style;
        document.head.appendChild(myStyle);
        /*let intercept=GM_GetValue*/
        let div = document.createElement('div');
        div.innerHTML = `<div style="left: 10px;top: 280px;" id="my1" class="button-3" >即刻开刷(中小学)</div>
                        <div style="position: fixed; left: 10px;top: 320px;;background: #ed5822;color: white;
            padding: 10px 20px;
            border-radius: 25px;
            cursor: pointer;
            box-shadow: 0 3px 15px rgba(0,0,0,0.2);
            z-index: 999999999999;
            transition: transform 0.3s;" id="my3"    >职业教育/高等教育 刷课</div>
            <div style="left: 10px;top: 370px;" id="my2"   class="button-3" >2222</div>`
        document.body.appendChild(div);
        const trigger = document.getElementById('my3')
        trigger.addEventListener('click', () => {
            if (location.href.includes("core.teacher.vocational.smartedu.cn")) {
                createControlPanel()
            } else {
                Swal.fire({
                    title: "注意",
                    text: "请在职业/高等教育的视频播放页面使用,中小学请用上面的按钮!",
                    icon: 'info',
                    // showCancelButton: true,
                    confirmButtonColor: "#FF4DAFFF",
                    // cancelButtonText: "取消,等会刷新",
                    confirmButtonText: "了解~",

                }).then((result) => {

                });

            }
        });
        trigger.addEventListener('mouseenter', () => trigger.style.transform = 'scale(1.05)');
        trigger.addEventListener('mouseleave', () => trigger.style.transform = 'none');
        document.getElementById('my1').addEventListener("click", async () => {
            try {
                await setProgress(requestObj.resourceLearningPositions.url + getResourceId() + '/' + getDynamicToken().token["user_id"], getVideoTime())
                if (Swal) {
                    Swal.fire({
                        title: "刷课成功!",
                        html: `
            <div style="text-align: left;">
                <p>此视频只剩下最后5s,请刷新后再观看!</p>
                <p>建议先刷完目录下视频再刷新!</p>
                <p>请勿播放视频,否则可能会导致进度更新失败!</p>
                <hr style="margin: 10px 0;">
                ${renderQQGroups()}
            </div>
        `,
                        icon: 'success',
                        confirmButtonColor: "#FF4DAFFF",
                        // cancelButtonText: "取消,等会刷新",
                        // 作者:zzzzzzys
                        // https://greasyfork.org/zh-CN/users/1176747-zzzzzzys
                        // 搬运可耻
                        confirmButtonText: "确定",

                    }).then((result) => {
                        if (result.isConfirmed) {
                        }
                    });
                }
            } catch (e) {
                console.error(e)
                if (Swal) {
                    Swal.fire({
                        title: "失败!",
                        text: e.toString() + "    请在视频播放页面使用!",
                        icon: 'error',
                        // showCancelButton: true,
                        confirmButtonColor: "#FF4DAFFF",
                        // cancelButtonText: "取消,等会刷新",
                        confirmButtonText: "点击去反馈",

                    }).then((result) => {
                        if (result.isConfirmed) {
                            window.open("https://greasyfork.org/zh-CN/scripts/525037/feedback")
                        }
                    });
                }
            }
        })
        document.getElementById('my2').addEventListener('click', function () {
            Swal.fire({
                title: '<span style="font-size:24px; color: #FF4DAF;">欢迎加入交流群</span>',
                html: `
        <div style="text-align: left; max-width: 580px; line-height: 1.7; font-size: 14px;">
            <!-- 社群入口 -->
            ${renderQQGroups()}

            <!-- 核心价值 -->
            <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px;">
                <!-- 左列 -->
                <div style="padding-right:15px; border-right:1px dashed #eee;">
                    <div style="color: #27ae60; margin-bottom:15px;">
                        <h4 style="margin:0 0 8px 0; font-size:15px;">📚 减负工具</h4>
<!--                        <ul style="margin:0; padding-left:18px;">-->
<!--                            <li>自动化备课工具套件</li>-->
<!--                            <li>智能学情分析报告</li>-->
<!--                            <li>教学资源智能检索</li>-->
<!--                        </ul>-->
                    </div>

                    <div style="color: #2980b9; margin-top:15px;">
                        <h4 style="margin:0 0 8px 0; font-size:15px;">🛡️ 使用规范</h4>
                        <ul style="margin:0; padding-left:18px;">
                            <li>仅限个人使用</li>
                            <li>禁止商业倒卖行为</li>
                            <li>禁止利用此脚本收费代刷</li>
                            <li>请勿批量自动化操作大量刷课(如需要请联系我,更加高效安全)</li>
                        </ul>
                    </div>
                </div>

                <!-- 右列 -->
                <div style="padding-left:15px;">
                    <div style="color: #e67e22;">
                        <h4 style="margin:0 0 8px 0; font-size:15px;">⚖️ 版权声明</h4>
                        <ul style="margin:0; padding-left:18px;">
                            <li>本工具完全免费</li>
                            <li>源码禁止二次传播</li>
<!--                            <li>保留原创法律权利</li>-->
                        </ul>
                    </div>

                    <div style="color: #9b59b6; margin-top:15px;">
                        <h4 style="margin:0 0 8px 0; font-size:15px;">💌 联系我们</h4>
                        <ul style="margin:0; padding-left:18px;">
<!--                            <li>反馈建议:[email protected]</li>-->
                            <li>紧急问题:请私聊群管理员</li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    `,
                icon: 'info',
                confirmButtonColor: "#FF4DAF",
                confirmButtonText: "2222",
                showCloseButton: true,
                width: 680,
                showDenyButton: true,
                denyButtonText: '<img src="https://img.icons8.com/fluency/24/star--v1.png" style="height:18px; vertical-align:middle;"> 前往好评', // 带图标的按钮
                denyButtonColor: '#FFC107',
                focusDeny: false,
                showCancelButton: false,

                // 新增按钮回调
                preDeny: () => {
                    window.open("https://greasyfork.org/zh-CN/scripts/525037/feedback", "_blank");
                    return false; // 阻止弹窗关闭
                },

                customClass: {
                    denyButton: 'swal-custom-deny',
                    popup: 'swal-custom-popup',
                    title: 'swal-custom-title'
                },
                footer: '<div style="color:#95a5a6; font-size:12px;">请合理使用。</div>'
            });
        });
    }
    main()
})();