北林OJ

北林OJ专用,替换C++头文件、展示当前题目可查看的答案、提交状态显示与CE原因显示、设置每页展示题目数、展示题目状态

// ==UserScript==
// @name        北林OJ
// @namespace   greasyfork.org
// @match       https://www.bjfuacm.com
// @match       https://www.bjfuacm.com/*
// @grant       unsafeWindow
// @grant       GM_addStyle
// @grant       GM_getValue
// @grant       GM_setValue
// @run-at      document-start
// @version     1.0
// @author      Gwen0x4c3
// @license     MIT
// @description 北林OJ专用,替换C++头文件、展示当前题目可查看的答案、提交状态显示与CE原因显示、设置每页展示题目数、展示题目状态
// ==/UserScript==

!(function() {
  'use strict';
  
  var $msg = {success:console.log,error:console.log,info:console.log}
  let h0x00=setInterval(()=>{
    if(document&&document.head&&document.body) {
      clearInterval(h0x00)
      function useMessage(){function n(n){for(var o=10,e=0;e<f.length;e++){var t=f[e];if(n&&n===t)break;o+=t.clientHeight+20}return o}function o(o){for(var e=0;e<f.length;e++){if(f[e]===o){f.splice(e,1);break}}o.classList.add(a.hide),f.forEach(function(o){o.style.top=n(o)+"px"})}function e(e){function i(){p.removeEventListener("animationend",i),setTimeout(o,x||t.duration||3e3,p)}function s(){"0"===getComputedStyle(p).opacity&&(p.removeEventListener("transitionend",s),p.remove())}var d=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"info",x=arguments[2],p=r.createElement("div");p.className=a.box+" "+d,p.style.top=n()+"px",p.style.zIndex=c,p.innerHTML='\n    <span class="'+a.icon+'"></span>\n    <span class="'+a.text+'">'+e+"</span>\n    ",c++,f.push(p),r.body.appendChild(p),p.addEventListener("animationend",i),p.addEventListener("transitionend",s)}var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=document,i="__"+Math.random().toString(36).slice(2,7),a={box:"msg-box"+i,hide:"hide"+i,text:"msg-text"+i,icon:"msg-icon"+i},s=r.createElement("style");s.textContent=("\n  ."+a.box+", ."+a.icon+", ."+a.text+" {\n    padding: 0;\n    margin: 0;\n    box-sizing: border-box;\n  }\n  ."+a.box+" {\n    position: fixed;\n    top: 0;\n    left: 50%;\n    display: flex;\n    padding: 12px 16px;\n    border-radius: 2px;\n    background-color: #fff;\n    box-shadow: 0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12);\n    white-space: nowrap;\n    animation: "+a.box+"-move .4s;\n    transition: .4s all;\n    transform: translate3d(-50%, 0%, 0);\n    opacity: 1;\n    overflow: hidden;\n  }\n  ."+a.box+'::after {\n    content: "";\n    position: absolute;\n    left: 0;\n    top: 0;\n    height: 100%;\n    width: 4px;\n  }\n  @keyframes '+a.box+"-move {\n    0% {\n      opacity: 0;\n      transform: translate3d(-50%, -100%, 0);\n    }\n    100% {\n      opacity: 1;\n      transform: translate3d(-50%, 0%, 0);\n    }\n  }\n  ."+a.box+"."+a.hide+" {\n    opacity: 0;\n    /* transform: translate3d(-50%, -100%, 0); */\n    transform: translate3d(-50%, -100%, 0) scale(0);\n  }\n  ."+a.icon+" {\n    display: inline-block;\n    width: 18px;\n    height: 18px;\n    border-radius: 50%;\n    overflow: hidden;\n    margin-right: 6px;\n    position: relative;\n  }\n  ."+a.text+" {\n    font-size: 14px;\n    line-height: 18px;\n    color: #555;\n  }\n  ."+a.icon+"::after,\n  ."+a.icon+'::before {\n    position: absolute;\n    content: "";\n    background-color: #fff;\n  }\n  .'+a.box+".info ."+a.icon+", ."+a.box+".info::after {\n    background-color: #1890ff;\n  }\n  ."+a.box+".success ."+a.icon+", ."+a.box+".success::after {\n    background-color: #52c41a;\n  }\n  ."+a.box+".warning ."+a.icon+", ."+a.box+".warning::after {\n    background-color: #faad14;\n  }\n  ."+a.box+".error ."+a.icon+", ."+a.box+".error::after {\n    background-color: #ff4d4f;\n  }\n  ."+a.box+".info ."+a.icon+"::after,\n  ."+a.box+".warning ."+a.icon+"::after {\n    top: 15%;\n    left: 50%;\n    margin-left: -1px;\n    width: 2px;\n    height: 2px;\n    border-radius: 50%;\n  }\n  ."+a.box+".info ."+a.icon+"::before,\n  ."+a.box+".warning ."+a.icon+"::before {\n    top: calc(15% + 4px);\n    left: 50%;\n    margin-left: -1px;\n    width: 2px;\n    height: 40%;\n  }\n  ."+a.box+".error ."+a.icon+"::after, \n  ."+a.box+".error ."+a.icon+"::before {\n    top: 20%;\n    left: 50%;\n    width: 2px;\n    height: 60%;\n    margin-left: -1px;\n    border-radius: 1px;\n  }\n  ."+a.box+".error ."+a.icon+"::after {\n    transform: rotate(-45deg);\n  }\n  ."+a.box+".error ."+a.icon+"::before {\n    transform: rotate(45deg);\n  }\n  ."+a.box+".success ."+a.icon+"::after {\n    box-sizing: content-box;\n    background-color: transparent;\n    border: 2px solid #fff;\n    border-left: 0;\n    border-top: 0;\n    height: 50%;\n    left: 35%;\n    top: 13%;\n    transform: rotate(45deg);\n    width: 20%;\n    transform-origin: center;\n  }\n  ").replace(/(\n|\t|\s)*/gi,"$1").replace(/\n|\t|\s(\{|\}|\,|\:|\;)/gi,"$1").replace(/(\{|\}|\,|\:|\;)\s/gi,"$1"),r.head.appendChild(s);var c=t.zIndex||1e4,f=[];return{show:e,info:function(n){e(n,"info")},success:function(n){e(n,"success")},warning:function(n){e(n,"warning")},error:function(n){e(n,"error")}}}
      $msg=useMessage();
      // $msg.success('脚本开始运行')
    }
  },100)
  
  function injectCSS() {
    GM_addStyle(".error-log{list-style-type:none;padding:0}.error-log li{background-color:#f8d7da;color:#721c24;padding:10px;margin-top:5px;border:1px solid #f5c6cb;border-radius:5px;font-size:14px}");
    GM_addStyle('.oj-button{z-index:10000;width:120px;height:30px;line-height:30px;text-align:center;color:black;font-weight:bold;cursor:pointer}.oj-panel{z-index:10000;background:white;position:fixed;left:20px;top:20px;width:390px;border:1px solid #000}.oj-header{position:relative;height:30px;background:rgb(250, 250, 250);cursor:move}.oj-close{position:absolute;right:10px;top:0;font-size:19px;cursor:pointer}.oj-body{min-height:200px;max-height:500px;overflow-y:auto;overflow-x:hidden}.oj-result{padding:10px;transition:.2s;font-size:14px;}.oj-result:hover{background:rgb(240,240,240);}')
    GM_addStyle('.ojh{}.ojh-button{}.ojh-save{background:rgb(246,246,246);}.ojh-save-content{display:inline-block;width:90%;height:200px;resize:none;margin:5px auto;vertical-align:top}.ojh-save-button{margin-left:100px}.ojh-body{max-height:500px;padding:10px;overflow-y:auto;background:rgb(240,240,240)}.ojh-file{position:relative;border-bottom:1px solid black;padding: 10px 2px;}.ojh-file-name{}.ojh-file-delete{display:block;position:absolute;right:10px;top:0}.ojh-file-content{display:block;width:100%;height:200px;resize:none;margin:5px auto}.text-button{display:inline-block;text-align:center;color:blue;cursor:pointer}');
  }
  
  const status_map={"-2":{name:"Compile Error",short:"CE",color:"orange",type:"warning"},"-1":{name:"Wrong Answer",short:"WA",color:"#f8d7da",type:"error"},0:{name:"Accepted",short:"AC",color:"rgb(232,249,240)",type:"success"},1:{name:"Time Limit Exceeded",short:"TLE",color:"#f8d7da",type:"error"},2:{name:"Time Limit Exceeded",short:"TLE",color:"#f8d7da",type:"error"},3:{name:"Memory Limit Exceeded",short:"MLE",color:"#f8d7da",type:"error"},4:{name:"Runtime Error",short:"RE",color:"#f8d7da",type:"error"},5:{name:"System Error",short:"SE",color:"#f8d7da",type:"error"},6:{name:"Pending",color:"orange",type:"warning"},7:{name:"Judging",color:"blue",type:"info"},8:{name:"Partial Accepted",short:"PAC",color:"blue",type:"info"},9:{name:"Submitting",color:"yellow",type:"warning"}}
  
  const store = {
    headers: GM_getValue('oj-headers', []),
    pagesize: GM_getValue('oj-pagesize', 20),
    difficulty: GM_getValue('oj-difficulty', ""),
    problems: {},
    hideAC: GM_getValue('oj-hideAC', false),
  }
  unsafeWindow.fuckingstore = store;
  
  function createElement(tag, clazz, attrs) {
    const elem = document.createElement(tag);
    elem.className = clazz;
    if (attrs) {
      for (let key in attrs) {
        elem[key] = attrs[key];
      }
    }
    return elem;
  }
  
  function sel(selector) {
    return document.querySelector(selector);
  }
  
  function selall(selector) {
    return document.querySelector(selector);
  }
  
  let errorLog = null;
  
  function initErrorLog() {
    var cardBody = document.querySelectorAll('.ivu-card-body')[1];
    if (!cardBody) {
      setTimeout(() => {
        initErrorLog();
      }, 200);
    } else {
      errorLog = document.createElement('ul');
      errorLog.id = 'errorLog';
      errorLog.className = 'error-log';
      cardBody.appendChild(errorLog);
    }
  }
  
  function addErrorLog(result, status, info) {
    if ([6, 7, 9].indexOf(result) != -1) {
      return;
    }
    var e = document.createElement('li');
    let html = "";
    html += status.short + "<br/>"
    if (result == -2) { // compile error
      html += info.err_info;
    } else {
      html += `耗时: ${info.time_cost} 内存:${submissionMemoryFormat(info.memory_cost)}`
    }
    e.innerHTML = html;
    e.style.backgroundColor = status.color;
    
    errorLog.prepend(e);
  }

  function submissionMemoryFormat(t) {
    if (void 0 === t)
      return "--";
    var e = parseInt(t) / 1048576;
    return String(e.toFixed(0)) + "MB"
  }
  
  function initHeaderReplace() {
    if (!document.querySelector('.ivu-card-body')) {
      setTimeout(() => {
        initHeaderReplace();
      }, 200);
      return;
    }
    const cardBody = document.querySelectorAll('.ivu-card-body')[1];
    const ojh = createElement('div', 'ojh');
    const body = createElement('div', 'ojh-body', {style: "display:none"})
    cardBody.prepend(ojh);
    
    const showButton = createElement('a', 'ojh-button text-button', {textContent: "展示头文件", style: "margin-right:40px;"});
    showButton.onclick = e => {
      if (showButton.textContent == '展示头文件') {
        showButton.textContent = '隐藏头文件';
        body.style.display = 'block';
      } else {
        showButton.textContent = '展示头文件';
        body.style.display = 'none';
      }
    }
    ojh.appendChild(showButton);
    
    const uploadButton = createElement('a', 'ojh-button text-button', {textContent: "添加头文件+", style: "margin-right:40px;"});
    const save = createElement('div', 'ojh-save', {style: "display:none;"});
    save.append(createElement('span', '', {innerText: "引用名称:"}))
    const saveInput = createElement('input', '', {style: "width:50%", placeholder: '代码中#include "../h/header.h",就填../h/header.h'});
    save.append(saveInput);
    save.append(createElement('br'))
    save.append(createElement('span', '', {innerText: "文件内容:"}))
    const saveArea = createElement('textarea', 'ojh-save-content');
    save.append(saveArea);
    const saveButton = createElement('button', 'ojh-save-button', {textContent: "保存"});
    uploadButton.onclick = e => {
      if (uploadButton.textContent == '添加头文件+') {
        uploadButton.textContent = '添加头文件-';
        save.style.display = 'block';
      } else {
        uploadButton.textContent = '添加头文件+';
        save.style.display = 'none';
      }
    }
    saveButton.onclick = e => {
      console.log(saveInput.value, saveArea.value)
      if (!saveInput.value) {
        $msg.error("引用名称没填");
        return;
      }
      if (!saveArea.value) {
        $msg.error("文件内容为空");
        return;
      }
      saveHeader(body, saveInput.value, saveArea.value);
      saveInput.value = saveArea.value = ""
    }
    
    const replaceButton = createElement('button', 'ojh-button', {textContent: "替换内容"});
    replaceButton.onclick = e => {
      $msg.info("开始替换代码中的头文件")
      let data = document.querySelector('.flex-container').__vue__.$data;
      let code = data.code;
      const regex = /#include "(.*?)"/g;
      while (true) {
        console.log("yici")
        let match;
        const headers = [];
        while ((match = regex.exec(code)) !== null) {
          headers.push(match[1]);
        }
        // 找是否存在header
        let find = false;
        for (let i = 0; i < headers.length; i++) {
          console.log("找是否匹配" + headers[i]);
          for (let storedHeader of store.headers) {
            if (headers[i] == storedHeader.name) {
              const escapedHeader = storedHeader.name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
              const regex = new RegExp(`#include "${escapedHeader}"`, 'g');
              let content = '// ' + storedHeader.name + "\n";
              content += storedHeader.content + "\n";
              code = code.replace(regex, content);
              find = true;
              break;
            }
          }
        }
        if (!find) {
          if (headers.length != 0) {
            $msg.info("未找到头文件:" + JSON.stringify(headers))
          }
          break;
        }
      }
      data.code = code;
      $msg.success("替换完成")
    }
    
    save.appendChild(saveButton);
    ojh.appendChild(uploadButton);
    ojh.appendChild(replaceButton);
    
    
    ojh.appendChild(save);

    ojh.append(body);
    showHeaders(body)
  }
  
  function showHeader(body, header) {
    const file = createElement('div', 'ojh-file', {id: "ojh-file-" + header.name});
    const name = createElement('span', 'ojh-file-name text-button', {innerText: header.name});
    const wrapper = createElement('div', 'ojh-file-wrapper', {style: "display: none;"})
    name.onclick = e => {
      if (wrapper.style.display == 'none') {
        wrapper.style.display = 'block';
      } else {
        wrapper.style.display = 'none';
      }
    }
    const deleteButton = createElement('a', 'ojh-file-delete text-button', {textContent: "删除"})
    deleteButton.onclick = e => {
      if (confirm("是否删除?")) {
        deleteHeader(header.name)
        document.getElementById('ojh-file-' + header.name)?.remove();
      }
    }
    file.append(name);
    file.append(deleteButton);
    
    const content = createElement('textarea', 'ojh-file-content', {value: header.content})
    const save = createElement('button', '', {textContent: "保存"});
    save.onclick = e => {
      saveHeader(body, header.name, content.value)
    }
    wrapper.append(content);
    wrapper.append(save);
    file.append(wrapper)
    
    body.append(file);
  }
  
  function showHeaders(body) {
    for (let header of store.headers) {
      showHeader(body, header);
    }
  }
  
  function saveHeader(body, name, content) {
    let headerElem = document.getElementById('ojh-file-' + name);
    if (!headerElem) {
      showHeader(body, {name, content})
    }
    for (let header of store.headers) { // 找是否有重复的
      if (header.name == name) {
        header.content = content;
        $msg.success("修改成功")
        GM_setValue('oj-headers', store.headers);
        return;
      }
    }
    store.headers.push({name, content});
    GM_setValue('oj-headers', store.headers);
    $msg.success("添加成功")
  }
  
  function deleteHeader(name) {
    console.log("删除头文件" + name);
    for (let i = 0; i < store.headers.length; i++) {
      if (store.headers[i].name == name) {
        store.headers.splice(i, 1);
        break;
      }
    }
    GM_setValue('oj-headers', store.headers);
    $msg.success("删除成功")
  }

  function initAnswerPanel() {
    if (!document.querySelector('.oj-menu')) {
      setTimeout(() => {
        initAnswerPanel();
      }, 200);
      return;
    }
    if (document.querySelector('.oj-panel')) {
      return;
    }
    const panel = createElement('div', 'oj-panel')
    const header = createElement('div', 'oj-header')
    const close = createElement('div', 'oj-close')
    close.innerText = '×'
    const body = createElement('div', 'oj-body')
    header.appendChild(close)
    panel.appendChild(header)
    panel.appendChild(body)
    document.body.appendChild(panel)
    let lastX = GM_getValue('box_last_x', 100)
    let lastY = GM_getValue('box_last_y', 100)
    panel.style.left = lastX + 'px'
    panel.style.top = lastY + 'px'
    panel.style.display = 'none'
    header.addEventListener('mousedown', makeDraggableFunction(panel, false, null, () => { 
        GM_setValue('box_last_x', parseInt(panel.style.left))
        GM_setValue('box_last_y', parseInt(panel.style.top))
    }), false)
    
    const showButton = createElement('span', 'oj-button ivu-menu-item')
    showButton.innerText = '看可见答案'
    document.querySelector('.oj-menu').appendChild(showButton)
    showButton.addEventListener('click', e => {
      showButton.style.display = 'none'
      panel.style.display = 'block'
      body.innerHTML = ''
      getAnswers()
    })
    close.addEventListener('click', e => {
      panel.style.display = 'none'
      showButton.style.display = 'block'
      stop = true;
    })
  }
  
   function makeDraggableFunction(elem, allowMoveOut, exec, callback) {
    let handleMouseDown = function (event) {
      let offsetX = parseInt(elem.style.left)
      let offsetY = parseInt(elem.style.top)
      let innerX  = event.clientX - offsetX
      let innerY  = event.clientY - offsetY
      if (!!exec) {
        exec()
      }
      document.onmousemove = function (event) {
        elem.style.left = event.clientX - innerX + 'px'
        elem.style.top = event.clientY - innerY + 'px'
        if (!allowMoveOut) {
          if (parseInt(elem.style.left) <= 0) {
            elem.style.left = '0px'
          }
          if (parseInt(elem.style.top) <= 0) {
            elem.style.top = '0px'
          }
          if (
            parseInt(elem.style.left) >=
            window.innerWidth - parseInt(elem.style.width)
          ) {
            elem.style.left =
              window.innerWidth - parseInt(elem.style.width) + 'px'
          }
          if (
            parseInt(elem.style.top) >=
            window.innerHeight - parseInt(elem.style.height)
          ) {
            elem.style.top = window.innerHeight - parseInt(elem.style.height) + 'px'
          }
        }
      }
      document.onmouseup = function () {
        document.onmousemove = null
        document.onmouseup = null
        if (!!callback) {
          callback()
        }
      }
    }
    return handleMouseDown
  }
  
  let stop = false;
  function getProblemId() {
    let url = location.href;
    if (url.indexOf('/problem') != -1) {
      url = url.substring(url.lastIndexOf('/') + 1);
      return parseInt(url);
    }
    return null;
  }
  function getAnswers() {
    let problemId = getProblemId();
    if (!problemId) {
      alert("未在答题界面!")
      return;
    }
    stop = false;
    let total = -1;
    getList(problemId, 1);
  }
  
  function getList(problemId, page) {
    const offset = (page - 1) * 100;
    fetch(`https://www.bjfuacm.com/api/submissions?myself=0&result=0&username=&page=${page}&problem_id=${problemId}&limit=100&offset=${offset}`, {
      "headers": {
        "accept-language": "zh-CN,zh;q=0.9",
        "content-type": "application/json;charset=utf-8",
      },
      "body": null,
      "method": "GET",
    }).then(res => res.json()).then(res => {
      // console.log(res)
      const {results, total} = res.data;
      let html = ''
      for (let result of results) {
        if (result.show_link) {
          const info = result.statistic_info;
          html += `<div class="oj-result">
                    <a href="https://www.bjfuacm.com/status/${result.id}" target="_blank">查看答案</a> 
                    <span>耗时${info.time_cost}MS 内存${submissionMemoryFormat(info.memory_cost)} 
                    作者<a href="https://www.bjfuacm.com/user-home?username=${result.username}" target="_blank">${result.username}</a></span></div>`
        }
      }
      document.querySelector('.oj-body').innerHTML += html;
      if (!stop && offset < total) {
        getList(problemId, page + 1);
      } else {
        document.querySelector('.oj-body').innerHTML += "<p style='text-align:center;'>—————— 已加载全部 ——————</p>";
      }
    }).catch(err => {
      console.error(err);
      alert("ERROR: " + err)
    });
  }
  
  /**
   * 为list添加每页展示数量的选项
   */
  function initPageOption(parent, onchange) {
    if (!sel('.content-app')) {
      setTimeout(initPageOption, 200);
      return;
    }
    setTimeout(() => {
      let vue = sel('.content-app').children[0].__vue__;
      console.log(vue)
      if (parent) {
        vue = vue.$parent;
      }
      vue.limit = store.pagesize;
      if (onchange) {
        onchange(vue, store.pagesize)
      }
      const filter = sel('.filter');
      const pageSelect = createElement('select', '', {style: "margin-right:10px;"})
      for (let pagesize of [10, 20, 30, 50, 100]) {
        const option = createElement('option', '', {label: `${pagesize}个/页`, textContent: `${pagesize}个/页`, value: pagesize});
        pageSelect.append(option);
        if (vue.limit == pagesize) {
          pageSelect.value = pagesize;
        }
      }
      pageSelect.onchange = e => {
        if (onchange) {
          onchange(vue, pageSelect.value);
        }
        store.pagesize = pageSelect.value;
        GM_setValue('oj-pagesize', store.pagesize);
      }
      filter.prepend(pageSelect);
      if (parent) { // if in problem list page
        const hideACLabel = createElement('label', '', {style: 'margin-right:10px', innerText: '隐藏已完成'});
        const hideACCheck = createElement('input', '', {type: 'checkbox', checked: store.hideAC});
        hideACCheck.onchange = e => {
          store.hideAC = hideACCheck.checked;
          GM_setValue('oj-hideAC', store.hideAC);
          onchange(vue, pageSelect.value);
        }
        hideACLabel.append(hideACCheck);
        filter.prepend(hideACLabel);
      }
    }, 200)
  }
  
  function hookRequest() {
    const originalOpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function(method, url) {
      if (url.indexOf('/api/submission?id=') != -1) {
        this.addEventListener('readystatechange', function() {
          if (this.readyState == 4) {
            const res = JSON.parse(this.responseText);
            const result = res.data.result;
            const status = status_map[result]
            console.log(res, status)
            if (!res.data.statistic_info) {
              return;
            }
            const info = res.data.statistic_info;
            addErrorLog(result, status, info);
            store.problems[res.data.problem] = {status: result};
          }
        })
      } else if (url.indexOf('/api/profile') != -1) {
        this.addEventListener('readystatechange', function() {
          if (this.readyState == 4) {
            const res = JSON.parse(this.responseText);
            store.problems = res.data.acm_problems_status.problems;
            console.log('SOLVED: ', store.problems)
          }
        })
      } else if (url.indexOf('/api/problem') != -1) {
        this.addEventListener('readystatechange', function() {
          if (this.readyState == 4) {
            const res = JSON.parse(this.responseText);
            const list = res.data.results;
            for (let i = 0; i < list.length; i++) {
              const problem = list[i];
              let status = store.problems[problem.id]
              if (status) {
                if (status.status == 0) {
                  if (store.hideAC) {
                    list.splice(i, 1);
                    i--;
                  } else {
                    problem.title = '✔️ ' + problem.title;
                  }
                } else {
                  problem.title = '❌ ' + problem.title;
                }
              }
            }
            Object.defineProperty(this, 'responseText', {writable: true})
            this.responseText = JSON.stringify(res);
          }
        })
      }
      originalOpen.apply(this, arguments);
    }
  }
  
  function urlContains(url, targets) {
    for (let target of targets) {
      if (url.indexOf(target) != -1) {
        return true;
      }
    }
    return false;
  }
  
  let lastPath = "DAMNSONWHEREDYOUFINDTHAT";
  setInterval(() => {
    if (location.pathname != lastPath) {
      lastPath = location.pathname;
      if (lastPath.indexOf('/problem/') != -1) {
        injectCSS();
        initErrorLog();
        initAnswerPanel();
        initHeaderReplace();
      } else if (['/problems', '/structure', '/started'].indexOf(lastPath) != -1) {
        initPageOption(true, (vue, pagesize) => {
          vue.limit = pagesize;
          vue.query.page = 1;
          if (!vue.query.difficulty || vue.query.difficulty == '') {
            vue.query.difficulty = store.difficulty;
          } else {
            store.difficulty = vue.query.difficulty;
            GM_setValue('oj-difficulty', store.difficulty);
          }
          vue.getProblemList();
        });
      } else if (lastPath == '/status') {
        initPageOption(false, (vue, pagesize) => {
          vue.limit = pagesize;
          vue.page = 1;
          vue.getSubmissions();
        });
      }
      console.log("path切换为" + lastPath)
    }
  }, 500);
  hookRequest();
})()