Greasy Fork

Greasy Fork is available in English.

ヤフオクで非表示とメモ

q:非表示 w:アンドゥ b:NGワード Shift+Q/Shift+B:NG編集 12:メモを追加 34:自由メモ Shift+!:メモを編集 Shift+":自動メモのみ全削除 .:上限価格

当前为 2020-02-16 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name ヤフオクで非表示とメモ
// @description q:非表示 w:アンドゥ b:NGワード Shift+Q/Shift+B:NG編集 12:メモを追加 34:自由メモ Shift+!:メモを編集 Shift+":自動メモのみ全削除 .:上限価格
// @match *://auctions.yahoo.co.jp/search/*
// @match *://page.auctions.yahoo.co.jp/jp/auction/*
// @match *://auctions.yahoo.co.jp/seller/*
// @match *://auctions.yahoo.co.jp/category/list/*
// @match *://cpu.userbenchmark.com/*
// @version     0.4.3
// @grant       GM_setValue
// @grant       GM_getValue
// @grant       GM_deleteValue
// @run-at      document-idle
// @namespace http://greasyfork.icu/users/181558
// @require https://code.jquery.com/jquery-3.4.1.min.js
// ==/UserScript==

(function() {
  const debug = 0; //Math.random() > 0.9; // 1だとデバッグモード
  const ENABLEAUTOMEMO = 7; // 0で自動メモをオフ 1でオン 2~7:大きくするほど一時的に表示が崩れる代わりに確実
  const CUSTOMAUTOMEMORE = [/(Windows.*bit)/gmi, /((?:HDD|HDD|SSD|SSD|ハードディスク|ストレージ).*?(?:GB|TB|GB|TB|無し|なし|無|欠品|欠))/mi, /((?:10|テン)(?:key|キー))/mi, /(768.{1,3}576)|(800.{1,3}600)|(832.{1,3}624)|(1024.{1,3}768)|(1152.{1,3}864)|(1,?280.{1,3}960)|(1400.{1,3}1050)|(1440.{1,3}1080)|(1600.{1,3}1200)|(2048.{1,3}1536)|(2304.{1,3}1728)|(3200.{1,3}2400)|(854.{1,3}480)|(1024.{1,3}576)|(1136.{1,3}640)|(1280.{1,3}720)|(1,?36\d?.{1,3}768)|(1,?920.{1,3}1,?080)|(2048.{1,3}1152)|(2,?560.{1,3}1,?440)|(3200.{1,3}1800)|(3,?840.{1,3}2,?160)|(7680.{1,3}4320)|(640.{1,3}400)|(1280.{1,3}800)|(1,?440.{1,3}900)|(1680.{1,3}1050)|(1,?920.{1,3}1,?200)|(2560.{1,3}1600)|(2880.{1,3}1800)|(3840.{1,3}2400)|(480.{1,3}320)|(960.{1,3}640)|(176.{1,3}144)|(400.{1,3}240)|(352.{1,3}288)|(640.{1,3}350)|(720.{1,3}480)|(800.{1,3}480)|(864.{1,3}480)|(1024.{1,3}480)|(1024.{1,3}600)|(1280.{1,3}600)|(1120.{1,3}750)|(1280.{1,3}768)|(1152.{1,3}870)|(1280.{1,3}1024)|(1,?600.{1,3}900)|(1,?600.{1,3}1024)|(2048.{1,3}1080)|(4096.{1,3}2160)|(8192.{1,3}4320)/m, /(非光沢|ノングレア|ノーグレア|アンチグレア|光沢|グレア)/m, /((?:30|40)\s?(?:pin|ピン))/mi, /(LVDS.*$|eDP)/mi, /^(.*リカバリ.*)$/mi, /(仕事率[^0-90-9\n]*[0-9,0-9,]*\s*[wW])/mi, /(\[?\s?関東[^0-9,0-9,\n]*[0-9,0-9,]*\s*円[-~]?)/m, /(\[?\s?本州[^0-9,0-9,\n]*[0-9,0-9,]*\s*円[-~]?)/m, /(HDMI.{0,10}入力.{2,3}|入力.{0,20}HDMI.{2,3})/mi, /(電源入り.{2,10})/mi];
  //const CUSTOMAUTOMEMORE = [/$()^/]; // 無指定
  // ,/(フルHD|Full\s?HD|FHD|WXGA|FWXGA|QVGA|WXGA\+|SXGA|SXGA\+|HD\+|WXGA\+\+|WSXGA|WSXGA\+|UXGA|FHD|2K|WUXGA|FHD\+|UltraWideFHD|QXGA|WQHD|WQXGA|UltraWideQHD\+|QUXGA|QFHD|UHD4K|DCI4K|8KFUHD)/m
  const ENABLEHELP = 1; // 1で動作ヘルプを表示する
  const SWON = 0; // 1でストップウォッチ測定してconsole.log()
  const alsoClearBenchMemoWhenClearAutoMemo = 0;
  var swb = new Date();

  sw("start")
  const COLOR1 = "#6080ff",
    COLOR2 = "#c03020",
    COLOR3 = "#808080",
    COLORCPUSCORE = "#a08000",
    KEYHIDE = "q",
    KEYUNDO = "w",
    KEYBW = "b",
    KEYEDIT = "Shift+Q",
    KEYEDIT2 = "Shift+B",
    KEYMAXP = ".",
    KEYMEMO1 = "1",
    KEYMEMO2 = "2",
    KEYMEMO1S = "3",
    KEYMEMO2S = "4",
    KEYRESETMEMO = "Shift+!",
    KEYRESETMEMOAUTO = "Shift+\"";
  var mousex = 0;
  var mousey = 0;
  var maey = 0;

  // userbenchmarkでの動作
  if (location.href.match(/cpu.userbenchmark.com\/.*\/Rating\/|cpu.userbenchmark.com\/SpeedTest\//i)) { //userbenchmark
    setTimeout(() => {
      let cpuscore = $(eleget0('//td[last()]/table/tbody/tr[last()]/td[contains(@class,"mcs-caption")]')).css("border", "4px dotted blue").text();
      let cpuscore1t = "1C:" + $(eleget0('//td[3]/table[@class="mcs-table"]/tbody/tr[1]/td/span')).css("border", "4px dotted blue").text();
      cpuscore = cpuscore.replace(/(.*\%).*/, "$1").trim();
      let ubmodel = eleget0('//h1[@class="pg-head-title"]/a[@class="stealthlink"]').innerText.trim();
      let lasttitle = pref("lastItemName") || "";
      let modelno = (ubmodel.replace(/^core i\d-?(\S?\s?\d{3,5}.*$)/gi, "$1").replace(/^Core2 Duo (.?\d{3,5}.*$)/gi, "$1").trim());
      for (let title of (lasttitle ? lasttitle.indexOf(modelno) != -1 ? [modelno] : [lasttitle, modelno] : [modelno])) {
        for (let memo of [
            (document.body.innerText.match(/TDP\s*\d* W/m) || [""])[0],
            cpuscore, cpuscore1t,
          ]) {
          var tmp = pref('YAJSearchMyMemo') || [];
          var isExist = tmp.filter(e => e.t == title && e.m == memo);
          popup3(title + "<br>" + memo, 0, 2);
          if (isExist.length == 0) {
            if (title && memo) {
              let tmp = pref('YAJSearchMyMemo') || [];
              tmp.push({ t: title, m: memo, c: COLORCPUSCORE })
              pref('YAJSearchMyMemo', tmp)
            }
          }
        }
      }
      pref("lastItemName", "");
      popup3("Task completed");
    }, 500);
    return;
  }
  if (location.href.indexOf("userbenchmark.com") != -1) return;
  pref("lastItemName") ? (pref("lastItemName", ""), popup3("Task has been cleared")) : 0;

  //  $(eleget0('//input[@class="InputText__input" and @name="max"]')).css('ime-mode', 'inactive'); // 上限価格はIME offにする

  document.addEventListener('keydown', function(e) {
    if (/input|textarea/i.test(e.target.tagName) == false) {
      var key = (e.shiftKey ? "Shift+" : "") + (e.altKey ? "Alt+" : "") + (e.ctrlKey ? "Ctrl+" : "") + e.key;
      if (key === KEYHIDE) { // hide
        e.preventDefault();
        var ele = location.href.indexOf("://page.auctions.yahoo.co.jp/jp/auction/") != -1 ? eleget0('//h1[@class="ProductTitle__text"]') : document.elementFromPoint(mousex, mousey);
        blockElement(ele);
        return false;
      }
      if (key == KEYUNDO) { // undo
        e.preventDefault();
        let undoTitle = (pref('YAJSearchHideTitle') || "").match(/\|[^\|]*$|^[^|]*$/);
        pref('YAJSearchHideTitle', (pref('YAJSearchHideTitle') || "").replace(/\|[^\|]*$|^[^|]*$/, ""))
        if (undoTitle[0]) {
          showByTitle(undoTitle[0].replace(/^\|/, ""))
          popup2("『" + undoTitle[0].replace(/^\|/, "") + "』<br>を非表示登録から削除しました<br><br>編集後:<br>" + (pref('YAJSearchHideTitle') || "").substr(0, 500));
        }
        return false;
      }
      if (key == KEYBW) { // NGword
        e.preventDefault();
        addNGWord();
        return false;
      }

      if (key === KEYEDIT || key === KEYEDIT2) { // edit NGs
        e.preventDefault();
        let tmp = prompt(KEYEDIT + "/" + KEYEDIT2 + ":\n非表示にするタイトルを正規表現で編集してください\n|で区切ると複数指定できます\n空欄を入力すれば全削除できます\n\n" + (pref('YAJSearchHideTitle') || ""), pref('YAJSearchHideTitle') || "");
        if (tmp !== null) {
          pref('YAJSearchHideTitle', tmp || "")
          document.body.remove();
          location.reload();
        }
        return false;
      }
      if (key == KEYMEMO1) { // 1memo
        e.preventDefault();
        var ele = location.href.indexOf("://page.auctions.yahoo.co.jp/jp/auction/") != -1 ? eleget0('//h1[@class="ProductTitle__text"]') : document.elementFromPoint(mousex, mousey);
        memoElement(ele, document);
        return false;
      }
      if (key == KEYMEMO2) { // 2memo
        e.preventDefault();
        var ele = location.href.indexOf("://page.auctions.yahoo.co.jp/jp/auction/") != -1 ? eleget0('//h1[@class="ProductTitle__text"]') : document.elementFromPoint(mousex, mousey);
        memoElement(ele, document, COLOR2);
        return false;
      }
      if ((key == KEYMEMO1S || key == KEYMEMO2S)) { // free memo
        e.preventDefault();
        var target = (prompt("メモを付けたい出品物のタイトルが含むキーワードを入力してください") || "").trim();
        if (!target) return;
        var memo = (prompt("『" + target + "』\nに付けるメモを書いてください") || "").trim();
        if (!memo) return;
        storeMemo(target.trim(), memo, key == KEYMEMO1S ? COLOR1 : COLOR2)
        return false;
      }
      if (key == KEYRESETMEMO) { // reset
        e.preventDefault();
        //console.log(pref('YAJSearchMyMemo'))
        let tmp = prompt(KEYRESETMEMO + ":\nメモをJSON形式で編集してください\n空欄を入力すれば全削除されます\n\n" + JSON.stringify(pref('YAJSearchMyMemo') || []), JSON.stringify(pref('YAJSearchMyMemo') || []));
        if (tmp !== null) {
          pref('YAJSearchMyMemo', tmp || []);
          document.body.remove();
          location.reload();
        }
        return false;
      }
      if (key == KEYRESETMEMOAUTO) { // reset auto
        e.preventDefault();
        //console.log(pref('YAJSearchMyMemo'))
        var str = pref('YAJSearchMyMemo') || '[]';
        if (alsoClearBenchMemoWhenClearAutoMemo) {
          var newstr = str.filter(e => !(e.c == COLOR3 || e.c == COLORCPUSCORE)); // CPUスコアもリセット
          var newstr2 = str.filter(e => (e.c == COLOR3 || e.c == COLORCPUSCORE)); // CPUスコアもリセット
        } else {
          var newstr = str.filter(e => !(e.c == COLOR3));
          var newstr2 = str.filter(e => (e.c == COLOR3));
        }
        if (confirm(KEYRESETMEMOAUTO + ":\n自動メモのみ全て削除します。良いですか?\n\n消すもの:\n" + JSON.stringify(newstr2))) {
          pref('YAJSearchMyMemo', JSON.stringify(newstr));
          popup2("自動メモをクリアしました", 1);
          document.body.remove();
          location.reload();
        }
        return false;
      }
      if (location.href.indexOf("://page.auctions.yahoo.co.jp/jp/auction/") == -1) {
        if (key == KEYMAXP) { // maxprice
          e.preventDefault();
          let ele = eleget0('//input[@class="InputText__input" and @name="max"]');
          if (ele) {
            ele.focus();
            ele.scrollIntoView({ behavior: "smooth", block: "center", inline: "center" });
            ele.select();
          }
          popup2("上限価格にフォーカス", 1);
        }
        return false;
      }
    }
  }, false);

  document.addEventListener("mousemove", function(e) {
    mousex = e.clientX;
    mousey = e.clientY;
  }, false);

  run(); //setTimeout(() => { run() }, 100);
  document.body.addEventListener('AutoPagerize_DOMNodeInserted', function(evt) { run(evt.target); }, false);

  // キーワードの検索対象を切り替えるボタン
  if (location.href.indexOf("://page.auctions.yahoo.co.jp/jp/auction/") == -1) {
    for (let kw of [{ t: "タイトルからのみ検索する", s: "&f=0x2" }, { t: "タイトルと商品説明から検索する", s: "&f=0x4" }]) {
      var ele = eleget0('//div[@class="ptsOption"]/a/../../..');
      if (ele && !(location.href.match(kw.s))) {
        var ele2 = ele.parentNode.insertBefore(document.createElement("a"), ele.nextSibling);
        ele2.innerHTML = kw.t + " ";
        ele2.href = location.href.replace(/\&f\=.*(\&|$)/, "") + kw.s;
      }
    }
  }

  function run(node = document.body) {
    sw("run");
    // ホバーで操作案内をポップアップ
    let ih = $("<span class='phov' style='cursor:pointer; color:#505050; font-size:90%; background:#ffffffb0; padding:0px 4px 0px 4px; border-radius:9px;border:#505050 1px solid; position: absolute; bottom:13px; right: 5em;'>Q:非表示 W:アンドゥ 1:○メモ 2:×メモ</span>");
    $(node).find("li[class='Product']").add(elegeta('//div[@class="a1wrp"]/h3/a/../../..', node)).hover(function() {
      ih.appendTo(this).attr("title", "クリックでこのガイドを一時的に消す").click(function() { $(this).fadeOut(100).queue(function() { $(this).remove() }) });
    }, function() { $(".phov").remove() }); // 1行単位=検索結果&セラー画面の方
    sw("1gyou help");
    if (location.href.indexOf("://page.auctions.yahoo.co.jp/jp/auction/") != -1) { // 画面全体の方
      $("<span class='phov' style='cursor:pointer; color:#505050; font-size:90%; background:#ffffffc0; padding:3px; border-radius:9px;border:#505050 1px solid; position:fixed; bottom:1em; right: 1em;'>Q:非表示 W:アンドゥ 1:○メモ 2:×メモ</span>").appendTo(document.body).attr("title", "クリックでこのガイドを一時的に消す").click(function() { $(this).fadeOut(100).queue(function() { $(this).remove() }) });
    }
    sw("zentai help");

    if (pref('YAJSearchMyMemo')) {
      for (let a of pref('YAJSearchMyMemo').sort(function(a, b) {
          return (window.navigator.userAgent.toLowerCase().indexOf('chrome') == -1) ? (a.c == COLORCPUSCORE && b.c !== COLORCPUSCORE ? 1 : 0) : (a.c != COLORCPUSCORE && b.c == COLORCPUSCORE ? -1 : 0);
        })) {
        memoByTitle(a.t, a.m, node, a.c || COLOR1);
      }
    }
    sw("mymemo");

    // ヘルプを表示
    let help = KEYHIDE + ":非表示 " + KEYUNDO + ":アンドゥ " + KEYBW + ":NGワード " + KEYEDIT + "/" + KEYEDIT2 + ":NG編集 " + KEYMEMO1 + KEYMEMO2 + ":メモを追加 " + KEYMEMO1S + KEYMEMO2S + ":自由メモ " + KEYRESETMEMO + ":メモを編集 " + KEYRESETMEMOAUTO + ":自動メモのみ全削除 " + KEYMAXP + ":上限価格";
    if (pref('YAJSearchHideTitle')) {
      var i = 0;
      for (let title of pref('YAJSearchHideTitle').split("|")) {
        i += hideByTitle(title, node);
      }
      if (i && ENABLEHELP) { help = i + "個の出品を非表示にしました<BR>" + help; }
    }
    sw("block")
    popup2(help, 1)
    for (let t = 0; t < ENABLEAUTOMEMO; t++) { setTimeout(makeautomemo, 500 + t * 3000); } //debug&&t>0?popup3( t * t / 2 * 1000,2,1):0; }

    function makeautomemo() {
      if (ENABLEAUTOMEMO && (location.href.indexOf("://page.auctions.yahoo.co.jp/jp/auction/") != -1)) {
        for (let am of CUSTOMAUTOMEMORE) { autoMemo(am); }
        autoMemo(/(レターパック[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
        autoMemo(/(クリックポスト[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
        autoMemo(/(ゆうメール[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
        autoMemo(/(ゆうパケット[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
        autoMemo(/(ゆうパック[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
        autoMemo(/(定形外[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
        autoMemo(/(メール便[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
        autoMemo(/送料.*(全国一律\s*[0-9,0-9,]*.*円[-~]?)/m); //        autoMemo(/送料\s*(全国一律\s*[0-9,0-9,]*\s*円[-~]?)/m);
        autoMemo(/送料\s*[::]?(.*[都道府県]は[0-9,0-9,]*円[-~]?)/m);
        //        autoMemo(/送料\s*(.*は[0-9,0-9,]*円[-~]?)/m);
        autoMemo(/(Pentium.*?GHz)|(Celeron.*?GHz)|(Atom.*?GHz)|(Core\s?i\d.*?GHz)/mi) ? 0 :
          autoMemo(/(CPU[\s\S]{1,30}?GHz)/mi) ? 0 :
          autoMemo(/^(.*GHz)/gmi) ? 0 :
          //          autoMemo(/(Pentium[\s\S]{1,50}?$)|(Celeron[\s\S]{1,50}?$)|(Atom[\s\S]{1,50}?$)|(Core\s?i[\s\S]{1,50}?$)|(Ryzen\s?\d[\s\S]{1,50}?$)/mi);
          autoMemo(/(Pentium[0-9A-Za-z\-_.]*\W*[0-9A-Za-z\-_.]*[0-9A-Za-z\-_.]*\W*[0-9A-Za-z\-_.]*)|(Celeron[0-9A-Za-z\-_.]*\W*[0-9A-Za-z\-_.]*)|(Atom\s[0-9A-Za-z\-_.]*\W*[0-9A-Za-z\-_.]*)|(Core\s?i\d.[0-9A-Za-z\-_.]*)|(Ryzen\s?\d[0-9A-Za-z\-_.]*\W*[0-9A-Za-z\-_.]*)/mi);

        autoMemo(/([0-90-9]{2,4}年製)/m, ) ? 0 :
          autoMemo(/([0-90-9]{2,4}年)/m, ) ? 0 :
          autoMemo(/([0-90-9]{2,4}年製)/m, ) ? 0 :
          autoMemo(/([0-90-9]{2,4}年)/m);
        /*        autoMemo(/^(.*ジャンク.*)$/m) ? 0 :
                  autoMemo(/(^.*ジャンク.*)$/m);*/
        autoMemo(/発送元:(.{1,4}[都道府県])/m);
        //autoMemo(/()/m, document.body);
        //autoMemo(/()/m, document.body);
      }
    }
    sw("automemo");
    return;
  }

  function eletext(ele, xp) {
    let e = eleget0(ele);
    if (e) debugEle(e);
    return e ? e.innerText : "";
  }

  function autoMemo(re, text) {
    let automemotarget = eletext('//div[@class="ProductExplanation__commentArea"]') + "\n" + eletext('//div[@id="ProductProcedures"]') + "\n" + eletext('//h1[@class="ProductTitle__text"]') + '\n' + eletext('//ul[@class="ProductInformation__items"]/li[2]');
    let node = document.body;
    let sou = automemotarget.match(re);
    if (sou) {
      sou.shift();
      var memo = Array.from(new Set(sou)).join(" ").replace(/[A-Za-z0-9.,]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 65248) }).replace(/\s{2,99}| /gm, " ").trim();
      // node.innerHTML=node.innerHTML.replace(re,"<mark>$1</mark>");
      var title = getTitle();
      var tmp = pref('YAJSearchMyMemo') || [];
      var isExist = tmp.filter(e => e.t == title && e.m == memo);
      if (isExist.length == 0) {
        debug ? popup3(memo, 2, 1, 5000) : 0;
        storeMemo(title, memo, COLOR3, node);
      }
      return true;
    }
    return false;
  }

  function getTitle(x, y) {
    var ele = location.href.indexOf("://page.auctions.yahoo.co.jp/jp/auction/") != -1 ? eleget0('//h1[@class="ProductTitle__text"]') : document.elementFromPoint(mousex, mousey);
    if (!ele) return;
    var title = getTitleFromParent(ele);
    if (!title) return;
    return title;
  }

  function memoElement(ele, node, color = COLOR1) { //A memo
    if (!ele) return;
    var title = getTitleFromParent(ele);
    if (!title) return;
    var memo = (prompt("『" + title + "』\nのメモを書いてください") || "").trim();
    storeMemo(title, memo, color, node);
    return true;
  }

  function storeMemo(title, memo, color = COLOR1, node = document) {
    if (title && memo) {
      let tmp = pref('YAJSearchMyMemo') || [];
      tmp.push({ t: title, m: memo, c: color })
      pref('YAJSearchMyMemo', tmp)
      memoByTitle(title, memo, node, color);
    }
  }

  function memoByTitle(title, memo, node, color) {
    if (title.indexOf('"') != -1) return; // todo:タイトルに"があると正しく検索できないので処理しない
    var xp = isSeller() ? '//div[@class="a1wrp"]/h3/a[contains(text(),"' + title + '")]|.//div[@class="a1wrp"]/h3/a/em[contains(text(),"' + title + '")]/..' :
      '//a[contains(@class,"Product__titleLink") and contains(text(),"' + title + '")]/../..|.//h1[@class="ProductTitle__text" and contains(text(),"' + title + '")]/..|.//div[@class="a1wrp"]/h3/a[contains(text(),"' + title + '")]';
    for (let titleEle of elegeta(xp, node)) {
      if (titleEle) {
        let ele = titleEle.parentNode.parentNode.insertBefore(document.createElement("span"), titleEle.parentNode.nextSibling);
        let isCPU = memo.match(/Pentium|Celeron|Core\s?i\d|Ryzen|GHz/i);
        ele.innerHTML = '<span class="' + escape(title + memo + color) + '" title="『' + title + '』についたメモ(クリックで削除)' + (isCPU ? "\n\n右クリックでuserbenchmark検索\nhttps://duckduckgo.com/?q=!ducky+" + memo.replace(/[\u30a0-\u30ff\u3040-\u309f\u3005-\u3006\u30e0-\u9fcf\s]+/g, "+") + "+userbenchmark" : "") + '" style="cursor:' + (isCPU ? "help" : "pointer") + '; font-size:90%; font-weight:bold; margin:0px 1px; text-decoration:none !important; text-align:center; padding:1px 6px 1px 6px; line-height: 1.4em; border-radius:12px; background-color:' + color + '; color:white;">' + memo + '</span>';
        $(ele).hide().fadeIn(150);

        // CPUモデルナンバーを右クリックでuserbenchmark検索
        if (isCPU) {
          $(ele).appendTo($(ele)).on('contextmenu', (function(title, memo) {
            return function() {
              if (pref("lastItemName") == undefined) { // 前回の処理が終わってないとだめ
                pref("lastItemName", title);
                popup3(title);
                memo = memo.replace(/[\u30a0-\u30ff\u3040-\u309f\u3005-\u3006\u30e0-\u9fcf\s]+/g, "+");
                window.open("https://duckduckgo.com/?q=!ducky+" + memo + "+userbenchmark");
                setTimeout(() => {
                  if (pref("lastItemName")) {
                    popup3("Investigating " + memo + " timed out");
                    pref("lastItemName", "");
                  }
                }, 30000); // 30秒以内に見ないとだめ
              }
              return false;
            }
          })(title, memo));
        }

        setRemoveMemo(ele, title, memo, color)
      }
    }
  }

  function setRemoveMemo(ele, title, memo, color) { // メモをクリックで消す処理
    ele.onclick = (e) => {
      pref('YAJSearchMyMemo', (pref('YAJSearchMyMemo') || []).filter(n => !(n.t == title && n.m == memo && n.c == color)))
      for (let e of elegeta('//span[@class="' + escape(title + memo + color) + '"]')) $(e).hide(200).queue(function() { $(this).remove() }); //e.remove(); //ele.remove();
    }
  }

  function getTitleFromParent(ele) { // ele要素の親の出品物タイトルを返す
    if (ele.className == "ProductTitle__text") return ele.innerText.replace(/\|/g, '\|').trim();
    for (let i = 0; i < (isSeller() ? 5 : 4); i++) {
      var ele2 = elegeta('//a[@class="Product__titleLink"]|.//a[@class="Product__titleLink u-textBold"]|.//div[@class="a1wrp"]/h3/a', ele);
      if (ele2.length == 1) { return ele2[0].innerText.replace(/\|/g, '\|').trim(); }
      ele = ele.parentNode;
    }
    return;
  }

  function blockElement(ele) { //Q toggle
    if (!ele) return;
    var title = getTitleFromParent(ele);
    if (!title) return;
    if ((pref('YAJSearchHideTitle') || "").match(new RegExp("(^|\|)" + title.replace(/(\(|\)|\[|\]|\?|\*|\^|\$|\.|\+|\{|\}|\|)/gm, "\\$1") + "($|\|)"))) {
      pref('YAJSearchHideTitle', (pref('YAJSearchHideTitle') || "").replace(new RegExp("(^|\|)" + title.replace(/(\(|\)|\[|\]|\?|\*|\^|\$|\.|\+|\{|\}|\|)/gm, "\\$1") + "($|\|)"), "").replace(/(^\|)|(\|\|)|(\|$)/gm, ""));
      showByTitle(title);
      popup2("『" + title + "』<br>を非表示登録から削除しました<br><br>編集後:<br>" + (pref('YAJSearchHideTitle') || "").substr(0, 500));
      return;
    } else {
      if ((pref('YAJSearchHideTitle') || "").indexOf(title) != -1) return;
    }
    hideByTitle(title);
    if (pref('YAJSearchHideTitle')) pref('YAJSearchHideTitle', pref('YAJSearchHideTitle') + "|" + title);
    else pref('YAJSearchHideTitle', title);
    popup2("『" + title + "』<br>を非表示登録しました(" + KEYUNDO + ":取り消し " + KEYEDIT + "/" + KEYEDIT2 + ":編集)<br><br>編集後:<br>" + pref('YAJSearchHideTitle').substr(0, 500));
  }

  function hideByTitle(title, node) {
    let i = 0;
    var xp = isSeller() ? '//div[@class="a1wrp"]/h3/a[contains(text(),"' + title + '")]/../../../..|.//div[@class="a1wrp"]/h3/a/em[contains(text(),"' + title + '")]/../../../../..' :
      '//a[contains(@class,"Product__titleLink") and contains(text(),"' + title + '")]/../../../../..|.//div[@class="a1wrp"]/h3/a[contains(text(),"' + title + '")]/../../../..|.//div[@class="a1wrp"]/h3/a/em[contains(text(),"' + title + '")]/../../../..';
    for (let ele of elegeta(xp, node)) {
      i++;
      setTimeout(function() { ele.style.opacity = "0.75" }, 17 * 0);
      setTimeout(function() { ele.style.opacity = "0.50" }, 17 * 1);
      setTimeout(function() { ele.style.opacity = "0.25" }, 17 * 2);
      setTimeout(function() {
        ele.style.display = "none";
        ele.style.opacity = "0"
      }, 17 * 3);
    }
    var xp = '//h1[@class="ProductTitle__text" and contains(text(),"' + title + '")]/../../../..'; // isearでハイライトされていると×
    for (let ele of elegeta(xp, node)) {
      i++;
      ele.style.opacity = "0.5";
    }
    return i;
  }

  function showByTitle(title) {
    var xp = isSeller() ? '//div[@class="a1wrp"]/h3/a[contains(text(),"' + title + '")]/../../../..|.//div[@class="a1wrp"]/h3/a/em[contains(text(),"' + title + '")]/../../../../..' :
      '//a[contains(@class,"Product__titleLink") and contains(text(),"' + title + '")]/../../../../..|.//div[@class="a1wrp"]/h3/a[contains(text(),"' + title + '")]/../../../..|.//div[@class="a1wrp"]/h3/a/em[contains(text(),"' + title + '")]/../../../..';
    for (let ele of elegeta(xp)) {
      setTimeout(function() {
        ele.style.display = "block";
        ele.style.opacity = "0.25"
      }, 17 * 0);
      setTimeout(function() { ele.style.opacity = "0.50" }, 17 * 1);
      setTimeout(function() { ele.style.opacity = "0.75" }, 17 * 2);
      setTimeout(function() { ele.style.opacity = "1" }, 17 * 3);
    }
    var xp = '//h1[@class="ProductTitle__text" and contains(text(),"' + title + '")]/../../../..'; // isearでハイライトされていると×
    for (let ele of elegeta(xp)) { ele.style.opacity = "1"; }
  }

  function addNGWord() {
    var newWord = (prompt("非表示にしたい出品物のタイトルが含むNGワードを入力してください") || "").trim();
    if (newWord) {
      hideByTitle(newWord)
      if (pref('YAJSearchHideTitle')) pref('YAJSearchHideTitle', pref('YAJSearchHideTitle') + "|" + newWord);
      else pref('YAJSearchHideTitle', newWord);
      popup2("『" + title + "』<br>を非表示登録しました(" + KEYUNDO + ":取り消し " + KEYEDIT + "/" + KEYEDIT2 + ":編集)<br><br>編集後:<br>" + pref('YAJSearchHideTitle').substr(0, 500));
    }
  }

  // キャッシュ付き
  var elegetaCacheXP = "";
  var elegetaCacheLastTime = 0;
  var elegetaCacheResult = [];
  var elegetaCacheNode = "";
  var ehit = 0,
    emiss = 0;

  function elegeta(xpath, node = document) {
    if (!xpath) return [];
    if (xpath === elegetaCacheXP && node === elegetaCacheNode && ((new Date().getTime()) - (elegetaCacheLastTime.getTime()) < 100)) {
      //console.log(++ehit,emiss,ehit/(ehit+emiss)*100+"% hits");
      return elegetaCacheResult;
    } // 100ms以内ならキャッシュを返す
    elegetaCacheXP = xpath;
    elegetaCacheLastTime = new Date();
    elegetaCacheNode = node;
    //    console.log(ehit,++emiss,ehit/(ehit+emiss)*100+"% hits");
    try {
      var array = [];
      var ele = document.evaluate("." + xpath, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
      for (var i = 0; i < ele.snapshotLength; i++) array[i] = ele.snapshotItem(i);
      elegetaCacheResult = array;
      return array;
    } catch (e) { return []; }
  }

  function eleget0(xpath, node = document) {
    if (!xpath) return null;
    try {
      var ele = document.evaluate("." + xpath, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
      return ele.snapshotLength > 0 ? ele.snapshotItem(0) : "";
    } catch (e) { popup2(e, 1); return null; }
  }


  function popup3(text, i = 0, lf = 1, timer = 5000) {
    let id = Math.random().toString(36).substring(2);
    let ele = document.body.appendChild(document.createElement("span"));
    ele.outerHTML = '<span id="mllbox' + id + '" style="all:initial; position: fixed; right:1em; bottom: ' + ((maey + i) * 2 + 1) + 'em; z-index:2147483647; opacity:1; font-size:90%; margin:0px 1px; text-decoration:none !important;  padding:1px 6px 1px 6px; word-break: break-all !important; border-radius:12px; background-color:#6080ff; color:white; ">' + text + '</span>';
    maey += lf;
    setTimeout(() => {
      eleget0('//span[@id="mllbox' + id + '"]').remove();
      maey = 0;
    }, timer);
  }
  var maet;

  function popup2(text, i = 0) {
    var mae = eleget0('//span[@id="mllbox"]');
    if (maet && mae) {
      mae.remove();
      clearTimeout(maet);
    }
    var ele = $('<span id="mllbox" style="all:initial; cursor:pointer; position: fixed; right:1em; bottom: ' + (i * 2 + 1) + 'em; z-index:2147483647; opacity:1; font-size:90%; margin:0px 1px; text-decoration:none !important; padding:1px 6px 1px 6px; word-break: break-all !important; border-radius:12px; background-color:#6080ff; color:white; ">' + text + '</span>').appendTo('body');
    maet = setTimeout(function() {
      var mae = eleget0('//span[@id="mllbox"]');
      if (mae) { mae.remove(); }
    }, 5000);
    $(ele).attr("title", "クリックでこのガイドを一時的に消す").click(function() {
      $(this).fadeOut(200).queue(function() {
        $(this).remove();
        clearTimeout(maet);
      })
    });
  }

  function pref(name, store = null) { // prefs(name,data)で書き込み(数値でも文字列でも配列でもオブジェクトでも可)、prefs(name)で読み出し
    if (store === null) { // 読み出し
      let data = GM_getValue(name);
      if (data == undefined) return null; // 値がない
      if (data.substring(0, 1) === "[" && data.substring(data.length - 1) === "]") { // 配列なのでJSONで返す
        try { return JSON.parse(data || '[]'); } catch (e) {
          console.log("データベースがバグってるのでクリアします\n" + e);
          pref(name, []);
          return;
        }
      } else return data;
    }
    if (store === "" || store === []) { // 書き込み、削除
      GM_deleteValue(name);
      return;
    } else if (typeof store === "string") { // 書き込み、文字列
      GM_setValue(name, store);
      return store;
    } else { // 書き込み、配列
      try { GM_setValue(name, JSON.stringify(store)); } catch (e) {
        console.log("データベースがバグってるのでクリアします\n" + e);
        pref(name, "");
      }
      return store;
    }
  }

  function debugEle(ele) {
    if (debug) {
      let col = getColorFromText(ele.innerText);
      //      let col = '#' + (0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6);
      ele.style.outline = "3px dotted " + col;
      ele.style.boxShadow = " 0px 0px 4px 4px " + col + "30, inset 0 0 100px " + col + "20";
      //      ele.title='\n@class="'+ele.className+'"\n@id="'+ele.id+'"';
    }
  }

  function getColorFromText(str) {
    var col = 0;
    for (letter of str) { col = (col + str.charCodeAt(letter) * 2097152) % 0xffffff; }
    return '#' + (0x1000000 + col).toString(16).substr(1, 6);
  }

  function sw(job) {
    if (SWON == 0) return;
    console.log(job, (new Date().getTime()) - (swb.getTime()) + "ms");
    swb = new Date();
  }

  function isSeller() {
    return location.href.match(/\/seller\//);
  }
})()