Greasy Fork

Greasy Fork is available in English.

我的搜索

订阅式搜索,打造属于自己的搜索引擎!

当前为 2023-01-17 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         我的搜索
// @namespace    http://tampermonkey.net/
// @version      3.2.0
// @description  订阅式搜索,打造属于自己的搜索引擎!
// @license MIT
// @author       zhuangjie
// @match      *://*/*
// @exclude  http://127.0.0.1*
// @exclude  http://localhost*
// @exclude  http://192.168.*
// @icon         data:image/png;base64,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
// @require      https://cdn.bootcdn.net/ajax/libs/jquery/3.6.2/jquery.min.js
// @grant        window.onurlchange
// @grant        GM_setValue
// @grant        GM_getValue
// @grant GM_deleteValue
// @grant GM_registerMenuCommand

// ==/UserScript==

(function() {
    'use strict';
    // 模块一:快捷键触发某一事件 (属于触发策略组)
    // 模块二:搜索视图(显示与隐藏)(属于搜索视图组)
    // 模块三:触发策略组触发策略触发搜索视图组视图
    // 模块四:根据用户提供的策略(策略属于数据生成策略组)生成搜索项的数据库
    // 模块五:视图接入数据库

    // 【函数库】
    // 加载样式
    function loadStyleString(css) {
        var style = document.createElement("style");
        style.type = "text/css";
        try {
            style.appendChild(document.createTextNode(css));
        } catch(ex) {
            style.styleSheet.cssText = css;
        }
        var head = document.getElementsByTagName('head')[0];
        head.appendChild(style);
    }
    // 数据缓存器
    let cache = {
        get(key) {
            return GM_getValue(key);
        },
        set(key,value) {
            GM_setValue(key,value);
        },
        remove(key) {
          GM_deleteValue(key);
        },
        cookieSet(cname,cvalue,exdays) {
           var d = new Date();
            d.setTime(d.getTime()+exdays);
            var expires = "expires="+d.toGMTString();
            document.cookie = cname + "=" + cvalue + "; " + expires;
        },
        cookieGet(cname) {
           var name = cname + "=";
           var ca = document.cookie.split(';');
            for(var i=0; i<ca.length; i++)
            {
                var c = ca[i].trim();
                if (c.indexOf(name)==0) return c.substring(name.length,c.length);
            }
            return "";
        }
    }
    // 加载全局样式
    loadStyleString(`
        .searchItem {
            background-image: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD//gAfQ29tcHJlc3NlZCBieSBqcGVnLXJlY29tcHJlc3P/2wCEAAQEBAQEBAQEBAQGBgUGBggHBwcHCAwJCQkJCQwTDA4MDA4MExEUEA8QFBEeFxUVFx4iHRsdIiolJSo0MjRERFwBBAQEBAQEBAQEBAYGBQYGCAcHBwcIDAkJCQkJDBMMDgwMDgwTERQQDxAUER4XFRUXHiIdGx0iKiUlKjQyNEREXP/CABEIAMgAyAMBIgACEQEDEQH/xAAdAAEAAgMBAQEBAAAAAAAAAAAABwgFBgkEAwEC/9oACAEBAAAAAL/AAAAAAAAAAAAAAAAAAGI5J9a8wAABzbutJ0d8Re3UiYqMZjAAHLnCdYI84i9upDg30zUAAI/4+9J5j4c9wvZDViPaABzexl+N8o/8ryx3Ikb/ANSNh4GyNgABG3PyI7q3TAh+Fttn7PAArZHl1gIdz8hfoA8GuvvtQBifmyv1AcyIeOsu5gYKjxvtwQHg1x9dtAMP/LJegAK96PbwCum4S1+gBHtG4tt9boCvNct8tXtgAoZgrr7zU/8AbX6xs9alldcq37LdgAaZzUvLLXNTpZHFN+g2zgACgOL6Ia3zb6SbJRbJXZAAFEbab1rPNvpJs2nVuuEAAB46IXryAAAAAAAAAAAAAAAAAAB//8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAgBAhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAgBAxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//8QALRAAAQQCAAMGBwEBAQAAAAAABAIDBQYBBwAIFRARFhcwVhITFCA2N0BgGCT/2gAIAQEAAQwA/wBfcbEzUKnY7O81l1v/AKb3V13rvjJ7vp9kYtlSrdnYZy0j+O780OynrbIrrMozGxGldnM7RprEs7htuX43h+n9kdmj/wBP637LJMogI5RCe5RMdeJtg1t0wn54/wDBzHa0coV5JkA2c9E0RstWtbyIYU5nEKhaHEIcbWlaN4fp/ZHZo/8AT+t+M5xjGc5z3YtU3malHHUZ/wDNToTMtKIcdTn6X+Db2uxdl0qSgVYRg8sQkAokExlTJPK1s7NsqrlPliMrl9wAFSurNhR4DWXSeNRBFxGq9fR5zWWirzM5jQUxw6+4htC3VoabTlS67DohIxkTuxl71eZe22SR2PMV4sslmI1vzC3WiLZCOfVNwmv9sUvZA6VwUjhB/HMrouckpzN7pEM6dxyuaquMBajrjZYgyJF48kNT+JPFvgWN6xxeYGRLPbkQR3SG6VVimSuqygymscTtqhq01nJxHxEWK/zM3lbI68hBa1mpVFiFjkkOui+lsrTdQ2Yzh2VYULK7H0fddcrcKLF6hDClFAkMlhEujkaR5jZuRm4el3jKS/Qu2xTWDTIWEzhnDrrrzi3XnFOOVykTVjylxlr5Adbp8RWUZcGRl0r01oQ4hbbiMKRsvlkq9oy/K1RxuCltW8sdohLfE2K3GgtC/faNZyh0uXIxLzC2q9rWMictkyqknGYxhOMJTjGMelOWus1nDObDPgR3HmxrP33CcebGs/fcJwBsnXp5DQYN1hXifRet1VCdWOTYo9D3jmne5Y7jxzTvcsdxGzcNMJc6TKClejvrrPmpaes/N7+3U3WfLendf+PqH33vMgmoT+YvC8ldusvr/G0L0/4+/wBCcqlZs2GcWGAAkePKfWfsSE48p9Z+xITgXXGvY4lsuPpcMyR6JNQqb7zjz9cj1u+Bqd7ajuPA1O9tR3EfDw0MlzpMYKJ6a1obQpxxWEpv/MTXK1l+OrDaJmT1tzFWOYtUZA2gMJ0b77ruSajJ86JgRhUM0/dENOKaBnkIjDkqStKVoVjKfT2Btaq65aw3JvKJlL/uS4X9Tg5RP0MSMMQY+0KIO4+/p3QUwBMRVuuWEi4+/ZOopIuRPsVaxh/DzDwzrjBLK2nahsqx1FSGWH/qo+nbCgLm38sF1TB3pcw9RszV+kZ9QJRMZQNEXC6LaKNYXDxFK1nUdfjpRCAYWbxvLbEtHy2ajVZRwTjl+2JZ5exFVmckipIfjzJonVOi+KAfreN4XuxRc6NXoY8gBjTWzpMyVxWLLIuFdlqolet7GcSgmElXDVFiq6nSR28yMbpyAlzLfHyrDDyAPV2RcRqHVDpheU5MJIfLIfLJdU4/y/UXNbr7llkWcpk78WSDSrUWI7lt7iglkHUmqllOZcf3fSczsCifAZyo9h94V9kkdzLb2vrczc62FKJynBX8G7b4q5Wt4QR7OYnUdEXe7YOM+33xaEpQlKEJwlOyPwG4dmt/wGn8KSlaVIWnCk7QpiqZZnx2EZxG6fuaqpZmRSXM4jP4LNoK9gzxI0JFYPjdV0JqgVdmOcyhclxsj8BuHZrf8Bp/ZsilIu9edAb+BB9Z0ncnZ8NMyAgMD+OxxSJyvzMJl35WPJvYvVOl+HXe+Ai0QEBDQeHfm/7D/8QAPRAAAgECAwMIBQsEAwAAAAAAAQIDBBEAEiEFEzEQFDAyQUJRYRUiQGNxFiNSYnJzdIGCsrMgJGDRQ5GS/9oACAEBAA0/AP8AL9lbNqa0xA2MhhQsE8sxxvM/MtzHzLL9DdY2rs2mrREdd2ZkDFPyPslJWSxU1MKaGXexI1rzGQMSWxSOKbaUCaBZgNHX6kg5Pk/W/wAfJ8n6L+PkkOSBTwzeJ8hhnG8jZVACk90gaW9h268lZSN2Ryk3mhxtHLR7SXwjY+rN8Yjh1DKym4IPAg4+T9b/AB8nyfov48AXJOIbxwj6oOrfnimIkkPYT3V9hQc52dM3/HVRj1fgH6rYp5XhmjcWZJIzlZT5gjGwI1ETMbtLQcEPxi6mJtg14jjXi7CEnKOSHYFAJY24oxhBynFWpzkcVi4H/vhh2CqBxJOgGD68zeLn/XTbOWCOkpLlImDxBzKRoGLE4uAaSrkJkjX3MpuRgIDLs+pslTF8F74815KxANqUdIC84nXhMkY1cPiKglpIIKyJoJp5JiO49iEUDk3+/wB7lbd76+bebm+7z31vbkaIRssalmUr5DsOIh8xHILMXPeIPC3IRdaePWRv9DzOL6RQtZmH134nFSsgkjdiyrkQsHF+BFujjjyQ7SprCZQOCuODpgHTaNGpMYHvV4x4ibNHLC5SRGHarLYg4rZRS0e0+E4mfSNJuxw3QQOYpqni5ddGCeAGHN2dyWYnxJOO2pmBC/pHFsMtnqJeuR4Ad0dIwKsrC4IPEEYclzCqXoZm80GsfxTGyquKrhhpZDNJNNC2ZOwBV6CrmaV0lYoyO5ufG4wLEIR8wh+B6354AsAOjlvuxVVCRF/shiCcfjI8fjI8SmyRrWRZmPgovqeiU2dDUJdT4HH364+/XCdYQSq5X4gdDvk5pnvl5pkG63fl/R6Ojz7y+fd67rPfXNktfoOakLk62QkB7W7ct/6N42/y8Nxb183l0MV92aqnSUp9ksCRj8HHj8HHiI3SVaOLMh8VNtD0Tm7sadNTj7hcfcLh+uYIlQt8SOPRqCWYmwAHacJdTIGtRxMPFxrIfJcbTqo6WKamjMTxSzHKnaQy9BQzvBJJMhkaR4zZu0WGGIAkLf2znyY9T88EAgjUEHpHTPDs+nsZSDwZzwRcE6UFKxEZHvW4yYlbLHFEhd3PgqrqTijlFTS7O4zGZNUeXsUL0FS5nno+EgkbV2j8QcIbOkilWU+BBx20c5JQfYPFMIl5KOXSQDxU94dHXxQGCeOMvHHu4hGYjbqkEYvrU1UZEjj3URsTgraWuns9RJ+rur5LyUy/39VTEpLvTwiRxqoXElG9RFLUyNLLE8RHfNyVIPJnyZc/qZ72y7zqX8r8kdKk8klO5jkleQnvCxsMVCnmVROc8olHGNnOpDcgWyVcNkmT8+0eRwCfn4FJdB7xNSMUYleeexCEMhUID2liemcbiiibv1DjT4heJxNI0sjtxZ3NyT5k42xGpjDCxio+KD4ydbEWyqpkccQd2dRyS7LpWdzxY7sanGykYyADWSl4t/462IZFkjdeKupuCPMHCDc1kY7k6DXTwbiPYdlM9NTAcJHvaSXFFaqrm7CgOkf6zhQAABYADsGPRNV+w8noml/YMMCCCLgg4q71FEfBCdY/0HG02SnnHYjk2jk9hlnbmtQk0SARsdBIHIKkYqSJ6+VOBlI0QfVQcnomq/YeT0TS/sHJAd9RSvoBJ2qfJ8QVCPPM00b50Q3tGEJJJ9krqKenD/RMilQcbzJznMvNrX6+88MUNHBTl/pmNQCf8w//xAAUEQEAAAAAAAAAAAAAAAAAAABw/9oACAECAQE/ACn/xAAUEQEAAAAAAAAAAAAAAAAAAABw/9oACAEDAQE/ACn/2Q==);
            background-size: 100% 100%;
            background-clip: content-box;
            background-origin: content-box;

        }
        #my_search_view {
           animation-duration: 1s;
           animation-name: my_search_view;
        }
        .resultItem {
           animation-duration: 0.5s;
           animation-name: resultItem;
        }
        @-webkit-keyframes my_search_view{

   0%{width: 0px;}

   50%{width: 60%;}

   100%{width: 80%;}

}

        @-webkit-keyframes resultItem{

   0%{opacity: 0;}

   40%{opacity: 0.6;}
   50%{opacity: 0.7;}
   60%{opacity: 0.8;}

   100%{opacity: 1;}

}

    `)

    //防抖函数模板
    function debounce(fun, wait) {
        let timer = null;
        return function (...args) {
            // 清除原来的定时器
            if (timer) clearTimeout(timer)
            // 开启一个新的定时器
            timer = setTimeout(() => {
                fun.apply(this, args)
            }, wait)
        }
    }
    // 判断是否为指定指令
    function isInstructions(val,cmd) {
        return val == ":"+cmd;
    }
    // 全局注册表
    let ERROR = {
        tell(info) {
            console.error("ERROR " + info)
        }
    }

    //registry.searchData.SEARCH_DATA_KEY
    let registry = {
        view: {
            viewVisibilityController: () => { ERROR.tell("视图未初始化,但你使用了它的未初始化的注册表信息!") },
            viewDocument: null,
            setButtonVisibility: () => { ERROR.tell("按钮未初始化!") },
            titleHandlerFuns: []

        },
        searchData: { //registry.searchData.getDataLength
            data: [],
            subscribeKey: "subscribeKey",
            // 事件函数
            dataChange: [],
            // 持久化Key
            SEARCH_DATA_KEY: "SEARCH_DATA_KEY",
            // 搜索搜索出来的数据
            searchData: [],
            pos: 0,
            getFaviconAPI: "https://ico.di8du.com/get.php?url=",

            getDataLength(target = "SELECT") {
                // 持久化的数据项数
                let cacheData = cache.get(this.SEARCH_DATA_KEY) == null?[]:cache.get(this.SEARCH_DATA_KEY).data;
                let tmpData = this.data.length === 0?cacheData:this.data;
                let dataLength = (tmpData == null)?0:tmpData.length;
                let inputDesc = `我的搜索(❤️ 可以搜索“申请录入”让数据库更丰富哦~)`;
                if(target == "UPDATE") {
                    setTimeout(()=>{
                        $("#search_input").attr("placeholder",this.getDataLength());
                    },1200)
                    return `可以搜索( 🔁 数据库更新到 ${dataLength}条)`;
                }
                return inputDesc;

            }

        }
    }
    let dao = {}
    function showControlButton() {
        // 会显示一个按钮
        // 初始化按钮
        let viewDocument = registry.view.viewDocument;
        if(viewDocument == null) return;
        // 视图已初始化,可以显示按钮

    }
    function hideControlButton() {
       // 隐藏掉输入框右边按钮
    }

    // 实现模块一:使用快捷键触发指定事件
    function triggerAndEvent(goKeys = "ctrl+alt+s", fun, isKeyCode = false) {
        // 监听键盘按下事件

        let handle = function (event) {
            let isCtrl = goKeys.indexOf("ctrl") >= 0;
            let isAlt = goKeys.indexOf("alt") >= 0;
            let lastKey = goKeys.replaceAll("alt", "").replaceAll("ctrl", "").replace(/\++/gm,"").trim();
            // 判断 Ctrl+S
            if (event.ctrlKey != isCtrl || event.altKey != isAlt) return;
            if (!isKeyCode) {
                // 查看 lastKey == 按下的key
                if (lastKey.toUpperCase() == event.key.toUpperCase()) fun();
            } else {
                // 查看 lastKey == event.keyCode
                if (lastKey == event.keyCode) fun();
            }

        }
        // 如果使用 document.onkeydown 这种,只能有一个监听者
        $(document).keyup(handle);
    }

    // 解决有些网站不加载图片
    // 插入 meta 标签
/*    var oMeta = document.createElement('meta');
    oMeta.content = "default-src 'self' data: * 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src * ;img-src *";
    oMeta['http-equiv'] = "Content-Security-Policy";
    document.getElementsByTagName('head')[0].appendChild(oMeta);
*/
    // 【数据初始化】
    // 获取存在的订阅信息
    function getSubscribe() {
        // 查看是否有订阅信息
        let subscribeKey = registry.searchData.subscribeKey;
        let subscribeInfo = cache.get(subscribeKey);
        if(subscribeInfo == null ) {
           // 初始化订阅信息(初次)
           subscribeInfo = `
              <tis::https://raw.githubusercontent.com/18476305640/xiaozhuang/dev/%E6%88%91%E7%9A%84%E6%90%9C%E7%B4%A2%E8%AE%A2%E9%98%85%E6%96%87%E4%BB%B6.txt />
           `;
           cache.set(subscribeKey,subscribeInfo);
        }
        return subscribeInfo;
    }
    function editSubscribe(subscribe) {
       // 判断导入的订阅是否有效
       // 获取订阅信息(得到的值肯定不会为空)
       let pageTextHandleChainsY = pageTextHandleChains.init(subscribe);
       let tisHasFetchFun = pageTextHandleChainsY.parseSingleTab("tis","fetchFun");
       let tisNotFetchFun = pageTextHandleChainsY.parseSingleTabValue("tis");

       let tis = [...tisHasFetchFun, ...tisNotFetchFun];
       // 生成订阅信息存储
       let subscribeText = "\n";
       for(let aTis of tisHasFetchFun) {
          subscribeText += `<tis::${aTis.tabValue} fetchFun="${aTis.attrValue}" />\n`
       }
       for(let aTis of tisNotFetchFun) {
          subscribeText += `<tis::${aTis.tabValue} />\n`
       }
       // 持久化
       let newSubscribeInfo = subscribeText.replace(/\n+/gm,"\n\n");
       cache.set(registry.searchData.subscribeKey,newSubscribeInfo);
       return tis.length;
    }
    // 存储订阅信息,当指定 sLineFetchFun 时,表示将解析“直接页”的配置,如果没有指定 sLineFetchFun 时,只解析内容
    // 在提取函数中 \n 要改写为 \\n
    let dataSources = getSubscribe()+ `
       <fetchFun name="mLineFetchFun">
         function(pageText) {
              let type = "sketch"; // url   sketch
              let lines = pageText.split("\\n");
                let search_data_lines = []; // 扫描的搜索数据 {},{}
                let current_build_search_item = {};
                let current_build_search_item_resource = "";
                let point = 0; // 指的是上面的 current_build_search_item
                let default_desc = "--无描述--"
                function getTitleLineData(titleLine) {
                   const regex = /# ([^()()]+)[((]?([^()()]*)[^))]?/;
                   let matchData =  regex.exec(titleLine)
                   return {
                      title: matchData[1],
                      desc: ((matchData[2]==null || matchData[2] == "")?default_desc:matchData[2])
                   }
                }
                for (let i = 0; i < lines.length; i++) {
                    let line = lines[i];
                    if(line.indexOf("# ") == 0) {
                       // 当前新的开始工作
                       point++;
                       // 创建新的搜索项目容器
                       current_build_search_item = {...getTitleLineData(line)}
                       // 重置resource
                       current_build_search_item_resource = "";
                       continue;
                    }
                    // 如果是刚开始,没有标题的内容行,跳过
                    if(point == 0) continue;
                    // 向当前搜索项目容器追加当前行
                    current_build_search_item_resource += (line+"\\n");
                    // 如果是最后一行,打包
                    let nextLine = lines[i+1];
                    if(i === lines.length-1 || ( nextLine != null && nextLine.indexOf("#") == 0 )) {
                       // 加入resource,最后一项
                       current_build_search_item.resource = current_build_search_item_resource;
                       // 打包装箱
                       search_data_lines.push(current_build_search_item);
                    }
                }
                // 添加种类
                for(let line of search_data_lines) {
                   line.type = type;
                }
                return search_data_lines;
         }
       </fetchFun>
       <fetchFun name="sLineFetchFun">
         function(pageText) {
              let type = "url"; // url   sketch
              let lines = pageText.split("\\n");
                let search_data_lines = []
                for (let line of lines) {

                    let search_data_line = (function(line) {
            const baseReg = /([^::\\n]+)[((](.*)[))]\\s*[::]\s*(.+)/gm;
            const ifNotDescMatchReg = /([^::]+)\\s*[::]\\s*(.*)/gm;
            let title = "";
            let desc = "";
            let resource = "";

         let captureResult = null;
         if( !(/[()()]/.test(line))) {
             // 兼容没有描述
             captureResult = ifNotDescMatchReg.exec(line);
             if(captureResult == null ) return;
             title = captureResult[1];
             desc = "--无描述--";
            resource = captureResult[2];
         }else {
            // 正常语法
            captureResult = baseReg.exec(line);
            if(captureResult == null ) return;
            title = captureResult[1];
            desc = captureResult[2];
            resource = captureResult[3];
         }
         return {
            title: title,
            desc: desc,
            resource: resource
         };
          })(line);
                    if (search_data_line == null || search_data_line.title == null) continue;
                    search_data_lines.push(search_data_line)
                }

                for(let line of search_data_lines) {
                   line.type = type;
                }
                return search_data_lines;
         }
      </fetchFun>
    `;


    // github CDN加速包装器
    function cdnPack(githubResourceUrl) {

       let githubUrlFlag = "raw.githubusercontent.com";

       // 如何不满足github url ,不加速
       if(githubResourceUrl.indexOf(githubUrlFlag) < 0) return githubResourceUrl;
       return "https://proxy.zyun.vip/"+githubResourceUrl;
    }

    // 模块四:初始化数据源


    // 使用责任链模式——对pageText进行操作的工具
    const pageTextHandleChains = {
        pageText: "",
        setPageText(newPageText) {
            this.pageText = newPageText;
        },
        getPageText() {
            return this.pageText;
        },
        init(newPageText = "") {
           // 深拷贝一份实例
           let wo = {...this};
           // 初始化
           wo.setPageText(newPageText);
           return wo;
        },
        // 解析双标签-获取指定标签下指定属性下的值
        parseDoubleTab(tabName,attrName) {
            // 返回指定标签下指定属性下的值
            const regex = RegExp(`<\\s*${tabName}[^<>]*\\s*${attrName}="([^<>]*)"\\s*>([\\s\\S]*?)<\/\\s*${tabName}\\s*>`,"gm");
            let m;
            let tabNameArr = [];
            let copyPageText = this.pageText;
            // 注意下面的 copyPageText 不能改变
            while ((m = regex.exec(copyPageText)) !== null) {
                // 这对于避免零宽度匹配的无限循环是必要的
                if (m.index === regex.lastIndex) {
                    regex.lastIndex++;
                }
                tabNameArr.push({
                    attrValue: m[1],
                    tabValue: m[2]
                })
                const newPageText =this.pageText.replace(m[0], "");
                this.pageText = newPageText;
            }
            return tabNameArr;
        },
            // 解析双标签-只获取值
          parseDoubleTabValue(tabName) {
                // 返回指定标签下指定属性下的值
                const regex = RegExp(`<\\s*${tabName}[^<>]*\\s*>([\\s\\S]*?)<\/\\s*${tabName}\\s*>`,"gm");
                let m;
                let tabNameArr = [];
                let copyPageText = this.pageText;
                while ((m = regex.exec(copyPageText)) !== null) {
                    // 这对于避免零宽度匹配的无限循环是必要的
                    if (m.index === regex.lastIndex) {
                        regex.lastIndex++;
                    }
                    tabNameArr.push({
                        tabValue: m[1]
                    })
                    const newPageText =this.pageText.replace(m[0], "");
                    this.pageText = newPageText;
                }

                return tabNameArr;
            },
                // 获取指定单标签指定属性与标签值(标签::值)
              parseSingleTab(tabName,attrName) {
                    // 返回指定标签下指定属性下的值
                    const regex = RegExp(`<${tabName}::([^\\s<>]*)\\s*${attrName}="([^"<>]*)"\\s*\/>`,"gm");
                    let m;
                    let tabNameArr = []
                    let copyPageText = this.pageText;
                    while ((m = regex.exec(copyPageText)) !== null) {
                        // 这对于避免零宽度匹配的无限循环是必要的
                        if (m.index === regex.lastIndex) {
                            regex.lastIndex++;
                        }
                        tabNameArr.push({
                            tabValue: m[1],
                            attrValue: m[2]
                        })

                        const newPageText =this.pageText.replace(m[0], "");
                        this.pageText = newPageText;
                    }

                    return tabNameArr;
                },
                   parseSingleTabValue(tabName) {
                        // 返回指定标签下指定属性下的值
                        const regex = RegExp(`<${tabName}::([^\\s<>]*)[^<>]*\/>`,"gm");
                        let m;
                        let tabNameArr = []
                        let copyPageText = this.pageText;
                        while ((m = regex.exec(copyPageText)) !== null) {
                            // 这对于避免零宽度匹配的无限循环是必要的
                            if (m.index === regex.lastIndex) {
                                regex.lastIndex++;
                            }
                            tabNameArr.push({
                                tabValue: m[1]
                            })
                            const newPageText =this.pageText.replace(m[0], "");
                            this.pageText = newPageText;
                        }
                        return tabNameArr;
                    },

                        // 清除指定单双标签
                  cleanTabByTabName(tabName) {
                            const regex = RegExp(`<\\s*${tabName}[^<>]*>([^<>]*)(<\/[^<>]*>)*`,"gm");
                            // 替换的内容
                            const subst = ``;
                            // 被替换的值将包含在结果变量中
                            const cleanedText = this.pageText.replace(regex, subst);
                            this.pageText = cleanedText;

                        }
    }
    // 从 订阅信息(或页) 中解析出配置(json)
    function getConfigFromDataSource(pageText) {

       let config = {
          // {url、fetchFun属性}
          tis: [],
          // {name与fetchFun属性}
          fetchFuns: []
       }
       // 从config中放在返回对象中
       let pageTextHandleChainsX = pageTextHandleChains.init(pageText);
       let fetchFunTabDatas = pageTextHandleChainsX.parseDoubleTab("fetchFun","name");
       for(let fetchFunTabData of fetchFunTabDatas) {
          config.fetchFuns.push( { name:fetchFunTabData.attrValue,fetchFun:fetchFunTabData.tabValue } )
       }
       // 获取tis
        let tisHasFetchFun = pageTextHandleChainsX.parseSingleTab("tis","fetchFun");
        let tisNotFetchFun = pageTextHandleChainsX.parseSingleTabValue("tis");
        let tisArr = [...tisHasFetchFun, ...tisNotFetchFun]
        for(let tis of tisArr) {
          config.tis.push( { url:tis.tabValue, fetchFun:tis.attrValue } )
        }

        return config;

    }
    // 将url转为文本(url请求得到的就是文本),当下面的dataSourceUrl不是http的url时,就会直接返回,不作请求
    function urlToText(dataSourceUrl) {
        // dataSourceUrl 转text
        return new Promise(function (resolve, reject) {
            if((dataSourceUrl.trim().indexOf("http") != 0 ) ) return resolve(dataSourceUrl) ;
            $.ajax({
                url: cdnPack(dataSourceUrl+"?time="+new Date().getTime()),
                success: function (result) {
                    resolve(result)
                }
            });
        });
    }
    // 下面的 dataSourceHandle 函数
    let globalFetchFun = [];
    // tis处理队列
    let waitQueue = [];
    // 将解析出来的部分数据push 到 registry.searchData.data的操作队列 (push到全局不能并发,所以这里必须是单线程操作)
    let searchDataController = {
       // 加入到全局的等待队列
       queueData: [],
       // 是否空闲
       isIdle: true,
       // 是否第一次 pushToGlobal
       isFirsPush: true,
       // 给外面触发,加入到队列中
       pushToGlobal:function(newItems) {
          if(this.isFirsPush) {
             this.isFirsPush = false;
             // 清空全局数据容器的数据
             registry.searchData.data = [];
          }
          this.queueData.push(...newItems);
          // 如果当前不是空闲的,其它线程当会处理刚才push的数据到全局中
          if(!this.isIdle) return;
          // 设置当前为工作模式
          this.isIdle = false;
          // 处理队列中的数据
          let newItem = null;
          while((newItem = this.queueData.pop() ) != null) {
             // 下一个编号索引号
              let nextIndex = registry.searchData.data.length;
              newItem.index = nextIndex;
              registry.searchData.data[nextIndex] = newItem;
          }
          // 设置当前空闲
          this.isIdle = true;
          // 更新视图显示条数
          $("#search_input").attr("placeholder",registry.searchData.getDataLength("UPDATE"));

       },
    }
    function dataSourceHandle(resourcePageUrl,tisTabFetchFunName) {
        urlToText(resourcePageUrl).then(text => {
            if(tisTabFetchFunName == null) {
                // --> 是配置 <--
                let data = []
                // 解析配置,是一个json
                let config = getConfigFromDataSource(text);
                console.log("解析的配置:",config)
                // 将FetchFun放到全局解析器中
                globalFetchFun.push(...config.fetchFuns);
                // 将tis放到处理队列中
                waitQueue.push(...config.tis);
                let tis = null;
                while((tis = waitQueue.pop()) != undefined) {
                    // tis有两个url,第二是fetchFun
                    dataSourceHandle(tis.url,tis.fetchFun);
                }
                // 清理内容
                pageTextHandleChains.setPageText("");
            }else {
                // --> 是内容 <--
                // 解析内容
                if(tisTabFetchFunName === "") return;
                let fetchFunStr = getFetchFunGetByName(tisTabFetchFunName);

                let search_data_line =(new Function('text', "return ( " + fetchFunStr + " )(`"+text.replace(/[`]/gm,"<反引号>")+"`)"))();
                // 将之前修改为 <wrapLine> 改为真正的换行符 \n
                let replaceBefore = "<反引号>";
                let replaceAfter = "`";
                // 处理并push到全局数据容器中
                for(let item of search_data_line) {
                    item.title = item.title.replaceAll(replaceAfter,replaceBefore);
                    item.desc = item.desc.replaceAll(replaceAfter,replaceBefore);
                    item.resource = item.resource.replaceAll(replaceAfter,replaceBefore);
                }
                // 加入到push到全局的搜索数据队列中,等待加入到全局数据容器中
                searchDataController.pushToGlobal(search_data_line);
                // 触发搜索数据改变事件(做缓存等操作,观察者模式)
                for(let fun of registry.searchData.dataChange) {
                   fun(search_data_line);
                }
            }
        })


    }
    // 根据fetchFun名返回字符串函数
    function getFetchFunGetByName(fetchFunName) {
        for(let fetchFunData of globalFetchFun) {
           if(fetchFunData.name == fetchFunName) {
              return fetchFunData.fetchFun;
           }
        }
    }
    // 缓存数据
    function cacheSearchData(newSearchData) {
        console.log("触发了缓存,当前数据",registry.searchData.data)
        // 当有数据加入到全局数据容器时,会触发缓存,当前函数会执行
        let SEARCH_DATA_KEY = registry.searchData.SEARCH_DATA_KEY;
        cache.remove(SEARCH_DATA_KEY)
        cache.set(SEARCH_DATA_KEY,{
            data: registry.searchData.data,
            expire: new Date().getTime() + (1000*60*60*1) // 一个小时
        })
        // 加载一下图片,让服务器的redis缓存图标
        loadWebFavicon(newSearchData);
    }

    // 加载一下网站图标,让远程redis有记录,下次会很快
    async function loadWebFavicon(searchItems) {
        let CACHE_FLAG = "loadHistory";
        let loadHistory = cache.get(CACHE_FLAG);
        if(loadHistory == null) loadHistory = [];
        // 创建容器
        let imgBox=document.createElement("div");
        imgBox.style="display:none";
        document.body.appendChild(imgBox);
        for(let item of searchItems) {
            let resource = item.resource.trim();
            if(resource.toUpperCase().indexOf("HTTP") == 0) {
               // 如果历史中有,跳过此项后续操作
                if(loadHistory.includes(resource)) continue;
               // 记录一下,下次不会再进行此操作,给服务减压
                loadHistory.push(resource);
               // 装箱
               var img=document.createElement("img");
               img.src = registry.searchData.getFaviconAPI+resource;
               imgBox.appendChild(img);
            }
            if(item === searchItems[searchItems.length-1] ) {
                // 这是最后一个,去掉痕迹
                setTimeout(function() {
                   // 将记录持久化
                   cache.set(CACHE_FLAG,loadHistory);
                   imgBox.remove();
                },500)
            }
        }
    }
    // 检查是否已经执行初始化
    function checkIsInitializedAndSetInitialized(secondTime) {
       let key = "DATA_INIT";
       let value = cache.cookieGet(key);
       if(value != null && value != "") return true;
       cache.cookieSet(key,key,1000*secondTime);
       return false;
    }
    // 【数据初始化主函数】
    let isInitialized = false;
    function dataInitFun() {
        // 检查是否已经执行初始化
        if(isInitialized) return;
        // 设置为已初始化,保障只初始化一次,如果不能保障,同时初始化时,出现重复数据
        isInitialized = true;
        // 从缓存中获取数据,判断是否还有效
        const SEARCH_DATA_KEY = registry.searchData.SEARCH_DATA_KEY;
        // cache.remove(SEARCH_DATA_KEY)
        let dataBox = cache.get(registry.searchData.SEARCH_DATA_KEY);

        if(dataBox != null) {
            // 只要数据不为空,不管是否过期,先用着,直接将之前缓存的数据放在全局搜索数据容器中
            registry.searchData.data = dataBox.data
            // 缓存信息不为空,深入判断是否使用缓存的数据
            let dataExpireTime = dataBox.expire;
            let currentTime = new Date().getTime();
            // console.log("缓存的数据:",dataBox.data)
            // 数据多大时,才开启缓存
            const TRIGGER_CACHE_DATA_LENGTH = 300;
            // 判断是否有效,有效的话放到全局容器中
            let isValid = (dataExpireTime != null && dataExpireTime > currentTime && dataBox.data != null && dataBox.data.length > 0);
            // 如果网站比较特殊,忽略数据过期时间
            if(!isValid && window.location.host.toUpperCase().indexOf("GITHUB.COM") >= 0) {
               isValid = true;
            }
            // 如果数据过期,或数据量不满足缓存大小,会去请求数据
            if(isValid && dataBox.data.length >= TRIGGER_CACHE_DATA_LENGTH ) {
                console.log("我的搜索:本次从缓冲中获取, 数据有效期还有"+parseInt((dataExpireTime - currentTime)/1000/60)+"分钟!", dataBox.data)
                return
            };
        }
        // 内部将使用递归,解析出信息
        dataSourceHandle(dataSources,null);
        // 监听数据改变
        registry.searchData.dataChange.push(cacheSearchData)
    }
    // 判断是否要直接执行初始化函数-如果没有数据,这里要直接执行
    (function() {
        let SEARCH_DATA_KEY = registry.searchData.SEARCH_DATA_KEY;
        if(cache.get(SEARCH_DATA_KEY) == null) {
          // 执行初始化函数
          dataInitFun();
        }

    })();

    // 模块二
    registry.view.viewVisibilityController = (function () {

        // 整个视图对象
        let viewDocument = null;
        let searchInputDocument = null;
        let matchItems = null;
        let searchBox = null;

        let isInitializedView = false;
        let viewName = "my_search_view"
        let controlButton = null;
        let textShow = null;
        let matchResult = null;
        let initView = function () {
            // 初始化视图
            let view = document.createElement("div")

            view.innerHTML = (`
             <div id="${viewName}">
                <div id="searchBox" >
                    <input placeholder="${registry.searchData.getDataLength()}" id="search_input" />
                    <button id="controlButton">Bug</button>
                </div>
                <div id="matchResult">
                    <ol id="matchItems">
                       <!-- <li><a href="#">webGL水族馆(测试电脑性能)</a></li> -->
                    </ol>
                </div>
                <div id="text_show">

                </div>
             </div>
         `)
            // 设置样式
            view.style = `
             position: fixed;left: 25%;right: 25%;top:50px;
             border:2px solid #cecece;z-index:10000;
             background: #ffffff;
             overflow: hidden;
         `;

            // 挂载到文档中
            document.body.appendChild(view)
            // 整个视图对象放在组件全局中/注册表中
            registry.view.viewDocument = viewDocument = view;


            // 搜索框对象
            searchInputDocument = $("#search_input")
            matchItems = $("#matchItems");
            searchBox = $("#searchBox")
            controlButton = $("#controlButton")
            textShow = $("#text_show")
            matchResult = $("#matchResult");
            searchBox.css({
                "height": "45px",
                "background": "#ffffff",
                "padding": "0px",
                "box-sizing": " border-box",
                "z-index": "10001",
                "position":"relative"

            })

            searchInputDocument.css({
                "width": "100%",
                "height": "100%",
                "border": "none",
                "outline": "none",
                "font-size": "15px",
                "background": "#fff",
                "padding": "0px 10px",
                "box-sizing": " border-box",
                "color":"rgba(0,0,0,.87)",
                "font-weight":"400"
            })
            $("#matchResult > ol").css({
                "margin": "0px",
                "padding": "0px 15px",
                "overflow": "hidden"

            })

            controlButton.css({
                "position": "absolute",
                "font-size":"12px !important",
                "right": "5px",
                "margin":"10px 7px",
                "padding":"3px 15px",
                "border-radius":"13.5px",
                "border":"none",
                "display":"none", // 默认隐藏,由函数控制
            })
            textShow.css({
                "display":"none",
                "width":"100%",
                "box-sizing": "border-box",
                "padding": "5px 10px 7px",
                "font-size": "15px",
                "line-height":"25px",
                "max-height":"450px",
                "overflow": "auto",
                "text-align":"left"
            })
            // 初始化搜索数据
            dataInitFun();

            // 在搜索的结果集中上下选择移动然后回车(相当点击)
             searchInputDocument.keydown(function(event){
                 let e = event || window.event || arguments.callee.caller.arguments[0];

                 if(e && e.keyCode!=38  && e.keyCode!=40 && e.keyCode!=13) return;
                 if(e && e.keyCode==38){ // 上
                     registry.searchData.pos --;

                 }
                 if(e && e.keyCode==40){ //下
                     registry.searchData.pos ++;
                 }
                 // 如果是回车 && registry.searchData.pos == 0 时,设置 registry.searchData.pos = 1 (这样是为了搜索后回车相当于点击第一个)
                 if(e && e.keyCode==13 && registry.searchData.pos == 0){ // 回车选择的元素
                     registry.searchData.pos = 1;
                 }
                 // 当指针位置越出时,位置重定向
                 if(registry.searchData.pos < 1 || registry.searchData.pos > registry.searchData.searchData.length ) {
                     if(registry.searchData.pos < 1) {
                         // 回到最后一个
                         registry.searchData.pos = registry.searchData.searchData.length;
                     }else {
                         // 回到第一个
                        registry.searchData.pos = 1;
                     }
                 }
                 // 设置显示样式
                 let activeItem = $($("#matchItems > li")[registry.searchData.pos-1]);
                 // if(activeItem == null) return;
                 // 设置活跃背景颜色
                 activeItem.css({
                    "background":"#dee2e6"
                 })
                 // 设置其它子元素背景为默认统一背景
                 activeItem.siblings().css({
                    "background":"#fff"
                 })

                 if(e && e.keyCode==13){ // 回车
                     // 点击当前活跃的项,点击
                     activeItem.find("a")[0].click();
                 }

                // 取消冒泡
                e.stopPropagation();
                // 取消默认事件
                e.preventDefault();

             })
            // 将输入框的控制按钮设置可见性函数公开放注册表中
            registry.view.setButtonVisibility = function (buttonVisibility = false) {
                // registry.view.setButtonVisibility
                controlButton.css({
                      "display": buttonVisibility?"block":"none"
                })
            }
            function searchUnitHandler(beforeData = [],keyword = "") {
                // 如果没有搜索内容,返回空数据
                if(keyword.trim() == "" || registry.searchData.data.length == 0 ) return [];
                // 切割搜索内容以空格隔开,得到多个 keyword
                let searchUnits = keyword.split(/\s+/);
                // 弹出一个 keyword
                 keyword = searchUnits.pop();
                // 本次搜索的总数据容器
                let searchResultData = [];
                let searchLevelData = [
                    [],[],[] // 分别是匹配标题/desc/url 的结果
                ]
                // 数据出来的总数据
                //let searchData = []
                // 前置处理函数,这里使用观察者模式
                // searchPreFun(keyword);
                // 搜索操作
                for (let dataItem of beforeData) {
                    keyword =keyword.toUpperCase();
                    // 将数据放在指定搜索层级数据上
                    if ((dataItem.title.toUpperCase().indexOf(keyword) >= 0 && searchLevelData[0].push(dataItem) )
                        || (dataItem.desc.toUpperCase().indexOf(keyword) >= 0 && searchLevelData[1].push(dataItem) )
                        || (dataItem.resource.toUpperCase().indexOf(keyword) >= 0 && searchLevelData[2].push(dataItem) ) ) {
                        // 向满足条件的数据对象添加在总数据中的索引
                    }
                }
                console.log("层级数据:",searchLevelData)
                // 将上面层级数据放在总容器中
                searchResultData.push(...searchLevelData[0])
                searchResultData.push(...searchLevelData[1])
                searchResultData.push(...searchLevelData[2])
                if(searchUnits.length > 0) {
                   searchResultData = searchUnitHandler(searchResultData,searchUnits.join(" "));
                }
                return searchResultData;
            }
            // 给输入框加事件
            // 执行 debounce 函数返回新函数
            let handler = function (e) {
                let key = e.target.value.trim();
                // 过滤
                // 数据出来的总数据
                let searchData = []
                // 递归搜索,根据空字符切换出来的多个keyword
                let searchResultData = searchUnitHandler(registry.searchData.data,key)
                console.log("搜索总数据:",searchResultData)
                // 放到视图上
                // 置空内容
                matchItems.html("")
                // 最多显示条数
                let show_item_number = 15;
                function getFlag(searchResultItem) {
                    let resource = searchResultItem.resource.trim();
                    let sketchFavicon = "data:image/png;base64,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";
                    let loadErrorFlagIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAAXNSR0IArs4c6QAAExhJREFUeF7tnYu1JDcRQLURgCNYE4EhgsURGEewEAFsBAsRGCJYHIHZCIAIDBEAERhHAOfOa832zHRPq6UqqSSVznnn7dnXH6lUt+uj36vgpYUEPg8hvA4h/DyE8NOlAr/cqMj67/HP/wgh/Pfu2n+HEPihxH//vUXDRnvnq9EaZKg9KP4XIQRg4Adlj79rVROQACpC87cQwo/L/9WqQ9fvcUBku+9NCAFLEH9kny73NMABlr+EELA00frIvWGQJzkgZR3ZCxBHrQQQgOHHgVlJywE5Up3Hv38VQvjV8hPjh/NPsX0HwPw5hPDt7NbFAUlTVGKH3y5Q8O+ZClYFWD5uJAeGl4MDst/FWAesxe+WAHt4ZThoIHELMQtWBWimKA7IYzcTYL8NIfx6Cg3Ia2R0wf40ulVxQD4pCGC8XzJQeWoz311YlT+GEIYFxQF5Sck6GGVwDwvKzIA4GGVQbN0dQRkm+zUjIA6GPBhbT8T1+kPvMcpMgJCV+saD7zp0LG/BopAFxKJ0WWYBhDGM368mBnbZWR1XmrTwb3ocdBwdECYIfvBxDDNo8ZHqKuM1KiC4U2SmMO9ebEmAMZR3y6CjrZpt1GZEQAjCv3N3yrzuMSqP23W/tsVUxUcDBKuBGffShwSwJl9bXp8yCiC4VFiNrVV5fajK3LXEFSY2MVdGAMRdKnNqlVUhky5X74C4S5Wli2ZvMudy9QqIu1RmdVykYgTvrEFpXnoEBDj+6mMbzXVHuwIkW5iq0rT0BggDf8Ax6lLXpspg8OVYEaxJs9ITIA5HMzVp+uKmkPQCCJskMGXELUdTXW32cvb2+rLFoGIPgLD0FTi8zC2BJpBYB8ThqAMFe2ExDhG3NeU3hTEmXFt+s4FF60Ia+Bc1LYllQBwOXXX8z7KeHB8/ZT4U7i2uLtkl9hVuVapaEquA8MUiW+VFRwKkT0vmrDE1hPt/olO9w6dWg8QiIJ6tOtSP7Av+uVgBib14sShAwmK0FgWXkImOqsUaIA6HXnez7FVjry+sPW5aC7dLPQVsCRC+SN8vRwToqcmcT9aeukHf4XYxN652UYXECiA+fURPrbThWNecfYvZzaR2xkutjVYAISD3tRyykHBQDlmnFvvo8l5Aqel2EY8Ql4gWC4AQ6LUwzaKCNPYw4OCDE8czWlSvdhBPqpoxEokExFVerQHxdK6O6qp8TTOrWjOI54MAJGKlJSAelIt1482D1PzxgurWtCalYzw3zWwJCGvI8VW9yEnAIhzr1pFmJjbRHmBkYqNI7NUKEFKCbAPqRUYCxBwon3iQKlO9m6cw1oXyakJCPPKzxCk0T5vYAhAExHiHFxkJWAjIz7YElwtIOCZbq/B8LElRqQ2Ixx1F3fVwM1NHCIJTJhvKvrn8aTUgKY5HagPiKd1yxYpPYB+p3rdW1YakOPVbExBGWf8lpx/TPqnlAKCG0IGE9KzWoGLRpMaagPhoebl6cRQzwXiPLtWz1msH7tlZrVqAkM4lreslTwIsbgIMkdRlXhXU79LUkeyViDUA8cA8T7cIwHE9mK06Mhhr6WjGqFkBew1AGBhqtagmTzXr3BUBAIL7teB1amDzLXwM3ihVjbGRU3O1tAHxMY/bngYKPhgEjqPFEVI6TTKHD4bGQOLpsRFtQDwwf1EbgmtSsqe+XlIa1+FzNOORUwG7JiBuPULAYgDGLDGEJItYWY2FV6esiCYgBJdvJSXW2bO01oB3Jobs6pLcweJquFrJVkQLkNkHBbMyJtmqNO6NWq5WshXRAmRm62F9ynlvOGm5WklWRAOQma0HW3j62npZBLWyWklWRAOQma3H6Ty7rC4N+zStAcRDKyINyMzWw4NyXT4J2KUnNB72mTQgM4+ae+yhC4jWBh9Prb40ID9MfMjNobnW1Z8pnq4xDeVpxlESEK2UXC89/5lPH1HvKg0XHtcNK7JZJAHRSsepS13oBZKyFKrSkI/RSALtWn+pTmXUE/dq5iIly5llmNJ2DSuyG6xLdapv4xOCu1gp6i1zjbQV2d0mSAoQtvFhcuLMxYP0er2vYUU2s5ASgPis3RfFsLQfbj1Vbfcm6Zh3c2RdApCZxz7W6uETFOvCopE1fRgTkQCErXwwebMX8Z3FZxdoQvuJHSSnwz+4WaWAaPiCCXIxe4nHIXW7Rtp7YeXnzYbqpYD4Wea3CsGgE7FIy4Nr6qpo27dJu1lYJLKR11IKiHS6ra245d7O7FNy674GXU6me0/6n/ArOIDn+oErBcTjj+e9wxcpCvt+XTr/z4Zwbm3KNFx6fta7ZeeZS61KAPH4o6xj13fTyVgbMmFudc7JVdqLuYlDSgDx+ONcR6ZeTX6fndt9J5Q0iUkvprqJQ0oAkSY3TRzzXIXrBSyAwlJeL9sSkA7Uecs1DikBxOOPuioLKBEaB+aT7DUWUl3jkFxAfPZuXTi23gYw/OAzzxzoawByjUNyAdGoVHuV67cGBPbAgktG585UNHTxujtNLiAeoNtVQYJMQJkFFg1ArhneXECkMwd21a3vmmFZSKaMPGipBchlfU8uINKDM32rYR+1BxTSx6PFK1qAXObV5QLiC6T6gGKrloAy0oCkljdzyWTlAiI9/6Vfdeu35qPs46XlzVzW9+QA4lNM+oXivuZYE0DpuWh9rC+ZrBxAtHy+njup57rfzF7trCGam4VcFsDlAKJZqc76Z4jq9rpUuMZeCK9yANEKiobQtg4bQWaLj15PBTg4/5IZHZrFAdGUbifP7ilYBwiOFOcjXaM4IDWkbPwdvZxpwnmXgFFzgxAHxLjyalePU3gtb/hH3QCDqU3a7tSWrL/MiUF8HYi22tZ7/s3y0nqv3X0TELxZjrFjnUdNayEGiNbAjIH+maoKPy4KyOTGloWz0Bk64MeaNcuyIA5IS3WSe/fh8WNyr3p4Epbh/bIHVQvXKbVpDkiqpAa8rlVwTjzxTaOY4mw3OiBnJTbI9S2sB5YCMACkl/IuJ0h3F6uX7t2vZ+3pJcQWHwzGGEc96RbkSEID/r12apdsFHBYjjX2utkBWSTDzM24xU5cUESHrrMrpB9HKDVHzgnEa416a/RNFiDSB5doNCzlmWz7yZgOP6m7GQJNTEWSibnP06//j+skt+ZPadPRNbVSu8gJq3GzU/pR5Qz+PQuQ3icrAgZtAAztEoFCUQhOWwNz3a1DseF8JL7rMN7YEslUgOB7AwYWsFUBEurwulEFtAGpNcu2lvg+y8li9WZBalqMlI7DqjC9nJ/aFmX3NNeUih9cQ7yG5egxGN9r2tCTFfG3UcIarlSOfuGKUD/cr7MWJWfr0Zhk0FhmO+oq02EBYREQlq71PKNUcGJwj4ty/wUmq0Y71meNpD73/joUGUDYV5lsVmpy4tn7RnOr1m3NAsTy14IvK1/l0fZ+ygVi677YfwDHR4SPSWoB5HtrR1zV0+h4altxzT/PiUFqrAVObcT6ul7XVue0tfSe9U4gzIxAduvzSADhiyUTBVBbKe3SOli/P3tXExqmtdVKjtAgHT/erUa69Pb6D0i23Lz0J49z5WWtfo4FQQT4rmcDSw3RkbrlC9dLrKEhg7PP9KMr0iSWvXEcj7cwYdHhSOvo+6s0TmTKq4ntu4r25pU+wD1HVJcG5Nw4+T0W+q6HLrjMeM51sSwMFubWvYfO0ayjBeuv2T6pZ1/0K1fJLKR6c+suJcBen2Ph42ZddtclAblKZmED69y6W+8c7foRpJNkqT3NRbtdks8vPoLNQqrXAclXCQseQH7t9e+8jqmVKFlrX/ZyRJa+rIZ9g58zud+1X8dZ3yWAtPZlPYtVzq5Dsi3D68e3BJDWZrrm0tFyVbT7BIfktm9u1uyXAMJjcXFaBXsttq6xq+ZlNXNIPsnv5jiIUkBark8nE8PmZ15kJOCQvMjxxnUvBaT1aVPXYEpGR6Z/im9Mfjc2WApI66nvWBGmBHg2S4Ztlsz2vhNJiSQe1uyXAtI6DuH9GktIS4Tc672tvQELcntYUyQBSMs4JArVISlTL5/h+yK/hy1ZJQCxIlwGLolJ3N06B8vIa8rPSOKyxPb+BglALLhZsV2sKgQSic0Izgi352s5LZYxrdnL5mm/UoBYyn5gQagPrl/O9jgzKUrrwV5Lst48L0UKkNbZrGeCXm+Xg2XhB3eMEdPZ3bHW04WsALK7470UIDTUyjr1VKFHS8NBlrOW1hNOrch9d9qSJCC9pgmJWxg93bMmBG4cXh83h+DaUYoD8tKTuzPDJQGxsIgqV3GBBHfj4/KAeBwx0y/uB85GmkXsgITwdE6fJCDoloUxkVxIYjYOV/HZccQjbVDngLxkPXd3/JcGxMqYSAkkR/dupgOPbjL699mD9M2xj3VfSQPSY7B+Vne1z9g4W5+S62cH5HBNkQYgo0+bHmma/QwWf+8Dcmg9uFEDkBmsCKlhNmDrvcwMyKH10ARkdCuC7BitJ2DveVrLrC5WkvXQBGQGKxKtR8+gcJDOwwS93s1iQv2TM5FaLhZ1nMGKxL7IOYwmoR9VL5nVvTp1FLYmIDNZkbU1IT6xPseLgdDv3Xocf4C0AZnJikRpM+jE4JPlMusU91PWQzsGiQrCNA6O85qpWJ6OMmtgjv4lZa7WiqptQXiX5anwWtBaTQPjWhGYl55lzmApbiTPoX9b7Y12pv+yBnhrAEIjZju0xeq+waULpJjYx6zt+xgLUHg2sPA7nsl+RoG1r31Yb57ywlqAzLTlvuW5WiXu1dmdLMmS8fM2RRGVr8nuk1qAzJL2ZQCKr6jVLFbu7N0s92RReuTBe1u5YUV9UhMQ5JXbQcofGLHHZ5lxsbcfP+iHjPiDzA9KXjJjoNS1O27Z/hVFu2/WBmTkgD15dLaktwvuzV3QJtGuVkdPl1i+i6hrA8I7S/zgAv1QvTV5bo9qLZ4/PHdMSiLhkPvuEnFJWL4mgIzoakl8ZUuUIeXenNWeZwPzvXrkvDulTc+uKXKt4oNbWBDePVpWS0qRSpXi2f058YcE+C3ij+ys1b0AWwFCPVoITlMBLQfouRMTSwFpMedrd4+rnM5vCcho8YjloxhyXZxSQGofp0DcwYeX6U0ipTUgNGKkuVpHe2yJdNrJh5RkkEpcxxaB+em5VkeytAAI6UcUq9VA0pGMzv4dS0JHMeZjoZRkDXPX37dI55fAvNtPFgChcrk+sgUF3KuDhZWGEpMTNzd1fiL4FscpEHfEnS9FdcIKIDSqhUkWFebOw1qCIiHTMzOTh4KD/rQEyMiQtFiSK5VBwv0lQ3dUJGA8esf930UGA5+91Bog1NXSWSNnO+zoevEg8skLS2KP+8c+c7Nwbdjcu/bhn+IZqy1ZWgRkZEiwJCib9mxfEh+sOS9dGBV1Zn1yF89+vfj8QPFsH+OjD0bu36vAYdHFWgssN3efK/Ra99WwIrXHH2rJLr6nhgwv77JqQagbXz9SpaOtZ6dNmmeM9HpOSypk1eCwDsjIkJzJDKUqDte1GH84U7/Sa6vC0QMgUaAjBu7SO5+0SLGWKnzq/cQcWEb0oGqx7GLdC2I0SCQDdokBwaqKd+Jl1QLynrJYe/KTTF2e6CO1SyXiESzHh0bZJDXBLA9uCkdPLta6I1oMSGkqQsmMWdKswCGVztVs59lnM32E9pWshT/7zofre3KxRoYkJx55vyxfLlYCgw9Qm1t1tq29AhIzNoyVMGjVezmzloSRa+Dg94hlb3O6Jm3tGRAEhmtB8P5VE+nJvvRomShtZdPpFiPXsi3dflqzTNWzxvUOSGzbCINjZLVox5bPDRQkKEaMNehDXCpiS7GVgFJEjwLIaC6XVP/28BwsJ/Brz0/LksVIgIzmcmV1aEc34VJhNYgjzZbRAImCRvDsKD/KMl6zCpRZMXY8pI+apnBT6j4qINGaAImF3cVT+mKGa7qwGuuOGBmQ2E7SoYAy2qzg3oAyHWvsCXMGQNaZLoJBd7vqooU7RXbOXIYqRQwzAeJBfIpGyF1jclzjbPNmA2TtdmFNLB4VdrYPrV0PGLi0/JhM3Z4R2KyARBmxvhpQPJA/ozXb1w4FRmzi7IA4KOVgcDYKHxnGM7q3GPficEBuJeIWJR2YCEb1VX7pVSy/0gHZliGgsBaB7MsIs4XLNeXTEz4uE0RNj4BLNdgBOZYkEwUBBWBmTREzmZCge0g36pkKOCDHgKyvABKmSIwwvf6o5bhQAAEY5qeEHDUm9+8OSJ7kmHYOLIzS8zOKG4alYJ08YFg5viGvh4TuckBkBIkbFmHhdy+uWAQCGPgZLgtV2r0OSKkEt+9fA4O1sTAgicuEq8SUDwcisd8dkERBCVwGKIDDD//G0vBbchIlg3UAAAgRBqyCu0uZHeiAZApO6bYI0frx8f9Q9PsJf1v/p1S1OR/rgMzZ797qRAk4IImC8svmlIADMme/e6sTJeCAJArKL5tTAg7InP3urU6UgAOSKCi/bE4JOCBz9ru3OlECDkiioPyyOSXggMzZ797qRAk4IImC8svmlIADMme/e6sTJeCAJArKL5tTAv8H9tmE9nVFdD4AAAAASUVORK5CYII=";

                    if(!resource.toUpperCase().indexOf("HTTP") == 0) return searchResultItem.type=="sketch"?`<img src="${sketchFavicon}"  />`:`<img src="${sketchFavicon}"  />`;

                    function loaded() {
                       alert("loaded!")
                    }
                    return `<img src="${registry.searchData.getFaviconAPI+resource}" onerror="this.src='${loadErrorFlagIcon}';" class="searchItem" />`
                    // return `<img src="${registry.searchData.getFaviconAPI+resource}" class="searchItem" />`
                }
         /*       $("#matchItems").on("load","li img", function (){
                   alert("加载完成!")
                })*/

                // 标题flag颜色选择器
                function titleFlagColorMatchHandler(flagValue) {
                   let vcObj = {
                      "系统项":"rgb(0,210,13)",
                      "非最佳":"rgb(244,201,13)",
                      "推荐":"rgb(91,184,93)",
                      "装机必备":"#9933E5",
                      "好物":"rgb(247,61,3)",
                      "Adults only": "rgb(244,201,13)"
                   }
                   let resultFlagColor = "#5eb95e";
                   Object.getOwnPropertyNames(vcObj).forEach(function(key){
                       if(key == flagValue) {
                           resultFlagColor = vcObj[key];
                       }
                   });
                   return resultFlagColor;
                }

                // 标题内容处理程序
                function titleFlagHandler(title) {
                    if(!(/[\[]?/.test(title) && /[\]]?/.test(title))) return -1;
                    // 格式是:[flag]title(desc):resource 这种的
                    const regex = /\[\s*([^\]]+)\s*\]\s*(.+)\s*/;
                    let m;
                    if ((m = regex.exec(title)) !== null) {
                        if(m.length != 3) return title;
                        // 正确提取
                        let style = `
                            background: ${titleFlagColorMatchHandler(m[1])};
                            color: #fff;
                            font-size: 10px;
                            padding: 2.5px 5px;
                            border-radius: 5px;
                            font-weight: 700;
                            box-sizing: border-box;
                        `;
                        return `<span style="${style}">${m[1]}</span> ${m[2]}`;

                    }
                    return -1;
                }
                // 标题前面带“#”的titleHandler
                function title井Handler(title) {
                   // 去掉flag
                   title = title.replace(/\[.*\]/,"").trim();
                   if(title.indexOf("#") == 0) {
                      let style = `text-decoration:line-through;color:#a8a8a8;`;
                      return `<span style="${style}">${title.replace("#","")}</span>`;
                   }
                   return -1;
                }

                function titleHandler(title) {
                    let titleHandlerFuns = registry.view.titleHandlerFuns;
                    for(let titleHandlerFun of titleHandlerFuns) {
                        let result = titleHandlerFun(title.trim());
                        if(result != -1) return result;
                    }
                    return title;

                }
                // 添加标题处理器 title井Handler (优化级较高)
                registry.view.titleHandlerFuns.push(title井Handler);
                // 添加标题处理器 titleFlagHandler
                registry.view.titleHandlerFuns.push(titleFlagHandler);

                for(let searchResultItem of searchResultData ) {
                    // 限制条数
                    if(show_item_number-- <= 0) {
                        break;
                    }
                    // 将数据放入局部容器中
                    searchData.push(searchResultItem)
                    // 将符合的数据装载到视图  //
                    let item = `
                    <li class="resultItem">${getFlag(searchResultItem)}
                        <a href="${searchResultItem.resource}" target="_blank" title="${searchResultItem.desc}" index="${searchResultItem.index}" >
                             ${titleHandler(searchResultItem.title)}
                             <span class="desc">(${searchResultItem.desc})</span>
                        </a>
                    </li>`
                    matchItems.html(matchItems.html() + item)

                }
                // 给刚才添加的img添加加载完成事件,去除加载背景
                for(let imgObj of $("#matchItems").find('img')) {
                   imgObj.onload = function(e) {
                       $(e.target).css({
                          "background": "rgba(0,0,0,0)"
                       })
                   }
                }


                 // 隐藏文本显示视图
                textShow.css({
                    "display":"none"
                })
                // 让搜索结果显示
                matchResult.css({
                    "display":"block"
                })
                // 将搜索的数据放入全局容器中
                registry.searchData.searchData = searchData;
                // 指令归位(置零)
                registry.searchData.pos = 0;
                // 设置li样式
                $("#matchResult li").css({
                    "line-height": "30px",
                    "height": "30px",
                    "color": "#0088cc",
                    "list-style": "none", //decimal
                    "width":"100%",
                    "margin":"0px",
                    "display":"flex",
                    "justify-content":"left",
                    "align-items":"center",
                    "padding":"0px",
                    "margin":"0px"

                })
                $("#matchResult li>a").css({
                    "display":"inline-block",
                    "font-size":"15px",
                    "color": "#1a0dab",
                    "text-decoration":"none",
                    "text-align":"left",
                    "overflow":"hidden", //超出的文本隐藏
                    "text-overflow":"ellipsis", //溢出用省略号显示
                    "white-space":"nowrap", //溢出不换行
                    "cursor":"pointer",
                    "font-weight":"400"
                })
                $("#matchResult .desc").css({
                    "color":"#4d5156"
                })
                $("#matchResult img").css({
                 "display": "inline-block",
                 "width": "17px",
                 "height":"17px",
                 "margin":"0px 7px 0px 5px",
                  "box-shadow": "0 0 2px rgba(0,0,0,0.5)",
                  "border-radius": "30%",
                  "box-sizing": " border-box",
                  "padding":"2px",
                  "flex-shrink":"0" // 当容量不够时,不压缩图片的大小

                })



            }
            // 给查询出来的结果添加事件 -- 设置事件委托
            $("#matchItems").on("click","li > a",function(e) {
                // 设置为阅读模式
                // $("#search_input").val(":read");
                // 获取当前结果在搜索数组中的索引
                let dataIndex = parseInt($(e.target).attr("index"));
                console.log("target==>",dataIndex)
                let itemData = registry.searchData.data[dataIndex];
                // 如果是简述搜索信息,那就取消a标签的默认跳转事件
                if(itemData.resource.trim().indexOf("http") !== 0) {
                   // 取消默认事件
                   e.preventDefault();
                   matchResult.css({
                      "display": "none"
                   })
                   textShow.css({
                      "display":"block"
                   })
                   textShow.html("<span style='color:red'>标题</span>:"+itemData.title+"<br />"+ "<span style='color:red'>描述:</span>"+itemData.desc+"<br />"+"<span style='color:red'>简述内容:</span><br />"+itemData.resource.replace(/\n/gm,"<br />"))
                   return;
                }
                // 取消冒泡
                window.event? window.event.cancelBubble = true : e.stopPropagation();
                // 隐藏视图
                registry.view.viewVisibilityController(false)
                // 否则是URL跳转
            })
            const refresh = debounce(handler, 460)
            // 第一次触发 scroll 执行一次 fn,后续只有在停止滑动 1 秒后才执行函数 fn
            searchBox.on('input', refresh)

            // 初始化后将isInitializedView变量设置为true
            isInitializedView = true;
        }
        let hideView = function () {
            // 隐藏视图
            // 如果视图还没有初始化,直接退出
            if (!isInitializedView) return;
            // 让视图隐藏
            viewDocument.style.display = "none";
            // 将输入框内容置空
            searchInputDocument.val("")
            // 将之前搜索结果置空
            matchItems.html("")
            // 隐藏文本显示视图
            textShow.css({
                "display":"none"
            })
            // 让搜索结果显示
            matchResult.css({
              "display":"block"
            })
        }
        let showView = function () {
            // 让视图可见
            viewDocument.style.display = "block";
            //聚焦
            searchInputDocument.focus()
            // 当输入框失去焦点时,隐藏视图
            searchInputDocument.blur(function() {
                // 判断输入框的内容是不是":debug"或是否正处于阅读模式,如果是,不隐藏
                if(isInstructions(searchInputDocument.val(),"debug") || isInstructions(searchInputDocument.val(),"read")) return;
                // 当前视图是否在展示数据,如搜索结果,简述内容?如果在展示不隐藏
                let isNotExhibition = (($("#matchResult").css("display") == "none" || $("#matchItems > li").length == 0 ) && ($("#text_show").css("display") == "none" || $("#text_show").text().trim() == "") );
                if(!isNotExhibition) return;
                setTimeout(()=>{registry.view.viewVisibilityController(false)},200)
            });


        }

        // 返回给外界控制视图显示与隐藏
        return function (isSetViewVisibility) {
            if (isSetViewVisibility) {
                // 让视图可见 >>>
                // 如果还没初始化先初始化   // 初始化数据 initData();
                if (!isInitializedView) {
                    // 初始化视图
                    initView();
                    // 初始化数据
                    // initData();
                }
                // 让视图可见
                showView();
            } else {
                // 隐藏视图 >>>
                if (isInitializedView) hideView();
            }
        }
    })();
    // 触发策略——快捷键
    let useKeyTrigger = function (viewVisibilityController) {
        // 将视图与触发策略绑定
        triggerAndEvent("ctrl+alt+s", function () {
            // 让视图可见
            viewVisibilityController(true);
        })
        triggerAndEvent("Escape", function () {
            // 让视图不可见
            viewVisibilityController(false);
        })
    }

    // 触发策略组
    let trigger_group = [useKeyTrigger];
    // 初始化入选的触发策略
    (function () {
        for (let trigger of trigger_group) {
            trigger(registry.view.viewVisibilityController);
        }
    })();




    // 打开视图进行配置
    // 显示配置视图
    // 是否显示进度 - 进度控制
    GM_registerMenuCommand("订阅管理",function() {
        showConfigView();
    });
    GM_registerMenuCommand("清理缓存",function() {
        cache.remove(registry.searchData.SEARCH_DATA_KEY);
    });

    // 显示配置规则视图

    function showConfigView() {
        if($("#subscribe_save")[0] != null) return;
        // 显示视图
        var configViewContainer = document.createElement("div");
        configViewContainer.style=`
            width:450px; background:pink;
            position: fixed;right: 0px; top: 0px;
            z-index:10000;
            padding: 20px;
            border-radius: 14px;
        `
        configViewContainer.innerHTML = `
           <p id="title">订阅总览:</p>
           <textarea id="all_subscribe" ></textarea>
           <button id="subscribe_save" >保存并应用</button>
        `;

        // 设置样式
        document.body.appendChild(configViewContainer);
        document.getElementById("title").style="margin-bottom: 10px; font-size: 16px;";
        document.getElementById("all_subscribe").style="width:100%;height:150px";
        document.getElementById("subscribe_save").style=" margin-top: 20px; border: none; border-radius: 3px; padding: 4px 20px; cursor: pointer;";
        // 回显
        document.getElementById("all_subscribe").value = getSubscribe();
        // 保存
        document.getElementById("subscribe_save").onclick=function() {
            // 保存到对象
           let allSubscribe = document.getElementById("all_subscribe").value;
           let validCount = editSubscribe(allSubscribe);
           // 清除视图
           configViewContainer.remove();
           alert("保存配置成功!有效订阅数:"+validCount);
        }
    }

})();