Greasy Fork

来自缓存

Greasy Fork is available in English.

Youdao Fanyi's Friend

有道翻译免费导出

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Youdao Fanyi's Friend
// @namespace    http://tampermonkey.net/
// @version      2.2.1
// @description  有道翻译免费导出
// @author       Zzn
// @match        *://c.youdao.com/dict_document_web/#/*
// @match        *://c.youdao.com/dict_document_web/*
// @match        *://c.youdao.com/*
// @match        *://pdf.youdao.com/docview.html/*
// @match        *://pdf.youdao.com/docview.html?key=*
// @icon         http://shared.ydstatic.com/images/favicon.ico
// @grant        none
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/jspdf.umd.min.js
// @require https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js
// @require https://unpkg.com/pdf-lib/dist/pdf-lib.min.js
// ==/UserScript==

(function() {
    'use strict';

    //public SakiProgress
    var SakiProgress = {
        isLoaded: false,
        progres: false,
        pgDiv: false,
        textSpan: false,
        first: false,
        alertMode: false,
        init: function (color) {
            if (!this.isLoaded) {
                this.isLoaded = true;
                console.info("SakiProgress Initializing!\nVersion:1.0.3\nQinlili Tech:Github@qinlili23333");
                this.pgDiv = document.createElement("div");
                this.pgDiv.id = "pgdiv";
                this.pgDiv.style = "z-index:9999;position:fixed;background-color:white;min-height:32px;width:auto;height:32px;left:0px;right:0px;top:0px;box-shadow:0px 2px 2px 1px rgba(0, 0, 0, 0.5);transition:opacity 0.5s;display:none;";
                this.pgDiv.style.opacity = 0;
                this.first = document.body.firstElementChild;
                document.body.insertBefore(this.pgDiv, this.first);
                this.first.style.transition = "margin-top 0.5s"
                this.progress = document.createElement("div");
                this.progress.id = "dlprogress"
                this.progress.style = "position: absolute;top: 0;bottom: 0;left: 0;background-color: #F17C67;z-index: -1;width:0%;transition: width 0.25s ease-in-out,opacity 0.25s,background-color 1s;"
                if (color) {
                    this.setColor(color);
                }
                this.pgDiv.appendChild(this.progress);
                this.textSpan = document.createElement("span");
                this.textSpan.style = "padding-left:4px;font-size:24px;";
                this.textSpan.style.display = "inline-block"
                this.pgDiv.appendChild(this.textSpan);
                var css = ".barBtn:hover{ background-color: #cccccc }.barBtn:active{ background-color: #999999 }";
                var style = document.createElement('style');
                if (style.styleSheet) {
                    style.styleSheet.cssText = css;
                } else {
                    style.appendChild(document.createTextNode(css));
                }
                document.getElementsByTagName('head')[0].appendChild(style);
                console.info("SakiProgress Initialized!");
            } else {
                console.error("Multi Instance Error-SakiProgress Already Loaded!");
            }
        },
        destroy: function () {
            if (this.pgDiv) {
                document.body.removeChild(this.pgDiv);
                this.isLoaded = false;
                this.progres = false;
                this.pgDiv = false;
                this.textSpan = false;
                this.first = false;
                console.info("SakiProgress Destroyed!You Can Reload Later!");
            }
        },
        setPercent: function (percent) {
            if (this.progress) {
                this.progress.style.width = percent + "%";
            } else {
                console.error("Not Initialized Error-Please Call `init` First!");
            }
        },
        clearProgress: function () {
            if (this.progress) {
                this.progress.style.opacity = 0;
                setTimeout(function () { SakiProgress.progress.style.width = "0%"; }, 500);
                setTimeout(function () { SakiProgress.progress.style.opacity = 1; }, 750);
            } else {
                console.error("Not Initialized Error-Please Call `init` First!")
            }
        },
        hideDiv: function () {
            if (this.pgDiv) {
                if (this.alertMode) {
                    setTimeout(function () {
                        SakiProgress.pgDiv.style.opacity = 0;
                        SakiProgress.first.style.marginTop = "";
                        setTimeout(function () {
                            SakiProgress.pgDiv.style.display = "none";
                        }, 500);
                    }, 3000);
                } else {
                    this.pgDiv.style.opacity = 0;
                    this.first.style.marginTop = "";
                    setTimeout(function () {
                        SakiProgress.pgDiv.style.display = "none";
                    }, 500);
                }
            }
            else {
                console.error("Not Initialized Error-Please Call `init` First!");
            }
        },
        showDiv: function () {
            if (this.pgDiv) {
                this.pgDiv.style.display = "";
                setTimeout(function () { SakiProgress.pgDiv.style.opacity = 1; }, 10);
                this.first.style.marginTop = (this.pgDiv.clientHeight + 8) + "px";
            }
            else {
                console.error("Not Initialized Error-Please Call `init` First!");
            }
        },
        setText: function (text) {
            if (this.textSpan) {
                if (this.alertMode) {
                    setTimeout(function () {
                        if (!SakiProgress.alertMode) {
                            SakiProgress.textSpan.innerText = text;
                        }
                    }, 3000);
                } else {
                    this.textSpan.innerText = text;
                }
            }
            else {
                console.error("Not Initialized Error-Please Call `init` First!");
            }
        },
        setTextAlert: function (text) {
            if (this.textSpan) {
                this.textSpan.innerText = text;
                this.alertMode = true;
                setTimeout(function () { this.alertMode = false; }, 3000);
            }
            else {
                console.error("Not Initialized Error-Please Call `init` First!");
            }
        },
        setColor: function (color) {
            if (this.progress) {
                this.progress.style.backgroundColor = color;
            }
            else {
                console.error("Not Initialized Error-Please Call `init` First!");
            }
        },
        addBtn: function (img) {
            if (this.pgDiv) {
                var btn = document.createElement("img");
                btn.style = "display: inline-block;right:0px;float:right;height:32px;width:32px;transition:background-color 0.2s;"
                btn.className = "barBtn"
                btn.src = img;
                this.pgDiv.appendChild(btn);
                return btn;
            }
            else {
                console.error("Not Initialized Error-Please Call `init` First!");
            }
        },
        removeBtn: function (btn) {
            if (this.pgDiv) {
                if (btn) {
                    this.pgDiv.removeChild(btn);
                }
            }
            else {
                console.error("Not Initialized Error-Please Call `init` First!");
            }
        }
    }


    // Your code here...
    SakiProgress.init();
    console.log("Initializing ZnDownloader...");
    var jsPDF = null;
    try{
        jsPDF=jspdf.jsPDF;
        console.log("jsPDF Ready!")
    }catch{
        console.error("jsPDF Not Ready!")
    }

    //init param
    var pageTotal = 0;
    var PDFfile=false;
    var currentTime = 0;
    var imgList=[];
    var imgDataList=[];
    var imgEle=document.createElement("img");
    document.body.appendChild(imgEle);


    //多线程快速下载
    function downloadPicList(list) {
        var donePage = 0;
        for(var j=0;j<list.length;j++){
            toDataURL(list[j],j,function(data,page){
                imgDataList[page]=data;
                donePage++
                SakiProgress.setPercent(donePage/pageTotal*90)
                SakiProgress.setText("已下载"+donePage+"页...")
                if(donePage==pageTotal){
                    SakiProgress.setText("准备生成PDF...")
                    makePDF();
                }
            })
        }

        //读取图片并转base64
        function toDataURL(url,page, callback) {
            var xhr = new XMLHttpRequest();
            xhr.onload = function() {
                var reader = new FileReader();
                reader.onloadend = function() {
                    callback(reader.result,page);
                }
                reader.readAsDataURL(xhr.response);//to base64
                //console.log(j + "---" + xhr.response)
            };
            xhr.open('GET', url);
            xhr.responseType = 'blob';
            xhr.setRequestHeader('Access-Control-Allow-Origin','*');
            xhr.setRequestHeader('Access-Control-Allow-Methods','OPTIONS, GET, POST');
            xhr.setRequestHeader('Access-Control-Allow-Headers','x-requested-with');
            xhr.setRequestHeader('Access-Control-Max-Age','86400');

            xhr.setRequestHeader('Access-Control-Allow-Credentials','true');
            xhr.withCredentials = true;
            xhr.send();
        }

    }


    //制作PDF
    function makePDF(){
        console.log('make pdf...')
        //console.log(imgDataList)

        for(var k=0;imgDataList[k];k++){
            //imgEle.src=imgDataList[k];
            PDFfile.addImage(imgDataList[k],"JPEG",0,0,imgEle.naturalWidth,imgEle.naturalHeight,"Page"+(k+1),"SLOW")
            PDFfile.addPage();
            SakiProgress.setText("已生成"+k+"页...")
        }
        PDFfile.deletePage(imgDataList.length + 1);//delete the end blank page
        SakiProgress.setText("正在制作PDF...")
        PDFfile.save(getPdfName(),{returnPromise:true}).then(finish => {
            SakiProgress.clearProgress;
            SakiProgress.hideDiv();
        });
    }

    //批量下载
    function batchDownload() {
        SakiProgress.showDiv()
        SakiProgress.setText("正在读取页面信息...")
        console.log("Initializing image list...")

        //  https://doctrans-service.youdao.com/trandoc/doc/getFullOriginModeImg?docKey=64EBF13E1D134669B72DF4C694089EF5&pageName=tran-0.jpeg&src=new-fanyiweb&isCheckTermUpdate=false&isUseTerm=false

        $("#docTranslationImg").children().each(function(i,el){
            imgList[i]=$(this).children("img").attr("data-src")
        });
        //get docKey
        var docKey = getDocKey(imgList[0]);
        //calculate total page
        getTotalPage(docKey);
        for(var i=0;i<pageTotal;i++){
            imgList[i]=getImgUrl(docKey,i);
        }

        SakiProgress.setText("正在读取参数并建立PDF...")
        imgEle.onload=function(){
            var ori
            if(imgEle.naturalWidth>imgEle.naturalHeight){ori="l"}else{ori="p"}
            PDFfile=new jsPDF({
                orientation: ori,
                unit: 'px',
                format: [imgEle.naturalWidth,imgEle.naturalHeight],
                putOnlyUsedFonts:true,
            });
            SakiProgress.setText("正在准备下载页面...")
            downloadPicList(imgList,imgDataList)
        }
        imgEle.src=imgList[0]
    }

    //获取文件名
    function getPdfName(){
        // return $(".original-doc-name").first().html() + ".pdf";
        return "(" + $('#filenameInput').html() + ").pdf";
        // return "(" + $('.docName-text').children().html() + ").pdf";
    }

    function getTotalPage(docKey){
        var viewPage = 1;
        var isEnd = false;
        pageTotal = 0;
        var s = genSign(docKey);
        getTotalPage0()
        SakiProgress.setText("加载完成,共"+pageTotal+"页,等待下载...")
        function getTotalPage0(){
            var url = "https://doctrans-service.youdao.com/trandoc/doc/viewFullOriginModeJSON?docKey=" + docKey + "&viewPage=" + viewPage + "&src=new-fanyiweb";

            //调用url之前先调用其他两个url,
            SakiProgress.setText('viewPage: ' + viewPage + ' 正在加载')
            console.log('viewPage: ' + viewPage + ' 正在加载')
            var isGoOn = getFullOrign(docKey,s.sign,s.salt,viewPage)
            if(isGoOn != 205){//是否继续获取未加载页面
                //console.log('viewPage: ' + viewPage + ' 正在获取')
                var jsonStr = getUrlJson(url + "&_=" + getTimestamp());//同步获取json
                //console.log('viewPage: ' + viewPage + ' 正在判定')
                var recvJson = JSON.parse(jsonStr);
                isEnd = recvJson['data']
                //若isEnd不存在,可能真的不存在,也可能还未加载出来,但是既然能isGoOn,isEnd肯定是存在的,所以不需要其他判断
                if(isEnd != undefined){
                    var tranLength = recvJson['data']['tran'].length
                    //console.log(recvJson['data']['tran']);
                    pageTotal += (recvJson['data']['tran'][tranLength-1].pageOrder - recvJson['data']['tran'][0].pageOrder + 1); //TODO
                    //console.log('viewPage: ' + viewPage + ' 当前页数: ' + pageTotal)
                    SakiProgress.setText("正在加载翻译,已翻译"+pageTotal+"页")
                    if(!(isEnd=recvJson['data']['isEnd'])){
                        console.log('viewPage: ' + viewPage + ' 后面还有,继续')
                        viewPage++;
                        getTotalPage0();
                    }
                }else{//用于解决youdaofanyi后台反应不过来的问题
                    SakiProgress.setText("youdao太慢,正在重新访问链接...")
                    sleep(5000)
                    getTotalPage0()
                }
            }
        }
    }
    function sleep(delay) {
        for(var t = Date.now(); Date.now() - t <= delay;);
    }
    function getFullOrign(docKey,sign,salt,page){
        var url = "https://doctrans-service.youdao.com/trandoc/doc/genFullOriginPage?docKey=" + docKey + "&viewPage=" + page + "&isCheckTermUpdate=false&isUseTerm=false&imei=&sign=" + sign + "&salt=" + salt + "&src=new-fanyiweb"
        var url2 = "https://doctrans-service.youdao.com/trandoc/doc/originFullProgress?key=" + docKey + "&imei=&viewPage=" + page + "&src=new-fanyiweb"

        var jsonStr = getUrlJson(url + "&_=" + getTimestamp());//同步获取json
        var recvJson = JSON.parse(jsonStr);
        var errorcode = recvJson['errorcode']
        var docname = recvJson['docname']
        $('#filenameInput').html(docname)
        if(errorcode != 205){
            var jsonStr2 = getUrlJson(url2 + "&_=" + getTimestamp());//激活未加载的页面(此操作后可获取出未加载的页面)
            //return true;
        }//else{
        //    return false;
        //}
        return errorcode
    }

    function getDocKey(imgUrl){
    	// 通过当前页url获取docKey,而不是imgUrl
        return getQueryString(window.location.href, 'docKey')
        //TODO 兼容老版本
        //return getQueryString(window.location.href, 'key')
    }

    function getQueryString(url, name) {
        var arrObj = url.split("?");
        if (arrObj.length > 1) {
            var arrPara = arrObj[1].split("&");
            var arr;
            for (var i = 0; i < arrPara.length; i++) {
                arr = arrPara[i].split("=");

                if (arr != null && arr[0] == name) {
                    return arr[1];
                }
            }
            return "";
        }
        else {
            return "";
        }
    }

    //获取json
    function getUrlJson(url) {
        var xhr = new XMLHttpRequest();
        //         xhr.onload = function() {//异步
        //             callback(xhr.response);
        //         };
        xhr.open('GET', url, false);
        //xhr.responseType = 'json';//同步不能设置该项
        xhr.setRequestHeader('Access-Control-Allow-Origin','*');
        xhr.setRequestHeader('Access-Control-Allow-Methods','OPTIONS, GET, POST');
        xhr.setRequestHeader('Access-Control-Allow-Headers','x-requested-with');
        xhr.setRequestHeader('Access-Control-Max-Age','86400');
        xhr.setRequestHeader('Access-Control-Allow-Credentials','true');
        xhr.withCredentials = true;
        xhr.send(null);
        if (xhr.status === 200) {//同步
            return xhr.response
        }
    }

    //根据下标获取拼接好的图片url
    function getImgUrl(docKey, idx){
        return 'https://doctrans-service.youdao.com/trandoc/doc/getFullOriginModeImg?docKey=' + docKey + '&pageName=tran-' + idx + '.jpeg&src=new-fanyiweb&isCheckTermUpdate=false&isUseTerm=false'

    }

    //获取sign和salt
    function genSign(docKey) {
        var t = "new-fanyiweb"
        var n = "ydsecret://newfanyiweb.doctran/sign/0j9n2{3mLSN-$Lg]K4o0N2}"
        , o = (new Date).getTime();
        return {
            salt: o,
            sign: getSign_r(t + o + n + docKey)
        }
    }

    function getTimestamp(){
        currentTime++
        return currentTime;
    }

    //private
    function getSign_r(e,t){
        if(null==e)
            throw new Error("Illegal argument "+e);
        //r
        var r = {
            rotl: function(e, t) {
                return e << t | e >>> 32 - t
            },
            rotr: function(e, t) {
                return e << 32 - t | e >>> t
            },
            endian: function(e) {
                if (e.constructor == Number)
                    return 16711935 & r.rotl(e, 8) | 4278255360 & r.rotl(e, 24);
                for (var t = 0; t < e.length; t++)
                    e[t] = r.endian(e[t]);
                return e
            },
            randomBytes: function(e) {
                for (var t = []; e > 0; e--)
                    t.push(Math.floor(256 * Math.random()));
                return t
            },
            bytesToWords: function(e) {
                for (var t = [], n = 0, r = 0; n < e.length; n++,
                     r += 8)
                    t[r >>> 5] |= e[n] << 24 - r % 32;
                return t
            },
            wordsToBytes: function(e) {
                for (var t = [], n = 0; n < 32 * e.length; n += 8)
                    t.push(e[n >>> 5] >>> 24 - n % 32 & 255);
                return t
            },
            bytesToHex: function(e) {
                for (var t = [], n = 0; n < e.length; n++)
                    t.push((e[n] >>> 4).toString(16)),
                        t.push((15 & e[n]).toString(16));
                return t.join("")
            },
            hexToBytes: function(e) {
                for (var t = [], n = 0; n < e.length; n += 2)
                    t.push(parseInt(e.substr(n, 2), 16));
                return t
            },
            bytesToBase64: function(e) {
                for (var t = [], r = 0; r < e.length; r += 3)
                    for (var o = e[r] << 16 | e[r + 1] << 8 | e[r + 2], i = 0; i < 4; i++)
                        8 * r + 6 * i <= 8 * e.length ? t.push(n.charAt(o >>> 6 * (3 - i) & 63)) : t.push("=");
                return t.join("")
            },
            base64ToBytes: function(e) {
                e = e.replace(/[^A-Z0-9+\/]/gi, "");
                for (var t = [], r = 0, o = 0; r < e.length; o = ++r % 4)
                    0 != o && t.push((n.indexOf(e.charAt(r - 1)) & Math.pow(2, -2 * o + 8) - 1) << 2 * o | n.indexOf(e.charAt(r)) >>> 6 - 2 * o);
                return t
            },
            stringToBytes: function(e) {
                for (var t = [], n = 0; n < e.length; n++)
                    t.push(255 & e.charCodeAt(n));
                return t
            },
            bytesToString: function(e) {
                for (var t = [], n = 0; n < e.length; n++)
                    t.push(String.fromCharCode(e[n]));
                return t.join("")
            }
        }

        //function u
        var u = function(e, t) {
            e.constructor == String ? e = t && "binary" === t.encoding ? r.stringToBytes(e) : r.stringToBytes(e) : i(e) ? e = Array.prototype.slice.call(e, 0) : Array.isArray(e) || e.constructor === Uint8Array || (e = e.toString());
            for (var n = r.bytesToWords(e), s = 8 * e.length, c = 1732584193, l = -271733879, f = -1732584194, p = 271733878, d = 0; d < n.length; d++)
                n[d] = 16711935 & (n[d] << 8 | n[d] >>> 24) | 4278255360 & (n[d] << 24 | n[d] >>> 8);
            n[s >>> 5] |= 128 << s % 32,
                n[14 + (s + 64 >>> 9 << 4)] = s;
            var h = u._ff
            , y = u._gg
            , v = u._hh
            , g = u._ii;
            for (d = 0; d < n.length; d += 16) {
                var m = c
                , b = l
                , x = f
                , w = p;
                c = h(c, l, f, p, n[d + 0], 7, -680876936),
                    p = h(p, c, l, f, n[d + 1], 12, -389564586),
                    f = h(f, p, c, l, n[d + 2], 17, 606105819),
                    l = h(l, f, p, c, n[d + 3], 22, -1044525330),
                    c = h(c, l, f, p, n[d + 4], 7, -176418897),
                    p = h(p, c, l, f, n[d + 5], 12, 1200080426),
                    f = h(f, p, c, l, n[d + 6], 17, -1473231341),
                    l = h(l, f, p, c, n[d + 7], 22, -45705983),
                    c = h(c, l, f, p, n[d + 8], 7, 1770035416),
                    p = h(p, c, l, f, n[d + 9], 12, -1958414417),
                    f = h(f, p, c, l, n[d + 10], 17, -42063),
                    l = h(l, f, p, c, n[d + 11], 22, -1990404162),
                    c = h(c, l, f, p, n[d + 12], 7, 1804603682),
                    p = h(p, c, l, f, n[d + 13], 12, -40341101),
                    f = h(f, p, c, l, n[d + 14], 17, -1502002290),
                    c = y(c, l = h(l, f, p, c, n[d + 15], 22, 1236535329), f, p, n[d + 1], 5, -165796510),
                    p = y(p, c, l, f, n[d + 6], 9, -1069501632),
                    f = y(f, p, c, l, n[d + 11], 14, 643717713),
                    l = y(l, f, p, c, n[d + 0], 20, -373897302),
                    c = y(c, l, f, p, n[d + 5], 5, -701558691),
                    p = y(p, c, l, f, n[d + 10], 9, 38016083),
                    f = y(f, p, c, l, n[d + 15], 14, -660478335),
                    l = y(l, f, p, c, n[d + 4], 20, -405537848),
                    c = y(c, l, f, p, n[d + 9], 5, 568446438),
                    p = y(p, c, l, f, n[d + 14], 9, -1019803690),
                    f = y(f, p, c, l, n[d + 3], 14, -187363961),
                    l = y(l, f, p, c, n[d + 8], 20, 1163531501),
                    c = y(c, l, f, p, n[d + 13], 5, -1444681467),
                    p = y(p, c, l, f, n[d + 2], 9, -51403784),
                    f = y(f, p, c, l, n[d + 7], 14, 1735328473),
                    c = v(c, l = y(l, f, p, c, n[d + 12], 20, -1926607734), f, p, n[d + 5], 4, -378558),
                    p = v(p, c, l, f, n[d + 8], 11, -2022574463),
                    f = v(f, p, c, l, n[d + 11], 16, 1839030562),
                    l = v(l, f, p, c, n[d + 14], 23, -35309556),
                    c = v(c, l, f, p, n[d + 1], 4, -1530992060),
                    p = v(p, c, l, f, n[d + 4], 11, 1272893353),
                    f = v(f, p, c, l, n[d + 7], 16, -155497632),
                    l = v(l, f, p, c, n[d + 10], 23, -1094730640),
                    c = v(c, l, f, p, n[d + 13], 4, 681279174),
                    p = v(p, c, l, f, n[d + 0], 11, -358537222),
                    f = v(f, p, c, l, n[d + 3], 16, -722521979),
                    l = v(l, f, p, c, n[d + 6], 23, 76029189),
                    c = v(c, l, f, p, n[d + 9], 4, -640364487),
                    p = v(p, c, l, f, n[d + 12], 11, -421815835),
                    f = v(f, p, c, l, n[d + 15], 16, 530742520),
                    c = g(c, l = v(l, f, p, c, n[d + 2], 23, -995338651), f, p, n[d + 0], 6, -198630844),
                    p = g(p, c, l, f, n[d + 7], 10, 1126891415),
                    f = g(f, p, c, l, n[d + 14], 15, -1416354905),
                    l = g(l, f, p, c, n[d + 5], 21, -57434055),
                    c = g(c, l, f, p, n[d + 12], 6, 1700485571),
                    p = g(p, c, l, f, n[d + 3], 10, -1894986606),
                    f = g(f, p, c, l, n[d + 10], 15, -1051523),
                    l = g(l, f, p, c, n[d + 1], 21, -2054922799),
                    c = g(c, l, f, p, n[d + 8], 6, 1873313359),
                    p = g(p, c, l, f, n[d + 15], 10, -30611744),
                    f = g(f, p, c, l, n[d + 6], 15, -1560198380),
                    l = g(l, f, p, c, n[d + 13], 21, 1309151649),
                    c = g(c, l, f, p, n[d + 4], 6, -145523070),
                    p = g(p, c, l, f, n[d + 11], 10, -1120210379),
                    f = g(f, p, c, l, n[d + 2], 15, 718787259),
                    l = g(l, f, p, c, n[d + 9], 21, -343485551),
                    c = c + m >>> 0,
                    l = l + b >>> 0,
                    f = f + x >>> 0,
                    p = p + w >>> 0
            }
            return r.endian([c, l, f, p])
        }
        u._ff = function(e, t, n, r, o, i, a) {
            var u = e + (t & n | ~t & r) + (o >>> 0) + a;
            return (u << i | u >>> 32 - i) + t
        },u._gg = function(e, t, n, r, o, i, a) {
            var u = e + (t & r | n & ~r) + (o >>> 0) + a;
            return (u << i | u >>> 32 - i) + t
        },u._hh = function(e, t, n, r, o, i, a) {
            var u = e + (t ^ n ^ r) + (o >>> 0) + a;
            return (u << i | u >>> 32 - i) + t
        },u._ii = function(e, t, n, r, o, i, a) {
            var u = e + (n ^ (t | ~r)) + (o >>> 0) + a;
            return (u << i | u >>> 32 - i) + t
        },u._blocksize = 16,u._digestsize = 16

        var n=r.wordsToBytes(u(e,t));
        return t&&t.asBytes?n:t&&t.asString?r.bytesToString(n):r.bytesToHex(n)
    }

    //创建下载按钮
    var downloadBtn=$("<a id='exportDoc2' href='javascript:;'>导出文档</a>");
    var filenameInput = $("<span id='filenameInput'></span>");
    $("#app").prepend(filenameInput);
    $("#app").prepend(downloadBtn);
    // $("#exportDoc").parent().prepend(downloadBtn);
    // $("#exportDoc").remove();
    //TODO 兼容老版本
    $("#exportDoc").parent().prepend(downloadBtn);
    $("#exportDoc").remove();

    downloadBtn.bind("contextmenu",function(){
         return false;
    })
    downloadBtn.mousedown(function(e) {
        SakiProgress.showDiv()
        SakiProgress.setText("正在加载翻译,信息量大,请勿关闭页面...")
        currentTime = Date.now()
        setTimeout(function(){//是为了让进度条先显示出来
            batchDownload()
        },100)
    })
    // downloadBtn.click(function() {
    //     SakiProgress.showDiv()
    //     SakiProgress.setText("正在加载翻译,信息量大,请勿关闭页面...")
    //     currentTime = Date.now()
    //     setTimeout(function(){//是为了让进度条先显示出来
    //         batchDownload()
    //     },100)
    // });



})();