[
  {
    "bookSourceComment": "建议登录\n\n酷安 @吉王义昊\nGitHub：https://github.com/jiwangyihao/source-j-legado\n\n# 关于许可的额外声明（在线版本参见 GitHub，以在线版本为准）\n\n- 当许可证与本声明冲突时，以本声明为准；\n- 对于本仓库中的任意代码片段：按照 `MPL 2.0` 中有关约定执行；\n- 对于本仓库中的某一完整书源的转载或二次开发，需满足以下全部条件：\n  - 在[本仓库](https://github.com/jiwangyihao/source-j-legado)的 `issue` 中提出请求并具体说明转载地址、二次开发后的书源开源地址以及其他必要信息；\n  - 等待原作者（即本仓库的初始所有者和初始代码贡献者 [@jiwangyihao](https://github.com/jiwangyihao)）查看并通过 `issue` 或依据原作者要求更改转载方式或补充更详细的信息。\n  - 考虑到本项目弃坑的可能，新 `issue` 开启后超过 20 个工作日原作者没有回复或者原作者回复要求更改的 `issue` 在更改后超过 20 个工作日原作者没有回复即视为原作者通过该 `issue`：\n    - 此处的 `issue` 仅包括在[本仓库](https://github.com/jiwangyihao/source-j-legado)开启的，处于「开启状态」的 issue。（也就是说，请不要在已经关闭的 issue 中回复）。\n    - 对于此种方式通过的 issue，转载/二次开发者仍应当遵守本声明中已经写明的相关约定。\n  - 不得上传至源仓库或整理至`非轻小说专用`的书源合集中并应当避免其他人将转载/二次开发版本上传至源仓库或整理至`非轻小说专用`的书源合集中：\n    - 关于轻小说的定义的额外说明：不包括国内的原创网络文学作品（如 `SF 轻小说` 中的原创轻小说以及`起点中文网`中标签包含轻小说的作品）。\n    - 轻小说专用的定义：有且仅有想看轻小说的人可能会添加。\n  - 必须在转载/二次开发地址的明显位置完整包含本声明的全部内容。\n  - 必须保留源注释中原有的更改记录。",
    "bookSourceGroup": "轻小说,哔轻类似物",
    "bookSourceName": "轻之文库轻小说",
    "bookSourceType": 0,
    "bookSourceUrl": "https://m.wenkuchina.com",
    "bookUrlPattern": "",
    "concurrentRate": "",
    "coverDecodeJs": "",
    "customOrder": -41323,
    "enabled": true,
    "enabledCookieJar": true,
    "enabledExplore": true,
    "exploreUrl": "@js:\nres = []\n\n//筛选链接生成\nfunction generateFilterUrl(new_values) {\n  values = {\n    order: 'lastupdate',\n    anime: '0',\n    sortid: '0',\n    typeid: '0',\n    words: '0',\n    rgroupid: '0',\n    update: '0',\n    isfull: '0',\n    page: '{{page}}',\n  }\n  for (key in new_values) {\n  \t  values[key]=new_values[key]\n  \t}\n  return source.bookSourceUrl + '/wenku/' + values.order + '_' + values.anime + '_' + values.sortid + '_' + values.typeid + '_' + values.words + '_' + values.rgroupid + '_' + values.update + '_' + values.isfull + '_' + values.page + '.html';\n}\n\n//书架\nuser = ajax(source.bookSourceUrl + \"/user.php\")\n//java.toast(user)\ntry {\nif (user.match(/<h2 class=\"aui-center-title\">(登录|错误).*轻之文库轻小说.+<\\/h2>/gi)) {\n  //未登录\n  res.push(\n    {\n      title: `>> 我的书架 | 未登录 <<`,\n      url: '',\n      style: { layout_flexGrow: 1, layout_flexBasisPercent: 1 }\n    })\n} else {\n  //已登录\n  res.push(\n    {\n      title: `>> 我的书架 | ${user.match(/<span class=\"user-name\">.+<\\/span>/gi)[0].replace(/<\\/?span.*?>/gi,'')} <<`,\n      url: '',\n      style: { layout_flexGrow: 1, layout_flexBasisPercent: 1 }\n    })\n  bookcase = ajax(source.bookSourceUrl + \"/bookcase.php\")\n  bookcase.match(/<select[\\s\\S]+?<\\/select>/gi)[0].match(/<option.+<\\/option>/gi).forEach(option => {\n    res.push(\n      {\n        title: option.match(/>.*(?=<)/gi)[0].replace('>', ''),\n        url: source.bookSourceUrl + \"/bookcase.php?classid=\" + option.match(/value=\\\".+?(?=\\\")/gi)[0].replace(/(value=\\\")/gi, ''),\n        style: { layout_flexGrow: 1 }\n      })\n  })\n}\n} catch (e) {\n  throw(\"书架加载失败：\\n\"+e+\"\\n登录页源码：\\n\"+user)\n}\n\ncontent = ajax(source.bookSourceUrl + \"/wenku/\")\ncontent.match(/排序[\\s\\S]+?<\\/div>/gi)[0].match(/<a.+<\\/a>/gi).forEach(a => {\n  let filter = {}\n  let sortTitle = a.match(/>.+(?=<)/gi)[0].replace('>', '')\n  let type = \"order\"\n  let value = a.match(/\\/[^_/]+(?=_)/gi)[0].replace('/', '')\n  filter[type]=value;\n  content.match(/作品分类[\\s\\S]+?<\\/div>/gi)[0].match(/<a.+<\\/a>/gi).forEach((v, i) => {\n    let v_type = \"anime\"\n    let v_value = v.match(/\\/[^_/]+_\\d+(?=_)/gi)[0].replace(/\\/[^_/]+_/gi, '')\n    filter[v_type]=v_value;\n    if (i == 0) {\n      res.push(\n        {\n          title: `>> 作品分类 | ${sortTitle} <<`,\n          url: generateFilterUrl(filter),\n          style: { layout_flexGrow: 1, layout_flexBasisPercent: 1 }\n        })\n    } else {\n      res.push(\n        {\n          title: v.match(/>.+(?=<)/gi)[0].replace('>', ''),\n          url: generateFilterUrl(filter),\n          style: { layout_flexGrow: 1 }\n        })\n    }\n  })\n})\n\ncontent.match(/排序[\\s\\S]+?重置/gi)[0].match(/<li[\\s\\S]+?<\\/li>/gi).forEach(li => {\n  let sortTitle = li.match(/>.+(?=<\\/h3>)/gi)[0].replace('>', '')\n  res.push(\n    {\n      title: `>> ${sortTitle} <<`,\n      url: '',\n      style: { layout_flexGrow: 1, layout_flexBasisPercent: 1 }\n    })\n  li.match(/<a.+<\\/a>/gi).forEach((v, i) => {\n    if (i != 0) {\n      res.push(\n        {\n          title: v.match(/>.+(?=<)/gi)[0].replace('>', ''),\n          url: v.match(/href=\"[^\"]+(?=\")/gi)[0].replace('href=\"',\"\").replace(\"1.html\",\"{{page}}.html\"),\n          style: { layout_flexGrow: 1 }\n        })\n    }\n  })\n})\ntagContent = ajax(source.bookSourceUrl + \"/taglist/1.html\")\nres.push(\n  {\n    title: '>> 标签分类 <<',\n    url: '',\n    style: { layout_flexGrow: 1, layout_flexBasisPercent: 1 }\n  })\ntry {\ntagContent.match(/标签分类<\\/h3>[\\s\\S]+?重置/gi)[0].match(/<a.+<\\/a>/gi).forEach((v, i) => {\n  res.push(\n    {\n      title: v.match(/>.+(?=<)/gi)[0].replace('>', '').replace(\"&nbsp\",\"\"),\n      url: v.match(/href=\"[^\"]+(?=\")/gi)[0].replace('href=\"',\"\").replace(\"1.html\",\"{{page}}.html\"),\n      style: { layout_flexGrow: 1 }\n    })\n})\n} catch (e) {\n  throw(\"标签页解析错误：\"+e+\"\\n标签页源码：\\n\"+tagContent)\n}\nJSON.stringify(res)\n//throw(JSON.stringify(res))",
    "header": "{\n\"Referer\": \"https://m.wenkuchina.com/\",\n\"User-Agent\":\"\",\n\"Accept-Language\":\"zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6\",\n\"Accept\":\"*/*\"\n}",
    "jsLib": "function errorReg() {\n  return /(java.net.+Exception)|(okhttp.+Exception)|(error code: 1015)|(503 Service Temporarily Unavailable)|(Parse error.+in.+wwwroot.+php)|(_cf_chl_opt|challenges.css)|(<center.+>.+不支持)|(章节内容不支持该浏览器显示)/gi\n}\nfunction ajax(url) {\n  const { java, cookie } = this;\n  let content = \"\";\n  let time=1;\n  \tcontent = java.ajax(url);\n  \twhile (String(content).match(errorReg())) {\n    if (time>10) {\n  \t    java.toast(\"重试10次后仍请求失败：\"+url)\n  \t    throw(\"重试10次后仍请求失败：\"+url+content)\n  \t    break;\n    \t}\n    \tif(!!String(content).match(/不支持/gi)) {\n      //java.log(cookie.getCookie(url));\n      cookie.replaceCookie(url,java.webView(null,url,\"document.cookie\"));\n    \t}\n    \tif (!!String(content).match(/_cf_chl_opt|challenges.css/gi)) {\n    \t\t i = 1;\n      \twhile (!!String(content).match(/_cf_chl_opt|challenges.css/gi)) {\n\t       java.log('盾');\n\t       java.log(content);\n        if (i <= 1) {\n          java.toast(\"哦呼，五秒盾，正在尝试静默破盾ing……\");\n          content = java.webView(null,url,null);\n        } else {\n          java.toast(\"啊哦，静默破盾好像不管用，试试手动过校验吧！\");\n          content = java.startBrowserAwait(url,\"加载完毕后点完成，此页面可能会弹出多次\").body();\n        }\n        i++;\n      }\n      continue;\n    }\n  \t\t java.log(\"请求失败：\"+url)\n  \t\t java.log(\"重试\"+time+\"次\")\n  \t\t let t=new Date().getTime()\n    while (new Date().getTime() - t < 500) { }\n    if (String(content).match(/1015|503|php/gi)) {\n    \t  while (new Date().getTime() - t < 5000) { }\n    \t}\n  \t\t content = java.ajax(url);\n  \t\t time++;\n  \t}\n  \treturn String(content);\n}",
    "lastUpdateTime": 1717578188165,
    "loginUi": "[\n  {\n    \"name\": \"账号\",\n    \"type\": \"text\"\n  },\n  {\n    \"name\": \"密码\",\n    \"type\": \"password\"\n  }\n]",
    "loginUrl": "@js:\nfunction login() {\n  let une = source.getLoginInfoMap().get(\"账号\")\n  let pwd = source.getLoginInfoMap().get(\"密码\")\n  if (une && pwd) {\n    let body = String('username=' + une + '&password=' + pwd + '&usecookie=86400&act=login')\n    let url = source.bookSourceUrl + '/login.php?do=submit'\n    let res = java.post(url, body, {\n      \"Content-Type\": \"application/x-www-form-urlencoded\"\n    })\n    let ck = res.cookies()\n    if (res.body().match(/错误/gi)) {\n      throw(res.body().match(/<div class=\"aui-ver-form\">[\\s\\S]+<br>/gi)[0].replace(/<.+>\\s*/gi,\"\"))\n    }\n    let header = JSON.stringify({\n      \"Cookie\": String(ck).match(/\\{(.*?)\\}/)[1].replace(/,/g, ';')\n    })\n    source.putLoginHeader(header)\n  }\n}",
    "respondTime": 180000,
    "ruleBookInfo": {
      "author": "[property=\"og:novel:author\"]@content",
      "canReName": "1",
      "coverUrl": "[property=\"og:image\"]@content",
      "intro": "标签：{{@@class.tag-small red@text##\\s## - }}\n{{@@id.bookSummary@tag.content@textNodes}}",
      "kind": "class.book-cell@tag.p.1@ownText&&class.tag-small red@text\n##.*万字|·.*",
      "lastChapter": "class.gray ell@text##(\\d+-\\d+-\\d+\\s\\d+:\\d+)·(.*)##$2 • $1",
      "name": "[property=\"og:novel:book_name\"]@content",
      "tocUrl": "class.btn-normal red@href",
      "wordCount": "class.book-cell@tag.p.1@ownText##连载|完结"
    },
    "ruleContent": {
      "content": "id.acontent@html",
      "imageDecode": "",
      "imageStyle": "FULL",
      "nextContentUrl": "id.footlink@tag.a.-1@href\n@js:\n//121_2.html这样的是下一页，纯数字则是下一章\n//带有catalog是详情页\njava.log(\"url: \"+result)\nif (result==\"\") java.log(src)\nvar isNew=/(\\/(\\d+).html)|catalog/.test(result);\nvar out=isNew?'':result;\nout",
      "payAction": "",
      "replaceRegex": "##((?<=[\\u4e00-\\u9fa5“‘「（，])\\s+)?<!--\\s*\\（继续下一页\\）\\s*-->\\s*|((?<=[\\u4e00-\\u9fa5“‘「（，])\\s+)?\\（本章未完\\）\\s*|.+tmygod.+\\n",
      "title": "id.atitle@text"
    },
    "ruleExplore": {
      "author": "class.book-author@ownText",
      "bookList": "@js:\ni = 1;\n\nif (String(src).match(errorReg())) {\n  src=ajax(baseUrl);\n}\njava.setContent(src)\nresult = java.getElement(\"class.book-ol@tag.li\");\nresult;",
      "bookUrl": "a@href\n@js:\nresult.replace(/&cid=\\d+/gi, \"\")",
      "coverUrl": "img@data-src",
      "intro": "class.book-desc@text&&class.ell@text",
      "kind": "class.tag-small-group origin-right@tag.em.0@text&&\nclass.tag-small-group origin-right@tag.em.1@text&&\ntag.time@text\n@js:\nres=[]\nresult.forEach(item=>{\n    item.split(new RegExp(\"[ \\/]\",\"gi\")).forEach(i=>res.push(i))\n})\nres",
      "name": "class.book-li@tag.img@alt",
      "wordCount": "class.tag-small blue@text"
    },
    "ruleSearch": {
      "author": "class.book-author@textNodes",
      "bookList": "@js:\nif (String(result).match(errorReg())&&!result.includes(\"somework\")) {\n  result=ajax(baseUrl);\n}\nif (result.includes(\"no-js\")) {\n  java.log(result)\n  jsContent = java.cacheFile(java.getString(\"tag.script@src\").match(/http.+somework.+\\?v.+/gi)[0])\n  window = {\n    a: result.match(/window.a=\\'.+\\'/gi)[0].replace(/window.a=|\\'/gi, ''),\n    b: result.match(/window.b=\\'.+\\'/gi)[0].replace(/window.b=|\\'/gi, ''),\n    c: result.match(/window.c=\\'.+\\'/gi)[0].replace(/window.c=|\\'/gi, ''),\n    crypto: {\n      subtle: {\n        importKey(format, keyData, algorithm, extractable, keyUsages) {\n          return {\n            then(func) { func(keyData) }\n          }\n        },\n        decrypt(algorithm, key, data) {\n          cipher = java.createSymmetricCrypto(\"AES/CTR/NoPadding\", key, algorithm.counter)\n          return {\n            then: (func) => { func(cipher.decryptStr(data)) }\n          }\n        }\n      }\n    }\n  }\n  setTimeout = () => { }\n  function TextDecoder() { }\n  TextDecoder.prototype.decode = bytes => bytes\n  document = { cookie: \"\" }\n  java.log(jsContent)\n  funcName=String(jsContent).match(/^function.+\\(/gi)[0].replace(/function| |\\(/gi,'')\n  \tjava.log(funcName)\n  eval(funcName + ' = str => java.base64DecodeToByteArray(str)')\n  eval(String(jsContent)\n    .replace(/^function.+\\(/gi, 'function ('))\n  java.log(document.cookie)\n  cookie.replaceCookie(baseUrl, document.cookie)\n  do {\n    t = new Date().getTime()\n    while (new Date().getTime() - t < 5000) { }\n    java.setContent(result = ajax(baseUrl + \",\"\n      + JSON.stringify({\n        headers: {\n          Cookie: cookie.getCookie(baseUrl)\n        }\n      })))\n    java.log(result)\n  } while (result.includes(\"no-js\"))\n}\njava.getElement(\"class.book-ol book-ol-normal@tag.li\")",
      "bookUrl": "tag.a.0@href",
      "checkKeyWord": "我的青春恋爱喜剧",
      "coverUrl": "img@data-src",
      "intro": "class.book-desc@text",
      "kind": "class.tag-small-group origin-right@tag.em@text\n@js:\nres=[]\nresult.forEach(item=>{\n    item.split(new RegExp(\"[ \\/]\",\"gi\")).forEach(i=>res.push(i))\n})\nres",
      "name": "class.book-title-x@class.book-title@text"
    },
    "ruleToc": {
      "chapterList": "id.catelogX@class.chapter-li\n@js:\n    //现实debug(尝试修复正文链接问题，和目录不全)\n    //《好友角色的我怎么可能大受欢迎》第三卷12\n    //《我的青春恋爱喜剧》\n    //2022-8-19\n    //原来的代码在源注释（已移除）\n    //2022-8-20修复https://w.linovelib.com/novel/2765.html目录加载失败\n    //2023-9-30使用易于理解的变量命名\n    //2023-10-7处理cid(1)以及连续多个cid(0)\n    //2023-11-11解决了一个原来手滑写出的bug\n    //2023-11-16处理连续多个卷名\n    //2023-12-12适配新版卷名\n    //2024-2-6处理《谁说从妥协开始的恋爱一定没结果》\n\nres = result\n//java.log(res)\n\nfor (i = 0; i < res.length; i++) {\n    java.setContent(res[i])\n    if (java.getString(\"tag.a@href\").match(/javascript:cid\\(.+\\)/gi)) {\n        if (String(res[(i == res.length - 1?i:i+1)]).match(/javascript:cid\\(.+\\)/gi)) {\n            java.setContent(res[i - 1])\n            prevLink = java.getString(\"tag.a@href\")\n            if (prevLink == \"\") {\n                java.setContent(res[i - 2])\n                prevLink = java.getString(\"tag.a@href\")\n            }\n            content = ajax(source.bookSourceUrl + prevLink)\n            java.setContent(content)\n            foot = java.getElements(\"id.footlink\")\n            path = prevLink\n\n            //java.log(foot)\n            while (String(foot).match(/下一页|下一頁/gi)) {\n            \t    //java.log(foot)\n                str = content.match(/<script type\\=\\\"text\\/javascript\\\">var ReadParams.*/)\n                path = String(str).match(/url_next\\:'.*?html/)[0].replace(\"url_next:'\", \"\")\n                content = java.ajax(\"https://w.linovelib.com\" + path)\n                java.setContent(content)\n                foot = java.getElements(\"id.footlink\")\n            }\n\n            next = ajax(source.bookSourceUrl + path)\n            str = next.match(/<script type\\=\\\"text\\/javascript\\\">var ReadParams.*/)\n            path = String(str).match(/url_next\\:'.*?html/)[0].replace(\"url_next:'\", \"\")\n            java.log('l:'+path)\n            res[i] = String(res[i]).replace(/javascript:cid\\(.+\\)/gi, path)\n        } else {\n            nextLink = \"\"\n            for (var j=1;nextLink==\"\";j++) {\n                java.setContent(res[i + j])\n                nextLink = java.getString(\"tag.a@href\")\n            }\n            next = ajax(source.bookSourceUrl + nextLink)\n            str = next.match(/<script type\\=\\\"text\\/javascript\\\">var ReadParams.*/)\n            try {\n              path = String(str).match(/url_previous\\:'.*?html/)[0].replace(\"url_previous:'\", \"\")\n            } catch(e) {\n            \t  java.toast(String(next)+\"\\n\")\n            \t  java.log(next)\n            \t  throw(\"目录解析报错开始：\\n\"+String(next)+\"\\n结束\")\n            \t}\n            //java.log(path)\n\n            res[i] = String(res[i]).replace(/javascript:cid\\(.+\\)/gi, path)\n        }\n    }\n\n    //java.log(res[i])\n}\nres",
      "chapterName": "text",
      "chapterUrl": "@js:\n//只有不为卷名时返回URL，避免阅读自动合并\njava.getString(\"class.chapter-bar@text\")!=java.getString(\"text\") ? java.getString(\"tag.a@href\") : \"\"",
      "isVolume": "@js:\njava.getString(\"class.chapter-bar@text\")==java.getString(\"text\")",
      "updateTime": ""
    },
    "searchUrl": "<js>\npage == 1 ?\n  \"/search.html?searchkey={{key}}&searchtype=all\"\n  :\n  '/search/{{key}}/{{page}}.html'\n</js>",
    "weight": 0
  },
  {
    "bookSourceComment": "建议登录\n\n酷安 @吉王义昊\nGitHub：https://github.com/jiwangyihao/source-j-legado\n\n# 关于许可的额外声明（在线版本参见 GitHub，以在线版本为准）\n\n- 当许可证与本声明冲突时，以本声明为准；\n- 对于本仓库中的任意代码片段：按照 `MPL 2.0` 中有关约定执行；\n- 对于本仓库中的某一完整书源的转载或二次开发，需满足以下全部条件：\n  - 在[本仓库](https://github.com/jiwangyihao/source-j-legado)的 `issue` 中提出请求并具体说明转载地址、二次开发后的书源开源地址以及其他必要信息；\n  - 等待原作者（即本仓库的初始所有者和初始代码贡献者 [@jiwangyihao](https://github.com/jiwangyihao)）查看并通过 `issue` 或依据原作者要求更改转载方式或补充更详细的信息。\n  - 考虑到本项目弃坑的可能，新 `issue` 开启后超过 20 个工作日原作者没有回复或者原作者回复要求更改的 `issue` 在更改后超过 20 个工作日原作者没有回复即视为原作者通过该 `issue`：\n    - 此处的 `issue` 仅包括在[本仓库](https://github.com/jiwangyihao/source-j-legado)开启的，处于「开启状态」的 issue。（也就是说，请不要在已经关闭的 issue 中回复）。\n    - 对于此种方式通过的 issue，转载/二次开发者仍应当遵守本声明中已经写明的相关约定。\n  - 不得上传至源仓库或整理至`非轻小说专用`的书源合集中并应当避免其他人将转载/二次开发版本上传至源仓库或整理至`非轻小说专用`的书源合集中：\n    - 关于轻小说的定义的额外说明：不包括国内的原创网络文学作品（如 `SF 轻小说` 中的原创轻小说以及`起点中文网`中标签包含轻小说的作品）。\n    - 轻小说专用的定义：有且仅有想看轻小说的人可能会添加。\n  - 必须在转载/二次开发地址的明显位置完整包含本声明的全部内容。\n  - 必须保留源注释中原有的更改记录。",
    "bookSourceGroup": "轻小说,哔轻类似物",
    "bookSourceName": "三七轻小说",
    "bookSourceType": 0,
    "bookSourceUrl": "https://m.37yq.com",
    "bookUrlPattern": "",
    "concurrentRate": "",
    "coverDecodeJs": "",
    "customOrder": -41322,
    "enabled": true,
    "enabledCookieJar": true,
    "enabledExplore": true,
    "exploreUrl": "@js:\nres = []\n\n//筛选链接生成\nfunction generateFilterUrl(new_values) {\n  values = {\n    order: 'lastupdate',\n    anime: '0',\n    sortid: '0',\n    typeid: '0',\n    words: '0',\n    rgroupid: '0',\n    update: '0',\n    isfull: '0',\n    page: '{{page}}',\n  }\n  for (key in new_values) {\n  \t  values[key]=new_values[key]\n  \t}\n  return source.bookSourceUrl + '/wenku/' + values.order + '_' + values.anime + '_' + values.sortid + '_' + values.typeid + '_' + values.words + '_' + values.rgroupid + '_' + values.update + '_' + values.isfull + '_' + values.page + '.html';\n}\n\n//书架\nuser = ajax(source.bookSourceUrl + \"/user.php\")\n//java.toast(user)\ntry {\nif (user.match(/<h2 class=\"aui-center-title\">(登录|错误).*三七轻小说<\\/h2>/gi)) {\n  //未登录\n  res.push(\n    {\n      title: `>> 我的书架 | 未登录 <<`,\n      url: '',\n      style: { layout_flexGrow: 1, layout_flexBasisPercent: 1 }\n    })\n} else {\n  //已登录\n  res.push(\n    {\n      title: `>> 我的书架 | ${user.match(/<span class=\"user-name\">.+<\\/span>/gi)[0].replace(/<\\/?span.*?>/gi,'')} <<`,\n      url: '',\n      style: { layout_flexGrow: 1, layout_flexBasisPercent: 1 }\n    })\n  bookcase = ajax(source.bookSourceUrl + \"/bookcase.php\")\n  bookcase.match(/<select[\\s\\S]+?<\\/select>/gi)[0].match(/<option.+<\\/option>/gi).forEach(option => {\n    res.push(\n      {\n        title: option.match(/>.+(?=<)/gi)[0].replace('>', ''),\n        url: source.bookSourceUrl + \"/bookcase.php?classid=\" + option.match(/value=\\\".+?(?=\\\")/gi)[0].replace(/(value=\\\")/gi, ''),\n        style: { layout_flexGrow: 1 }\n      })\n  })\n}\n} catch (e) {\n  throw(\"书架加载失败：\\n\"+e+\"\\n登录页源码：\\n\"+user)\n}\n\ncontent = ajax(source.bookSourceUrl + \"/wenku/\")\ncontent.match(/排序[\\s\\S]+?<\\/div>/gi)[0].match(/<a.+<\\/a>/gi).forEach(a => {\n  let filter = {}\n  let sortTitle = a.match(/>.+(?=<)/gi)[0].replace('>', '')\n  let type = \"order\"\n  let value = a.match(/\\/[^_/]+(?=_)/gi)[0].replace('/', '')\n  filter[type]=value;\n  content.match(/作品分类[\\s\\S]+?<\\/div>/gi)[0].match(/<a.+<\\/a>/gi).forEach((v, i) => {\n    let v_type = \"anime\"\n    let v_value = v.match(/\\/[^_/]+_\\d+(?=_)/gi)[0].replace(/\\/[^_/]+_/gi, '')\n    filter[v_type]=v_value;\n    if (i == 0) {\n      res.push(\n        {\n          title: `>> 作品分类 | ${sortTitle} <<`,\n          url: generateFilterUrl(filter),\n          style: { layout_flexGrow: 1, layout_flexBasisPercent: 1 }\n        })\n    } else {\n      res.push(\n        {\n          title: v.match(/>.+(?=<)/gi)[0].replace('>', ''),\n          url: generateFilterUrl(filter),\n          style: { layout_flexGrow: 1 }\n        })\n    }\n  })\n})\n\ncontent.match(/排序[\\s\\S]+?重置/gi)[0].match(/<li[\\s\\S]+?<\\/li>/gi).forEach(li => {\n  let sortTitle = li.match(/>.+(?=<\\/h3>)/gi)[0].replace('>', '')\n  res.push(\n    {\n      title: `>> ${sortTitle} <<`,\n      url: '',\n      style: { layout_flexGrow: 1, layout_flexBasisPercent: 1 }\n    })\n  li.match(/<a.+<\\/a>/gi).forEach((v, i) => {\n    if (i != 0) {\n      res.push(\n        {\n          title: v.match(/>.+(?=<)/gi)[0].replace('>', ''),\n          url: v.match(/href=\"[^\"]+(?=\")/gi)[0].replace('href=\"',\"\").replace(\"1.html\",\"{{page}}.html\"),\n          style: { layout_flexGrow: 1 }\n        })\n    }\n  })\n})\ntagContent = ajax(source.bookSourceUrl + \"/taglist/1.html\")\nres.push(\n  {\n    title: '>> 标签分类 <<',\n    url: '',\n    style: { layout_flexGrow: 1, layout_flexBasisPercent: 1 }\n  })\ntry {\ntagContent.match(/标签分类<\\/h3>[\\s\\S]+?重置/gi)[0].match(/<a.+<\\/a>/gi).forEach((v, i) => {\n  res.push(\n    {\n      title: v.match(/>.+(?=<)/gi)[0].replace('>', ''),\n      url: v.match(/href=\"[^\"]+(?=\")/gi)[0].replace('href=\"',\"\").replace(\"1.html\",\"{{page}}.html\"),\n      style: { layout_flexGrow: 1 }\n    })\n})\n} catch (e) {\n  throw(\"标签页解析错误：\"+e+\"\\n标签页源码：\\n\"+tagContent)\n}\nJSON.stringify(res)\n//throw(JSON.stringify(res))",
    "header": "{\n\"Referer\": \"https://m.37yq.com\",\n\"User-Agent\":\"\",\n}",
    "jsLib": "function errorReg() {\n  return /(java.net.+Exception)|(okhttp.+Exception)|(error code: 1015)|(503 Service Temporarily Unavailable)|(Parse error.+in.+wwwroot.+php)|(_cf_chl_opt|challenges.css)|(<center.+>.+不支持)|(章节内容不支持该浏览器显示)/gi\n}\nfunction ajax(url) {\n  const { java, cookie } = this;\n  let content = \"\";\n  let time=1;\n  \tcontent = java.ajax(url);\n  \twhile (String(content).match(errorReg())) {\n    if (time>10) {\n  \t    java.toast(\"重试10次后仍请求失败：\"+url)\n  \t    throw(\"重试10次后仍请求失败：\"+url+content)\n  \t    break;\n    \t}\n    \tif(!!String(content).match(/不支持/gi)) {\n      //java.log(cookie.getCookie(url));\n      cookie.replaceCookie(url,java.webView(null,url,\"document.cookie\"));\n    \t}\n    \tif (!!String(content).match(/_cf_chl_opt|challenges.css/gi)) {\n    \t\t i = 1;\n      \twhile (!!String(content).match(/_cf_chl_opt|challenges.css/gi)) {\n\t       java.log('盾');\n\t       java.log(content);\n        if (i <= 1) {\n          java.toast(\"哦呼，五秒盾，正在尝试静默破盾ing……\");\n          content = java.webView(null,url,null);\n        } else {\n          java.toast(\"啊哦，静默破盾好像不管用，试试手动过校验吧！\");\n          content = java.startBrowserAwait(url,\"加载完毕后点完成，此页面可能会弹出多次\").body();\n        }\n        i++;\n      }\n      continue;\n    }\n  \t\t java.log(\"请求失败：\"+url)\n  \t\t java.log(\"重试\"+time+\"次\")\n  \t\t let t=new Date().getTime()\n    while (new Date().getTime() - t < 500) { }\n    if (String(content).match(/1015|503|php/gi)) {\n    \t  while (new Date().getTime() - t < 5000) { }\n    \t}\n  \t\t content = java.ajax(url);\n  \t\t time++;\n  \t}\n  \treturn String(content);\n}",
    "lastUpdateTime": 1716525120257,
    "loginUi": "[\n  {\n    \"name\": \"账号\",\n    \"type\": \"text\"\n  },\n  {\n    \"name\": \"密码\",\n    \"type\": \"password\"\n  }\n]",
    "loginUrl": "@js:\nfunction login() {\n  let une = source.getLoginInfoMap().get(\"账号\")\n  let pwd = source.getLoginInfoMap().get(\"密码\")\n  if (une && pwd) {\n    let body = String('username=' + une + '&password=' + pwd + '&usecookie=86400&act=login')\n    let url = source.bookSourceUrl + '/login.php?do=submit'\n    let res = java.post(url, body, {\n      \"Content-Type\": \"application/x-www-form-urlencoded\"\n    })\n    let ck = res.cookies()\n    if (res.body().match(/错误/gi)) {\n      throw(res.body().match(/<div class=\"aui-ver-form\">[\\s\\S]+<br>/gi)[0].replace(/<.+>\\s*/gi,\"\"))\n    }\n    let header = JSON.stringify({\n      \"Cookie\": String(ck).match(/\\{(.*?)\\}/)[1].replace(/,/g, ';')\n    })\n    source.putLoginHeader(header)\n  }\n}",
    "respondTime": 180000,
    "ruleBookInfo": {
      "author": "[property=\"og:novel:author\"]@content",
      "canReName": "1",
      "coverUrl": "[property=\"og:image\"]@content",
      "intro": "标签：{{@@class.tag-small red@text##\\s## - }}\n{{@@id.bookSummary@tag.content@textNodes}}",
      "kind": "class.book-cell@tag.p.1@ownText&&class.tag-small red@text\n##.*万字|·.*",
      "lastChapter": "class.gray ell@text##(\\d+-\\d+-\\d+\\s\\d+:\\d+)·(.*)##$2 • $1",
      "name": "[property=\"og:novel:book_name\"]@content",
      "tocUrl": "class.btn-normal red@href",
      "wordCount": "class.book-cell@tag.p.1@ownText##连载|完结"
    },
    "ruleContent": {
      "content": "id.acontent@html",
      "imageDecode": "",
      "imageStyle": "FULL",
      "nextContentUrl": "##url_next:'([^']*)'##$1###\n@js:\n//121_2.html这样的是下一页，纯数字则是下一章\n//带有catalog是详情页\njava.log(\"url: \"+result)\nif (result==\"\") java.log(src)\nvar isNew=/(\\/(\\d+).html)|catalog/.test(result);\nvar out=isNew?'':result;\nout",
      "payAction": "",
      "replaceRegex": "##((?<=[\\u4e00-\\u9fa5“‘「（，])\\s+)?<!--\\s*\\（继续下一页\\）\\s*-->\\s*|((?<=[\\u4e00-\\u9fa5“‘「（，])\\s+)?\\（本章未完\\）\\s*|.+tmygod.+\\n",
      "title": "id.atitle@text"
    },
    "ruleExplore": {
      "author": "class.book-author@ownText",
      "bookList": "@js:\ni = 1;\n\nif (String(src).match(errorReg())) {\n  src=ajax(baseUrl);\n}\njava.setContent(src)\nresult = java.getElement(\"class.book-ol@tag.li\");\nresult;",
      "bookUrl": "a@href\n@js:\nresult.replace(/&cid=\\d+/gi, \"\")",
      "coverUrl": "img@data-src",
      "intro": "class.book-desc@text&&class.ell@text",
      "kind": "class.tag-small-group origin-right@tag.em.0@text&&\nclass.tag-small-group origin-right@tag.em.1@text&&\ntag.time@text\n@js:\nres=[]\nresult.forEach(item=>{\n    item.split(new RegExp(\"[ \\/]\",\"gi\")).forEach(i=>res.push(i))\n})\nres",
      "name": "class.book-li@tag.img@alt",
      "wordCount": "class.tag-small blue@text"
    },
    "ruleSearch": {
      "author": "class.book-author@textNodes",
      "bookList": "@js:\nif (String(result).match(errorReg())&&!result.includes(\"somework\")) {\n  result=ajax(baseUrl);\n}\nif (result.includes(\"no-js\")) {\n  java.log(result)\n  jsContent = java.cacheFile(java.getString(\"tag.script@src\").match(/http.+somework.+\\?v.+/gi)[0])\n  window = {\n    a: result.match(/window.a=\\'.+\\'/gi)[0].replace(/window.a=|\\'/gi, ''),\n    b: result.match(/window.b=\\'.+\\'/gi)[0].replace(/window.b=|\\'/gi, ''),\n    c: result.match(/window.c=\\'.+\\'/gi)[0].replace(/window.c=|\\'/gi, ''),\n    crypto: {\n      subtle: {\n        importKey(format, keyData, algorithm, extractable, keyUsages) {\n          return {\n            then(func) { func(keyData) }\n          }\n        },\n        decrypt(algorithm, key, data) {\n          cipher = java.createSymmetricCrypto(\"AES/CTR/NoPadding\", key, algorithm.counter)\n          return {\n            then: (func) => { func(cipher.decryptStr(data)) }\n          }\n        }\n      }\n    }\n  }\n  setTimeout = () => { }\n  function TextDecoder() { }\n  TextDecoder.prototype.decode = bytes => bytes\n  document = { cookie: \"\" }\n  java.log(jsContent)\n  funcName=String(jsContent).match(/^function.+\\(/gi)[0].replace(/function| |\\(/gi,'')\n  \tjava.log(funcName)\n  eval(funcName + ' = str => java.base64DecodeToByteArray(str)')\n  eval(String(jsContent)\n    .replace(/^function.+\\(/gi, 'function ('))\n  java.log(document.cookie)\n  cookie.replaceCookie(baseUrl, document.cookie)\n  do {\n    t = new Date().getTime()\n    while (new Date().getTime() - t < 5000) { }\n    java.setContent(result = ajax(baseUrl + \",\"\n      + JSON.stringify({\n        headers: {\n          Cookie: cookie.getCookie(baseUrl)\n        }\n      })))\n    java.log(result)\n  } while (result.includes(\"no-js\"))\n}\njava.getElement(\"class.book-ol book-ol-normal@tag.li\")",
      "bookUrl": "tag.a.0@href",
      "checkKeyWord": "我的青春恋爱喜剧",
      "coverUrl": "a@href@js:\nvar id = result.match(/\\/(\\d+)\\.html/)[1];\n'https://m.37yq.com/files/article/image/'+parseInt(id/1000)+'/'+id+'/'+id+'s.jpg';",
      "intro": "class.book-desc@text",
      "kind": "class.tag-small-group origin-right@tag.em@text\n@js:\nres=[]\nresult.forEach(item=>{\n    item.split(new RegExp(\"[ \\/]\",\"gi\")).forEach(i=>res.push(i))\n})\nres",
      "name": "class.book-title-x@class.book-title@text"
    },
    "ruleToc": {
      "chapterList": "id.catelogX@class.chapter-li\n@js:\n    //现实debug(尝试修复正文链接问题，和目录不全)\n    //《好友角色的我怎么可能大受欢迎》第三卷12\n    //《我的青春恋爱喜剧》\n    //2022-8-19\n    //原来的代码在源注释（已移除）\n    //2022-8-20修复https://w.linovelib.com/novel/2765.html目录加载失败\n    //2023-9-30使用易于理解的变量命名\n    //2023-10-7处理cid(1)以及连续多个cid(0)\n    //2023-11-11解决了一个原来手滑写出的bug\n    //2023-11-16处理连续多个卷名\n    //2023-12-12适配新版卷名\n    //2024-2-6处理《谁说从妥协开始的恋爱一定没结果》\n\nres = result\n//java.log(res)\n\nfor (i = 0; i < res.length; i++) {\n    java.setContent(res[i])\n    if (java.getString(\"tag.a@href\").match(/javascript:cid\\(.+\\)/gi)) {\n        if (String(res[(i == res.length - 1?i:i+1)]).match(/javascript:cid\\(.+\\)/gi)) {\n            java.setContent(res[i - 1])\n            prevLink = java.getString(\"tag.a@href\")\n            if (prevLink == \"\") {\n                java.setContent(res[i - 2])\n                prevLink = java.getString(\"tag.a@href\")\n            }\n            content = ajax(source.bookSourceUrl + prevLink)\n            java.setContent(content)\n            foot = java.getElements(\"id.footlink\")\n            path = prevLink\n\n            //java.log(foot)\n            while (String(foot).match(/下一页|下一頁/gi)) {\n            \t    //java.log(foot)\n                str = content.match(/<script type\\=\\\"text\\/javascript\\\">var ReadParams.*/)\n                path = String(str).match(/url_next\\:'.*?html/)[0].replace(\"url_next:'\", \"\")\n                content = java.ajax(\"https://w.linovelib.com\" + path)\n                java.setContent(content)\n                foot = java.getElements(\"id.footlink\")\n            }\n\n            next = ajax(source.bookSourceUrl + path)\n            str = next.match(/<script type\\=\\\"text\\/javascript\\\">var ReadParams.*/)\n            path = String(str).match(/url_next\\:'.*?html/)[0].replace(\"url_next:'\", \"\")\n            java.log('l:'+path)\n            res[i] = String(res[i]).replace(/javascript:cid\\(.+\\)/gi, path)\n        } else {\n            nextLink = \"\"\n            for (var j=1;nextLink==\"\";j++) {\n                java.setContent(res[i + j])\n                nextLink = java.getString(\"tag.a@href\")\n            }\n            next = ajax(source.bookSourceUrl + nextLink)\n            str = next.match(/<script type\\=\\\"text\\/javascript\\\">var ReadParams.*/)\n            try {\n              path = String(str).match(/url_previous\\:'.*?html/)[0].replace(\"url_previous:'\", \"\")\n            } catch(e) {\n            \t  java.toast(String(next)+\"\\n\")\n            \t  java.log(next)\n            \t  throw(\"目录解析报错开始：\\n\"+String(next)+\"\\n结束\")\n            \t}\n            //java.log(path)\n\n            res[i] = String(res[i]).replace(/javascript:cid\\(.+\\)/gi, path)\n        }\n    }\n\n    //java.log(res[i])\n}\nres",
      "chapterName": "text",
      "chapterUrl": "@js:\n//只有不为卷名时返回URL，避免阅读自动合并\njava.getString(\"class.chapter-bar@text\")!=java.getString(\"text\") ? java.getString(\"tag.a@href\") : \"\"",
      "isVolume": "@js:\njava.getString(\"class.chapter-bar@text\")==java.getString(\"text\")",
      "updateTime": ""
    },
    "searchUrl": "<js>\npage == 1 ?\n  \"/so.html?searchkey={{key}}&searchtype=all\"\n  :\n  '/so/{{key}}/{{page}}.html'\n</js>",
    "weight": 0
  }
]