/**
 * rhhz.js ---仁和软件前端插件js集合
 * tools{
 * 	subTextMax:文本内容按长度设置截取,
 * 	menuView:按照页面设置进行页面菜单对应高亮
 * }
 * function{
 * 	hasChinese:判断当前对象中是否包含中文字符,
 * 	trim:解决IE 对jquery Trim方法的兼容性,
 * 	startWith:判断当前对象是否以字符开始,
 * 	endWith:判断字符串是否以字符结束,
 *  getFileUrl:获取本地资源文件的路径,
 *  preImg:预览本地图片,
 *  getUrlParam:获取URL参数列表,
 *  getRefSupIndex:获取参考文献引用索引,
 *  isNull:判断对象是否为空,
 *  formatDateToEn:将日期转换成英文格式 2016-1-1 --> 01 Jan 2016
 *  GetRandomNum:获取随机数
 *  dateStr:获取网页顶部显示需要的日期信息 参数，type 1:中文  2英文 3英文简写 （ 2017-1-11 星期三;  Wednesday, 11 January, 2017 ;Jan 20th, Wednesday
 * 	shareTools(type,obj):分享工具，qzone,sina,weixin,renren,google+,facebook,linkedin,twitter
 * }
 * 
 * @version     v1.0
 * @date 		2016-09-30
 */

+function ($) {
    //设置字符串截取默认参数
    var subTextDefaluts = {
        add_title: true,      //默认截取后设置全内容title
        trim: true,//默认截取后去除首尾空及换行，感觉没啥用，后面考虑取消
        content_type: 'html',//默认处理内容为html标签，如设置为text会清除原有标签
        keep_len: 10//默认截取保留10个字符，建议采用配置方式或者在标签中设置
    };

    //设置菜单高亮默认参数
    var menuDefaults = {
        defaultPage: 'index',			//默认获取不到页面索引，设置为首页
        pageViewId: 'pageViewId',		//页面索引取值ID
        hightLightTag: 'li',				//需要设置高亮的标签
        highLightClass: 'current',		//当前页选中高亮class
        pageRelAttr: 'rel_page',			//菜单列表中索引属性标识
        pageRelTag: 'li span'			//菜单列表中索引取值标签，默认取text().trim(),pageRelTag和pageRelAttr不需要同时存在
    }

    $.fn.subTextMax = function (options) {
        var opts = $.extend({}, subTextDefaluts, options);
        return this.each(function () {
            var keepindex = parseInt($(this).attr("keep_len") == undefined ? opts.keep_len : $(this).attr("keep_len"));//超出keep值需要截取
            var contentHtml = $(this).html().replace(/&nbsp;/ig, '').replace(/\s+/g, ' ').replace(/\t|\r|\n/g, "").replace('<sec> <b>', '<sec><b>').replace(/<br[ ]*[/]{0,1}>/g, "<br/>").trim();
            //var contentText = $(this).text().replace(/&nbsp;/ig, '').replace(/\s+/g, ' ').replace(/\t|\r|\n/g,"").trim();
            var contentText = filterHTMLTag(contentHtml);

            if (contentText.length > keepindex) {
                //如果需要，可加title，title为全部文本内容
                if (opts.add_title) {
                    if ($(this).attr("title") == '' || $(this).attr("title") == undefined) {
                        $(this).attr("title", contentText);
                    }
                }
                contentText = contentText.substr(0, keepindex);
                if (opts.content_type == 'text') {
                    $(this).html(contentText + "...");
                } else {
                    //对HTML标签内容进行截取分为四个步骤1存储原有标签  2按照text进行截取  3对截取后的text进行标签插入  4补全未闭合标签
                    //1.处理原有标签
                    //获取当前内容中的各个标签及所在位置
                    var rgx = /<[^<^>]+>/; //标签匹配正则
                    var index = 0;
                    var tags = new Array();
                    while (rgx.test(contentHtml)) {
                        var t = new Object();
                        //标签出现的位置
                        t.index = index + contentHtml.search(rgx);
                        //标签内容
                        t.tag = contentHtml.match(rgx).toString();
                        //每次匹配第一个标签，匹配完删除此标签，同时索引位置加当前标签的长度
                        var len = contentHtml.search(/<[^<^>]+>/) + contentHtml.match(/<[^<^>]+>/)[0].length;
                        contentHtml = contentHtml.substr(len);
                        index += len;
                        tags.push(t);
                    }
                    //2.截取text内容，上面已经截取过了
                    //3.填充原有标签
                    if (tags.length > 0) {
                        $.each(tags, function (i, e) {
                            if (e.index > contentText.length) {
                                //如果当前节点的开始位置大于当前返回字符串的长度则不再继续判断
                                tags = tags.slice(0, i);
                                return false;
                            } else {
                                //将原有标签插入原位置
                                contentText = contentText.substr(0, e.index) + e.tag + contentText.substr(e.index, contentText.length);
                            }
                        })
                    }
                    //4.闭合标签
                    //获取未闭合标签，标签填充时不需要填充的标签都被slice过滤掉了，所以剩下的都是已经在内容中的标签了，需要进行判断闭合处理
                    var insertTags = new Array();//已正确插入标签
                    var uncloseTags = new Array();//未闭合标签
                    if (tags.length > 0) {
                        $.each(tags, function (i, e) {
                            //先将所有插入的标签放到插入和未闭合列表中
                            uncloseTags.push(e.tag);
                            insertTags.push(e.tag);
                        })
                        $.each(insertTags, function (i, e) {
                            //自闭合标签不需要补全，删除如<br/>
                            if (/<[^<^>^\/]+\/>/.test(e)) {
                                uncloseTags.splice($.inArray(e, uncloseTags), 1);
                                return true;
                            }
                            //对左标签进行闭合判断，如果同时存在一组左右标签，则同时删除即可，由于成组的删除，所以不用考虑多个<div>对应一个</div>的情况，我们只需要按照顺序获取到未闭合的列表即可
                            if (/<[^<^>^\/]+>/.test(e)) {
                                var tagClosed = "";
                                if (e.indexOf(" ") > 0) {
                                    tagClosed = "</" + e.substring(1, e.indexOf(" ")) + ">";
                                } else {
                                    tagClosed = "</" + e.substring(1, e.length);
                                }
                                //同时存在闭合标签
                                if ($.inArray(tagClosed, uncloseTags) != -1) {
                                    uncloseTags.splice($.inArray(e, uncloseTags), 1);
                                    uncloseTags.splice($.inArray(tagClosed, uncloseTags), 1);
                                }
                            }
                        })
                    }
                    //此时uncloseTags已经是未闭合的标签列表了
                    //生成闭合标签，根据标签嵌套规则，右标签和左标签对应，如<div><p>   --  </p></div>，所以先将未闭合标签数组逆序
                    if (uncloseTags.length > 0) {
                        var closeTagStr = "";
                        uncloseTags.reverse();
                        $.each(uncloseTags, function (i, e) {
                            if (e.indexOf(" ") > 0) {
                                closeTagStr += "</" + e.substring(1, e.indexOf(" ")) + ">";
                            } else {
                                closeTagStr += "</" + e.substring(1, e.length);
                            }
                        })
                        contentText += "..." + closeTagStr;
                    } else {
                        contentText += "...";
                    }
                    //拼接完成
                    $(this).html(contentText);
                }

            }
        })
    }
}(jQuery);

/**
 * 自定义字符串结尾判定方法，以s结尾返回true，否则返回false
 * @param s
 * @return
 */
String.prototype.endsWith = function (s) {
    if (s == null || s == "" || this.length == 0 || s.length > this.length)
        return false;
    if (this.substring(this.length - s.length) == s)
        return true;
    else
        return false;
    return true;
}
String.prototype.endWith = function (s) {
    if (s == null || s == "" || this.length == 0 || s.length > this.length)
        return false;
    if (this.substring(this.length - s.length) == s)
        return true;
    else
        return false;
    return true;
}

/**
 * 自定义字符串开始判定方法，以s开始返回true，否则返回false
 * @param s
 * @return
 */
String.prototype.startsWith = function (s) {
    if (s == null || s == "" || this.length == 0 || s.length > this.length)
        return false;
    if (this.substr(0, s.length) == s)
        return true;
    else
        return false;
    return true;
}
String.prototype.startWith = function (s) {
    if (s == null || s == "" || this.length == 0 || s.length > this.length)
        return false;
    if (this.substr(0, s.length) == s)
        return true;
    else
        return false;
    return true;
}

/**
 * IE浏览器兼容jquery trim方法
 * @return
 */
String.prototype.trim = function () {
    return this.replace(/(^\s*)|(\s*$)/g, "");
}
/**
 * 获取地址栏url参数
 * @param name
 * @return
 */
function getUrlParam(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
    var r = window.location.search.substr(1).match(reg);
    if (r != null) return decodeURI(r[2]); return null;
    //return $("#language").val();
}

/**
 * 从参考文献引用信息中提取参考文献索引
 * 支持格式"[1,3,5-8,11,13-18,19]"
 * @param refSup
 * @return
 */
function getRefSupIndex(refSup) {
    if (!isNull(refSup)) {
        refSup = refSup.replace(/[\[|\]]/g, '').trim();
        var chars = ['~', '—', '–', '，', '-', '−', '⁃'];
        $.each(chars, function (ind, val) {
            var reg = new RegExp(val, "g");
            refSup = refSup.replace(reg, '&');
        });
        var refIndexs = [];
        $.each(refSup.split(","), function (i, e) {
            if (isNaN(e)) {
                var startEnd = e.split("&");
                var start = parseInt(startEnd[0]);
                var end = parseInt(startEnd[1]);
                for (var i = start; i <= end; i++) {
                    refIndexs.push(i);
                }
            } else {
                refIndexs.push(e);
            }
        })
        //alert(refIndexs);
        return refIndexs;
    }
    return null;
}

/**
 * 封装判断对象为空方法
 * @param object
 * @return
 */
function isNull(object) {
    return typeof (object) == "undefined" || object == null || object == "";
}

/**
 * 获取随机数
 * @param Min
 * @param Max
 * @return
 */
function GetRandomNum(Min, Max) {
    var Range = Max - Min;
    var Rand = Math.random();
    return (Min + Math.round(Rand * Range));
}

/**
 * 获取网页顶部显示需要的日期信息
 * @param type 1:中文  2英文 3英文简写
 * 	  2017-1-11 星期三
 * 	  Wednesday, 11 January, 2017 
 *    Jan 20th, Wednesday
 * @return
 */
function dateStr(type) {
    var date = new Date();
    return parseInt(type) == 1 ?
        formatDate(date, type) + " " + getTodayWeek(type) :
        getTodayWeek(type) + ", " + formatDate(date, type);
}


/**
 * 将日期格式化成英文格式
 * 2017-1-11
 * 11 January, 2017
 * Jan 11, 2017
 * @param date
 * */
function formatDate(date, type) {
    if (!isNull(date)) {
        var dateStr = JSON.stringify(date).substring(1, 11);
        var dateVal = dateStr.split("-");
        var month = dateVal[1];
        if (month.charAt(0) == 0) { month = month.charAt(1); }
        var monthArray = new Array
            ("January", "February", "March", "April", "May", "June", "July", "August",
                "September", "October", "November", "December");
        var monthArraySimple = new Array
            ("Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug",
                "Sep", "Oct", "Nov", "Dec");
        switch (type) {
            case 1:
                return dateStr;
            case 2:
                return dateVal[2] + " " + monthArray[month - 1] + ", " + dateVal[0];
            case 3:
                return monthArraySimple[month - 1] + " " + dateVal[2] + ", " + dateVal[0];
        }
    }
}

/**
 * 获取星期几
 * @param type 1:中文  2英文 3英文简写
 * @return
 */
function getTodayWeek(type) {
    var chinese = new Array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六");
    var english = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
    var englishSigle = new Array("Sun.", "Mon.", "Tues.", "Wed.", "Thur.", "Fri.", "Sat.");
    var week = new Date().getDay();
    switch (type) {
        case 1:
            return chinese[week];
        case 2:
            return english[week];
        case 3:
            return englishSigle[week];
    }
}

/**
 * 分享工具方法
 * @param type
 * @return
 */
function shareTools(type, obj) {
    if (obj && obj.parents(".shareUrlTools").length) {
        var url = window.location.protocol + "//" + window.location.host + obj.parents(".shareUrlTools").attr("data-url");
        var title = obj.parents(".shareUrlTools").attr("data-title");
    } else {
        var url = window.location;
        var title = $("head title").text();
    }
    var description = $("meta[name='abstract']").attr("content") || $("meta[name='description']").attr("content") || $("meta[name='dc.description']").attr("content") || $("meta[http-equiv='description']").attr("content");
    var shareUrl = "";
    switch (type) {
        case 'qzone':
            shareUrl = "http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=" + url + "&title=" + title;
            break;
        case 'sina':
            shareUrl = "http://service.weibo.com/share/share.php?title=" + title + "&url=" + url + "&pic=";
            break;
        case 'weixin':
            shareUrl = local_host + "util/QrcodeServlet?url=" + url;
            break;
        case 'renren':
            shareUrl = "http://widget.renren.com/dialog/share?resourceUrl=" + url + "&srcUrl=" + url + "&title=" + title + "&pic=&description=" + description;
            break;
        case 'google+':
            shareUrl = "https://plus.google.com/share?url=" + url + "&t=" + title;
            break;
        case 'facebook':
            shareUrl = "http://www.facebook.com/sharer.php?s=100&p[title]=" + title + "&p[summary]=" + description + "&p[url]=" + url + "&p[images]=";
            break;
        case 'linkedin':
            shareUrl = "http://www.linkedin.com/shareArticle?armin=armin&ro=true&mini=true&url=" + url + "&source=&title=" + title + "&summary=" + description;
            break;
        case 'twitter':
            shareUrl = "https://twitter.com/intent/tweet?text=" + title + "&url=" + url;
            break;
        default:
            shareUrl = "http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=" + url + "&title=" + title;
            break;
    }
    if ("weixin" == type) {
        $(".weixinQrcode").attr("src", shareUrl);
    } else {
        window.open(shareUrl, "_blank");
    }
}
function closeWeiXinBox(obj) {
    $(obj).parent().hide();
}

//过滤HTML标签
function filterHTMLTag(str) {
    if (!str) {
        return str;
    } else {
        var msg = str.replace(/<\/?[^>]*>/g, ''); //去除HTML Tag
        msg = msg.replace(/[|]*\n/, ''); //去除行尾空格
        msg = msg.replace(/&nbsp;/ig, ''); //去掉npsp
        return msg;
    }
}

//查询条件相关方法
function SearchCond(field, operator, value, dataType, relation, paramEntity) {
    this.dataType = dataType;
    this.paramName = field;
    this.operate = operator;
    this.paramValue = value;
    this.relation = relation;
    this.paramEntity = paramEntity;
}

function SearchTools_put(conds, searchCond) {
    if (searchCond.paramValue != null && searchCond.paramValue != "") {
        conds.push(searchCond);
    }
}

function OrderByCond(field, value) {
    this.dataType = "";
    this.paramName = field;
    this.operate = "";
    this.paramValue = value;
}

function OrderTools_put(conds, orderByCond) {
    if (orderByCond.paramValue != null && orderByCond.paramValue != "") {
        conds.push(orderByCond);
    }
}

function isNull(object) {
    return typeof (object) == "undefined" || object == null || object == "";
}

/**
 * 处理内容中的xml链接标签
 * @param input 内容
 * @returns {*} 处理结果
 */
function convertLink(input) {
    var output = input;
    output = output.replace(/<ext-link/g, "<a")
        .replace(/<\/ext-link/g, "</a")
        .replace(/xlink:href/g, "href")
        .replace(/ext-link-type="uri"/g, "target=\"_blank\"");

    return output;
}

/**
 * 按索引获取内容中的正则匹配结果
 * @param source 内容
 * @param regx 正则表达式
 * @param index 索引
 * @returns {*|string} 索引位置的正则匹配结果
 */
function getMatcherByIndex(source, regx, index) {

    var pattern = new RegExp(regx);
    var list = source.match(pattern);
    if (!isNull(list)) {
        var result = list[index];
        if (!isNull(result)) {
            return result;
        }
    }

    return "";
}

function isNull(object) {
    return typeof (object) == "undefined" || object == null || object == "";
}

/**
 * 处理内容中的xml链接标签
 * @param input 内容
 * @returns {*} 处理结果
 */
function convertLink(input) {
    var output = input;
    output = output.replace(/<ext-link/g, "<a")
        .replace(/<\/ext-link/g, "</a")
        .replace(/xlink:href="([^"]*)"/g, "href=\"$1\"")
        .replace(/ext-link-type="uri"/g, "target=\"_blank\"");

    return output;
}

/**
 * 正则替换,replaceAll不好用,重写逻辑
 * @param source 源字符串
 * @param target 替换结果
 * @param regx 正则表达式
 * @returns {*} 替换结果
 */
function replaceRegx(source, target, regx) {
    var result = source;
    var pattern = new RegExp(regx, 'g');
    var list = result.match(pattern);
    if (!isNull(list))
        for (var i = 0; i < list.length; i++) {
            var str = list[i];
            result = result.replace(str, target);
        }

    return result;
}

/**
 * 判断内容是否包含doi:
 * @param context
 * @returns {boolean}
 */
function isContainsByDoi(context) {
    if (!isNull(context)) {
        var re = context.toUpperCase().replace(/ /g, "");
        return re.indexOf("DOI:") != -1;
    }
    return false;
}

/**
 * 处理公式内容
 * @param sourceStr 需要处理的字符串
 * @returns {*|string|string} 处理结果
 */
function convertMathHtml(sourceStr) {

    if (isNull(sourceStr)) return "";
    sourceStr = replaceRegx(sourceStr, "", "<[/]{0,1}multi_end[/]{0,1}>");
    sourceStr = replaceRegx(sourceStr, "", "<[/]{0,1}multi_start[/]{0,1}>");
    sourceStr = sourceStr.trim();
    sourceStr = sourceStr.replace(/jlmText/g, "text");

    //xdf20220615 兼容mml格式公式,剔除mml:
    sourceStr = sourceStr.replace(/<mml:/g, "<").replace(/<\/mml:/g, "</").replace(/:mml/g, "");

    //xdf20220712 剔除输出数据中的cdata标签
    sourceStr = sourceStr.replace(/<!\[CDATA\[/g, "").replace(/]]>/g, "");

    var tempStr = sourceStr;
    if (sourceStr.indexOf("<disp-formula") != -1) { //独立段落行公式

        var imgSrc = "";
        //如果是公式图片，直接图片输出
        if (sourceStr.indexOf("graphic ") != -1) {
            imgSrc = getMatcherByIndex(sourceStr, "xlink:href=\"(.*?)\"", 1);
        }

        tempStr = replaceRegx(tempStr, "", "<label>.*?</label>");
        tempStr = replaceRegx(tempStr, "", "<disp-formula.*?>");
        tempStr = replaceRegx(tempStr, "", "<tex-math.*?>");
        tempStr = replaceRegx(tempStr, "", "<graphic.*?>.*?</graphic>");
        tempStr = replaceRegx(tempStr, "", "<alternatives.*?>");
        tempStr = replaceRegx(tempStr, "", "<graphic.*?>");

        tempStr = tempStr.replace(/<label\/>/g, "")
            .replace(/\\begin{document}/g, "").replace(/\\end{document}/g, "")
            .replace(/\\begin{equation} \\begin{CJK}{GBK}{song}/g, "")
            .replace(/\\end{CJK} \\end{equation}/g, "")
            .replace(/<\/disp-formula>/g, "")
            .replace(/<\/tex-math>/g, "")
            .replace(/<\/alternatives>/g, "")
            .replace(/<\/graphic>/g, "").trim();

        if (tempStr.startsWith("<p>") && tempStr.endsWith("</p>")) {
            tempStr = replaceRegx(tempStr, "", "\r\n\t");
            tempStr = tempStr.replace(/<p>/g, "").replace(/<\/p>/g, "").trim();
            if (tempStr.startsWith("$") && !tempStr.startsWith("$$")) {
                tempStr = "$" + tempStr + "$";
            }
        }
        //如果是公式图片，直接图片输出
        if (sourceStr.indexOf("graphic ") !== -1) {
            var result = "";
            if (sourceStr.indexOf("<tex-math") !== -1) {//如内容包含<tex-math,隐藏图片
                result = tempStr + "<p class='img-formula' style='display:none;'><img class='formula-img' src='" + imgSrc + "'></p>";
            } else {
                result = tempStr + "<p class='img-formula'><img class='formula-img' src='" + imgSrc + "'></p>";
            }
            result = convertLink(result);
            return result;
        }
    } else if (sourceStr.indexOf("<tex-math") !== -1) { //非段落公式且内容中包含公式则为行内公式
        //正则匹配inline-formula,循环处理
        var pattern = new RegExp("(<inline-formula[^>]*>[\\s\\S]*?</inline-formula>)", "g");

        var results = sourceStr.match(pattern);
        if (results) {
            for (var i = 0; i < results.length; i++) {
                currentMath = results[i]
                var imgSrc = getMatcherByIndex(currentMath, "xlink:href=\"(.*?)\"", 1);
                var textMathStr = getMatcherByIndex(currentMath, "<tex-math.*?>([\\s\\S]*?)</tex-math?>", 0);
                var textMath = textMathStr;
                textMath = replaceRegx(textMath, "", "<tex-math.*?>");
                textMath = replaceRegx(textMath, "", "<inline-graphic>.*?</inline-graphic>");
                textMath = replaceRegx(textMath, "\\$", "\\$((\n)|[ ])*\\$");
                textMath = replaceRegx(textMath, "", "<inline-graphic.*?>.*?</inline-graphic>");
                textMath = replaceRegx(textMath, "", "<inline-graphic.*?>");
                textMath = replaceRegx(textMath, "", "</inline-graphic>");
                textMath = textMath.replace(/\\begin{document}/g, "$")
                    .replace(/\\end{document}/g, "$")
                    .replace(/\\begin{equation} \\begin{CJK}{GBK}{song}/g, "$")
                    .replace(/\\end{CJK} \\end{equation}/g, "$")
                    .replace(/<\/tex-math>/g, "");

                var mathId = getMatcherByIndex(currentMath, "<tex-math.*?id=\"(.*?)\">", 0);
                mathId = replaceRegx(mathId, "", "<tex-math.*?id=\"");
                mathId = replaceRegx(mathId, "", "\">");
                if (!isNull(imgSrc)) {//有图片时将图片隐藏后输出
                    var imgTag = "<span class=\"inline-formula-span\">" + textMath
                        + "</span><img text_id='" + mathId + "' class='formula-img' style='display:none;' src='" + imgSrc + "'>";
                    sourceStr = sourceStr.replaceAll(textMathStr, imgTag);
                } else {
                    sourceStr = sourceStr.replaceAll(currentMath, textMath);
                }
            }
        }

        if (!isNull(sourceStr)) {
            tempStr = sourceStr;
            tempStr = replaceRegx(tempStr, "", "<label>.*?</label>");
            tempStr = tempStr.replace(/<label\/>/g, "");
            tempStr = tempStr.replace(/\\\\begin{equation} \\\\begin{CJK}{GBK}{song}/g, "")
                .replace(/\\\\end{CJK} \\\\end{equation}/g, "");
            tempStr = replaceRegx(tempStr, "", "<disp-formula.*?>");
            tempStr = tempStr.replace(/<\/disp-formula>/g, "");
            tempStr = replaceRegx(tempStr, "", "<tex-math.*?>");
            tempStr = tempStr.replace(/<\/tex-math>/g, "");
            if (tempStr.indexOf("</graphic>") != -1) {
                tempStr = replaceRegx(tempStr, "", "<graphic.*?>.*?</graphic>");
            }
            tempStr = replaceRegx(tempStr, "", "<graphic.*?>");
            tempStr = tempStr.replace(/<\/graphic>/g, "").trim();
        }
    } else if (sourceStr.indexOf("<graphic ") !== -1) {
        // var imgSrc = "";
        // imgSrc = getMatcherByIndex(sourceStr, "xlink:href=\"(.*?)\"", 0);

        // tempStr = replaceRegx(tempStr, "", "<graphic.*?>.*?</graphic>");

        // tempStr = tempStr.replace(/<\/graphic>/g, "").trim();

        // var result = tempStr + "<img class='formula-img' src='" + imgSrc + "'>";
        // result = convertLink(result);
        // return result;

        var parser = new DOMParser();
        var parseTempStr = parser.parseFromString(tempStr, "text/xml");
        var graphics = parseTempStr.getElementsByTagName("graphic");
        for (var i = 0; i < graphics.length; i++) {
            var graphicNode = graphics[i];

            // 检查是否包含特定的xlink:href 属性
            if (graphicNode.getAttribute("xlink:href")) {

                // 获取 xlink:href 属性的值
                var imageUrl = graphicNode.getAttribute("xlink:href");

                // 创建新的 <img> 元素，并设置 src 属性
                var imgElement = document.createElement('img');
                imgElement.src = imageUrl;

                // 替换原来的 <graphic> 元素
                graphicNode.parentNode.replaceChild(imgElement, graphicNode);
            }
        }

        // 此时，parseTempStr 已经包含了替换后的结果
        tempStr = new XMLSerializer().serializeToString(parseTempStr);

        return tempStr;
    }
    tempStr = convertLink(tempStr);
    return tempStr;

}

/**
 * 拼装参考文献链接
 * @param source url或doi
 * @param isIcon 是否展示为按钮
 * @param type 类型:doi,url
 * @returns {string} 拼装的a链接html
 */
function getReferLinkHtml(source, isIcon, type) {
    var typeClass = 'ref-doi';
    if (type == 'url') typeClass = 'ref-url'

    var iconClass = '';
    var show = source;
    if (isIcon && isIcon == "true") {
        iconClass = 'icon';
        show = '';
    }

    var href = source;
    if (type != 'url') href = 'https://dx.doi.org/' + source;

    return ' <a class=\"mainColor ' + typeClass + ' ' + iconClass + '\" href=\"' + href + '\" target=\"_blank\">' + show + '</a>';
}

/**
 * 获取参考文献的输出结果
 * @param content 参考文献的文本内容
 * @param doi 参考文献的doi
 * @param isIcon 链接是否要显示为按钮
 * @param isUp doi:是否需要大写
 * @param url 参考文献的链接
 * @returns {string} 拼装后的参考文献
 */
function referenceDOIReplace(content, doi, isIcon, isUp, url) {
    var doiHtml = "";
    if (isNull(doi)) doi = "";
    if (isNull(url)) url = "";
    if (isContainsByDoi(content)) {//判断是否包含doi:
        if (!isNull(doi)) {//传入doi时直接将doi转为链接进行替换
            doiHtml = getReferLinkHtml(doi, isIcon, 'doi');
            content = content.replaceAll(doi, doiHtml);
        } else {//未传入doi时,从内容中切出doi,然后转为链接并进行替换
            var re = content.toUpperCase().replace(/ /g, "");
            var inner = re.indexOf("DOI:") + 4;
            doi = content.replace(/ /g, "").substring(inner);

            if (doi.endsWith(".")) {
                doi = doi.substring(0, doi.length - 1);
            }
            doiHtml = getReferLinkHtml(doi, isIcon, 'doi');
            content = content.replaceAll(doi, doiHtml);
        }
    } else {//不包含doi:时
        if (content.indexOf("doi.org") != "-1" && content.indexOf(doi) != "-1" && !isNull(doi)) {//doi的链接是带有doi.org的完整链接时,整条链接转a标签
            var doiurl = content.substring(content.indexOf("http"), content.indexOf(doi));
            doiHtml = " <a class=\"mainColor ref-doi\" href=\"" + doiurl + doi + "\" target=\"_blank\">" + doiurl + doi + "</a>";
            content = content.replaceAll(doiurl + doi, doiHtml);
        } else if (!isNull(doi)) {//doi的链接不是带doi.org的完整链接时,且有传入doi,将'doi:'+doi链接拼装到内容尾部
            doiHtml = getReferLinkHtml(doi, isIcon, 'doi');
            if ("U" == isUp) {
                content = content + "<span>" + " doi: ".toUpperCase() + doiHtml + "</span>";
            } else {
                content = content + "<span>" + " doi: ".toLowerCase() + doiHtml + "</span>";
            }
        } else if (!isNull(url)) {//没有doi:,没有doi.org,没有传入doi的情况,一般不是doi而是其他链接,需要判断是否传入url
            if (url.lastIndexOf("/10.") != -1) {//有传入url时,看看url是不是包含doi,如果是,则将doi切出,转为链接后拼装至内容尾部
                doi = url.substring(url.lastIndexOf("/10.") + 1, url.length);
                doiHtml = getReferLinkHtml(doi, isIcon, 'doi');
                if ("U" == isUp) {
                    content = content + "<span>" + " doi: ".toUpperCase() + doiHtml + "</span>";
                } else {
                    content = content + "<span>" + " doi: ".toLowerCase() + doiHtml + "</span>";
                }
            } else {//如果url不包含doi,按普通链接处理
                doiHtml = getReferLinkHtml(url, isIcon, 'url');
                // 如果内容中包含url，则替换内容中的url为链接形式
                if (content.indexOf(url) != "-1") {
                    content = content.replaceAll(url, doiHtml);
                } else {
                    content = content + doiHtml;
                }
            }
        } else if (content.indexOf("http") != "-1") {//没有doi:,没有doi.org,没有传入doi和url的情况,但是内容中包含链接
            if (content.indexOf("<a") == "-1" && content.indexOf("<ext-link") == "-1") {
                try {
                    var isConvertHttpUrl = allData.dic.referenceHttpUrl;
                    if ("1" == isConvertHttpUrl) {//仅当后台配置=1时才对内部链接进行处理
                        //使用正则匹配内容中的链接并逐条转为html后替换
                        // var pattern = new RegExp("^(http://|ftp://|https://|www){0,1}[^\u4e00-\u9fa5\\s]*?\\.(com|net|cn|me|tw|fr)[^\u4e00-\u9fa5\\s]*", "g");
                        // var pattern = new RegExp("(http|ftp|https)://(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}(?:[-a-zA-Z0-9@:%_\+.~#?&/=]+)*$", "g");
                        var pattern = /https?:\/\/[\w\-\.]+\.[a-z]+(?:\/[\w\.\/?%&=-]*)?/gi;
                        var results = content.match(pattern);
                        for (var i = 0; i < results.length; i++) {
                            var httpUrl = results[i];
                            if (!isNull(httpUrl) && httpUrl.endsWith(".")) {
                                httpUrl = httpUrl.substring(0, httpUrl.length - 1);
                            }

                            doiHtml = getReferLinkHtml(httpUrl, isIcon, 'url');
                            content = content.replaceAll(httpUrl, doiHtml);
                        }

                    }
                } catch (e) {
                    console.log("doi链接处理未配置!!!")
                }
            } else if (content.indexOf("<ext-link") != "-1") {
                // 使用xlink:href属性时，需要声明xmlns:xlink命名空间
                var xmlWrapper = '<root xmlns:xlink="http://www.w3.org/1999/xlink">' + content + '</root>';
                // 创建DOMParser实例
                var parser = new DOMParser();
                // 解析为XML文档
                var parseTempStr = parser.parseFromString(xmlWrapper, "text/xml");

                // 遍历XML文档，转换ext-link为a标签
                function convertExtLinkToA(node) {
                    if (node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() === 'ext-link') {
                        var aTag = document.createElement('a');
                        // 复制属性
                        for (var i = 0; i < node.attributes.length; i++) {
                            var attr = node.attributes[i];
                            if (attr.name.startsWith('xlink:')) {
                                if (attr.name === 'xlink:href') {
                                    aTag.href = attr.value;
                                }
                            }
                        }
                        // 移动子节点到新创建的a标签中
                        while (node.firstChild) {
                            aTag.appendChild(node.firstChild);
                        }
                        // 替换原节点
                        node.parentNode.replaceChild(aTag, node);
                    } else {
                        for (var i = 0; i < node.childNodes.length; i++) {
                            var child = node.childNodes[i];
                            convertExtLinkToA(child);
                        }
                    }
                }

                // 调用函数进行转换
                convertExtLinkToA(parseTempStr.documentElement);

                // 序列化XML文档为字符串，注意这里直接序列化可能包含XML声明等额外信息，需要进一步处理
                var serializer = new XMLSerializer();
                var modifiedString = serializer.serializeToString(parseTempStr.documentElement);

                // 去除root标签，获取最终字符串
                content = modifiedString.replace(/<root[^>]*>|<\/root>/g, '');
            }
        }
    }
    return content;
}

/**
 * 半角转全角
 *
 * @param input 输入字符串参数
 * @return string 全角字符串
 */
function convert2DoubleByte(input) {
    var result = []
    for (var i = 0; i < input.length; i++) {
        var str = input[i];
        var charStr = input.charCodeAt(i);
        if (str == ' ') result.push('\u3000');
        else if (charStr < 177) {
            charStr = charStr + 65248;
            result.push(String.fromCharCode(charStr));
        }
    }
    return result.join('');
}


/**
 * 全角转半角
 *
 * @param input 输入字符串参数
 * @return string 半角字符串
 */
function convertSingleByte(input) {
    var result = []
    for (var i = 0; i < input.length; i++) {
        var str = input[i];
        var charStr = input.charCodeAt(i);
        if (str == '\u3000') result.push(' ');
        else if (str > '\uFF00' && str < '\uFF5F') {
            charStr = charStr - 65248;
            result.push(String.fromCharCode(charStr));
        }
    }
    return result.join('');
}

/**
 * 判断是否为附图 附表
 * @param tagId 图表的tagId
 * @returns {boolean}
 */
function isNotSupplementary(tagId) {
    if (isNull(tagId)) return false;
    var pattern = new RegExp("^Table[^A-Za-z]+$");
    var pattern1 = new RegExp("^Figure[^A-Za-z]+$");
    var matcher = tagId.match(pattern);
    var matcher1 = tagId.match(pattern1);
    if (allData.journal.publisherId == "shyfyx" || allData.journal.publisherId == "xhcl") {
        // 兼容上海预防医学中T1、F1的图、表
        var pattern2 = new RegExp("^T[^A-Za-z]+$");
        var pattern3 = new RegExp("^F[^A-Za-z]+$");
        var matcher2 = tagId.match(pattern2);
        var matcher3 = tagId.match(pattern3);
        return !isNull(matcher) || !isNull(matcher1) || !isNull(matcher2) || !isNull(matcher3);
    } else {
        return !isNull(matcher) || !isNull(matcher1);
    }
}


/**
 * 替换特殊字符
 */
function replaceXmlSpecialChar(sourceStr) {
    if (isNull(sourceStr)) return "";
    return sourceStr.replace(/©/g, "&#169;")
        .replace(/\*/g, "&#42;")
        .replace(/—/g, "&#8212;")
        .replace(/&gt;/g, "&#62;")
        .replace(/&lt;/g, "&#60;");
}

/**
 * 特殊字符输出转换
 * @param input
 * @returns {*|string}
 */
function convertInut(input) {
    //(<)(&)(>)(")(')
    //&lt，&amp; >" &apos; (')

    if (isNull(input)) return "";
    input = input.replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&apos;");
    return input;
}

/**
 * 处理摘要内容
 *
 * @param str      摘要
 * @param language 语言
 * @return string 处理结果
 */
function convertAbstractHtml(str, language) {
    if (isNull(str)) return "";
    var secReplace = "";
    var titleReplace = "";

    str = str.replace(/<italic>/g, "<i>").replace(/<\/italic>/g, "</i>")
        .replace(/<bold>/g, "<b>").replace(/<\/bold>/g, "</b>")
        .replace(/<underline>/g, "<u>").replace(/<\/underline>/g, "</u>") //下划线
        .replace(/<overline>/g, "<span style=\"text-decoration:overline\">").replace(/<\/overline>/g, "</span>") //上划线
        .replace(/<strike>/g, "<s>").replace(/<\/strike>/g, "</s>")//中划线、删除线
        .replace(/<p>/g, "").replace(/<\/p>/g, "")//p标签
        .replace(/<title\/>/g, ""); //空title

    try {
        if ("en" == language) {
            secReplace = allData.dic.abstractSecReplaceEn;
            titleReplace = allData.dic.abstractTitleReplaceEn;
        } else {
            secReplace = allData.dic.abstractSecReplaceCn;
            titleReplace = allData.dic.abstractTitleReplaceCn;
        }
    } catch (e) {
        console.log("方法convertAbstractHtml错误!摘要中sec,title替换标签未配置!!!")
    }

    if (isNull(secReplace)) {//默认替换为div
        str = str.replace(/<sec>/g, "<div>").replace(/<\/sec>/g, "</div>");
    } else {
        var secReplaceArr = secReplace.split("\\$\\$\\$");
        var secReplace1 = secReplaceArr[0];
        var secReplace2 = secReplaceArr[1];
        str = str.replace(/<sec>/g, secReplace1).replace(/<\/sec>/g, secReplace2);
    }

    if (isNull(titleReplace)) {//默认替换为b
        str = str.replace(/<title>/g, "<b>").replace(/<\/title>/g, "</b>&nbsp;");
    } else {
        var titleReplaceArr = titleReplace.split("\\$\\$\\$");
        var titleReplace1 = titleReplaceArr[0];
        var titleReplace2 = titleReplaceArr[1];
        str = str.replace(/<title>/g, titleReplace1).replace(/<\/title>/g, titleReplace2);
    }

    return convertMathHtml(str);
}


/**
 * 获取文章类型转换后的输出
 */
function getArticleTypeOutput(input, language) {
    if (isNull(input)) {
        try {
            //获取配置
            var settingVal = allData.dic.articleTypeTrans;
            //配置格式为 文章类型(储存):文章类型(中文输出),文章类型(英文输出);
            if (!isNull(settingVal)) {
                var convertMap = new Map();
                //解析配置文件
                var types = settingVal.split(";");
                for (var type in types) {
                    if (!isNull(type)) {
                        var typeToTrans = type.split(":");
                        var cnToEn = typeToTrans[1].split(",");
                        if ("en" == language) {
                            convertMap.put(typeToTrans[0], cnToEn[1]);
                        } else {
                            convertMap.put(typeToTrans[0], cnToEn[0]);
                        }
                    }
                }
                //获取文章类型所对应的输出
                return convertMap.get(input);
            }
        } catch (e) {
            console.log("方法getArticleTypeOutput错误!字典中articleTypeTrans未配置!!!")
        }

    }
    return "";
}

/**
 * 获取参考文献格式 1顺序编码制   2作者出版年制
 */
function getReferenceType(refLable) {
    return !isNull(refLable) && (/b[0-9]{1,3}/.test(refLable) || /[0-9]{1,3}/.test(refLable)) ? 1 : 2;
}

/**
 *  删除Html标签
 *  @return string
 */
function delHTMLTag(htmlStr) {
    if (isNull(htmlStr)) return "";

    var regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式
    var regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
    var regEx_html = "<[^>]+>"; //定义HTML标签的正则表达式
    //var regEx_space = "\\s*|\t|\r|\n";//定义空格回车换行符
    var regEx_space = "\t|\r|\n";//定义空格回车换行符

    htmlStr = replaceRegx(htmlStr, "", regEx_script);
    htmlStr = replaceRegx(htmlStr, "", regEx_style);
    htmlStr = replaceRegx(htmlStr, "", regEx_html);
    htmlStr = replaceRegx(htmlStr, "", regEx_space);

    return htmlStr.trim();
}

/**
 * 判断文章内容中是否有图片
 */
function isImg(context) {
    if (isNull(context)) return false;
    if (context.indexOf("img ") != "-1" && context.indexOf("src=") != "-1") {
        return true;
    }
    return context.indexOf("graphic") != "-1";
}


/**
 * 判断是否包含中文字符
 */
function containsChinese(input) {
    if (isNull(input)) return false;

    var result = []
    for (var i = 0; i < input.length; i++) {
        var str = input[i];
        var charStr = input.charCodeAt(i);
        if ((charStr >= 0x4e00) && (charStr <= 0x9fbb)) {
            return true;
        }
    }
    return false;
}


/**
 * 组装参考文献作者信息
 * @param surNames 单条参考文献的surNames
 * @param givenNames 单条参考文献的givenNames
 * @returns {null|*[]}
 */
function buildRefAuthor(surNames, givenNames) {
    var containsChinese = containsChinese(surNames) || containsChinese(givenNames);
    var surNameList = surNames.split("(\\%\\$\\%)");
    var givenNameList = givenNames.split("(\\%\\$\\%)");
    var authors = [];
    for (var i = 0; i < surNameList.length; i++) {
        if (!isNull(surNameList[i])) {
            var author = surNameList[i];
            //姓名同时存在时进行拼接
            if (givenNameList.length == surNameList.length)
                author = containsChinese ? surNameList[i] + givenNameList[i] : surNameList[i] + " " + givenNameList[i];
            authors.push(author);
        }
    }
    return authors.length == 0 ? null : authors;
}


/**
 * 判断字符串中是否包含数字
 *
 * @param inputStr
 * @return
 */
function isContainsNumber(inputStr) {
    if (!isNull(inputStr)) {
        var p = new RegExp(".*\\d+.*", "g");
        if (p.test(inputStr)) {
            return true;
        }
    }
    return false;
}

/**
 * 处理页码中转页等问题
 * @param pageNum 页码
 * @returns {*|string}
 */
function getSinglePageNum(pageNum) {
    if (!isNull(pageNum)) {
        if (pageNum.indexOf("(") != "-1") {
            pageNum = pageNum.substring(0, pageNum.indexOf("("));
        }
        if (pageNum.indexOf(",") != "-1") {
            pageNum = pageNum.substring(0, pageNum.indexOf(","));
        }
        if (pageNum.indexOf("-") != "-1") {
            pageNum = pageNum.substring(0, pageNum.indexOf("-"));
        }
        return pageNum.trim();
    }
    return "0";
}


/**
 * 输出文章页码
 * @param fpage 首页码
 * @param lpage 尾页码
 * @param pageLength 页码长度限制,一般为6,此为旧版针对elocationId设置,新版已丧失使用场景
 * @returns {string}
 */
function outputPages(fpage, lpage, pageLength) {
    if (isNull(pageLength) || isNull(fpage)) {
        return "";
    }
    var result = "";
    if (fpage.length < pageLength) {
        if (fpage == "0" || fpage == "00") {
            return "";
        }
        result = fpage;
        if (!isNull(lpage)) {
            result = result + "-" + lpage;
        }
    } else {
        result = fpage.substring(0, pageLength);
    }

    return result;
}

/**
 * 判断是否为doi
 * @param str
 * @returns {boolean}
 */
function isDoi(str) {
    var doiReg = new RegExp("^10.\\d{4,9}/[-._;()/:a-zA-Z0-9]+$");
    if (!isNull(str)) {
        return doiReg.test(str);
    }
    return false;
}

/**
 * 把字符串转成首字母大写,其余小写的形式
 */
function shiftString(sourceStr) {
    if (isNull(sourceStr)) return "";
    sourceStr = sourceStr.replace(/ /g, "").trim();
    var tempString = sourceStr.toLowerCase();
    return tempString[0].toUpperCase() + tempString.substring(1);
}

/**
 * 将作者地址信息中符号tag替换为数字tag
 */
function replaceAffilTag(addressTag) {
    if (isNull(addressTag)) return "";
    return addressTag.replace(/①/g, "1").replace(/②/g, "2").replace(/③/g, "3")
        .replace(/④/g, "4").replace(/⑤/g, "5").replace(/⑥/g, "6")
        .replace(/⑦/g, "7").replace(/⑧/g, "8").replace(/⑨/g, "9")
        .replace(/a/g, "1").replace(/b/g, "2").replace(/c/g, "3")
        .replace(/d/g, "4").replace(/e/g, "5").replace(/f/g, "6")
        .replace(/g/g, "7").replace(/h/g, "8").replace(/i/g, "9")
        .replace(/j/g, "10").replace(/k/g, "11").replace(/l/g, "12")
        .replace(/m/g, "13").replace(/n/g, "14").replace(/o/g, "15");
}


/**
 * 获取页码输出,优先elocationid,其次pageRange,最后用fpagelpage拼装
 */
function getPageOutput(elocationId, pageRange, fpage, lpage, pageLength) {

    if (!isNull(elocationId)) {
        return elocationId;
    }

    if (!isNull(pageRange)) {
        return pageRange;
    }

    return outputPages(fpage, lpage, pageLength);
}


/**
 * 查找字符串中包含字符串个数
 *
 * @param str     文本
 * @param findStr 要查找的字符串
 * @param isInit  是否内部调用，模式true
 */
function stringNumbers(str, findStr, isInit) {
    var counter = 0;
    if (isInit) {
        counter = 0;
    }
    var findStrSize = findStr.length;
    if (str.indexOf(findStr) == -1) {
        return 0;
    } else if (str.indexOf(findStr) != -1) {
        counter++;
        stringNumbers(str.substring(str.indexOf(findStr) + findStrSize), findStr, false);
        return counter;
    }
    return 0;
}

/**
 * 数字转指定编号
 * @param number
 * @returns {string}
 * @constructor
 */
function Number2ListItem(number) {
    if (isNull(number)) return "";
    var tmp = "0,&#9312;,&#9313;,&#9314;,&#9315;,&#9316;,&#9317;,&#9318;,&#9319;,&#9320;,&#9321;,&#9322;," +
        "&#9323;,&#9324;,&#9325;,&#9326;,&#9327;,&#9328;,&#9329;,&#9330;,&#9331;,&#12881;,&#12882;" +
        ",&#12883;,&#12884;,&#12885;,&#12886;,&#12887;,&#12888;,&#12889;,&#12890;,&#12891;" +
        ",&#12892;,&#12893;,&#12894;,&#12895;,&#12977;,&#12978;,&#12979;,&#12980;,&#12981;,&#12982;,&#12983;," +
        "&#12984;,&#12985;,&#12986;,&#12987;,&#12988;,&#12989;,&#12990;,&#12991;,(51),(52),(53),(54),(55),(56),(57),(58),(59)," +
        "(60),(61),(62),(63),(64),(65),(66),(67),(68),(69)," +
        "(70),(71),(72),(73),(74),(75),(76),(77),(78),(79)," +
        "(80),(81),(82),(83),(84),(85),(86),(87),(88),(89),(90)";
    var tmpIndex = tmp.split(",");
    if (number > 90) {
        return "";
    }
    return tmpIndex[number];
}

/**
 * 转换作者简介中的邮箱为可点击的邮箱地址
 * 有mailto： 标识的不转换
 *
 * @param input
 * @return
 */
function convertAuthorEmailHref(input) {

    //空的就直接返回
    if (isNull(input)) return input;

    //包含mailto的直接返回
    if (input.indexOf("mailto:") != "-1") return input;

    var emailHref = input;
    var reg = "[A-Za-z0-9\\u4e00-\\u9fa5]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+";

    try {
        var regSetting = allData.dic.excelAuthorEmailHrefConvert;
        if (!isNull(regSetting)) {
            reg = regSetting;
        }
    } catch (e) {
        console.log("方法convertAuthorEmailHref错误!字典中excelAuthorEmailHrefConvert未配置!!!")
    }


    var pattern = new RegExp(reg, 'g');                //编译正则表达式
    var list = input.match(pattern);
    if (!list) {
        return;
    } else {
        for (var i = 0; i < list.length; i++) {
            var email = list[i];

            if (!isNull(email)) {
                emailHref = emailHref.replace(new RegExp(email, 'g'), "<a href=\"mailto:" + email + "\">" + email + "</a>");
            }
        }
    }

    return emailHref;
}

/**
 * 替换表格中的图片路径
 * @param {*} content 表格内容
 * @param {*} article 文章
 */
function repalceTableImg(content, article) {
    if (!content) {
        return;
    } else {
        var srcStart = ""
        if (article.articleState && article.articleState != "") {
            srcStart = filePath + "journal/article/" + allData.journal.publisherId.toLowerCase() + "/newcreate/";
        } else {
            srcStart = filePath + "journal/article/" + allData.journal.publisherId.toLowerCase() + "/" + article.year + "/" + article.issue + "/";
        }
        return content.replace(/src="/g, 'src="' + srcStart);
    }
}

/**
 * 判断是否是数字类型
 */
function isNumber(obj) {
    return typeof parseInt(obj) === 'number' && !isNaN(parseInt(obj));
}

/**
 * 去除普通空格（\s）、制表符、换行符和 &nbsp;（非断空格）
 */
function removeSpacesAndNbsp(inputString) {
    // 使用正则表达式匹配普通空格、制表符、换行符和&nbsp;
    var regex = /[\s\u00A0]+/g;
    return inputString.replace(regex, '');
}

/**
 * 数字转带圈的数字，仅支持1-50，50后的普通字符集没有
 */
function arabicToCircledNumber(arabicNumber) {
    if (isNull(arabicNumber)) return "";
    if (arabicNumber >= 1 && arabicNumber <= 50) {
        const circledNumbers = [
            '①', '②', '③', '④', '⑤',
            '⑥', '⑦', '⑧', '⑨', '⑩',
            '⑪', '⑫', '⑬', '⑭', '⑮',
            '⑯', '⑰', '⑱', '⑲', '⑳',
            '㉑', '㉒', '㉓', '㉔', '㉕',
            '㉖', '㉗', '㉘', '㉙', '㉚',
            '㉛', '㉜', '㉝', '㉞', '㉟',
            '㊱', '㊲', '㊳', '㊴', '㊵',
            '㊶', '㊷', '㊸', '㊹', '㊺',
            '㊻', '㊼', '㊽', '㊾', '㊿'
        ];
        return circledNumbers[arabicNumber - 1];
    } else {
        return arabicNumber.toString(); // 超出范围的数字原样返回
    }
}

/**
 * 过滤文章的作者，把文章的英文作者authorEnList追加到article上
 */
function articleAuthors2AhthorsEn(article) {
    if (article && article.authors && article.authors.length) {
        article.authorEnList = [];
        $.each(article.authors, function (i, author) {
            if (author.authorNameEn) {
                article.authorEnList.push(author);
            }
        })
    }
    return article;
}
/**
 * 过滤文章的作者，把文章的中文作者authorCnList、英文作者authorEnList追加到article上
 */
function articleAuthors2AuthorsCnOrAuthorsEn(article) {
    if (article && article.authors && article.authors.length) {
        article.authorCnList = [];
        article.authorEnList = [];
        $.each(article.authors, function (i, author) {
            author.authorNameEn ? article.authorEnList.push(author) : '';
            author.authorNameCn ? article.authorCnList.push(author) : '';
        })
    }
    return article;
}
/**
 * 过滤文章的keywords，把文章的中文作者keywordsCnList、英文作者keywordsEnList追加到article上
 */
function articleKeyword2KeywordCnOrKeywordEn(article) {
    if (article && article.keywords && article.keywords.length) {
        article.keywordCnList = [];
        article.keywordEnList = [];
        $.each(article.keywords, function (i, keyword) {
            keyword.keywordEn ? article.keywordEnList.push(keyword) : '';
            keyword.keywordCn ? article.keywordCnList.push(keyword) : '';
        })
    }
    return article;
}
/**
 * 转义字符串中的单引号、双引号
 */
function escapeString(str) {
    if (str) {
        return str.replace(/[\"\']/g, function (match) {
            switch (match) {
                case '\"': return '&quot;';
                case "\'": return '&#39';
            }
        });
    }
}

if (!String.prototype.replaceAll) {
    String.prototype.replaceAll = function (str, newStr) {
        // If a regex pattern
        if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {
            return this.replace(str, newStr);
        }
        // If a string
        return this.replace(new RegExp(str, 'g'), newStr);
    };
    template.defaults.imports.replaceAll = String.prototype.replaceAll;
}

/**
 * 替换内容中的图片路径
 */
function replaceImg(context, path) {
    if (context && path) {
        // 创建一个正则表达式，匹配<img src="...">中的src属性
        var regex = /<img\s+src="([^"]+)"/g;

        // 通过循环匹配所有的<img>标签，并替换其中的src属性
        var updatedContext = context;
        var match = regex.exec(context);
        while (match !== null) {
            var originalSrc = match[1];
            var replacement = '<img src="' + path + originalSrc + '"';
            updatedContext = updatedContext.replace('<img src="' + originalSrc + '"', replacement);
            match = regex.exec(context);
        }

        return updatedContext;
    }
}

if (typeof Object.assign !== 'function') {
    Object.defineProperty(Object, 'assign', {
        value: function (target) {
            'use strict';
            if (target == null) {
                throw new TypeError('Cannot convert undefined or null to object');
            }

            var to = Object(target);

            for (var index = 1; index < arguments.length; index++) {
                var nextSource = arguments[index];

                if (nextSource != null) {
                    for (var nextKey in nextSource) {
                        if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
                            to[nextKey] = nextSource[nextKey];
                        }
                    }
                }
            }
            return to;
        },
        writable: true,
        configurable: true
    });
}
/**
 * 对作者中的通讯作者以通讯作者的correspSort排序，如果没有，则默认排序
 * @param {*} authors 作者数组
 */
function sortCorresper(authors) {
    if (!authors) return authors;
    var itemsWithIndex = [];
    var itemsWithoutIndex = [];

    for (var i = 0; i < authors.length; i++) {
        var item = authors[i];
        if (typeof item.correspSort !== 'undefined') {
            itemsWithIndex.push(item);
        } else {
            itemsWithoutIndex.push(item);
        }
    }

    itemsWithIndex.sort(function (a, b) {
        return a.correspSort - b.correspSort;
    });

    return itemsWithIndex.concat(itemsWithoutIndex);
}

/**
 * 校验检索词输入状态
 * @return
 */
function checkSearchNew(form) {
    var searchText = $(form).find("input[name='q']").val().replace(" ", "");
    if (isNull($("#language").val()) || $("#language").val() == "cn") {
        if (typeof (searchText) == "undefined" || searchText == "" || searchText == "请输入检索词！") {
            alert("请输入检索词！");
            return false;
        } else {
            if ($(".formToken").length && $(".formToken").val() != "") {
                return true;
            }
        }
    } else if ($("#language").val() == "en") {
        if (typeof (searchText) == "undefined" || searchText == "" || searchText == "Please enter the search word") {
            alert("Please enter the search word");
            return false;
        } else {
            if ($(".formToken").length && $(".formToken").val() != "") {
                return true;
            }
        }
    }
    return false;
}

function kb2Mb(value) {
    var n = 1;
    if (typeof value === 'number' && !isNaN(value) && value != 0) {
        return Math.round(value / 1024 * Math.pow(10, n)) / Math.pow(10, n);
    } else {
        return 0;
    }
}

/**
 * doi引文转cstr引文
 * @param {*} doiCitation doi引文
 * @param {*} CSTR CSTR号，一般可直接使用doi号
 * @return CSTRCitation
 */
function doiCitation2CSTRCitation(doiCitation, CSTR) {

    // 将字符串包裹在一个临时的 div 中
    var $doicitation = $('<div>' + doiCitation + '</div>');

    // 使用 jQuery 选择器获取 a 标签
    var $a = $doicitation.find('a');
    if ($a.length > 0) {
        var href = $a.attr('href');
        var text = CSTR ? CSTR : $a.text();

        if (href.includes('doi')) {
            var cstrHref = 'https://www.cstr.cn/' + text;

            // 更新 a 标签的 href 和文本
            $a.attr('href', cstrHref);
            $a.text(text);

            // 替换 "DOI:" 为 "CSTR:"
            $doicitation.html($doicitation.html().replace('DOI:', 'CSTR:'));
        }
    }

    // 移除临时的 div 并返回处理后的 HTML
    return $doicitation.html();
}

dayjs.extend(window.dayjs_plugin_relativeTime);
template.defaults.imports.filterHTMLTag = filterHTMLTag;
template.defaults.imports.startsWith = String.prototype.startsWith;
template.defaults.imports.endsWith = String.prototype.endsWith;
template.defaults.imports.trim = String.prototype.trim;
template.defaults.imports.split = String.prototype.split;
template.defaults.imports.fromCharCode = String.fromCharCode;
template.defaults.imports.isNull = isNull;
template.defaults.imports.convertLink = convertLink;
template.defaults.imports.isNotSupplementary = isNotSupplementary;
template.defaults.imports.getReferLinkHtml = getReferLinkHtml;
template.defaults.imports.isContainsByDoi = isContainsByDoi;
template.defaults.imports.replaceRegx = replaceRegx;
template.defaults.imports.referenceDOIReplace = referenceDOIReplace;
template.defaults.imports.convertMathHtml = convertMathHtml;
template.defaults.imports.delHTMLTag = delHTMLTag;
template.defaults.imports.convertAuthorEmailHref = convertAuthorEmailHref;
template.defaults.imports.outputPages = outputPages;
template.defaults.imports.repalceTableImg = repalceTableImg;
template.defaults.imports.convertAbstractHtml = convertAbstractHtml;
template.defaults.imports.isNumber = isNumber;
template.defaults.imports.removeSpacesAndNbsp = removeSpacesAndNbsp;
template.defaults.imports.arabicToCircledNumber = arabicToCircledNumber;
template.defaults.imports.articleAuthors2AhthorsEn = articleAuthors2AhthorsEn;
template.defaults.imports.articleAuthors2AuthorsCnOrAuthorsEn = articleAuthors2AuthorsCnOrAuthorsEn;
template.defaults.imports.articleKeyword2KeywordCnOrKeywordEn = articleKeyword2KeywordCnOrKeywordEn;
template.defaults.imports.escapeString = escapeString;
template.defaults.imports.encodeURIComponent = encodeURIComponent;
template.defaults.imports.decodeURIComponent = decodeURIComponent;
template.defaults.imports.replace = String.prototype.replace;
template.defaults.imports.replaceImg = replaceImg;
template.defaults.imports.JSON = JSON;
template.defaults.imports.sortCorresper = sortCorresper;
template.defaults.imports.kb2Mb = kb2Mb;
template.defaults.imports.doiCitation2CSTRCitation = doiCitation2CSTRCitation;