Greasy Fork

2024华医公需课:百县千镇万村;选修课:前三

2024年公需课:<<“百县千镇万村高质量发展工程”与城乡区域协调发展>> 自动听课和自动考试脚本. 华医的其它课程可以自动听课,但没有自动考试. 新增选修前三个课程:《高质量发展医院感染管理体系》,《全科医生互联网健康管理及诊疗能力提升》,《做好医患沟通,科学防范医疗纠纷》。支持医师定期考核。

// ==UserScript==
// @name         2024华医公需课:百县千镇万村;选修课:前三
// @namespace    http://tampermonkey.net/
// @version      1.9
// @description  2024年公需课:<<“百县千镇万村高质量发展工程”与城乡区域协调发展>> 自动听课和自动考试脚本. 华医的其它课程可以自动听课,但没有自动考试. 新增选修前三个课程:《高质量发展医院感染管理体系》,《全科医生互联网健康管理及诊疗能力提升》,《做好医患沟通,科学防范医疗纠纷》。支持医师定期考核。
// @author       han2ee
// @include        http://cme*.91huayi.com/*
// @include        https://cme*.91huayi.com/*
// @include        https://dk.91huayi.com/*
// @run-at        document-start
// @grant   GM_xmlhttpRequest
// @grant   GM.setValue
// @grant   GM.getValue
// @grant unsafeWindow
// @license MIT
// ==/UserScript==


(function() {
    'use strict';
    const DK_HOST = "dk.91huayi.com";
    var courseInterID = 0;
    let first = true;
    // save the alert
    var _alert =window.alert;
    // ignore the alert
    function overrideSelectNativeJS_Functions () {
        window.alert = function alert (message) {
            console.log (message);
            return true;
        }
    }
    (function (funcToRun) {
        var D = document;
        var scriptNode = D.createElement ('script');
        scriptNode.type = "text/javascript";
        scriptNode.textContent = '(' + funcToRun.toString() + ')()';
        var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
        targ.appendChild (scriptNode);
    })(overrideSelectNativeJS_Functions);
    const requestAsync = function(url, data) {
        // console.log(data);
        return new Promise((resolve, reject) => {
            var reportAJAX_Error = (rspObj) => {
                console.error (`Request error: ${data}`);
                reject(`Request => Error ${data}  RES ${rspObj.status}!  ${rspObj.statusText}`);
            }

            var processJSON_Response = (rspObj) => {
                if (rspObj.status != 200 && rspObj.status != 304) {
                    reportAJAX_Error (rspObj);
                } else {
                    resolve(rspObj.responseText);
                }
            };
            GM_xmlhttpRequest ( {
                method:         "GET",
                url:            url,
                timeout: 6000,
                headers: {
                    "Referer": document.location.href,
                    "Content-Type": "application/x-www-form-urlencoded"
                },
                //data:           data,
                responseType:   "text/html",
                onload:         processJSON_Response,
                onabort:        reportAJAX_Error,
                onerror:        reportAJAX_Error,
                ontimeout:      reportAJAX_Error
            });
        });
    }

    const getUrlParameter = function getUrlParameter(sParam) {
        var sPageURL = window.location.search.substring(1),
            sURLVariables = sPageURL.split('&'),
            sParameterName,
            i;

        for (i = 0; i < sURLVariables.length; i++) {
            sParameterName = sURLVariables[i].split('=');

            if (sParameterName[0] === sParam) {
                return typeof sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
            }
        }
        return false;
    };

    const findFirstLesson = function(studyImgArr) {
        if (studyImgArr) {
            for (let i = 0; i < studyImgArr.length; i++) {
                if (studyImgArr[i].src.endsWith("anniu_01a.gif")) {
                    return i;
                }
            }
        }
        return -1;
    }
    const nextLesson = async function(cwid) {
        let cid = await GM.getValue('cid');
        console.log("CID", cid);
        let hrefs = await GM.getValue(cid);
        for (let i = 0; i < hrefs.length - 1; i++) {
            if (hrefs[i].indexOf(cwid) != -1) {
                window.location.href = hrefs[i + 1];
            }
        }
    }

    const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

    function isPromise(obj) {
        return !!obj && ((typeof obj === 'object' && typeof obj.then === 'function') || (typeof obj === 'function' && typeof obj().then === 'function'));
    }
    /**
     * Wait Resource.
     *
     * @param {Function} resourceFn pred function to check resource
     * @param {Object} options
     * @returns Promise
     */
    function waitResource(resourceFn, options) {
        var optionsRes = Object.assign(
            {
                interval: 3000,
                max: 10
            },
            options
        );
        var current = 0;
        return new Promise((resolve, reject) => {
            var timer = setInterval(() => {
                if (isPromise(resourceFn)) {
                    resourceFn().then(res => {
                        if(res) {
                            clearInterval(timer);
                            resolve();
                        }
                    });
                } else if (resourceFn()) {
                    clearInterval(timer);
                    resolve();
                }
                current++;
                if (current >= optionsRes.max) {
                    clearInterval(timer);
                    reject('Time out');
                }
            }, optionsRes.interval);
            });
    }

    const ANSWER_DICT = {
        // 2024年公需课:“百县千镇万村高质量发展工程”与城乡区域协调发展
        '3b1a3ece-f378-4d36-9986-b16b00e6fdb6': ['f165a244-4e02-48d0-a215-b169012b5f80', '574d2df2-f95a-460f-98ba-b169012b5f80', '815bd9c0-8e80-41f5-a062-b169012b5f80', '69e04f4d-24ef-4686-a5ba-b169012b5f80'],
        'a1b5247f-9886-49ad-8eff-b16b00e49da8': ['26859b07-a91f-469f-b841-b16a0119cbb5'],
        'bc7f1f2e-eca9-41f1-bf88-b16b00e49da8': ['c8cfe096-53e1-42cd-b9ed-b16a0119e47a'],
        '9168cbab-b03b-41ca-a9b2-b16b00e49da8': ['cae6c76d-6206-46ee-b857-b16a011a3254'],
        '2795f469-be56-4e2e-b5e2-b16b00e49da8': ['ad3b9e5f-fcf8-44fc-8112-b16a011a4683'],
        '1a9123af-7d1b-4f4e-9395-b16b00e4abab': ['42b39277-208a-43ef-9da2-b16a011a59fa'],
        '452d1c6c-76e5-44bd-9a09-b16b00e4abab': ['23b0cc7b-7b29-4522-9c92-b16a011a72e6'],
        'f670baa2-d165-4317-b2ca-b16b00e4bae0': ['fb0474ce-b639-4a49-8630-b16c0118bb73', 'f8727505-1669-427a-87f7-b16c0118bb73'],
        '0dda685a-7324-4e8a-857b-b16b00e4abab': ['09615a55-cee7-4b52-a82c-b16a011a898c'],
        'ae56f8d0-e7c5-448a-9f07-b16b00e4abab': ['0813346a-6607-49df-8859-b16a011a9f45'],
        '657c8efa-3291-4196-ba3a-b16b00e4bae0': ['b5adb467-f33f-4b40-9ea3-b16c0119cc37', 'ebdfa592-60f7-4b77-bfdb-b16c0119cc37', '2fe3d4f8-24f3-4597-b0c1-b16c0119cc37'],
        'c23686db-ac34-40b9-95ff-b16b00e4bae0': ['36eb21d1-3e56-4936-98c6-b16a011aeb1d'],
        '02e1acd3-3c5b-4df0-b0da-b16b00e4cb16': ['6dbe03dc-ec31-4ac2-88b9-b16c011bcb8f', '4ed22733-6c5f-4052-a483-b16c011bcb8f', '506df3cc-7c06-4e85-8682-b16c011bcb8f'],
        'b7c39b62-d760-4ce5-a8f1-b16b00e4cb16': ['c7f98c36-648a-4790-ad44-b16c011cf4f9', '2e0c15a1-22f8-4140-a101-b16c011cf4f9'],
        'cbf51a55-2cba-4b93-9904-b16b00e4cb16': ['11071ff2-0703-495e-8739-b16a011b2341'],
        'd5023032-7465-4a2a-a834-b16b00e4cb16': ['052be890-a475-46e8-ac65-b16a011b350f'],
        'ab93eb00-8443-4aa9-ab85-b16b00e4d941': ['2a5cedb5-2ce7-4417-a8a5-b16a011b465b'],
        '97a529c3-1ccc-4932-bac9-b16b00e4d941': ['09124584-dd71-4f0e-8ec3-b16a011b5783'],
        'bf64f8fa-3afc-42b1-a274-b16b00e4d941': ['0257004c-b25e-46a1-9ea6-b16a011b67a1'],
        '20b79b3e-bc11-410b-b79e-b16b00e4d941': ['a8be41c3-64af-418f-a5bf-b16a011b783f'],
        '84c2348b-33bd-4e4b-89ae-b16b00e4e547': ['f9304af9-7501-4c18-906e-b16a011b8933'],
        'c08172d3-1b93-4688-a975-b16b00e4e547': ['f0a167e0-dcda-42cf-b7cf-b16a011b9c24'],
        'e2ce2f9f-dde3-46c3-9204-b16b00e4e547': ['853da226-df48-469a-83f0-b16a011bad8a'],
        '0bbacf92-eb4c-41db-85f7-b16b00e4f682': ['761f1d80-98b3-4217-911e-b16c01255691', '276fa66c-ae48-4c20-ba10-b17000b5976d', '7becb0e1-3e40-4c8e-a77e-b16c01255691', 'e38c7cc9-32d7-43c6-bbd1-b16c01255691', '6d9a3c50-c7c2-405d-8ed5-b16c01255691'],
        'f5069d7a-7e44-42ea-b94e-b16b00e4f682': ['516d8f88-02c8-4ef9-a5e7-b16a011c4eee'],
        '90419ef2-0d8e-4804-8ffd-b16b00e4f682': ['61b3d86e-0daf-4800-addc-b16a011c3e31'],
        '531953c7-7e3f-4a55-ba30-b16b00e4f682': ['df71b2c5-7f08-486e-b501-b16a011c2a13'],
        'c3107439-f923-47fc-9146-b16b00e50852': ['ddc8a5ea-0061-4d39-81da-b19600ad8898', '0fab0c07-152f-47d7-aeae-b16c0126dd3f'],
        'cc37530d-def0-4bb3-aed6-b16b00e50852': ['fa19f1c9-b885-45f0-a977-b16c012750ea', '1fe2df38-334d-4642-b9e1-b16c0127986d'],
        'b3606225-bc35-4eea-8d61-b16b00e50852': ['2ef3169c-2416-4a69-b05a-b16a011be852'],
        '811693e1-6160-4682-aecb-b16b00e50852': ['8330099f-a2fa-44ea-bbb9-b16c0128873d', '91153778-00f9-4857-9f33-b16c01281e61'],

        // 2024 选修: 做好医患沟通,科学防范医疗纠纷
        '89757d91-ca0b-4ec0-9fd5-ed5260cb9528': ['6242964d-872a-4e67-8f26-a9bb00e061b7', '24f3466b-db5a-4400-85b0-a9bb00deb5dc', '5942ea98-7f6f-4530-b4c9-a9bb00deb5dc', 'c6df9306-1cd7-4735-ad20-b0ec00d73b5c', 'e73c9c40-4387-45ae-8bad-a9bb00deb5dc'],
        '11601d22-31e0-4303-b740-8d6422279c39': ['ab1c60ee-a6fb-40b2-b25d-a9bb00e120b8', '44a3e7f6-64d4-44f6-904f-a9bb00e120b8', 'c69c77c8-b9f7-416c-bf02-b0ec00d7b406', 'b2c4cded-7c82-45d2-b08b-a9bb00e120b8', '043d2c1d-d0de-4dfe-bdb5-a9bb00e120b8'],
        '0c3042cf-0886-4158-84c9-b0ab010af9a7': ['0b4a87cd-1e6d-4a34-8ddc-aecb00e0edbf', '6a295606-34b6-4894-951a-aecb00e0edbf', '01705f20-07e0-4738-a0d6-b1db010c1aff', '81196448-1023-48e7-9990-aecb00e0edbf', '7e470ed3-2c82-49f8-8166-aecb00e0edbf'],
        'd3c92dc3-2c9a-46c8-ab88-b0ab010ad3e3': ['7b49232c-9480-4f47-940d-aecb00e3f472', '4c510513-6ab8-472e-a2a3-aecb00e3f472', '9d1406ba-43dd-43cc-9102-b1db010ffd46', '8eda4f56-18e1-422d-b6d6-aecb00e3f472', 'e24e4d59-f3ef-47b0-9dd2-aecb00e3f472'],
        '3939e515-54e2-474c-9b02-fcc3b00b603d': ['14eb4925-19bb-477d-9f4c-abd40113194e', 'f4550b89-1a6e-4862-98de-abd40113194e', '0d86be91-c6a1-4a4c-8809-abd40113194e', 'f62a8443-8409-4df6-ba9e-abd40113194e', 'fae911e0-9c09-4901-8bba-abd40113194e'],
        '3fe17c2c-5425-471a-8b28-d5fd0a2704e3': ['5fb8e353-e4ea-4f1d-b14e-abd401166433', '6c99f2f9-de73-4504-a8dd-abd401166433', '2f742316-4d0e-4484-b300-abd401166433', '7f6cc528-4878-4ecb-bf55-abd401166433', '68fa5b6d-cd5b-4b63-9407-abd401166433'],

        // 2024 选修: 全科医生互联网健康管理及诊疗能力提升
        'd2014343-2094-4c38-9199-af34009fd753': ['44e6c25f-2f6e-46dc-b721-af1f009f2c26', '5a474d91-81ab-4134-856b-af1f009f2c26', '26422ecd-3aab-4bd2-bbe8-af1f009f2c26', '3e3dd8ad-9ef3-4d3f-ae8e-af1f009f2c26', 'bd537d58-91f6-4607-97f4-af1f009f2c26'],
        '3d6938b4-d24f-48cf-b1ad-af3400a074e3': ['c9a56f54-36b9-45c5-b179-af330120181f', '0574e223-e34e-4c6f-bb66-af330120181f', '09b44adf-ed31-4f69-bae1-af330120181f', '6e39c76f-0a32-4289-ad39-af330120181f', '027933b3-bd87-4793-a8d0-af330120181f'],
        '52d2ad4b-8dcb-41fd-a24b-af3400a08662': ['88bb3c8b-7428-44d8-870e-af290100603d', 'eedefd38-03d5-4280-bf30-af290100603d', 'b975748f-3a84-418f-9934-af290100603d' ,'f577602c-183c-4ec7-a19c-af290100603d', '3eefa70f-9c21-4120-82e4-af290100603d'],
        '0d2cfd99-4b3e-41d6-b2fc-af3400a097ab': ['8a2089fe-b8f4-4bc8-9b17-af33011ea874', 'da64816e-36be-4727-baf7-af33011ea874', 'e02eff51-2e10-465c-811f-af33011ea874', '782a6b1c-7a99-486c-a424-af33011ea874', '66918c6d-81c8-4e6e-8434-af33011ea874'],
        'fca2bf60-d69f-43e0-bc42-af3400a0bf54': ['028956a2-6b0f-49d0-b23d-af2a00a1610e', 'da808ce4-4622-4667-a7cb-af2a00a1610e', 'e7dd8501-c51f-419f-b344-af2a00a1610e', 'c7c90bd0-ad9c-4975-ac5e-af2a00a1610e', '11a40990-2385-401e-89cc-af2a00a1610e'],
        '00cde1d5-70cd-4d43-9d0d-af3400a0a995': ['bec79d54-8c24-439e-8fd2-af2e00b38820', '91396139-334b-494e-ac35-af2e00b38820', 'ce127b93-5349-47c5-9b37-af2e00b38820', '6747cd8b-23fe-40fc-8e6e-af2e00b38820', '7303b5fc-dad6-46aa-abe4-af2e00b38820'],

        // 2024 选修: 高质量发展医院感染管理体系
        '51c7d4f0-a104-44a6-a379-ae4c01095490': ['5172a41e-2dec-4cb0-80e7-ae4c00f02800', '23e2c352-cdae-47f3-82ef-ae4c00f02800', '06cf20e2-a95a-47aa-9fb3-ae4c00f02800', '0adbca83-4984-4b37-8810-ae4c00f02800', '81dbb819-e886-45b7-bf90-ae4c00f02800'],
        '6818d63f-d0e8-4ad8-9bd7-ae4c01095490': ['c64fbf44-ef6f-4a95-8923-ae4c00f10497', '39b500b6-373b-45be-911a-ae4c00f10497', '7426aae0-223c-4807-af1c-ae4c00f10497', '36af1960-fc2f-4318-95e4-ae4c00f10497', '7530a1d4-2d68-4b2b-a19e-ae4c00f10497'],
        '8317a5c7-1253-4251-a891-ae4c01095490': ['71663320-1afc-4f67-ad1c-ae4c00f1adab', '0fa5611a-e227-4e7e-b1dd-ae4c00f1adab', '9ff29367-0079-4c05-90be-aeca0102e09f', '41a67d92-1af0-4abd-9abf-ae4c00f1adab', '6075d4b3-a194-4209-b782-ae4c00f1adab'],
        '198d2e70-da27-468d-b3d9-ae4c011672be': ['a0300b43-97c6-467b-9d8b-ae4c00f89705', 'be95521f-f4e8-40dd-841c-ae4c00f89705', '3f1116b5-e6a5-4b5b-aea1-ae4c00f89705', 'b1e1bfdd-2d64-4b7f-bdaf-ae4c00f89705', '9415d9e7-5f19-40ad-83a7-ae4c00f89705'],
        '9e51104e-5a5d-445e-b2db-ae4c0112285d': ['a463d333-11a9-4cc8-a246-ae4c00f8e642', '597ddb5d-ea60-4f2b-a1f6-ae4c00f8e642', 'a811b75e-2b90-4035-94da-ae4c00f8e642', 'acaaff02-9fc4-4f82-a58a-ae4c00f8e642', 'cc959ca7-d76f-4e6d-8846-ae4c00f8e642'],
        '28b744ac-3220-467e-8735-aeb700e73fc6': ['4ff8b781-984c-4ba4-bdb6-ae7c00a173cf', '96267a5d-5d75-4c62-aa16-b04c00a6a95a', '1f2a2973-d859-4194-8920-ae7c00a173cf', '4ff2fa71-c59a-4999-9ca3-ae7c00a173cf', '58c5172c-8cef-4d14-b56e-ae7c00a173cf'],
    };

    // intercept alert window
    if (getUrlParameter('cwid') || getUrlParameter('cid')) {
        let alrtScope;
        if (typeof unsafeWindow === "undefined") {
            alrtScope = window;
        } else {
            alrtScope = unsafeWindow;
        }
        alrtScope.alert = function (str) {
            console.log ("Greasemonkey intercepted alert: ", str);
        };
    }
    if (window.top !== window.self) {
        return;
    }
    // 单个课程页面
    if (window.location.host !== DK_HOST && window.location.pathname == '/course_ware/course_ware_polyv.aspx') {
        console.log("单个课程页面");
        /*
        // 修改播放器init参数 倍速:'speed': true  可拖动'ban_seek': false
        let scriptIndex = 0;
        new MutationObserver(function(mutations) {
            // check at least two H1 exist using the extremely fast getElementsByTagName
            // which is faster than enumerating all the added nodes in mutations
            let scriptList = document.getElementsByTagName('script');
            if (scriptList.length > 10) {
                this.disconnect(); // disconnect the observer
            }
            for (; scriptIndex < scriptList.length; scriptIndex++) {
                let scriptEle = scriptList[scriptIndex];
                if (scriptEle.innerHTML && scriptEle.innerHTML.indexOf("'speed': false")) {
                    scriptEle.innerHTML = scriptEle.innerHTML.replace("'speed': false", "'speed': true").replace("'ban_seek': banSeek", "'ban_seek': false");
                    console.log("REPLACE");
                    this.disconnect();
                    break;
                }
            }
        }).observe(document, {childList: true, subtree: true});
        */
        // 拦截first,不让加载视频中间的问题
        let inter = setInterval(function() {
            try {
                if (first && typeof player !== "undefined") {
                    first = false;
                    console.log("FIRST:", first);
                    player.sendQuestion = function(data) {};
                    clearInterval(inter);
                }
            } catch (err) {
                console.log(err);
            }
        }, 10);
        let initRateFlag = true;
        let lastTime = 0;
        courseInterID = setInterval(async function() {
            if (first) { // mare sure the player.sendQuestion is empty function
                console.log("sendQuestion should be empty function");
                return;
            }

            if (typeof closeProcessbarTip === "function") { // close the warning
                closeProcessbarTip();
            }
            if (!$("#jrks")[0].getAttribute('disabled')) { // finish lesson
                let cwid = getUrlParameter('cwid');
                if (ANSWER_DICT[cwid]) {
                    try {
                        let examHref = $("#jrks")[0].href;
                        if (examHref && examHref.indexOf("exam.aspx") != -1) {
                            let content = await requestAsync(examHref, {});
                            if (content.indexOf("请进行课件观看学习完成后再进行考试") != -1) {
                                window.location.reload(); // 重听
                                clearInterval(courseInterID);
                            } else {
                                window.location = $("#jrks")[0].href; // 跳到考试
                                clearInterval(courseInterID);
                            }
                        }
                    } catch (err) {
                        console.error(err);
                    }
                } else { // jump to next
                    await nextLesson(cwid);
                    clearInterval(courseInterID);
                }
            }
            await GM.setValue("curCWID", getUrlParameter('cwid'));

            // Resume video
            let curTime = player.j2s_getCurrentTime();
            if (curTime === lastTime && curTime < player.j2s_getDuration()) {
                console.log(curTime, "try to resume");
                // resume
                player.j2s_setVolume(0); // avoid the "user didn't interact with doc" error
                player.j2s_resumeVideo();
                console.log("resume successfully");
            }
            lastTime = curTime;

            if (initRateFlag) {
                let rate = await GM.getValue('rate', 1);
                if (player) {
                    player.changeRate(rate);
                    initRateFlag = false;
                }
            } else {
                await GM.setValue('rate', player.currentRate);
            }
        }, 3000);
    }

    if (window.location.pathname == '/pages/noplay.aspx') {
        setTimeout(async function() {
            let cwid = await GM.getValue("curCWID");
            window.location.href = "/course_ware/course_ware.aspx?cwid=" + cwid;
            // document.querySelector(".yes").click();
        }, 5000);
    }
    // 考试页面
    if (window.location.pathname == '/pages/exam.aspx') {
        setTimeout(async function() {
            await waitResource(() => !!document.querySelector("#btn_submit"));
            let cwid = getUrlParameter('cwid');
            console.log("CWID:", cwid);
            let answer = ANSWER_DICT[cwid];
            if (answer) {
                for (let item of answer) {
                    if (item.startsWith('gvQuestion')){
                        $('#' + item).click();
                    } else {
                        $(`[value=${item}]`).click();
                    }
                    await wait(200);
                }
                $('#btn_submit').click();
            }
        }, 3000);
    }

    // 考试结果页面
    if (window.location.pathname == '/pages/exam_result.aspx') {
        setTimeout(async function() {
            let cwid = getUrlParameter('cwid');
            await nextLesson(cwid);
        }, 3000);
    }
    // 目录页面
    if (window.location.pathname == '/pages/course.aspx') {
        console.log("目录面");
        let interId = setInterval(async function() {
            let hrefs = document.querySelectorAll(".course h3 a");
            let vals = [];
            for (let i = 0; i < hrefs.length; i++) {
                // if (hrefs[i].children[0].src.endsWith("anniu_01a.gif")) {
                vals.push(hrefs[i].href);
                // }
            }
            // console.log(vals);
            let cid = getUrlParameter('cid')
            await GM.setValue(cid, vals);
            await GM.setValue('cid', cid);
            console.log("Course list have been set.");
            clearInterval(interId);
        }, 3000);
    }

    // 医师定期考核目录页面
    if (window.location.pathname == '/course_ware/course_ware_list.aspx') {
        console.log("目录面");
        let interId = setInterval(async function() {
            // find the first course to learn
            let eles = document.querySelectorAll(".xx"); //.nextElementSibling.click()
            if (eles.length === 0) {
                eles = document.querySelectorAll(".wx");
            }
            if (eles.length > 0) {
                eles[0].nextElementSibling.click();
                clearInterval(interId);
            }
        }, 3000);
    }

    // 医师定期考核单个课程页面
    if (window.location.host === DK_HOST && window.location.pathname == '/course_ware/course_ware_polyv.aspx') {
        console.log("单个课程页面");
        // 拦截first,不让加载视频中间的问题
        let inter = setInterval(function() {
            try {
                if (first && typeof player !== "undefined") {
                    first = false;
                    console.log("FIRST:", first);
                    player.sendQuestion = function(data) {};
                    clearInterval(inter);
                }
            } catch (err) {
                console.log(err);
            }
        }, 10);
        let initRateFlag = true;
        let lastTime = 0;
        courseInterID = setInterval(async function() {
            if (first) { // mare sure the player.sendQuestion is empty function
                console.log("sendQuestion should be empty function");
                return;
            }

            if (typeof closeProcessbarTip === "function") { // close the warning
                closeProcessbarTip();
            }

            // Resume video
            let curTime = player.j2s_getCurrentTime();
            if (curTime === lastTime && curTime < player.j2s_getDuration()) {
                console.log(curTime, "try to resume");
                // resume
                player.j2s_setVolume(0); // avoid the "user didn't interact with doc" error
                player.j2s_resumeVideo();
                console.log("resume successfully");
            }
            lastTime = curTime;

            if (initRateFlag) {
                let rate = await GM.getValue('rate', 1);
                if (player) {
                    player.changeRate(rate);
                    initRateFlag = false;
                }
            } else {
                await GM.setValue('rate', player.currentRate);
            }
        }, 3000);
    }
})();