bikamanhua.com(哔咔漫画/PicAcg) 增强

增强体验:1. 自动调节图片高度、宽度;2. 手动修改图片最大高度, 一行装下更多图; 3. 使用方向键或鼠标按键/滚轮进行快速翻页; 4. 阅读背景、图片边框

// ==UserScript==
// @name         bikamanhua.com(哔咔漫画/PicAcg) 增强
// @version      3.5
// @namespace    zrh
// @author       RainWater
// @license MIT
// @description 增强体验:1. 自动调节图片高度、宽度;2. 手动修改图片最大高度, 一行装下更多图; 3. 使用方向键或鼠标按键/滚轮进行快速翻页; 4. 阅读背景、图片边框
// @description:zh-CN  增强体验:1. 自动调节图片高度、宽度;2. 手动修改图片最大高度, 一行装下更多图; 3. 使用方向键或鼠标按键/滚轮进行快速翻页; 4. 阅读背景、图片边框
// @description:en  1. Automatically adjust the height and width of the picture; 2. Manually modify the maximum height of the picture to fit more pictures in one line; 3. Use the arrow keys or mouse buttons/wheel to quickly turn pages; 4. Read the background and picture borders
// @match        https://manhuabika.com/*
// @match        http://manhuabika.com/*
// @match        https://manhuapica.com/*
// @match        http://manhuapica.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=manhuabika.com
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @run-at       document-end
// ==/UserScript==



// IOS Safari 浏览器兼容
if (typeof unsafeWindow === 'undefined') {
    unsafeWindow = window;
  }
  // 下一页点击区域比例
  var nextPageScreenClickPercent = 70;

  // 图片最大高度
  var myImgMaxHeightNum = "800";
  // 图片懒加载
  var isLazyLoad = "0";
  // 自动隐藏栏
  var isAutoHide = "1";
  // 透明度
  var myBottomOpacity = 95;
  // 图片边框颜色
  var myBorderColor = "#89e5f5";
  // 图片边框宽度
  var myBorderSize = 1.5;
  // 背景颜色
  var myBackgroundColor = "#dca0a0";

  // 是否启用 自动宽度(竖屏模式)( scriptInit 函数中根据设备类型重新赋默认值)
  var isVerticalModeEnable = '0';

  // 是否启用 自动高度(scriptInit函数中根据设备类型重新赋默认值)
  var isAutoHeightModeEnable = '0';

  // 是否启用 滚动翻页
  var isWheelTurnPageEnable = '1';

  // 滚动临界值
  var scrollThreshold = 20;

  // 当前是否为手机(不保存到localStorage)
  var isMobile = false;



  var pica_urls = ['https://manhuabika.com/', 'https://manhuapica.com/','http://manhuabika.com/', 'http://manhuapica.com/'];

  (function() {

      'use strict';

      // webtoon 漫画本插件不启动
      if (store.session("webtoon"))
        return;


      // 网页BUG修复
      // DOMAINBUGFIX();

      // // 替换函数
      functionReplace();

      // 插件初始化
      scriptInit();

      // 加载配置参数
      readLocalStorage();

      // 添加网页标题
      addTitle();

      // 插件添加菜单
      addMenu();
      // 减少冗余动画
      lessLoaderDisplay();
      // 添加自定义函数
      addUserVar();

      // 添加网页标题
      addTitle();

      //去广告
      removeAD();

      // 本子欣赏页面
      if (document.URL.indexOf("pchapter") !== -1) {

          pchapterFunc();

      }

      // 本子搜索页面
      if((document.URL.indexOf("pcomiclist") !== -1)) {
        pcomiclistFunc();
      }

      // 本子预览页面
      if((document.URL.indexOf("pcomicview") !== -1)) {
        pcomicviewFunc();
      }


      // 所有页面
      allPageFunc();

  })();
  // 脚本初始化
  function scriptInit(){
    // 移动设备在没有设定的情况下,默认开启竖屏模式
    isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
    console.log("是否为移动设备:" + isMobile)
    if (isMobile) {
      isVerticalModeEnable = '1';
      isAutoHeightModeEnable = '0';
      isWheelTurnPageEnable = '0';
    } else {
      isVerticalModeEnable = '0';
      isAutoHeightModeEnable = '1';
      isWheelTurnPageEnable = '1';
    }
  }


  // 添加用户自定义变量/函数
  function addUserVar() {
    unsafeWindow.userGetComicInfo = userGetComicInfo;
    unsafeWindow.userGetChapterInfo = userGetChapterInfo;

  }

  function pchapterComponentsAssemble(){
    console.log("hello")
    // $(".appBottomMenu").prepend($(`<div id="mobile-left-box"><button id="btn-left-box-trigger">LEFT BOX TRIGGER</button></div>`))
    $("body").append($("<div id='bottom-wrapper'></div>"))
      $(".appBottomMenu").appendTo($('#bottom-wrapper'))
      $(".appBottomMenu").prepend($(`
  <div id="my-setting-div" class=" user-fixed">

    <div class=" collapse" id="my-collapse-div">

    </div>
    <button class="btn-collapse-toggle btn btn-primary" data-bs-toggle="collapse" data-bs-target="#my-collapse-div" aria-expanded="false" aria-controls="my-collapse-div">
      哔咔优化
    </button>
  </div>
      `))

    let collapseDiv = $("#my-collapse-div")[0]
    let ul = $("<ul></ul>");
    $("#left-box>*").each(function(){
      let li_item = $("<li></li>")
      $(this).appendTo($(li_item))
      $(li_item).appendTo(ul)

  })

    ul.appendTo(collapseDiv)

      GM_addStyle(`
  #my-collapse-div{
    position: absolute;
    z-index= 99999;
    inset: auto auto 0px 0px;
    transform: translateY(-${$(".appBottomMenu").height()}px);
    background-color: ${myBorderColor};
    padding: 15px 15px 15px 15px;
    border-radius: 20px;

  }
  #my-collapse-div>ul{
    list-style: none;
    padding-left: 0px;
  }
  `)

  }

  function allPageFunc(){
    // 设置背景色
    GM_addStyle(`
      body, body.bg-white{
        background-color: ${myBackgroundColor} !important;
      }
    `)

  }
  // functionReplace: 函数替换, 有些优化可以直接通过替换函数的方式进行
  function functionReplace(){
      // 哔咔的数据获取、网页渲染JS代码都在HTML的body中以script标签的方式嵌入, 执行的所有操作都在JQuery.()中被定义
      // 当脚本run-at设置为document-idle(默认)或document-end时,该脚本定义的函数恰好覆盖了之前已定义的,且jquery的ready事件尚未触发(Jquery的ready事件晚于DOMContentLoaded)
      // 可以放心地替换函数

      // 替换 loadBanKeys
      // 修复所有页面 "屏蔽組件需要您至少訪問一次分類界面" 的 bug
      unsafeWindow.loadBanKeys = function() {
        // 如果session中已经存在cats列表,直接渲染即可
        let catsList = store.session("catCache")
        if (catsList) {
          $.each(catsList.value, function(idx, item) {
            // 过滤掉非bankey的cats
            if (typeof item._id === 'undefined') {
              return;
            }
            // console.log(item)
            $(".my-ban-key").append('<button onclick="banButtonClick(this)" class="mt-4 my-ban-key-btn btn-sm btn btn-outline-primary bg-white rounded shadowed me-1 mb-1">' + item.title + "</button>")
          })
        } else{
          // 否则使用自定义函数 myGetCatsAndLoadBanKeys 获取并渲染bankeys
          myGetCatsAndLoadBanKeys()
        }
    }

      // 替换jumpUtils, 让本子预览页面在新tab中打开
      unsafeWindow.jumpUtils= function(path, dataArr){
        let url = '/' + path + '/?' + $.param(dataArr);
        window.open(url, '_blank').focus();
      }
      // 替换catBtn, 使得本子搜索页面在新tab中打开
      unsafeWindow.catBtn= function catBtn(catCard) {
      var getLink = $(catCard).attr('data-href');
      var isWeb = $(catCard).attr('data-web');
      if (isWeb == 'undefined' || getLink == 'undefined') {
            window.open('/pcomiclist/?catname=' + $(catCard).text(), '_blank');
            return;
        } else {
            if (getLink.indexOf('donate.wikawika.xyz') > 0) {
                window.open(getLink, '_blank');
            } else if (getLink.indexOf('http') < 0) {
                window.location.href = getLink;
            } else {
                $('#catModalBasic').modal('show');
                $(".my-modal-cat-title").text($(catCard).text());
                $('.my-cat-iframe').attr('src', getLink);
                $('.my-cat-iframe').fadeIn();
            }
        }
      }

      // 替换readChapter, 使得本子某一章的欣赏页面在新tab中打开
      unsafeWindow.readChapter = function(chapterId){
        var maxchapter = $(".my-cview-button").length;
          if (maxchapter == 0)
              maxchapter = getPar('maxchapter');
          addCidReadCache(cid, chapterId);
          let url = '/pchapter/?cid=' + cid + '&chapter=' + chapterId + '&chapterPage=' + 1 + "&maxchapter=" + maxchapter;
          window.open(url, '_blank').focus();
      }


      // 替换原先bankey的click事件, 使得bankey列表更改后视图立刻刷新
      unsafeWindow.banButtonClick = function(element) {

        let bankey = getStore("bankey");
        if (bankey == undefined)
            bankey = Array();
        if (bankey.indexOf($(element).text().trim()) >= 0) {
            bankey.splice(bankey.indexOf($(element).text().trim()))
        } else
            bankey.push($(element).text().trim());
        setStore("bankey", bankey);
        console.log(getStore("bankey"));
        initBanKeyView();
        // 立刻将被ban的漫画从视图中删除
        banKeyListCard();
      }
      // 替换原先的banKeyListCard函数, 该函数原用于加载漫画列表时读取屏蔽词信息并删除含有对应屏蔽词的漫画
      // 替换后的函数将原先用于替换被屏蔽的漫画的 "根據關鍵詞屏蔽:XXX" 删除, 并且删除屏蔽词时会将被屏蔽的漫画重新显示出来
      unsafeWindow.banKeyListCard = function () {
          let bankey = getStore("bankey");
          if (bankey == undefined)
              return;
        $.each($(".cat-item"), function(idx, value) {
            let bolckText = "";
            $.each(bankey, function(keyidx, key) {
                if ($(value).text().indexOf(key) > 0) {
                    bolckText += key + "、"
                }
            });
            if (bolckText !== "") {
                $(value).css("display", "none");
            } else if($(value).css("display")==="none"){
                $(value).css("display", "block");
            }
          });
        }

      if (isLazyLoad === '0') {
        // 替换本子每page加载函数, 取消lazyload
        unsafeWindow.loaderchapter = function loaderchapter(setCid, setChapterId, setChapterPage) {
          var setTime = getTimeOnece();
          var mothod = 'GET';
          var pathname = 'comics/' + setCid + '/order/' + setChapterId + '/pages?page=' + setChapterPage;
          $.ajax({
              type: mothod,
              contentType: 'application/json; charset=UTF-8',
              crossBrowser: true,
              url: ProxyBaseUrl + pathname,
              beforeSend: function(request) {
                  $.each(postHeader(setTime, pathname, mothod), function(idx, obj) {
                      request.setRequestHeader(obj.name, obj.value);
                  });
                  var smartChange = setSmartViewChange(cid);
                  if (smartChange != undefined)
                      request.setRequestHeader("image-quality", smartChange);
              },
              success: function(data) {console.log(data);
                  try {
                      if (data.code == 200)
                          console.log("伺服器鏈接成功");
                      if (data.data == undefined || data.data.ep == undefined || data.data.pages == undefined || data.data.pages.docs == undefined) {
                          checkDataNullCode(modalClassId, data);
                      } else {
                          if (data.data.pages.docs.length == 0)
                              toastUtils("這篇漫畫沒有内容/(ㄒoㄒ)/~~\r\n(有可能是漫畫被封印了)", "關閉", 100000);
                          $.each(data.data.pages.docs, function(idx, itemValue) {
                              $('.chapter-images').append('<img src="' + loadingPic + '" data-src="' + getS3ProxySet() + itemValue.media.path + '" class="lazyload w-100">');
                          });
                          catPage = data.data.pages.page;
                          catMaxPage = data.data.pages.pages;
                          addPageJump(data.data.pages.pages);
                      }
                  } catch (err) {
                      setErrorTips(data, err);
                      $('#' + modalClassId).modal('show')
                  }
              },
              complete: function() {

                  console.log('加載完畢');
                  // getMyBanner(modalClassId, '/ad/?cat=readBanner&os=' + getDeviceTypes(), 'waterfallsFlow', ".chapter-images", 400, true);
                  retryImg();

                  // 取消lazyload, 将整个page的图片都加载出来
                  $(".chapter-images>img.lazyload").each(function(){
                    $(this).prop("src", $(this).attr('data-src'))
                  })

              },
              error: function(data) {
                  checkErrorCode(data, modalClassId);
                  $("#loader").fadeOut();
              }
          });
        }
      }
  }

  // https://manhuabika.com/pcomicview/* 的处理函数
  function pcomicviewFunc() {

  }

  // https://manhuabika.com/pchapter/* 的处理函数
  function pchapterFunc() {
      var helpContent =  `<div>哔咔增强插件:点击底部栏左侧的 “哔咔优化”以查看更多优化项</div>`

    //   // 将顶部的 div.my-body-tip 中的内容变成本插件的教程
      $("div.my-body-tip").html(helpContent)

      // 添加底部栏LazyLoad开关
      $(".appBottomMenu").prepend($(`<div id="right-box"></div>`))
      $(".appBottomMenu").prepend($(`<div id="left-box"></div>`))

      $(".appBottomMenu>a").appendTo("#right-box")
      console.log(isLazyLoad)

      // 添加底部菜单 自动宽度(竖屏模式) checkbox
      $("#left-box").append(
          $(`<div id="div-lazyload"><input class="form-check-input" type="checkbox" id="verticle-mode-checkbox"  ${isVerticalModeEnable==="1"?'checked':''}> <label class="form-check-label" for="verticle-mode-checkbox">自动宽度(手机推荐)</label></div>`).on("change", function(){
            let checkStatus = $("#verticle-mode-checkbox").prop('checked')
            localStorage.setItem("isVerticalModeEnable", checkStatus?'1':'0')
            isVerticalModeEnable=checkStatus?'1':'0';
            if(checkStatus) {


              GM_addStyle(`
              .chapter-images>img{
                  max-width: ${$(window).width()}px;
                }
                #my-image-sizer-div, #div-max-height{
                    display: none;
                }
              `);
            toastUtils('自动宽度:' +checkStatus, '關閉', 3000);

            }else {

              if(isAutoHeightModeEnable === '0'){
                GM_addStyle(`
                  #my-image-sizer-div, #div-max-height {
                  display: flex;
                  }
                `)
              }
            setIMGMaxHeight(myImgMaxHeightNum)

            toastUtils('自动宽度:' +checkStatus, '關閉', 3000);

            }

          }
      ))
      // 添加底部菜单 自动高度 checkbox
      $("#left-box").append(
        $(`<div id="div-lazyload"><input class="form-check-input" type="checkbox" id="auto-height"  ${isAutoHeightModeEnable==="1"?'checked':''}> <label class="form-check-label" for="auto-height">自动高度(电脑推荐)</label></div>`).on("change", function(){
          let checkStatus = $("#auto-height").prop('checked')
          localStorage.setItem("isAutoHeightModeEnable", checkStatus?'1':'0')
          isAutoHeightModeEnable=checkStatus?'1':'0';
          if(checkStatus) {
            GM_addStyle(`
            .chapter-images>img{
                max-height: ${$(window).height()}px;
              }
              #my-image-sizer-div, #div-max-height{
                  display: none;
              }
            `);
          toastUtils('自动高度:' +checkStatus , '關閉', 3000);

          }else {

            if(isVerticalModeEnable === '0'){
              GM_addStyle(`
                #my-image-sizer-div, #div-max-height {
                display: flex;
                }
              `)
            }
          setIMGMaxHeight(myImgMaxHeightNum)

          toastUtils('自动高度:' +checkStatus, '關閉', 3000);

          }

        }
    ))

    // 添加底部菜单 滚动翻页 checkbox
    $("#left-box").append(
      $(`<div id="div-lazyload"><input class="form-check-input" type="checkbox" id="wheel-turn-page"  ${isWheelTurnPageEnable==="1"?'checked':''}> <label class="form-check-label" for="wheel-turn-page">滚动翻页(推荐)</label></div>`).on("change", function(){
        let checkStatus = $("#wheel-turn-page").prop('checked')
        localStorage.setItem("isWheelTurnPageEnable", checkStatus?'1':'0')
        isWheelTurnPageEnable=checkStatus?'1':'0';
        if(checkStatus) {
          toastUtils('滚动翻页:' +checkStatus , '關閉', 3000);
      }
    }
  ))

      // 添加底部栏LazyLoad开关
      // 添加底部栏LazyLoad开关
      $("#left-box").append(
          $(`<div id="div-lazyload"><input  class="form-check-input" type="checkbox" id="lazyload-checkbox" name="lazyload-checkbox" value="图片惰性加载" ${isLazyLoad==="1"?'checked':''}> <label class="form-check-label" for="lazyload-checkbox">图片惰性加载</label></div>`).on("change", function(){
            let checkStatus = $("#lazyload-checkbox").prop('checked')
            localStorage.setItem("isLazyLoad", checkStatus?'1':'0')
            isLazyLoad=checkStatus?'1':'0'
            toastUtils('图片惰性加载:' +checkStatus +" (设置已保存,页面刷新后生效)", '關閉', 3000);
          }
      ))
      // 添加底部栏LazyLoad开关

      // 底部添加 自动隐藏 选择框
      $("#left-box").append(
          $(`<div id="div-ah"><input  class="form-check-input" type="checkbox" id="fixed-checkbox" name="fixed-checkbox" value="自动隐藏" ${isAutoHide==="1"?'checked':''}> <label class="form-check-label" for="fixed-checkbox">自动隐藏</label></div>`).on("change", function(){
              let checkStatus = $("#fixed-checkbox").prop('checked')
              localStorage.setItem("isAutoHide", checkStatus?'1':'0')
              isAutoHide=checkStatus?'1':'0'
              if (checkStatus){
                $(".user-fixed").addClass("must-hide");
              } else{
                $(".user-fixed").removeClass("must-hide");

              }

            toastUtils('自动隐藏底部栏和高度调节器:' +checkStatus , '關閉', 3000);

          }
      ))
      // 底部添加 自动隐藏 选择框

      // 添加翻页点击区域比例调节框
      $("#left-box").append(
        $(`<div id="div-bs"><label class="form-label" for="nextPageScreenClickPercent">下一页点击区域比例(%)</label><input class="form-control" type="number" id="nextPageScreenClickPercent" value="${nextPageScreenClickPercent}" min="0" max="100" step="0.5" ></input></div>`).on("input", function(){
          nextPageScreenClickPercent = $("#nextPageScreenClickPercent").prop("value")
          $("div.chapter-images").css("background-color", $("#my-border-size-input").prop("value"))

          localStorage.setItem("nextPageScreenClickPercent", nextPageScreenClickPercent)
          toastUtils('下一页点击区域比例:' +nextPageScreenClickPercent , '關閉', 3000);
      }))
      // 添加翻页点击区域比例调节框

      // 添加滚动翻页临界值调节框
      $("#left-box").append(
        $(`<div id="div-bs"><label class="form-label" for="scrollThreshold">触发滚动翻页的最小距离</label><input class="form-control" type="number" id="scrollThreshold" value="${scrollThreshold}" min="1" max="1000" step="5" ></input></div>`).on("input", function(){
          scrollThreshold = $("#scrollThreshold").prop("value")
          localStorage.setItem("scrollThreshold", scrollThreshold)
          toastUtils('触发滚动翻页的距离:' +scrollThreshold , '關閉', 3000);
      }))
      // 添加滚动翻页临界值调节框

      // 底部添加 透明度 调节器
      $("#left-box").append(
          $(`<div id="div-or"><label class="form-label" for="opacity-regulator">透明度</label><input class="form-range" type="range" id="opacity-regulator" name="opacity-regulator" value="${myBottomOpacity}" min="50" max="100"> </or>`).on("change", function(){
            myBottomOpacity=$("#opacity-regulator").prop('value')

            localStorage.setItem("myBottomOpacity", myBottomOpacity)
            GM_addStyle(`
              .must-show, .user-fixed, .user-fixed:hover {
                opacity: ${myBottomOpacity/100} !important;
              }
               .user-fixed, .user-fixed:hover {
                opacity: ${myBottomOpacity/100};
              }


              `)
            toastUtils('透明度设置:' + myBottomOpacity +'%', '關閉', 1000);
          }
      ))
      // 底部添加 透明度 调节器

      // 添加图片边框粗细调节框
      $("#left-box").append(
        $(`<div id="div-bs"><label class="form-label" for="my-border-color-picker">边框粗细</label><input class="form-control" type="number" id="my-border-size-input" value="${myBorderSize}" min="0" max="100" step="0.5" ></input></div>`).on("input", function(){
          myBorderSize = $("#my-border-size-input").prop("value")
          $("div.chapter-images").css("background-color", $("#my-border-size-input").prop("value"))
          GM_addStyle(`
            .chapter-images>img{
              border: ${myBorderSize}px solid ${myBorderColor}!important;
            }
          `);
          localStorage.setItem("myBorderSize", myBorderSize)
          toastUtils('边框粗细已储存:' +myBorderSize , '關閉', 3000);
      }))
      // 添加图片边框粗细调节框

      // 添加边框颜色选择器
      $("#left-box").append(
        $(`<div id="div-bc"><input type="color" id="my-border-color-picker" value="${myBorderColor}"> </input><label for="my-border-color-picker">边框色</label></div>`).on("input", function(){
          myBorderColor = $("#my-border-color-picker").prop("value")
          $("div.chapter-images").css("background-color", $("#my-border-color-picker").prop(myBorderColor))
          GM_addStyle(`
            .chapter-images>img{
              border: ${myBorderSize}px ${myBorderColor} solid !important;
            }
            #my-collapse-div{
              background-color: ${myBorderColor};
            }
          `);
          localStorage.setItem("myBorderColor", myBorderColor)
          toastUtils('边框色已储存:' +myBorderColor , '關閉', 3000);
      }))
      // 添加边框颜色选择器

      // 添加背景颜色选择器
      $("#left-box").append(
            $(`<div id="div-bgc"><input type="color" id="my-bg-color-picker" value="${myBackgroundColor}" ></input><label for="my-bg-color-picker">背景色</label></div>`).on("input", function(){
              myBackgroundColor = $("#my-bg-color-picker").prop("value")
              $("div.chapter-images").css("background-color", $("#my-bg-color-picker").prop("value"))
              GM_addStyle(`
                div.chapter-images, body, body.bg-white{
                  background-color: ${myBackgroundColor} !important;
                }
              `);
              localStorage.setItem("myBackgroundColor", myBackgroundColor)
              toastUtils('背景色已储存:' +myBackgroundColor , '關閉', 3000);



          })
        )
        // 添加背景颜色选择器

      // 添加底部图片高度文本框
      $("#left-box").append(
            $(`<div id="div-max-height"><input class="form-control" id="my-max-height-input" type='number' min="100" max="1800" value="${myImgMaxHeightNum}"></input></div>`).on("input", function(){
            $(".chapter-images>img").css("max-height", $("#my-max-height-input").prop("value")+"px")
            $("#my-image-sizer").prop("value", $("#my-max-height-input").prop("value"))
            // myImgMaxHeightNum = $(this).prop("value")
              setIMGMaxHeight($("#my-max-height-input").prop("value"))
          })
        )
      // 添加底部图片高度文本框


      $("#div-max-height").append(
          $(`<button class="btn btn-primary" style="width:100%;">存储高度</button>`).on("click", function(){
              localStorage.setItem("myImgMaxHeightNum", myImgMaxHeightNum)
            toastUtils('最大高度已储存:' +myImgMaxHeightNum , '關閉', 3000);
          }
      ))







      // 添加左侧垂直图片最大高度input-range
      $("body").append(
            $(`<div id="my-image-sizer-div" class="user-fixed"></div>`).append($(`<input id="my-image-sizer"  type="range" id="imgsizescoller" name="cowbell" min="100" max="1800" value="${myImgMaxHeightNum}" step="1"> <label for="my-image-sizer">图片最大高度</label>`).on("input", function(){

            myImgMaxHeightNum = $("#my-image-sizer").prop("value")
            $(".chapter-images>img").css("max-height", myImgMaxHeightNum+"px")
            $("#my-max-height-input").prop("value", myImgMaxHeightNum)
            setIMGMaxHeight(myImgMaxHeightNum)
              // console.log(myImgMaxHeightNum)
          }))
      )

      var curIMGTop = 0;
      var lastDate = null;


      // 方向键左右翻页
      document.addEventListener('keydown', function(e){


        // 左键翻页
        if(e.key === "ArrowLeft") {
          let lst = $(".chapter-images img").filter(function(){
            return window.scrollY - 5 > $(this).offset().top;
          })
          // console.log(lst.length)

          // 通过翻页到达最顶部,以显示 顶部内容
          if (lst.length === 0) {
            scrollTo({top:0, left: window.scrollX, behavior:"instant"})
            return;
          }
          // lst[lst.length - 1].scrollIntoView({ behavior: "instant" });
          scrollTo({top:lst[lst.length - 1].offsetTop, left:  window.scrollX, behavior:"instant"})

          curIMGTop = lst[lst.length - 1].offsetTop;


        }

        // 右键翻页
        if(e.key === "ArrowRight") {
          let lst = $(".chapter-images img").filter(function(){
            return window.scrollY + 5 < $(this).offset().top;
          })

          // 通过翻页到达最底部,以显示按钮 “點擊跳轉下一章節”
          if (lst.length === 0) {
            scrollTo({top:document.body.scrollHeight, left: window.scrollX, behavior:"instant"})

            return;
          }
          // console.log(lst.length)
          if (lst.length === 0) {
            catPage++;
            if (catPage <= catMaxPage) {
              loaderchapter(cid, chapter, catPage);
              toastUtils('加載第' + catPage + "頁", '關閉', 3000);
              console.log('load next');
            } else {
              toastUtils('已经到最底部咯~', '關閉', 3000);

            }
            return;
          }
          // lst[0].scrollIntoView({ behavior: "instant"});
          scrollTo({top:lst[0].offsetTop, left: window.scrollX, behavior:"instant"})

          curIMGTop = lst[0].offsetTop;


        }

      } );

      setTimeout(()=>{
        // 取消并重新添加页面的scroll事件(该事件触发时会默认修改所有input的value,导致input:range的value被更改)(window变量访问不到页面的window,只能用unsafeWindow)
        $(unsafeWindow).off('scroll')
        // 重新添加scroll绑定
        $(unsafeWindow).scroll(pchapterFixedScrollingCallBack);
      },1000);

        // 添加用户CSS
        pchapterAddUserCSS();
        // 组装用户组件
        pchapterComponentsAssemble();

      // 添加鼠标点击事件,实现点击上下半屏翻页
      addEventListener("click", e=>{
        // console.log(e)
        if (e.target.nodeName === "IMG" || e.target.className.indexOf("chapter-images")!==-1) {

          // 触发document上的keydown事件达到调用翻页功能
          // 需要注意的是dispatchEvent在开发者工具的Console中调用只会返回true, 不会真正触发
          if (e.clientY/window.innerHeight > (100-nextPageScreenClickPercent)/100){
            document.dispatchEvent(new KeyboardEvent('keydown',{'key':'ArrowRight'}))
          } else {
            document.dispatchEvent(new KeyboardEvent('keydown',{'key':'ArrowLeft'}))
          }
        }
      })

      // 添加鼠标滚动事件,实现 滚动翻页
      var scrolled = true;
      let acc = 0;
      let lastAcc = 0;
      let wheelEventTimeOut= null;
      addEventListener("wheel", e=>{
        if (isWheelTurnPageEnable === '0')
          return;

        // 阻止浏览器默认的滚动行为
        e.preventDefault();
        //e.stopPropagation();

        // 滚动翻页通过acc在一个方向上的wheel的距离的累加值超过某个thredshoud来触发
        acc += e.deltaY;
        if ((e.deltaY > 0 && acc < 0) || e.deltaY < 0 && acc > 0) {
          acc = e.deltaY;
        }
        // console.log(acc + " " + e.deltaY)
        if (acc > scrollThreshold) {
          document.dispatchEvent(new KeyboardEvent('keydown',{'key':'ArrowRight'}))

          acc = 0;
        } else if (acc < -scrollThreshold) {
          document.dispatchEvent(new KeyboardEvent('keydown',{'key':'ArrowLeft'}))

          acc = 0;
        }
        clearTimeout(wheelEventTimeOut)
        wheelEventTimeOut = setTimeout(timeout=>{
          acc = 0;
          // console.log("wheel timeout...")
        },100)

      }
      ,{passive: false})

      // 如果开启了自动高度或自动宽度,则在窗口大小发生变化时,自动调节窗口大小
      window.addEventListener('resize',function(){
        if(isAutoHeightModeEnable) {
          GM_addStyle(`
          .chapter-images>img{
            max-width: ${window.innerWidth}px;
          }
          `)
        }

        if (isVerticalModeEnable) {
          GM_addStyle(`
          .chapter-images>img{
            max-height: ${window.innerHeight}px;
          }
          `)
        }
      });

        // 如果停用lazyload
      if(isLazyLoad === "0") {
        $(".chapter-images>img.lazyload").each(function(){
          $(this).prop("src", $(this).attr('data-src'))
        })
      }
  }

  // https://manhuabika.com/pcomiclist/* 的处理函数
function pcomiclistFunc() {
    // 修复bankey显示不全的问题
    GM_addStyle(`.blog-post{
    margin-top: 100px;
    }
    #appCapsule>.blog-post a.fab{
      height: auto !important;
    }
    .my-ban-key{
      width: 70% !important;

      overflow-x:auto;

    }
    .my-ban-key-btn{
      margin: 5px 5px 5px 5px !important;
    }
  body{
    background-color: ${myBackgroundColor} !important;
  }

  .col-2{
    width: 8% !important;
  }
  }

  .fab button{
    margin-left: 5px;
  }
  `)

  $('.fab>div').append($(`
    <button class="btn btn-info col-2 mt-4 text-center">展开</button>
  `).on('click',function(){
    $('.my-ban-key').css('white-space', 'normal')
  }))
  $('.fab>div').append($(`<button class="btn btn-info col-2 mt-4 text-center">折叠</button>`).on('click',function(){
    $('.my-ban-key').css('white-space', 'nowrap')
  }))
}


  var pageIndex = 0;
  var pageCount = 0;
  var imgIndex = 0;
  var imgCount = 0;
  // 页面pchapter: 修正后的scroll回调函数
  function pchapterFixedScrollingCallBack() {
    var percent = $('.blog-post').readpercent(true);

    // 在进度条显示:本章已看图数/当前章节图片总数
    let lst = $(".chapter-images img").filter(function(){
      // console.log(this.getBoundingClientRect().y)
      // 距离 视窗顶部的距离 小于 2px (浮点数不能直接===0判等)
      if (this.getBoundingClientRect().y < 2) {
        return true;
      }
      return false;
    })

    if (lst.length > 0){
      imgIndex = $(".chapter-images img").index(lst[lst.length-1])+1
    } else {
      // 如果上一个filter操作结果lst没有元素,那么说明用户到了底部,已经看到了最后一张图片
      imgIndex = lst.length + 1
    }
    // console.log(lst)

    $('.my-read-tip').text(`进度:${percent}%(${imgIndex}/${imgCount})(點擊可跳轉)`);
    // 在进度条显示:本章已看图数/当前章节图片总数

    // 修改
    // $(input').val(percent);
    $('.my-read-range>input').val(percent);

    if ($(document).scrollTop() <= 0) {
        setStore('isTop', true);
    } else {
        setStore('isTop', false);
    }
    if ($(document).scrollTop() >= $(document).height() - $(window).height() - $(".appBottomMenu").height()) {
        if (getStore('isEnd') != true) {
            catPage++;
            console.log('load new page' + catPage + "max" + catMaxPage + "bool" + (catPage <= catMaxPage));
            if (catPage <= catMaxPage) {
                loaderchapter(cid, chapter, catPage);
                toastUtils('加載第' + catPage + "頁", '關閉', 3000);
                console.log('load next');
            } else {
                chapter = parseInt(getPar('chapter'));
                if (chapter < maxchapter) {
                    console.log("加載下一章節");
                    chapter++;
                    if ($('.my-jump-readChapter').length == 0) {
                        $('.blog-post').append('<div class="fab-button animate bottom-center dropdown" style="bottom:75px!important;"><button  onclick="readChapter(\'' + chapter + '\')" class="btn btn-primary my-jump-readChapter">點擊跳轉下一章節</button></div>')
                    }
                    toastUtils('還有下一章,點擊底部加載更多吧!', '關閉', 3000);
                } else {
                    toastUtils('已經看完咯~', '關閉', 3000);
                }
            }
        } else {}
        setStore('isEnd', true);
    } else {
        if ($('.bottom-center').length > 0) {
            $('.bottom-center').remove();
        }
        setStore('isEnd', false);
    }
    setTimeout(()=>{
      $(".lazyloaded.retry").remove()
    },3000)
  }


  //  从localStorage中读取配置信息
  function readLocalStorage() {
    let myImgMaxHeightNum_t = localStorage.getItem("myImgMaxHeightNum")
    let isLazyLoad_t = localStorage.getItem("isLazyLoad")
    let myBottomOpacity_t = localStorage.getItem("myBottomOpacity")
    let myBorderColor_t = localStorage.getItem("myBorderColor")
    let myBorderSize_t = localStorage.getItem("myBorderSize")
    let myBackgroundColor_t = localStorage.getItem("myBackgroundColor")
    let isAutoHide_t = localStorage.getItem("isAutoHide")
    let isVerticalModeEnable_t = localStorage.getItem("isVerticalModeEnable")
    let isAutoHeightModeEnable_t = localStorage.getItem("isAutoHeightModeEnable")
    let isScriptEnable_t = localStorage.getItem("isScriptEnable");
    let nextPageScreenClickPercent_t = localStorage.getItem("nextPageScreenClickPercent");
    let isWheelTurnPageEnable_t = localStorage.getItem("isWheelTurnPageEnable");
    let scrollThreshold_t = localStorage.getItem("scrollThreshold");

    if (myImgMaxHeightNum_t !== null) myImgMaxHeightNum = myImgMaxHeightNum_t;
    if (isLazyLoad_t !== null) isLazyLoad = isLazyLoad_t;
    if (myBottomOpacity_t !== null) myBottomOpacity = myBottomOpacity_t;
    if (myBorderColor_t !== null) myBorderColor = myBorderColor_t;
    if (myBorderSize_t !== null) myBorderSize = myBorderSize_t;
    if (myBackgroundColor_t !== null) myBackgroundColor = myBackgroundColor_t;
    if (isAutoHide_t !== null) isAutoHide = isAutoHide_t;
    if (isVerticalModeEnable_t !== null) isVerticalModeEnable = isVerticalModeEnable_t;
    if (isAutoHeightModeEnable_t !== null) isAutoHeightModeEnable = isAutoHeightModeEnable_t;
    if (isScriptEnable_t !== null) isScriptEnable = isScriptEnable_t;
    if (nextPageScreenClickPercent_t !== null) nextPageScreenClickPercent = nextPageScreenClickPercent_t;
    if (isWheelTurnPageEnable_t !== null) isWheelTurnPageEnable = isWheelTurnPageEnable_t;
    if (scrollThreshold_t !== null) scrollThreshold = scrollThreshold_t;



  }



  // 页面pchapter: 添加用户样式
  function pchapterAddUserCSS(){
    console.log("USE CSS")
    // 为底部栏添加user-fixed类
    $(".appBottomMenu").addClass("user-fixed");
    $("input.form-range").addClass("user-fixed")

      // 如果启用自动隐藏
    if(isAutoHide === "1") {
      $(".user-fixed").addClass("must-hide")
    }




   GM_addStyle(`
   .chapter-images{
    display: flex;
    flex-direction: row;
    justify-content: center;
    flex-wrap: wrap;
    align-items: flex-start;
    box-sizing: border-box;
  }
  .chapter-images>img{
      width: auto !important;
      box-sizing: border-box;
      border: ${myBorderSize}px solid ${myBorderColor}!important;
      border-top-width:  ${myBorderSize}px;
      border-bottom-width:  ${myBorderSize}px;
      max-height: ${myImgMaxHeightNum}px ;
  }
    body{
      width: 100% !important;
    }
    .chapter-images>a{
        display: none;
    }


    .appBottomMenu {
      position: none;
      left: auto;
      right: auto;
    }

    #my-image-sizer-div{
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      z-index: 999;
      position: fixed;
      height: 100%;
      left: 0px;
      bottom: 10%;
      height:80%;
    }

  #my-image-sizer{
      appearance: slider-vertical;
    height:100%;
  }
    .lazyloaded.retry{
    display:none !important;
    }

  #right-box{
    display:flex;
    flex-direction: row;
  }

  .must-hide{
    opacity: 0 !important;
  }

  div.chapter-images {
    background-color: ${myBackgroundColor} !important;
  }

  #left-box{
        display: flex;
      flex-direction: row;
      align-items: center;
  }

  .must-show{
    opacity: ${myBottomOpacity/100} !important;
  }

  .user-fixed{
    opacity: ${myBottomOpacity/100};
  }

  #bottom-wrapper{
    width: 100%;
    display: flex;
    flex-direction: row;
    justify-content: center;
  }

  #my-collapse-div>ul>li{
      margin-top: 3px;
  }

    `)

    // 自动宽度(竖屏优化模式)
    if (isVerticalModeEnable === "1") {
    GM_addStyle(`
    .chapter-images>img{
    max-width: ${$(window).width()}px;
    }
    #my-image-sizer-div, #div-max-height{
    display: none;
    }
    `);
    }

    // 自动高度
    if (isAutoHeightModeEnable === "1") {
      GM_addStyle(`
      .chapter-images>img{
      max-height: ${$(window).height()}px;
      }
      #my-image-sizer-div, #div-max-height{
      display: none;
      }
      `);
      }

    $(".user-fixed").on("mouseenter", function(){
      // 100%
      $(".user-fixed").addClass("must-show");
      $(".user-fixed").removeClass("must-hide");


    })

    $(".user-fixed").on("mouseleave", function(){
      // 只有开启了自动隐藏功能,并且鼠标移出.user-fixed区域时选项框处于未显示状态,才会执行隐藏
      if (isAutoHide === "1"&&$("#my-collapse-div.show").length===0) {
        $(".user-fixed").addClass("must-hide");
       $(".user-fixed").removeClass("must-show");

      }
    })
  }

  // 获取本子信息
  function userGetComicInfo(cidSet) {
      if (getPar == '') {
          alert('錯誤的信息!');
          document.location.href = '/';
      }
      var setTime = getTimeOnece();
      var mothod = 'GET';
      var pathname = 'comics/' + cidSet;
      return $.ajax({
          type: mothod,
          contentType: 'application/json; charset=UTF-8',
          crossBrowser: true,
          url: ProxyBaseUrl + pathname,
          beforeSend: function(request) {
              $.each(postHeader(setTime, pathname, mothod), function(idx, obj) {
                  request.setRequestHeader(obj.name, obj.value);
              });
              request.setRequestHeader('signature', getsignature(pathname, setTime, mothod));
              $(".my-loading-view").hide();
              $("#loader").fadeIn();
          }
      });
  }


  // 获取chapter信息
  function userGetChapterInfo(setCid, setChapterId, setChapterPage) {
      var setTime = getTimeOnece();
      var mothod = 'GET';
      var pathname = 'comics/' + setCid + '/order/' + setChapterId + '/pages?page=' + setChapterPage;
      return $.ajax({
          type: mothod,
          contentType: 'application/json; charset=UTF-8',
          crossBrowser: true,
          url: ProxyBaseUrl + pathname,
          beforeSend: function(request) {
              $.each(postHeader(setTime, pathname, mothod), function(idx, obj) {
                  request.setRequestHeader(obj.name, obj.value);
              });
              var smartChange = setSmartViewChange(cid);
              if (smartChange != undefined)
                  request.setRequestHeader("image-quality", smartChange);
          }
      });
  }

  function addTitle(){
      // 漫画阅读页
      if (typeof cid!=="undefined") {
        // 为页面添加标题title
        userGetComicInfo(cid).then(data=>{
          document.title = data.data.comic.title
          if(typeof chapter!=="undefined"){
            userGetChapterInfo(cid,chapter,chapterPage).then(data_cpt=>{
            document.title = data_cpt.data.ep.title +"-"+data.data.comic.title
            pageIndex = data_cpt.data.pages.page;
            pageCount = data_cpt.data.pages.pages;
            imgCount = data_cpt.data.pages.total;
            });
          }

        });
      }
      // 非漫画阅读页

      if (typeof catName !== "undefined" && catName){
        document.title = catName + "-搜索"
      }

      if (typeof tagName !== "undefined" && tagName){
        document.title = tagName + "-搜索"
      }
      if (typeof searchArticle !== "undefined" && searchArticle){
        document.title = searchArticle + "-搜索"
      }
      if (typeof searchkeys !== "undefined" && searchkeys){
        document.title = searchkeys + "-搜索"
      }

      if (document.URL.indexOf("phome")!==-1||isPica(document.URL)) {
        document.title = "主页"
      }
      if (document.URL.indexOf("pcat")!==-1) {
        document.title = "分类"
      }
      if (document.URL.indexOf("pgame")!==-1) {
        document.title = "游戏"
      }
      if (document.URL.indexOf("puser")!==-1) {
        document.title = "个人中心"
      }

  }

  // 减少loader框显示的时间
  function lessLoaderDisplay() {
    GM_addStyle(`
    #loader{
      opacity:0;
    }
    `)
  }

  function isEmpty(obj){
    return (typeof obj === "undefined" || obj === null);
  }

  function removeAD() {
    // console.log("removeAD1");

      // 去除section标签中的广告
      GM_addStyle(`
      section.splide{
          display: none !important;
      }
    `)
        // 本子欣赏页面
      if (document.URL.indexOf("pchapter") !== -1) {

      }


      // 本子预览页面
      else if((document.URL.indexOf("pcomicview") !== -1)) {

      }

      else if (document.URL.indexOf("phome")!==-1||isPica(document.URL)) {
        // 循环+timer 去除modal
        let t = 0;
        let timer = setInterval(
            ()=>{
                $("#homecontentbox").modal('hide')
                if (t++ > 60){
                    clearInterval(timer)
                    console.log("Modal已成功去除")
                }
            },50
        )
        // 这条样式用于移除最上面的div.modal, 否则会导致页面无法操作
        $('document').ready(function(){
            $("#homecontentbox").modal('hide')
        })
        GM_addStyle(`
            .listview.image-listview.media.mb-2.tiplistview, #homecontentbox, #homecontentbox * {
                display: none !important;
                opacity: 0;
            }

        `);
        // console.log("removeAD2");

    console.log("ad works")


      }
        // console.log("removeAD3");

      unsafeWindow.getAdList = ()=>{}
      unsafeWindow.getMyBanner = ()=>{}


      // DOM 改变时,执行广告屏蔽
      onDOMChange(function(){
        $("a").each(function(){
                let str = $(this).attr("data-href")
        if(!isEmpty(str)&&str.indexOf("/ad/") !== -1) this.remove();
        })

      })

  }

  // 添加 DOM 改变时执行的函数
  function onDOMChange(func) {
      let observer = new MutationObserver(func);

      observer.observe(document.body, {
        characterDataOldValue: true,
        subtree: true,
        childList: true,
        characterData: true
      });
  }

  function setIMGMaxHeight(height) {
    myImgMaxHeightNum = height;
    GM_addStyle(`
    .chapter-images>img{
      max-height: ${height}px;
    }
  `)
  }

  function isPica(url) {
    // console.log(url);
    // console.log(pica_urls)

    for (let i = 0; i < pica_urls.length; i++) {
      if (url.indexOf(pica_urls[i]) !== -1)
        return true;
    }
    return false;
  }

  function addMenu() {
    const menu_command_id_2 = GM_registerMenuCommand("重置插件/RESET", function(event) {
      reset();

      alert("插件重置成功!刷新页面后生效~")
    }, "l");
  }

  function reset() {
    localStorage.removeItem("myImgMaxHeightNum");
    localStorage.removeItem("isLazyLoad");
    localStorage.removeItem("myBottomOpacity");
    localStorage.removeItem("myBorderColor");
    localStorage.removeItem("myBorderSize");
    localStorage.removeItem("myBackgroundColor");
    localStorage.removeItem("isAutoHide");
    localStorage.removeItem("isScriptEnable");
    localStorage.removeItem("nextPageScreenClickPercent");
    localStorage.removeItem("isVerticalModeEnable");
  }

  function DOMAINBUGFIX(){
    fixSubstituteDomainUnableAccessError_20230825();
  }

  // 修复因主站域名出现问题,使用备用站点时有些请求仍然发往总站,从而出现错误的BUG
  function fixSubstituteDomainUnableAccessError_20230825() {
    unsafeWindow.getMyrecommend = function(comicCid) {
      url = `https://recomend.${window.location.hostname}/pic-like-get/?c=`;
      // url = `${window.location.protocol}//recomend.${window.location.hostname}/pic-like-get/?c=`;
      //https://picaapi.picacomic.com/comics/62fdc34af0163a0c122c8ed3/recommendation
      var setTime = getTimeOnece();
      var mothod = 'GET';
  //console.log('getpage'+page);
      var pathname =
          url + comicCid;
      $.getJSON(pathname, function (data) {
          try {

              if (data != undefined) {
                  var insertCount = 0;

                  $.each(data, function (idx, comic) {
                      insertCount++;
                      var src = comic.pic.replace(new URL(comic.pic).origin + "/static/", getS3ProxySet());
                      $('.my-like-list').append(' <li style="max-width: 150px;" onclick="showComic(\''
                          + comic.id + '\')" class="splide__slide me-2"><div class="card  product-card"><div class="card-body text-center"><img style="object-fit: cover;min-height: 150px;" class="image infoimg lazyload"  data-src="'
                          + src + '"><h2 style="height: 40px;max-height: 40px;" class="title text-primary overflow-hidden text-center">'
                          + comic.title + '</h2></div></div></li>\n');
                  });
                  if (insertCount > 0) {

                      scolleSplide('.my-like-splide');
                      $('.splide__pagination').hide()
                      $('.my-other-view-comic').show()
                      $('.my-other-like').text($('.my-other-like').text() + "(Web 推薦 LV5下開啓)")
                  }
              }
          } catch (err) {
              console.error(err);

          }
      });

  }
  }


// 用于修复在没有打开 分类 页面时,搜索页面的bankey无法打开
// 增添了callback, 用于成功返回catsList时候回调函数
function myGetCatsAndLoadBanKeys(modalClassId, callback) {
  var setTime = getTimeOnece();
  var mothod = 'GET';
  var pathname = "categories";
  $.ajax({
      type: mothod,
      contentType: 'application/json; charset=UTF-8',
      crossBrowser: true,
      url: ProxyBaseUrl + pathname,
      beforeSend: function(request) {
          $.each(postHeader(setTime, pathname, mothod), function(idx, obj) {
              request.setRequestHeader(obj.name, obj.value);
          });
      },
      success: function(data) {
          try {
              if (data.code == 200)
                  console.log("伺服器鏈接成功");
                // console.log(data.data);
              if (data.data == undefined || data.data.categories == undefined) {
                console.log("data.data.categories or data.data undefined");
              } else {
                  setSession('catCache', data.data.categories);
                  // // rainwater增添部分:cats列表加载完成后重新调用loadBanKeys方法
                  loadBanKeys();
                  // // rainwater增添部分
              }
          } catch (err) {
          }
      },
      complete: function() {
      },
      error: function(data) {
      }
  });
}