HiNativeTool

Handy Hinative tool!!

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(У мене вже є менеджер скриптів, дайте мені встановити його!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name             HiNativeTool
// @name:en          HiNativeTool
// @namespace        http://tampermonkey.net/
// @version          1.3.1
// @description      Handy Hinative tool!!
// @description:en   Handy Hinative tool!!
// @author           Collen Zhou
// @match            *://hinative.com/*
// @grant            unsafeWindow
// @grant            GM_getValue
// @grant            GM_setValue
// @grant            GM_listValues
// @grant            GM_xmlhttpRequest
// @grant            unsafeWindow
// @require          http://code.jquery.com/jquery-3.4.1.min.js
// ==/UserScript==
//The file is auto created with script, changes might get lost!
(function() {
    'use strict';/*this is generated code don't edit*/
    console.log("Hinative tool is running!")
    window. gm_get = GM_getValue
    window. gm_set = GM_setValue
    function toggle_setting(){
            let visible=$('#popup').is(':visible')
            var pop_up=$(window.popuphtml)
            if(visible)
            pop_up.hide()
            else{
            pop_up.show()
            }
            $('#popup').replaceWith(pop_up)
            setup_popup()

    }

    let s=$("<li></li>")
    let ts=$("<span id='setting' title='sript settings' style='font-size: 22px;cursor: pointer;'  >⚙️</span>")
    ts.click(toggle_setting)
    s.append(ts)
    $(".nav_activity").after(s)

window. TMStorage = function () {
}
//添加TM支持
TMStorage.prototype = {
  get: function (keys, callback) {
    let count = 0;/*this is generated code don't edit*/
    let sum = keys.length
    let obj = {}

    for (let key of keys) {
      let key1 = key
      window. result = gm_get(key1)

      if (result == "undefined")
      {

        continue
      }

      else
      {

        obj[key1] = gm_get(key1)
      }

    }

    callback(obj)
  },
  set: function (obj1, callback) {
    let count = 0;/*this is generated code don't edit*/
    let sum = Object.keys(obj1).length
    let obj = obj1
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        const value = obj[key];/*this is generated code don't edit*/
        gm_set(key, value)
      }
    }
    if (typeof callback === "undefined")
      return
    else {
      callback(obj)
    }
  }
}
TMStorage.prototype.constructor = TMStorage

window. Mode = function () {
}

Mode.prototype = {
  Mode: null,
  Storage: null,
  OnInstalled: function (callback) { },
  OnPageUpdate: function (callback) { },
  ExecuteScript: function (script, callback) { },
  unsafeWindow:window
}
Mode.prototype.constructor = Mode

//添加TM支持
window. TMMode = function () {
  Mode.call(this)
  this.Mode = "TM"
  this.Storage = new TMStorage()
  this.unsafeWindow=unsafeWindow
  this.OnPageUpdated = function (callback) {
    callback.call(this)
  }
  this.ExecuteScript = function (obj, callback) {

    eval(obj.code)


    callback.call(this)
  }

}
TMMode.prototype = new Mode()
TMMode.prototype.constructor = new TMMode()

window. ExtensionMode = function () {
  Mode.call(this)
  this.Mode = "extension"
  this.Storage = chrome.storage.local
  this.OnPageUpdated = function (callback) {
    chrome.tabs.onUpdated.addListener(callback)
  }
  this.OnInstalled = function (callback) {
    chrome.runtime.onInstalled.addListener(callback)
  }
  this.ExecuteScript = function (script, callback) {
    chrome.tabs.executeScript(script, callback)
  }
}
ExtensionMode.prototype = new Mode()
ExtensionMode.prototype.constructor = ExtensionMode

window. mode = new TMMode()
window. storage = mode.Storage

function log(obj) {
  if (show_log)
      console.log(obj)
}


//执行一个字典里所有的脚本,并在所有脚本都执行完后调用resolve
function preload(dict) {
  let len = Object.keys(dict).length
  let count = 0;/*this is generated code don't edit*/
  return new Promise(resolve=>{
    for (let key in dict) {
      if (dict.hasOwnProperty(key)) {
        let val = dict[key];/*this is generated code don't edit*/
        let key1 = key
         add_script_value(key1, val).then(function () {
          if (++count == len) {
            resolve()
          }
        })
      }
    }
  })
}

//添加一个页面变量值,如果不存在则创建并设置默认值
function add_script_value(key1, dflt1) {
  let key = key1
  let dflt = dflt1
  return new Promise(resolve => {
    storage.get([key], function (result) {

      if (typeof result[key] === "undefined") {
        let obj = {}
        obj[key] = dflt
        result[key] = dflt
        log("undefined key:"+key)
        storage.set(obj)
      }

      set_variable(key,result[key]).then(function () {
        resolve()
      });/*this is generated code don't edit*/

    });/*this is generated code don't edit*/
  })
}

function set_variable(key,value)
{
  let code = "window."+key + ' = ' +JSON.stringify(value)
  return execute_script(code);/*this is generated code don't edit*/
}



//执行一个脚本返回resolve
function execute_script(script) {
  let script1=script
  return new Promise(resolve=>{
    mode.ExecuteScript({
      code: script1
    },()=>{
      let e=chrome.runtime.lastError
      resolve()
    })
  })
}

function parse_to_querystring(obj){
  //转换成query url
  var esc = encodeURIComponent;/*this is generated code don't edit*/

  var qry = Object.keys(obj)
    .map((k) => esc(k.toString().replace(/\/\d+$/,"")) + "=" + esc(obj[k]))
    .join("&");/*this is generated code don't edit*/
  return qry
}


function add_loading(ele){
  let loading = null;/*this is generated code don't edit*/
  //添加loading图片
  if ($(ele).find(".script_loading").length == 0) {
    loading = String.raw`<div class="script_loading" style="width: 16px;height: 16px;display: inline-block;background: url(//cdn.hinative.com/packs/media/loadings/default-091d6e81.gif) no-repeat;background-size: 16px 16px;"> </div>`;/*this is generated code don't edit*/
    loading = $(loading);/*this is generated code don't edit*/
    ele.append(loading);/*this is generated code don't edit*/
  }
  function ok() {
    loading.remove();/*this is generated code don't edit*/
  }
  return ok;/*this is generated code don't edit*/
}


// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';/*this is generated code don't edit*/
mode.OnInstalled(function () {
  //添加popup
  chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
    chrome.declarativeContent.onPageChanged.addRules([{
      conditions: [new chrome.declarativeContent.PageStateMatcher({
        pageUrl: { hostEquals: 'hinative.com' },
      })
      ],
      actions: [new chrome.declarativeContent.ShowPageAction()]
    }]);/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
})
// execute_script("window.need_featured_answer=true")

mode.OnPageUpdated(function (tabId, changeInfo, tab) {
  execute_script("window.data_loaded=false")
  //在这里初始化变量
  let obj={
    "show_log": false,
    "extension_enabled": true,
    "auto_block": false,
    "need_featured_answer": true,
    "cache_new_users": false,
    "block_rate_below": 0.3,
    "validity_duration": 7,
    "blocked_users": [],
    "result_buffer": {},
    "white_list": [],
    "self_name":(()=>{})(),
    "self_url":(()=>{})(),
    "questions_info":{},
    "request_interval":200,
    "fap_count":2,
    "old_question_age":7,
    "rearrange":true,
    "questions_info":{},
    "languages":{},
    "selected_languages":[],
  }
  //数据加载完后添加全局变量data_loaded
  preload(obj).then(function(){
    // alert("preloaded")
    execute_script("window.data_loaded=true")
  })

  $.ajaxSetup({
    crossDomain: true,
    xhrFields: {
        withCredentials: true
    }
});/*this is generated code don't edit*/
})

$(document).ready(function () {
  // https://hinative.com/en-US 只监听qeustions路径
  if (!window.location.pathname.match(/^\/[^\/]*$/)) return;/*this is generated code don't edit*/
  //缓存的结果,减少xhr次数
  // result_buffer
  //数据是否加载完
  // data_loaded = false
  //用来填充的个数
  //被屏蔽的用户列表
  // blocked_users = []

  //现在是否正在blocking过程中
  window.blocking = false;/*this is generated code don't edit*/
  //新用户最大提问数
  window.new_user_qustion_count = 3;/*this is generated code don't edit*/
  //自动屏蔽的用户数组
  window.auto_blocked_users = [];/*this is generated code don't edit*/
  //已经被屏蔽的问题块
  window.blocked_blocks = new Set();/*this is generated code don't edit*/
  //已经用于填充的问题块数
  window.filling_blocks_count = 0;/*this is generated code don't edit*/
  //存放请求的队列
  window.request_queue = [];/*this is generated code don't edit*/
  //页面是否正在添加新的提问
  window.appending = false;/*this is generated code don't edit*/
  //是不是第一次加载完blocks
  window.first_loaded = true;/*this is generated code don't edit*/
  //是否只查看已回答的问题
  window.only_answered = jq_must_find(
    document.body,
    "input[data-questions-not-answered-only]"
  ).is(":checked");/*this is generated code don't edit*/
  //请求最小间隔,以免给hinative服务器造成负担
  // request_interval

  //开启请求循环
  start_request_interval();/*this is generated code don't edit*/
  //获取用户信息和语言信息
  get_info();/*this is generated code don't edit*/
  //监听blocks变化
  setInterval(() => {
    if (
      !(typeof data_loaded === "undefined") &&
      data_loaded &&
      extension_enabled
    ) {
      process_multilanguage();/*this is generated code don't edit*/
      process_blocking();/*this is generated code don't edit*/
      process_scroll();/*this is generated code don't edit*/
      process_order();/*this is generated code don't edit*/
    }
  }, 200);/*this is generated code don't edit*/
  re_arrange();/*this is generated code don't edit*/
  //每三分钟不活动刷新一次
  // var timeout;/*this is generated code don't edit*/
  // document.onmousemove = function () {
  //   clearTimeout(timeout);/*this is generated code don't edit*/
  //   timeout = setTimeout(function () {
  //     location.reload();/*this is generated code don't edit*/
  //   }, 60 * 1000 * 3);/*this is generated code don't edit*/
  // };/*this is generated code don't edit*/
});/*this is generated code don't edit*/
//自动排序问题
function process_order() {
  let dqf = $(".body[data-questions-feed]");/*this is generated code don't edit*/
  var sorted = dqf.find(".d_block").sort(function (a, b) {
    return (
      new Date($(b).find(".timeago").attr("title")).getTime() -
      new Date($(a).find(".timeago").attr("title")).getTime()
    );/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
  var arr = dqf.find(".d_block").toArray();/*this is generated code don't edit*/
  var equal = true;/*this is generated code don't edit*/
  for (let i = 0; i < sorted.length; i++) {
    const a = sorted[i];/*this is generated code don't edit*/
    const b = arr[i];/*this is generated code don't edit*/
    if (a !== b) {
      equal = false;/*this is generated code don't edit*/
      break;/*this is generated code don't edit*/
    }
  }
  if (!equal) {
    sorted.prependTo(dqf);/*this is generated code don't edit*/
    $("#time_line").remove();/*this is generated code don't edit*/
    for (const ele of sorted) {
      //七天前的消息线
      if (
        $("#time_line").length == 0 &&
        $(".body[data-questions-feed]").has(ele) &&
        new Date().getTime() -
          new Date(jq_must_find(ele, ".timeago").get(0).title).getTime() >
          86400 * 1000 * validity_duration
      ) {
        window.time_line = $(
          "<div id='time_line'><div style='height:1px;background-color:black'></div><div style='text-align:center'>接下来是" +
            validity_duration +
            "天前的消息</div></div>"
        );/*this is generated code don't edit*/
        $(ele).before(time_line);/*this is generated code don't edit*/
      }
    }
  }
}
//重新安排页面,去除广告,添加快捷入口,显示未回答问题等
function re_arrange() {
  if (rearrange) {
    $("main").append(
      "<div style='text-align:center'>如果需要新的提问,请下滑刷新~~ <br/>scroll down to refresh</div>"
    );/*this is generated code don't edit*/
    //添加提问和回答快速入口
    let q = $(
      "<li><a  title='my questions' href='" +
        window.self_url +
        "/questions' style='font-size: 22px;cursor: pointer;'  >❔</a></li>"
    );/*this is generated code don't edit*/
    let a = $(
      "<li><a  title='my answers' href='" +
        window.self_url +
        "/answers' style='font-size: 22px;cursor: pointer;'  >💡</a></li>"
    );/*this is generated code don't edit*/
    $(".nav_activity").after(q);/*this is generated code don't edit*/
    $(".nav_activity").after(a);/*this is generated code don't edit*/
    //等待直到所有数据加载完成
    while (!data_loaded) {}
    get_unanswered_questions();/*this is generated code don't edit*/
  }
}

function get_unanswered_questions() {
  if (typeof self_url !== "undefined") {
    let ctr = $(".l_sidebar_container");/*this is generated code don't edit*/
    let old = ctr.contents();/*this is generated code don't edit*/
    ctr.append("<div class='feedback_modal'>我未被回答的问题</div>");/*this is generated code don't edit*/
    traverse_user_questions(self_url, 0, ":has(.has_no_answer)", function (
      txt,
      block
    ) {
      let page = to_jq(txt);/*this is generated code don't edit*/
      //如果没有回答 也没有人选择回答,就继续
      if (page.find("div[data-answer-id]").length > 0) {
        if ($(page.find(".count")).length != 0) {
          let has_no_answer = true;/*this is generated code don't edit*/
          $(page.find(".count")).each(function () {
            if ($(this).find("p").find("span").text().trim() != "0")
              has_no_answer = false;/*this is generated code don't edit*/
          });/*this is generated code don't edit*/
          if (!has_no_answer) {
            return;/*this is generated code don't edit*/
          }
        } else {
          return;/*this is generated code don't edit*/
        }
      }

      console.log("find!");/*this is generated code don't edit*/
      let ele = $(block).clone();/*this is generated code don't edit*/
      let href = $(block).attr("href");/*this is generated code don't edit*/
      let wrapper = $(
        "<div class='wrapper wrapper_fukidashi' style='border: solid;border-width: 1px;margin-bottom: 20px;border-radius: 10px;'></div>"
      );/*this is generated code don't edit*/
      let ques = jq_must_find(ele, ".mod_question_content_decorated");/*this is generated code don't edit*/
      let word = jq_must_find(ques, ".keyword");/*this is generated code don't edit*/
      let timeago = jq_must_find(ele, ".timeago");/*this is generated code don't edit*/
      ques.append(timeago);/*this is generated code don't edit*/
      word.css("cursor", "pointer");/*this is generated code don't edit*/
      word.click(function () {
        location.href = href;/*this is generated code don't edit*/
      });/*this is generated code don't edit*/
      wrapper.css("borderColor", "#2c2d30");/*this is generated code don't edit*/
      let re_ask = $("<span style='cursor: pointer;margin-left:2px'>重新提问</span>");/*this is generated code don't edit*/
      // 请求格式如下
      // let deletepage.find(".new_question").get(0).serialize()
      // delete
      // https://hinative.com/zh-CN/questions/16072745?_method: deleteauthenticity_token: 2LYt
      // new question
      // authenticity_token: Kls2QleQBbWLxPk2yRSYfHVSFocO+JJs1wAejR4714ACx4IHRSK8ttI3ocqhd0anZMIfj5ZhrWyiSHCbVBVaOg==
      // source:
      // type: WhatsayQuestion
      // question[language_id]: 22
      // question[question_keywords_attributes][0][name]: 手机欠费了
      // photo:
      // image[id]:
      // audio[id]:
      // question[supplement]: thank you
      // question[prior]: 0
      //获得提问类型
      let query = new FormData();/*this is generated code don't edit*/
      query.append("source", "");/*this is generated code don't edit*/
      let type = txt.match(/(?<=question_type:\s*')\w+(?=')/);/*this is generated code don't edit*/
      if (type == "ChoiceQuestion") {
        query.append(
          "question[content]",
          jq_must_find(page, ".keyword").text()
        );/*this is generated code don't edit*/
      } else if (type == "DifferenceQuestion") {
        let i = 0;/*this is generated code don't edit*/
        jq_must_find(page, ".keyword").each(function () {
          query.append(
            "question[question_keywords_attributes][][name]",
            $(this).text()
          );/*this is generated code don't edit*/
          query.append(
            "question[question_keywords_attributes][][id]",
            ""
          );/*this is generated code don't edit*/
          query.append(
            "question[question_keywords_attributes][][_destroy]",false
           ) ;/*this is generated code don't edit*/
          i++;/*this is generated code don't edit*/
        });/*this is generated code don't edit*/
      } else {
        query.append(
          "question[question_keywords_attributes][0][name]",
          jq_must_find(page, ".keyword").text()
        );/*this is generated code don't edit*/
      }

      query.append("photo", "");/*this is generated code don't edit*/
      query.append("image[id]", "");/*this is generated code don't edit*/
      query.append("audio[id]", "");/*this is generated code don't edit*/
      query.append("question[supplement]", page.find(".desc_box").text().trim());/*this is generated code don't edit*/
      query.append("question[prior]", 0);/*this is generated code don't edit*/
      let lang_id = -1;/*this is generated code don't edit*/
      let lang_text = jq_must_find(page, ".tag b").text();/*this is generated code don't edit*/
      log("lang_text:" + lang_text);/*this is generated code don't edit*/
      for (const val in languages) {
        if (languages.hasOwnProperty(val)) {
          const text = languages[val];/*this is generated code don't edit*/
          if (text.trim() == lang_text) {
            lang_id = val;/*this is generated code don't edit*/
            break;/*this is generated code don't edit*/
          }
        }
      }
      if (lang_id == -1) {
        log("未能找到对应语言,请刷新个人信息重试!");/*this is generated code don't edit*/
      }
      query.append("question[language_id]", lang_id);/*this is generated code don't edit*/
      re_ask.click(function () {
        let req = request_get(
          "https://hinative.com/zh-CN/questions/new?type=" + type,
          function () {},
          false,
          true
        );/*this is generated code don't edit*/
        let ap = to_jq(req.responseText);/*this is generated code don't edit*/
        query.append(
          "authenticity_token",
          jq_must_find(ap, "input[name='authenticity_token']").val()
        );/*this is generated code don't edit*/
        // let qry=parse_to_querystring(query)
        let ok = add_loading(re_ask);/*this is generated code don't edit*/
        mode.unsafeWindow.$.post({
          url: "https://hinative.com/zh-CN/questions?type=" + type,
          data: query,
          processData: false,
          contentType: false,
          success: (_) => {
            ok();/*this is generated code don't edit*/
            delete_question();/*this is generated code don't edit*/
          },
        });/*this is generated code don't edit*/
        timeago.attr("title", new Date().toTimeString());/*this is generated code don't edit*/
      });/*this is generated code don't edit*/
      let dlt = $("<span style='cursor: pointer;margin-left:2px' >删除问题</span>");/*this is generated code don't edit*/
      let del_data = {
        _method: "delete",
        authenticity_token: jq_must_find(page, "meta[name='csrf-token']").attr(
          "content"
        ),
      };/*this is generated code don't edit*/
      dlt.click(function () {
        delete_question();/*this is generated code don't edit*/
      });/*this is generated code don't edit*/
      function delete_question() {
        let ok = add_loading(dlt);/*this is generated code don't edit*/
        mode.unsafeWindow.$.post({
          url: href,
          data: del_data,
          success: () => {
            ok();/*this is generated code don't edit*/
            get_unanswered_questions();/*this is generated code don't edit*/
          },
        });/*this is generated code don't edit*/
        wrapper.hide();/*this is generated code don't edit*/
      }

      wrapper.append(ques);/*this is generated code don't edit*/
      wrapper.append(re_ask);/*this is generated code don't edit*/
      wrapper.append(dlt);/*this is generated code don't edit*/
      $(".l_sidebar_container").append(wrapper);/*this is generated code don't edit*/
    }).then(function () {
      old.remove();/*this is generated code don't edit*/
    });/*this is generated code don't edit*/
  }
}

function process_multilanguage() {
  if (first_loaded && $("li[data-next-page]>a").length > 0) {
    intercept();/*this is generated code don't edit*/
    get_questions().remove();/*this is generated code don't edit*/
    $("li[data-next-page]>a").attr(
      "href",
      $("li[data-next-page]>a")
        .get(0)
        .href.replace(/page=\d+/g, "page=1")
    );/*this is generated code don't edit*/
    first_loaded = false;/*this is generated code don't edit*/
  }
}
//拦截请求,并添加请求
function intercept() {
  let origin = XMLHttpRequest.prototype.open;/*this is generated code don't edit*/
  XMLHttpRequest.prototype.open = function (...args) {
    let url = args[1];/*this is generated code don't edit*/
    this.__url = url;/*this is generated code don't edit*/
    return origin.apply(this, args);/*this is generated code don't edit*/
  };/*this is generated code don't edit*/
  var accessor = Object.getOwnPropertyDescriptor(
    XMLHttpRequest.prototype,
    "response"
  );/*this is generated code don't edit*/
  Object.defineProperty(XMLHttpRequest.prototype, "response", {
    get: function () {
      let response = accessor.get.call(this);/*this is generated code don't edit*/
      if (
        typeof this.__auto === "undefined" &&
        this.__url.indexOf("questions?") > 0
      ) {
        window.appending = true;/*this is generated code don't edit*/
        let url = this.__url.split("?")[0];/*this is generated code don't edit*/
        let params = this.__url.split("?")[1];/*this is generated code don't edit*/
        let page = params.match(/(?<=page=)\d+/)[0];/*this is generated code don't edit*/
        let lang_id = params.match(/(?<=language_id=)\d+/)[0];/*this is generated code don't edit*/
        let append = "";/*this is generated code don't edit*/
        for (const lang of selected_languages) {
          if (lang == lang_id) continue;/*this is generated code don't edit*/
          let url1 = url + "?language_id=" + lang + "&page=" + page;/*this is generated code don't edit*/
          console.log("appended request:" + url1);/*this is generated code don't edit*/
          let req = request_get(url1, null, false, true);/*this is generated code don't edit*/
          append = append + req.responseText;/*this is generated code don't edit*/
        }
        let apd = to_jq(append);/*this is generated code don't edit*/
        apd.find(".hide").remove();/*this is generated code don't edit*/
        $(response.body).append(apd);/*this is generated code don't edit*/
        apd = $(response.body);/*this is generated code don't edit*/
        //把已经回答的问题去掉
        if (only_answered) {
          jq_must_find(apd, ".d_block").each(function () {
            let no_anser = $(this).find(".has_no_answer");/*this is generated code don't edit*/
            if (no_anser.length == 0) {
              $(this).remove();/*this is generated code don't edit*/
            }
          });/*this is generated code don't edit*/
        }
        window.appending = false;/*this is generated code don't edit*/
      }

      return response;/*this is generated code don't edit*/
    },
    set: function (str) {
      return accessor.set.call(this, str);/*this is generated code don't edit*/
    },
    configurable: true,
  });/*this is generated code don't edit*/
}
//自动下拉以刷新提问
function process_scroll() {
  if (window.appending == true) return;/*this is generated code don't edit*/
  if (typeof scroll_bar === "undefined") {
    window.scroll_bar = $(
      "<div class='scroll_bar' style='display:block;height:" +
        0 +
        "px;width:20px'>❀</div>"
    );/*this is generated code don't edit*/
    $("body").append(scroll_bar);/*this is generated code don't edit*/
  }
  let bh = scroll_bar.css("height").replace("px", "");/*this is generated code don't edit*/
  var remain =
    window.innerHeight - ($("html").get(0).getClientRects()[0].height - bh);/*this is generated code don't edit*/
  if (remain > 0) {
    let tmp = $("html").get(0).scrollTop;/*this is generated code don't edit*/
    console.log("scroll");/*this is generated code don't edit*/
    $("html").get(0).scrollTop = 0;/*this is generated code don't edit*/
    $("html").get(0).scrollTop = $("html").get(0).scrollHeight;/*this is generated code don't edit*/
    $("html").get(0).scrollTop = tmp;/*this is generated code don't edit*/
  }

  scroll_bar.css("height", new Number(remain) + 100);/*this is generated code don't edit*/
}

//获得所有问题块
function get_questions() {
  return $(".l_main_container .d_block");/*this is generated code don't edit*/
}

function get_info() {
  //得到自身信息
  (function get_self_username() {
    if (typeof self_name === "undefined") {
      let p_url = $(".spec_nav_profile>a").get(0).href;/*this is generated code don't edit*/
      let req = request_get(p_url, null, false);/*this is generated code don't edit*/
      let name = to_jq(req.responseText).find(".owner_name>span").text().trim();/*this is generated code don't edit*/
      storage.set({
        self_name: name,
      });/*this is generated code don't edit*/
      storage.set({
        self_url: p_url,
      });/*this is generated code don't edit*/
      log("get self name:" + name + " self url:" + p_url);/*this is generated code don't edit*/
      // get_user_info(p_url, name)
    }
  })();/*this is generated code don't edit*/
  if (typeof languages === "undefined" || languages.length == 0) {
    let req = request_get(self_url + "/edit", null, false);/*this is generated code don't edit*/
    // console.log(req.responseText)
    let options = to_jq(req.responseText).find(
      ".native_language_select>option"
    );/*this is generated code don't edit*/
    let langs = {};/*this is generated code don't edit*/
    options.each(function () {
      langs[$(this).val()] = $(this).text();/*this is generated code don't edit*/
    });/*this is generated code don't edit*/
    storage.set({
      languages: langs,
    });/*this is generated code don't edit*/
    log("get languages:");/*this is generated code don't edit*/
    log(langs);/*this is generated code don't edit*/
  }
}

//主要的执行过程
function process_blocking() {
  if (blocking) {
    log("blokcing");/*this is generated code don't edit*/
    return;/*this is generated code don't edit*/
  }
  //阻塞标示,以免两个interval同时运行,造成多次paint
  blocking = true;/*this is generated code don't edit*/
  try {
    //遍历每个回答
    get_questions().each(function () {
      if (this.processed != true) process(this);/*this is generated code don't edit*/
    });/*this is generated code don't edit*/
  } finally {
    blocking = false;/*this is generated code don't edit*/
  }
}

function process(ele) {
  let b_block = $(ele).get(0);/*this is generated code don't edit*/
  //用 div替换a
  if (b_block.outerHTML.startsWith("<a")) {
    let newDiv = $(
      b_block.outerHTML.replace(/^<a/, "<div").replace("/a>$/", "/div>")
    );/*this is generated code don't edit*/
    $(b_block).replaceWith(newDiv);/*this is generated code don't edit*/
    b_block = newDiv.get(0);/*this is generated code don't edit*/
    ele = b_block;/*this is generated code don't edit*/
  }
  let href = get_href(ele);/*this is generated code don't edit*/
  let usr = jq_must_find(ele, ".username").text();/*this is generated code don't edit*/
  let wrapper = jq_must_find(ele, ".username_wrapper");/*this is generated code don't edit*/
  ele.processed = true;/*this is generated code don't edit*/
  //更新问题信息到本地
  let q_info = questions_info[href];/*this is generated code don't edit*/
  if (typeof q_info === "undefined") {
    q_info = {
      url: href,
      blocked: false,
      select_urls: [],
    };/*this is generated code don't edit*/
    questions_info[href] = q_info;/*this is generated code don't edit*/
    storage.set({
      questions_info: questions_info,
    });/*this is generated code don't edit*/
  }

  //如果是屏蔽用户则不用画
  if (!check_block(b_block)) {
    //log("return:" + usr)
    return;/*this is generated code don't edit*/
  }

  //如果已经画过了也不用画
  if (b_block.painted == true) {
    return;/*this is generated code don't edit*/
  }

  let block = b_block;/*this is generated code don't edit*/
  //判断是不是选择型问题
  if (
    $(block).find("*:contains('does this sound natural')").length > 0 ||
    $(block).find("*:contains('听起来自然吗?')").length > 0
  ) {
    let c_url = href + "/choice_result";/*this is generated code don't edit*/
    let c_req = request_get(c_url, null, false);/*this is generated code don't edit*/
    //如果已经投过票了,则跳过这个问题
    if (c_req.responseText.indexOf(self_name) > -1) {
      log("usr:" + usr + " skip quesion because I have selected");/*this is generated code don't edit*/
      add_block(block);/*this is generated code don't edit*/
      return;/*this is generated code don't edit*/
    }
  }

  //如果该用户没加载过,或者用户数据过期了就继续加载数据,否则重画
  if (typeof result_buffer[usr] === "undefined") {
    //没有加载过就继续
    log("usr not in buffer:" + usr);/*this is generated code don't edit*/
  } else if (!(typeof validity_duration === "undefined")) {
    let duration =
      (new Date().getTime() - result_buffer[usr].time) / (86400 * 1000);/*this is generated code don't edit*/
    //判断数据是否过期,单位为天
    if (duration >= validity_duration) {
      log("validity_duration:" + validity_duration + "duration:" + duration);/*this is generated code don't edit*/
      log(usr + " data expired!");/*this is generated code don't edit*/
    } else {
      //已经加载过了
      //如果是新的方块则重新画一遍
      do_painting(b_block, result_buffer[usr].txt);/*this is generated code don't edit*/
      return;/*this is generated code don't edit*/
    }
  }
  let loading_ok = add_loading(wrapper);/*this is generated code don't edit*/
  // let loading = null;/*this is generated code don't edit*/
  // //添加loading图片
  // if ($(b_block).find(".script_loading").length == 0) {
  //   loading = String.raw`<div class="script_loading" style="width: 16px;height: 16px;display: inline-block;background: url(//cdn.hinative.com/packs/media/loadings/default-091d6e81.gif) no-repeat;background-size: 16px 16px;"> </div>`;/*this is generated code don't edit*/
  //   loading = $(loading);/*this is generated code don't edit*/
  //   wrapper.append(loading);/*this is generated code don't edit*/
  // }

  function success() {
    //更新数据到本地
    update_result_buffer();/*this is generated code don't edit*/
    loading_ok();/*this is generated code don't edit*/
  }

  //发送请求
  request_get(href, function (evt) {
    let q_url = href;/*this is generated code don't edit*/
    //得到用户页面
    let txt = evt.srcElement.response;/*this is generated code don't edit*/
    let page = to_jq(txt);/*this is generated code don't edit*/
    let vote = page.find("#js-choice_vote");/*this is generated code don't edit*/
    let select_urls = [];/*this is generated code don't edit*/
    //保存选择项
    if (vote.length > 0) {
      let div = $("<div>");/*this is generated code don't edit*/
      //获得投票选项
      vote.find(".list-group-item").each(function () {
        // let clone = $(this).clone()
        // clone.css("display", "inline-block")
        // div.append(clone)
        let link = jq_must_find(this, "a");/*this is generated code don't edit*/
        let url = link.attr("href");/*this is generated code don't edit*/
        if (url == "") {
          //设置keyword
          jq_must_find(page, "#question_keyword_id").val(
            link.attr("data-url").match(/\d+$/)
          );/*this is generated code don't edit*/
          let form = jq_must_find(page, "form[data-text-correction-form]");/*this is generated code don't edit*/
          url =
            q_url +
            "/content_corrections?" +
            form.serialize() +
            "&commit=Submit%20correction";/*this is generated code don't edit*/
          log("href:" + href);/*this is generated code don't edit*/
        }
        select_urls.push(url);/*this is generated code don't edit*/
      });/*this is generated code don't edit*/
    }

    let wrp = $(page.find(".chat_content_wrapper").get(0));/*this is generated code don't edit*/
    //https://hinative.com/en-US/questions/15939889/choice_result

    q_info.select_urls = select_urls;/*this is generated code don't edit*/
    storage.set({
      questions_info: questions_info,
    });/*this is generated code don't edit*/
    //获得用户profileurl,如果没有则不继续了
    if (wrp.find(".username").length == 0) return;/*this is generated code don't edit*/
    let p_url = wrp.find("a").get(0).href;/*this is generated code don't edit*/
    let usr1 = usr;/*this is generated code don't edit*/
    get_user_info(p_url, usr1).then(function (buffer) {
      let b_block1 = b_block;/*this is generated code don't edit*/
      let buffer1 = buffer;/*this is generated code don't edit*/
      if (b_block1.painted == true) {
        return;/*this is generated code don't edit*/
      }

      //保存了基本信息和用户地址
      result_buffer[buffer.usr] = buffer1;/*this is generated code don't edit*/
      do_painting(b_block1);/*this is generated code don't edit*/
      if (!need_featured_answer) {
        success();/*this is generated code don't edit*/
      } else {
        get_user_featured_answer(p_url, buffer1).then(function (buffer) {
          success();/*this is generated code don't edit*/
          log("featrued loaded:" + buffer.usr);/*this is generated code don't edit*/
          result_buffer[buffer.usr] = buffer;/*this is generated code don't edit*/
          //将所有同名的block都加上rate
          get_questions().each(function () {
            if (this.featrued_painted != true) {
              let a_usr = jq_must_find(this, ".username");/*this is generated code don't edit*/
              if (a_usr.text() == buffer.usr) {
                do_featrued_painting(this);/*this is generated code don't edit*/
              }
            }
          });/*this is generated code don't edit*/
        });/*this is generated code don't edit*/
      }
    });/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
}

function create_question_info(url) {
  return {
    url: url,
    blocked: false,
  };/*this is generated code don't edit*/
}

//更新缓存到本地
function update_result_buffer() {
  let clone = result_buffer;/*this is generated code don't edit*/
  //如果选择不缓冲新人,则不将新人数据上传
  if (!cache_new_users) {
    clone = Object.assign({}, result_buffer);/*this is generated code don't edit*/
    let not_recording = [];/*this is generated code don't edit*/
    for (const usr in clone) {
      if (
        result_buffer[usr].info.q_n.replace("K", "000").replace(".", "") <=
        new_user_qustion_count
      ) {
        //如果是新人则不缓存数据
        not_recording.push(usr);/*this is generated code don't edit*/
      }
    }
    for (const usr of not_recording) {
      delete clone[usr];/*this is generated code don't edit*/
    }
  }

  storage.set({
    result_buffer: clone,
  });/*this is generated code don't edit*/
}

function block_user(user_name, auto_blocked = true) {
  if (auto_blocked) auto_blocked_users.push(user_name);/*this is generated code don't edit*/
  blocked_users.push(user_name);/*this is generated code don't edit*/
  blocked_users = Array.from(new Set(blocked_users));/*this is generated code don't edit*/
  let clone = Array.from(blocked_users);/*this is generated code don't edit*/
  //自动生成的block将不被储存到本地
  for (const usr of auto_blocked_users) {
    if (clone.indexOf(usr) > -1) clone.splice(clone.indexOf(usr), 1);/*this is generated code don't edit*/
  }

  storage.set({
    blocked_users: clone,
  });/*this is generated code don't edit*/
}

//将block屏蔽掉
//update代表是否更新本次操作到本地
function add_block(ele, update = true, is_auto = true) {
  let usr = jq_must_find(ele, ".username");/*this is generated code don't edit*/
  //如果用户被屏蔽,则隐藏这个提问
  blocked_blocks.add(ele);/*this is generated code don't edit*/
  if (update) {
    let href = get_href(ele);/*this is generated code don't edit*/
    questions_info[href].blocked = true;/*this is generated code don't edit*/
    questions_info[href].is_auto = is_auto;/*this is generated code don't edit*/
    storage.set({
      questions_info: questions_info,
    });/*this is generated code don't edit*/
  }

  if ($("#blocked_blocks").length == 0)
    $(".country_selector").append(
      "<span style='cursor: pointer;' > blocked questions count:<b id='blocked_blocks'>" +
        blocked_blocks.length +
        "</b></span>"
    );/*this is generated code don't edit*/
  else {
    $("#blocked_blocks").text(blocked_blocks.size);/*this is generated code don't edit*/
  }

  log("已隐藏用户问题:" + usr.text());/*this is generated code don't edit*/
  ele.style.display = "none";/*this is generated code don't edit*/
}

//添加用户到白名单
function add_white_list(user_name) {
  white_list.push(user_name);/*this is generated code don't edit*/
  storage.set({
    white_list: Array.from(new Set(white_list)),
  });/*this is generated code don't edit*/
}
//获得绘制基本信息
function get_paint_info(usr_page) {
  //获得反应率以及其他信息
  let matches = usr_page.match(/level_\d/);/*this is generated code don't edit*/
  let info = {};/*this is generated code don't edit*/
  let color = "white";/*this is generated code don't edit*/
  if (matches != null) {
    //获得用户profile rate
    info.rate = matches[0];/*this is generated code don't edit*/
  }

  //获得questions number
  let numbers = usr_page.match(/(?<=font_numbers_large['"]>)[^<]+/g);/*this is generated code don't edit*/
  // log(txt)

  if (numbers == null) {
    info.q_n = 0;/*this is generated code don't edit*/
    info.a_n = 0;/*this is generated code don't edit*/
  } else {
    info.q_n = numbers[0];/*this is generated code don't edit*/
    info.a_n = numbers[1];/*this is generated code don't edit*/
  }

  return info;/*this is generated code don't edit*/
}
//对需要框框上色
function do_painting(ele) {
  //设置一个painted属性
  ele.painted = true;/*this is generated code don't edit*/
  let usr = jq_must_find(ele, ".username");/*this is generated code don't edit*/
  let wrp = jq_must_find(ele, ".username_wrapper");/*this is generated code don't edit*/
  let url = get_href(ele);/*this is generated code don't edit*/
  let q_info = questions_info[url];/*this is generated code don't edit*/
  let buffer = result_buffer[usr.text()];/*this is generated code don't edit*/
  let info = buffer.info;/*this is generated code don't edit*/
  let div = $("<div>");/*this is generated code don't edit*/
  let header = $(ele).find(".img_box_question_answer");/*this is generated code don't edit*/
  let fuki = jq_must_find(ele, ".wrapper_fukidashi");/*this is generated code don't edit*/
  fuki.append(div);/*this is generated code don't edit*/
  //设置q_block才是问题入口
  let q_block = jq_must_find(ele, ".q_block");/*this is generated code don't edit*/
  q_block.css("cursor", "pointer");/*this is generated code don't edit*/
  q_block.click(function () {
    location.href = url;/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
  //添加用户页面入口
  usr.css("cursor", "pointer");/*this is generated code don't edit*/
  usr.click((_) => {
    location.href = buffer.profile_url;/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
  header.css("cursor", "pointer");/*this is generated code don't edit*/
  header.click((_) => {
    location.href = buffer.profile_url;/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
  if (q_info.select_urls.length > 0) {
    //画上是否自然选择项
    add_item(0, "Natural");/*this is generated code don't edit*/
    add_item(1, "A little unnatural");/*this is generated code don't edit*/
    add_item(2, "Unnatural");/*this is generated code don't edit*/
    add_item(3, "Don't konw");/*this is generated code don't edit*/
    function add_item(index, title) {
      let url = q_info.select_urls[index];/*this is generated code don't edit*/
      let s = $(
        "<span style='border-style: solid;border-width: 1px;margin: 2px;padding: 2px;cursor: pointer;' title='" +
          title +
          "'>" +
          title +
          "</span>"
      );/*this is generated code don't edit*/
      s.click(function () {
        var b = ele;/*this is generated code don't edit*/
        $(b).hide();/*this is generated code don't edit*/
        mode.unsafeWindow.$.post({
          url: url,
          dataType: "script",
          complete: function (xhr) {
            if (xhr.status == "302" || xhr.status == "200") process(b);/*this is generated code don't edit*/
          },
        });/*this is generated code don't edit*/
        console.log('$.post("' + url + '")');/*this is generated code don't edit*/
      });/*this is generated code don't edit*/
      div.append(s);/*this is generated code don't edit*/
    }
  }

  //确认是否需要自动隐藏
  let is_auto_blocked = false;/*this is generated code don't edit*/
  let color = "white";/*this is generated code don't edit*/
  //获得用户profile rate
  let rate = info.rate;/*this is generated code don't edit*/
  switch (rate) {
    case "level_1":
      color = "red";/*this is generated code don't edit*/
      is_auto_blocked = true;/*this is generated code don't edit*/
      break;/*this is generated code don't edit*/
    case "level_2":
      color = "orange";/*this is generated code don't edit*/
      is_auto_blocked = true;/*this is generated code don't edit*/
      break;/*this is generated code don't edit*/
    case "level_3":
      color = "#ffff80";/*this is generated code don't edit*/
      break;/*this is generated code don't edit*/
    case "level_4":
      color = "green";/*this is generated code don't edit*/
      break;/*this is generated code don't edit*/
  }

  let cwrp = jq_must_find(ele, ".chat_content_wrapper");/*this is generated code don't edit*/
  let cls = $(
    "<span style='display: inline-block;float: right; cursor: pointer;' title='close this question'>✕</span>"
  );/*this is generated code don't edit*/
  cls.click(function (e) {
    e.preventDefault();/*this is generated code don't edit*/
    add_block(ele, true, false);/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
  cwrp.prepend(cls);/*this is generated code don't edit*/
  //添加色彩显示
  wrp.append(
    "<span class='rate_badge' style=\"display:inline-block;width:16px;height:16px;border: darkblue;border-style: dotted;border-width: 1px;border-radius:8px;background-color:" +
      color +
      '"></span>'
  );/*this is generated code don't edit*/
  let q_n = info.q_n;/*this is generated code don't edit*/
  let a_n = info.a_n;/*this is generated code don't edit*/
  usr.get(0).style.fontWeight = "bold";/*this is generated code don't edit*/
  usr.get(0).style.color = "black";/*this is generated code don't edit*/
  usr.get(0).style.fontSize = "25";/*this is generated code don't edit*/
  wrp.append(
    $("<span style='cursor: pointer;'>" + " Q:" + q_n + " A:" + a_n + "</span>")
  );/*this is generated code don't edit*/
  //如果没有划过feture answer则画一次
  if (
    ele.featrued_painted != true &&
    typeof result_buffer[usr.text()].featured_answers != "undefined"
  ) {
    do_featrued_painting(ele);/*this is generated code don't edit*/
  }

  //自动屏蔽
  if (is_auto_blocked && auto_block) block_user(usr.text());/*this is generated code don't edit*/
  let in_white_list = white_list.indexOf(usr.text()) != -1;/*this is generated code don't edit*/
  //添加屏蔽选项
  let a = null;/*this is generated code don't edit*/
  //如果不存在于白名单则添加屏蔽选项
  if (!in_white_list) {
    a = $(
      "<span class='block' style='cursor:pointer' title='block this user'>❌</span>"
    );/*this is generated code don't edit*/
    a.before("&nbsp;");/*this is generated code don't edit*/
    a.click(function (e) {
      e.preventDefault();/*this is generated code don't edit*/
      block_user(usr.text(), false);/*this is generated code don't edit*/
      each_user_blocks(usr.text(), function () {
        do_painting(this);/*this is generated code don't edit*/
      });/*this is generated code don't edit*/
    });/*this is generated code don't edit*/
    wrp.append(a);/*this is generated code don't edit*/
  }

  //添加白名单选项
  a = $(
    "<span class='white'  style='cursor:pointer' title='add this user to white list'>" +
      (in_white_list ? "💗" : "💚") +
      "</span>"
  );/*this is generated code don't edit*/
  a.before("&nbsp;");/*this is generated code don't edit*/
  a.click(function (e) {
    e.preventDefault();/*this is generated code don't edit*/
    add_white_list(usr.text());/*this is generated code don't edit*/
    //将用户的问题去除白名单和黑名单选项
    each_user_blocks(usr.text(), function () {
      $(this).find(".block").remove();/*this is generated code don't edit*/
      $(this).find(".white").text("💗");/*this is generated code don't edit*/
    });/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
  wrp.append(a);/*this is generated code don't edit*/
  check_block(ele);/*this is generated code don't edit*/
}

//添加采纳率
function do_featrued_painting(ele) {
  ele.featrued_painted = true;/*this is generated code don't edit*/
  let usr = jq_must_find(ele, ".username");/*this is generated code don't edit*/
  let wrp = jq_must_find(ele, ".username_wrapper");/*this is generated code don't edit*/
  // log("result_buffer[" + usr.text() + "]:")
  // log(result_buffer[usr.text()])
  let a = result_buffer[usr.text()].answers;/*this is generated code don't edit*/
  let f = result_buffer[usr.text()].featured_answers;/*this is generated code don't edit*/
  let rate = (f / a).toFixed(2);/*this is generated code don't edit*/
  wrp.append(
    "<span  style='cursor: pointer;' class='rate_badage'> rate:" +
      (a != 0 ? rate : "No data!") +
      "</span>"
  );/*this is generated code don't edit*/
  if (rate <= block_rate_below) {
    //如果采纳率为0,则标红
    jq_must_find(ele, ".rate_badge", false).css("background-color", "red");/*this is generated code don't edit*/
    if (auto_block) {
      block_user(usr.text());/*this is generated code don't edit*/
      check_block(ele);/*this is generated code don't edit*/
    }
    return false;/*this is generated code don't edit*/
  }

  //采纳率大于0.6则标绿
  if (rate > 0.6) {
    jq_must_find(ele, ".rate_badge", false).css("background-color", "green");/*this is generated code don't edit*/
  }

  return true;/*this is generated code don't edit*/
}
//判断是否块块是否可画
function check_block(ele, why) {
  //如果已经屏蔽,则不用画了
  if (blocked_blocks.has(ele)) return false;/*this is generated code don't edit*/
  let usr = jq_must_find(ele, ".username");/*this is generated code don't edit*/
  //如果在白名单里则不必屏蔽
  if (white_list.indexOf(usr.text()) >= 0) {
    return true;/*this is generated code don't edit*/
  }
  //如果是黑名单用户则直接屏蔽
  if (blocked_users.indexOf(usr.text()) > -1) {
    add_block(ele, false, false);/*this is generated code don't edit*/
    return false;/*this is generated code don't edit*/
  }

  let q_info = questions_info[get_href(ele)];/*this is generated code don't edit*/
  if (typeof q_info === "undefined") {
  } else {
    var blockable = null;/*this is generated code don't edit*/
    //如果开启自动屏蔽了
    if (auto_block) {
      blockable = q_info.blocked;/*this is generated code don't edit*/
    } else if (q_info.blocked) {
      if (q_info.is_auto) blockable = false;/*this is generated code don't edit*/
      else {
        blockable = true;/*this is generated code don't edit*/
      }
    }
    if (blockable) {
      add_block(ele, false, true);/*this is generated code don't edit*/
      return false;/*this is generated code don't edit*/
    }
  }

  return true;/*this is generated code don't edit*/
}
//便遍历某个username的所有blocks
function each_user_blocks(username, handler) {
  get_questions().each(function () {
    if (jq_must_find(this, ".username").text() == username) {
      handler.call(this);/*this is generated code don't edit*/
    }
  });/*this is generated code don't edit*/
}

function get_href(ele) {
  let href = $(ele).attr("href");/*this is generated code don't edit*/
  return get_href_without_params(href);/*this is generated code don't edit*/
}
function get_href_without_params(href) {
  return href ? href.split("?")[0].trim() : {}[0];/*this is generated code don't edit*/
}
//获得用户提问,回应率,回答数
function get_user_info(p_url, usr) {
  let p_url1 = p_url;/*this is generated code don't edit*/
  let usr1 = usr;/*this is generated code don't edit*/
  // let qi=q_info
  return new Promise((resolve) => {
    request_get(p_url, function (evt1) {
      let txt = evt1.srcElement.response;/*this is generated code don't edit*/
      let buffer = {
        info: get_paint_info(txt),
        profile_url: p_url1,
        usr: usr1,
        time: new Date().getTime(),
      };/*this is generated code don't edit*/
      resolve(buffer);/*this is generated code don't edit*/
      return;/*this is generated code don't edit*/
    });/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
}

//判断两个链接id是否相等
function link_equal(link1, link2) {
  return (
    get_tail_number(get_href_without_params(link1)) ==
    get_tail_number(get_href_without_params(link2))
  );/*this is generated code don't edit*/
}
//获得字符串尾数字
function get_tail_number(str) {
  let match = str.match(/\d+$/);/*this is generated code don't edit*/
  if (match) {
    return match[0];/*this is generated code don't edit*/
  }
  return null;/*this is generated code don't edit*/
}
//遍历一个用户的问题
function traverse_user_questions(
  p_url,
  count,
  block_selector = "",
  page_loaded
) {
  log("get user_questions:" + p_url);/*this is generated code don't edit*/
  let p_url1 = p_url;/*this is generated code don't edit*/
  let page_count = count;/*this is generated code don't edit*/
  //如果设置为0则代表遍历所有问题
  if (page_count == 0) {
    let req = request_get(p_url, function () {}, false, true);/*this is generated code don't edit*/
    let info = get_paint_info(req.responseText);/*this is generated code don't edit*/
    page_count = Math.ceil(info.q_n / 10);/*this is generated code don't edit*/
  }

  return new Promise((resolve) => {
    //第一回答页面
    //在这里获得采纳的回答数
    let q_url = p_url1 + "/questions";/*this is generated code don't edit*/
    let blocks_count = 0;/*this is generated code don't edit*/
    let resolved = 0;/*this is generated code don't edit*/
    let answers = 0;/*this is generated code don't edit*/
    for (let current_page = 0; current_page < page_count; current_page++) {
      request_page(current_page);/*this is generated code don't edit*/
    }

    function request_page(index) {
      let q_url1 = q_url;/*this is generated code don't edit*/
      if (index > 0) {
        q_url1 = q_url + "?page=" + (index + 1);/*this is generated code don't edit*/
      }
      log("page:" + q_url1);/*this is generated code don't edit*/
      request_get(q_url1, function (evt) {
        let qtxt = evt.srcElement.response;/*this is generated code don't edit*/
        let page = to_jq(qtxt);/*this is generated code don't edit*/
        //获得第一页回答的问题
        let blocks = page.find(".d_block" + block_selector);/*this is generated code don't edit*/
        function check_out() {
          if (resolved == page_count && blocks_count == answers) {
            resolve();/*this is generated code don't edit*/
            return true;/*this is generated code don't edit*/
          } else {
            return false;/*this is generated code don't edit*/
          }
        }
        get_user_info();/*this is generated code don't edit*/
        //最后一页了,则取消继续查询
        if (page.find(".d_block").length == 0 || blocks.length == 0) {
          resolved++;/*this is generated code don't edit*/
          if (check_out()) {
            return;/*this is generated code don't edit*/
          }
        }

        let resolved_blocks = 0;/*this is generated code don't edit*/
        //初始化总的有回复的提问数
        blocks.each(function () {
          let badge = $(jq_must_find(this, ".badge_item").get(0)).text().trim();/*this is generated code don't edit*/
          log("badge:" + badge);/*this is generated code don't edit*/
          blocks_count++;/*this is generated code don't edit*/
          let fq_url = get_href(this);/*this is generated code don't edit*/
          let block = this;/*this is generated code don't edit*/
          //请求某一个问题的页面
          request_get(fq_url, function (evt) {
            let qtxt1 = evt.srcElement.response;/*this is generated code don't edit*/
            //最后一页
            if (qtxt1.indexOf('class="next"') < 0) page_loaded(qtxt1, block);/*this is generated code don't edit*/
            resolved_blocks++;/*this is generated code don't edit*/
            answers++;/*this is generated code don't edit*/
            if (blocks.length == resolved_blocks) {
              resolved++;/*this is generated code don't edit*/
            }
            if (check_out()) {
              return;/*this is generated code don't edit*/
            }
          });/*this is generated code don't edit*/
        });/*this is generated code don't edit*/
      });/*this is generated code don't edit*/
    }
  });/*this is generated code don't edit*/
}

// 获得用户采纳情况信息
function get_user_featured_answer(p_url, buffer) {
  log("getting user_featured_answer:" + p_url);/*this is generated code don't edit*/
  let buffer1 = buffer;/*this is generated code don't edit*/
  if (typeof buffer.featured_answers === "undefined") {
    buffer.featured_answers = 0;/*this is generated code don't edit*/
  }
  if (typeof buffer.answers === "undefined") {
    buffer.answers = 0;/*this is generated code don't edit*/
  }
  return new Promise((resolve) => {
    traverse_user_questions(
      p_url,
      fap_count,
      ":not(:has(.has_no_answer))",
      function (res) {
        //该问题已被采纳
        if (res.indexOf("featured_answer_label") > -1) {
          buffer1.featured_answers++;/*this is generated code don't edit*/
        } else {
          //未被采纳
        }
        buffer1.answers++;/*this is generated code don't edit*/
      }
    ).then(function () {
      buffer.time = new Date().getTime();/*this is generated code don't edit*/
      resolve(buffer);/*this is generated code don't edit*/
    });/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
}
// 将文本转化为jqnodes
function to_jq(html_text) {
  let qtxt = html_text;/*this is generated code don't edit*/
  let html = $.parseHTML(qtxt);/*this is generated code don't edit*/
  let page = $("<div>").append(html);/*this is generated code don't edit*/
  return page;/*this is generated code don't edit*/
}

//在一个元素中查找关键selector,如果不存在则报错
function jq_must_find(ele, selector, force = true) {
  let find = $(ele).find(selector);/*this is generated code don't edit*/
  if (force && find.length == 0) {
    if (extension_enabled) {
      alert(
        "未能找到关键样式:" + selector + " 请联系作者解决!,程序将被暂停运行~~"
      );/*this is generated code don't edit*/
    }
    extension_enabled = false;/*this is generated code don't edit*/
  }
  return find;/*this is generated code don't edit*/
}
function request(method, url, callback, async = true, auto = true) {
  let req = new XMLHttpRequest();/*this is generated code don't edit*/
  req.__auto = auto;/*this is generated code don't edit*/
  if (callback) req.addEventListener("load", callback);/*this is generated code don't edit*/
  req.open(method, url, async);/*this is generated code don't edit*/
  // req.setRequestHeader('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36')

  if (async) request_queue.push(req);/*this is generated code don't edit*/
  else {
    req.send();/*this is generated code don't edit*/
  }
  return req;/*this is generated code don't edit*/
}

//发送一次get请求
function request_get(url, callback, async = true, auto = true) {
  return request("GET", url, callback, async, auto);/*this is generated code don't edit*/
}

function start_request_interval() {
  //每秒一次请求
  setInterval(function () {
    if (request_queue.length > 0) {
      var req = request_queue.shift();/*this is generated code don't edit*/
      req.send();/*this is generated code don't edit*/
    }
  }, request_interval);/*this is generated code don't edit*/
}

//更新缓存的数据
function update_cache() {
  log("current result_buffer:");/*this is generated code don't edit*/
  log(result_buffer);/*this is generated code don't edit*/
  new Promise((resolve) => {
    storage.get(["result_buffer"], function (rslt) {
      const result_buffer =
        typeof rslt.result_buffer === "undefined" ? {} : rslt.result_buffer;/*this is generated code don't edit*/
      let resolved = 0;/*this is generated code don't edit*/
      const count = Object.keys(result_buffer).length;/*this is generated code don't edit*/
      log("count:" + count);/*this is generated code don't edit*/
      log("result_buffer:");/*this is generated code don't edit*/
      log(result_buffer);/*this is generated code don't edit*/
      for (const usr in result_buffer) {
        let p_url = result_buffer[usr].profile_url;/*this is generated code don't edit*/
        let usr1 = usr;/*this is generated code don't edit*/
        get_user_info(p_url, usr1).then(function (buffer1) {
          let buffer2 = buffer1;/*this is generated code don't edit*/
          //保存了基本信息和用户地址
          result_buffer[buffer2.usr] = buffer2;/*this is generated code don't edit*/
          if (need_featured_answer == true) {
            get_user_featured_answer(p_url, buffer2).then(function (buffer3) {
              result_buffer[buffer3.usr] = buffer3;/*this is generated code don't edit*/
              if (++resolved == count) resolve(result_buffer);/*this is generated code don't edit*/
              log(
                buffer3.usr +
                  "data updated:" +
                  resolved +
                  " left:" +
                  (count - resolved)
              );/*this is generated code don't edit*/
            });/*this is generated code don't edit*/
          } else {
            result_buffer[buffer1.usr] = buffer1;/*this is generated code don't edit*/
            if (++resolved == count) resolve(result_buffer);/*this is generated code don't edit*/
            log("resolved:" + resolved + " left:" + (count - resolved));/*this is generated code don't edit*/
          }
        });/*this is generated code don't edit*/
      }
    });/*this is generated code don't edit*/
  }).then((rb) => {
    log("resovled buffer:");/*this is generated code don't edit*/
    log(rb);/*this is generated code don't edit*/
    update_result_buffer();/*this is generated code don't edit*/
    alert("用户信息更新完成!");/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
}

window.popuphtml=String.raw`<div id='popup' style='padding:10px;display: inline-block;position: absolute;z-index: 100;background: white;transform: translate(0, 100%);border-style: double;bottom: 0;left: 0;'><!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <style>
    .popup {
      width: 400px;/*this is generated code don't edit*/
      height: 500px;/*this is generated code don't edit*/
    }

    .popup,td {
      position: relative;/*this is generated code don't edit*/
    }
    .option_table a {
      display: inline-block;/*this is generated code don't edit*/
      color:darkcyan;/*this is generated code don't edit*/
    }

    .option_table {
      text-align: right;/*this is generated code don't edit*/
    }

    .range {
      width: 120px;/*this is generated code don't edit*/
      margin: auto;/*this is generated code don't edit*/
      display: block;/*this is generated code don't edit*/
      top: 50%;/*this is generated code don't edit*/
      position: absolute;/*this is generated code don't edit*/
      transform: translate(0, -50%);/*this is generated code don't edit*/
    }

    .numer_input {
      text-align: right;/*this is generated code don't edit*/

      width: 120px;/*this is generated code don't edit*/
    }

    .button {
      border-style: outset;/*this is generated code don't edit*/
      padding: 0%;/*this is generated code don't edit*/
    }

    .list_table_container {
      text-align: left;/*this is generated code don't edit*/
      border-style: double;/*this is generated code don't edit*/
    }

    .list_table {
      display: inline-block;/*this is generated code don't edit*/
      height: 150px;/*this is generated code don't edit*/
      overflow: scroll;/*this is generated code don't edit*/
    }

  </style>
</head>

<body class="popup">
  <table class="option_table">
    <thead>
      <tr>Info</tr>
    </thead>
    <tbody>
      <tr>
        <td>username:</td>
        <td><input id="username" type="text" title="user name" disabled />
          <input id="refresh_profile" type="button" value="🔄"
          title="Refresh profile information!" class='button'></input>
        </td>
      </tr>
    </tbody>
  </table>
  <table class="option_table">
    <thead>
      <tr>Options</tr>
    </thead>
    <tbody>
      <tr>
        <td>Turn on:</td>
        <td><input id="switch" type="checkbox" title="Check to allow this extension to function" /><br /></td>
      </tr>
      <tr>
        <td>Auto-block:</td>
        <td><input id="auto" type="checkbox" title="Allow this script to block users automatically" /><br /></td>
      </tr>
      <tr>
        <td>Featured answers:</td>
        <td><input id="featured" type="checkbox" title="Check to buffer and show user answer-featuring rate" /><br />
        </td>
      </tr>
      <tr>
        <td>Qustions page count:</td>
        <td><input id="fap_count"  type="number" class="numer_input" min="1" step="1" max="10" pattern="\d*"
          title="set question pages count the script need to search, might cause low performance if set too high"
          /><br /></td>
      </tr>
      <tr>
        <td>Cache new users:</td>
        <td><input id="cache_new_users" type="checkbox"
            title="Check to cache new user's data,this option can be reverted." /><br /></td>
      </tr>
      <tr>
        <td>Show log:</td>
        <td><input id="show_log" type="checkbox" title="Show developer log" /><br /></td>
      </tr>
      <tr>
        <td>Re-arrange user interface:</td>
        <td><input id="rearrange" type="checkbox" title="Check to allow rearrange user interface" /><br /></td>
      </tr>
      <tr>
        <td>Block rate below:</td>
        <td><input id="block_rate_below" type="range" class="range" title="Block rate below" min="0" max="1"
            step="0.1" /><br /></td>
      </tr>
      <tr>
        <td>Data validity duration(d):</td>
        <td><input id="validity_duration" type="number" class="numer_input" min="0" step="1" pattern="\d*"
            title="interval of auto updateing data which has expired:" /><br /></td>
      </tr>
      <tr>
        <td>Request interval(ms):</td>
        <td><input id="request_interval" type="number" class="numer_input" min="0" step="100" pattern="\d*"
            title="min allowed interval of sending xhr requests:<br/> you might get banned if the value is set too low" /><br />
        </td>
      </tr>
      <tr>
        <td>Add language:</td>
        <td>
          <input id="add_language" type="button" value="➕"
          title="Add language so that you can view them at the same time!" class='button'></input>

          <select id="languages"></select>
        </td>
      </tr>
      <tr>
        <td> Clear cached data:</td>
        <td><input id="cached" type="button" value="🚮"
            title="Clear buffered responses,you might need to re-reqeust those data!" class='button'></input><br /></td>
      </tr>
      <tr>
        <td> Update chached data:</td>
        <td><input id="update" type="button" value="🆕" title="Update Cached Data,might take some time."
            class='button'></input><br /></td>
      </tr>

      <tr>
        <td class="list_table_container">
          <table>
            <thead>
              <tr>Blocked Users</tr>
            </thead>
            <tbody id="blocked_users" class="list_table">
            </tbody>
          </table>
        </td>
        <td class="list_table_container">
          <table>
            <thead>
              <tr>White List</tr>
            </thead>
            <tbody id="white_list" class="list_table">
            </tbody>
          </table>
        </td>
      </tr>
      <tr>
        <td class="list_table_container">
          <table>
            <thead>
              <tr>Selected Languages</tr>
            </thead>
            <tbody id="selected_languages" class="list_table">
            </tbody>
          </table>
        </td>
        <td>
        </td>
      </tr>
    </tbody>
    <tr><td>好用,想给作者点个赞→</td><td>
      <a href="https://www.zhihu.com/question/28931964/answer/1140052315">知乎</a>
      <a href="https://github.com/2482103133/HiNative-Chrome-Extension">Github</a>
  </td></tr>
  </table>

  <script src="/js/jquery-3.4.1.min.js"></script>
  <script src="/js/common.js"></script>
  <script src="/js/popup.js"></script>
</body>

</html></div>`
s.append(window.popuphtml)
function setup_popup() {
  //清空缓存的用户数据
  $("#cached").click(function () {
    clear_cache();/*this is generated code don't edit*/
    mode.ExecuteScript({ code: "location.reload()" });/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
  //更新缓存的用户数据
  $("#update").click(function () {
    popup_update_cache();/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
  //更新用户信息
  $("#refresh_profile").click(function () {
    storage.set(
      {
        self_url: {}[0],
        self_name: {}[0],
      },
      (_) => {
        mode.ExecuteScript({ code: "get_info()" },_=>{});/*this is generated code don't edit*/
        $("#username").get(0).refresh()
      }
    );/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
  //点击添加新语言
  $("#add_language").click(function () {
    let origin = storage.get(["selected_languages"], function (res) {
      let val = $("#languages").val();/*this is generated code don't edit*/
      let option = $("#languages>option[value=" + $("#languages").val() + "]");/*this is generated code don't edit*/
      res.selected_languages.push(val);/*this is generated code don't edit*/
      log("add language:" + val);/*this is generated code don't edit*/
      storage.set(
        {
          selected_languages: Array.from(new Set(res.selected_languages)),
        },
        function () {
          binding_selected_languages();/*this is generated code don't edit*/
          //刷新列表
          //   $("#selected_languages").get(0).show_list();/*this is generated code don't edit*/
        }
      );/*this is generated code don't edit*/
    });/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
  //设置title为value
  $("#block_rate_below").change(function () {
    this.title = $(this).val();/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
  //修改featured提示
  $("#featured").click(function (e) {
    if ($(this).is(":checked")) {
      if (confirm("Warning:Cache will be cleared,continue?")) {
        clear_cache();/*this is generated code don't edit*/
      } else {
        e.preventDefault();/*this is generated code don't edit*/
      }
    }
  });/*this is generated code don't edit*/
  storage.get(["languages"], function (res) {
    // console.log(res.languages);/*this is generated code don't edit*/
    for (const val in res.languages) {
      let text = res.languages[val];/*this is generated code don't edit*/
      let op = $("<option>");/*this is generated code don't edit*/
      op.val(val);/*this is generated code don't edit*/
      op.text(text);/*this is generated code don't edit*/
      $("#languages").append(op);/*this is generated code don't edit*/
    }
  });/*this is generated code don't edit*/
  set_binding("extension_enabled", $("#switch").get(0));/*this is generated code don't edit*/
  set_binding("auto_block", $("#auto").get(0));/*this is generated code don't edit*/
  set_binding("need_featured_answer", $("#featured").get(0));/*this is generated code don't edit*/
  set_binding("cache_new_users", $("#cache_new_users").get(0));/*this is generated code don't edit*/
  set_binding("block_rate_below", $("#block_rate_below").get(0));/*this is generated code don't edit*/
  set_binding("show_log", $("#show_log").get(0));/*this is generated code don't edit*/
  set_binding("rearrange", $("#rearrange").get(0));/*this is generated code don't edit*/
  set_binding("validity_duration", $("#validity_duration").get(0));/*this is generated code don't edit*/
  set_binding("self_name", $("#username").get(0));/*this is generated code don't edit*/
  set_binding("request_interval", $("#request_interval").get(0));/*this is generated code don't edit*/
  set_binding("fap_count", $("#fap_count").get(0));/*this is generated code don't edit*/
  binding_list("blocked_users", $("#blocked_users").get(0));/*this is generated code don't edit*/
  binding_list("white_list", $("#white_list").get(0));/*this is generated code don't edit*/
  binding_selected_languages();/*this is generated code don't edit*/
}
function binding_selected_languages() {
  binding_list(
    "selected_languages",
    $("#selected_languages").get(0),
    (list) => {
      // var that = this;/*this is generated code don't edit*/
      //转化列表显示
      storage.get(["languages"], function (res) {
        list.each(function () {
          $(this).text(res.languages[$(this).text()]);/*this is generated code don't edit*/
        });/*this is generated code don't edit*/
      });/*this is generated code don't edit*/
    }
  );/*this is generated code don't edit*/
}

function binding_list(key, tbody, onbind = () => {}) {
  ((key, tbody) => {
    let list = [];/*this is generated code don't edit*/
    let bind = onbind;/*this is generated code don't edit*/
    let body = $(tbody);/*this is generated code don't edit*/
    let k = key;/*this is generated code don't edit*/
    storage.get([k], function (rslt) {
      list = typeof rslt[k] === "undefined" ? [] : rslt[k];/*this is generated code don't edit*/
      show_list();/*this is generated code don't edit*/
      function remove_block(username) {
        while (list.indexOf(username) > -1) {
          list.splice(list.indexOf(username), 1);/*this is generated code don't edit*/
        }
        window.obj = {};/*this is generated code don't edit*/
        obj[k] = list;/*this is generated code don't edit*/
        storage.set(obj);/*this is generated code don't edit*/
      }
      function show_list() {
        body.empty();/*this is generated code don't edit*/
        for (const u of list) {
          let tr = $("<tr>");/*this is generated code don't edit*/
          tr.append($("<td value='" + u + "'>" + u + "</td>"));/*this is generated code don't edit*/
          let a = $(
            "<a href='#'' style='text-decoration: none' title='Remove this user from the list'>❌</a>"
          );/*this is generated code don't edit*/
          a.click(function () {
            $(this).closest("tr").hide();/*this is generated code don't edit*/
            remove_block(u);/*this is generated code don't edit*/
          });/*this is generated code don't edit*/
          let db = $("<td></td>");/*this is generated code don't edit*/
          db.append(a);/*this is generated code don't edit*/
          tr.append(db);/*this is generated code don't edit*/
          body.append(tr);/*this is generated code don't edit*/
        }
        if (typeof bind !== "undefined") bind(body.find("td[value]"));/*this is generated code don't edit*/
      }
      body.get(0).show_list = show_list;/*this is generated code don't edit*/
    });/*this is generated code don't edit*/
  })(key, tbody);/*this is generated code don't edit*/
}

function set_binding(key1, check1) {
  let key = key1;/*this is generated code don't edit*/
  let check = check1;/*this is generated code don't edit*/
  refresh()
  $(check).change(function () {
    set_status();/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
  function refresh(){
    storage.get([key], function (result) {
      switch (check.type) {
        case "checkbox":
          $(check).attr("checked", result[key]);/*this is generated code don't edit*/
          break;/*this is generated code don't edit*/
        default:
          $(check).val(result[key]);/*this is generated code don't edit*/
      }

    });/*this is generated code don't edit*/
  }
  check.refresh=refresh

  function set_status() {
    let value = (function () {
      switch (check.type) {
        case "checkbox":
          return $(check).is(":checked");/*this is generated code don't edit*/
        default:
          return $(check).val();/*this is generated code don't edit*/
      }
    })();/*this is generated code don't edit*/
    set_variable(key, value);/*this is generated code don't edit*/
    let obj = {};/*this is generated code don't edit*/
    obj[key] = value;/*this is generated code don't edit*/
    storage.set(obj);/*this is generated code don't edit*/
  }
}

function clear_cache() {
  storage.set({ result_buffer: {}, questions_info: {} }, function () {
    log("cache cleared!");/*this is generated code don't edit*/
  });/*this is generated code don't edit*/
}

function popup_update_cache() {
  mode.ExecuteScript(
    {
      code: "update_cache()",
    },
    () => chrome.runtime.lastError
  );/*this is generated code don't edit*/
}


    $('#popup').hide();/*this is generated code don't edit*/
    })();/*this is generated code don't edit*/