Greasy Fork

Greasy Fork is available in English.

ヤフオクで非表示とメモ

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

当前为 2020-05-25 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 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+":自動メモのみ全削除 .:上限価格 t:半透明モード
// @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/*
// @match *://webcomics.jp/*
// @match *://www.amazon.co.jp/*
// @match *://booklive.jp/index/no-charge*
// @match *://ebookjapan.yahoo.co.jp/free*
// @match *://ebookjapan.yahoo.co.jp/ranking/free/*
// @match *://sokuyomi.jp/*
// @match *://csbs.shogakukan.co.jp/free*
// @match *://www.rtings.com/*/tools/table*
// @match *://www.rtings.com/*/reviews/*
// @match *://www.nicovideo.jp/search/*
// @match *://www.nicovideo.jp/tag/*
// @match *://www.nicovideo.jp/user/*
// @match *://*.5ch.net/*
// @match *://www.ebay.com/sch/*
// @match *://www.ebay.com/itm/*
// @match *://jmty.jp/*
// @match *://greasyfork.org/*/scripts*
// @match *://ja.aliexpress.com/af/*
// @match *://ja.aliexpress.com/item/*
// @match *://ja.aliexpress.com/wholesale*
// @match *://www.cmoa.jp/freecontents*
// @match *://piccoma.com/web/waitfree_sale_list/*
// @match *://www.mangaz.com/*
// @match *://www.sukima.me/*
// @match *://*.userbenchmark.com/*
// @version     0.5.1
// @grant       GM_setValue
// @grant       GM_getValue
// @grant       GM_deleteValue
// @grant       GM_addStyle
// @run-at      document-idle
// @namespace http://greasyfork.icu/users/181558
// @require https://code.jquery.com/jquery-3.4.1.min.js
// ==/UserScript==

(function() {
  const ENABLE_AUTOMEMO = 7; // 0:自動メモを無効 1でオン 2~7:大きくするほど一時的に表示が崩れる代わりに確実
  const ENABLE_EXCEPT_YAJ = 1; // 1:ヤフオク以外でも有効 0:ヤフオクでのみ動作
  const ENABLE_HELP = 1; // 1:操作ガイドを表示 0:無効
  const WCA_HIDE_SOME_SITES = 0; // (Web漫画アンテナで)1:使いにくい又は遅いサイト(マンガPark、コミックファイア、コミックヴァルキリー、まんがライフSTORIA´、がうがうモンスター、Z、スポバトマンガ研究所、WEBコミックガンマ、COMICリュウ、ComicWalker、新都社)の項目を隠す 0:無効

  const ENABLE_MEASURE_TIME_SPENT = 0; // 1で速度測定して表示 sw("項目")
  const debug = 0; //Math.random() > 0.9; // 1~2だとデバッグモード dc(text)
  const debug2 = 0; //Math.random() > 0.9; // 1だとデバッグモード
  var swb;
  sw("reset") // = new Date();

  const SITES_TO_BE_HIDDEN_XP = '//div[@class="entry-site"]/a[text()="マンガPark" or text()="コミックファイア" or text()="コミックヴァルキリー" or text()="まんがライフSTORIA´" or text()="COMICメテオ" or text()="がうがうモンスター" or text()="Z" or text()="スポバトマンガ研究所" or text()="WEBコミックガンマ" or text()="COMICリュウ" or text()="ComicWalker" or text()="新都社"]/../..';
  //const SITES_TO_BE_HIDDEN_XP = '//div[@class="entry-site"]/a[not(text()="マンガPark" or text()="コミックファイア" or text()="コミックヴァルキリー" or text()="まんがライフSTORIA´" or text()="COMICメテオ" or text()="がうがうモンスター" or text()="Z" or text()="スポバトマンガ研究所" or text()="WEBコミックガンマ" or text()="COMICリュウ" or text()="ComicWalker" or text()="新都社")]/../..'; // 逆にこれらのサイトだけ表示する

  const LogMatch = 0;
  if (window != parent) return;
  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",
    KEYTOGGLEtranslucent = "t",
    KEYRESETMEMO = "Shift+!",
    KEYRESETMEMOAUTO = "Shift+\"";

  // 上が優先
  const SITEINFO = [{
      id: 'USERBENCHMARK',
      urlRE: '.*?.userbenchmark.com',
      listTitleXP: '//span/a[@class="nodec"]',
      listTitleSearchXP: '//span/a[@class="nodec" and +++]/../../../../..',
      listTitleMemoSearchXP: '//span/a[@class="nodec" and +++]|//h1[@class="pg-head-title"]/a[+++]',
      listGen: 5,
      observe: 1000,
      detailURLRE: /\/\/.*?.userbenchmark.com\/SpeedTest\/|\/\/.*?.userbenchmark.com\/.*?\/Rating\//i,
      detailTitleXP: '//h1[@class="pg-head-title"]/a',
      detailElementSearchXP: '//h1[@class="pg-head-title"]/a[+++]/../../..',
      automemoURLRE: /\/\/.*?.userbenchmark.com\/SpeedTest\/|\/\/.*?.userbenchmark.com\/.*?\/Rating\//i,
      automemoSearchFunc: () => { return eletext('//h3[@class="pg-head-toption"]/span[@class="pg-head-toption-post"]') + "\n"; },
      automemoFunc: () => { autoMemo(/(.*)/); },
    }, {
      id: 'SUKIMA',
      urlRE: '//www.sukima.me/(?!bv)',
      listTitleXP: '//a[@class="title-link"]/div[@class="item_title"]',
      listTitleSearchXP: '//a[@class="title-link"]/div[@class="item_title" and ***]/../..',
      listTitleMemoSearchXP: '//a[@class="title-link"]/div[@class="item_title" and ***]|//h1[@class="merchandise_title" and ***]/..',
      titleProcessFunc: title => { return title.replace(/\n\s*?\n\s*?|(?分冊版)?.*|【期間限定 無料お試し版】.*|[0-90-9]*?巻.*/g, "").trim() },
      listGen: 6,
      observe: 1500,
      detailURLRE: /\/book\/title\//,
      detailTitleXP: '//h1[@class="merchandise_title"]',
      detailElementSearchXP: '//h1[@class="merchandise_title" and ***]/../../../..',
      delay: 1600,
    }, {
      id: 'MANGAZ',
      urlRE: '//www.mangaz.com/',
      listTitleXP: '//div[@class="listBoxDetail"]/h4/a',
      listTitleSearchXP: '//div[@class="listBoxDetail"]/h4/a[***]/../../../..',
      listTitleMemoSearchXP: '//div[@class="listBoxDetail"]/h4/a[***]|//div[@class="bookHeadContents"]/div[@class="bookHeadDetail"]/h1[***]|//div[@id="seriesContents"]/div[@class="header"]/h2[***]',
      listGen: 7,
      titleProcessFunc: (title) => { return title.replace(/[0-90-9]+巻?$|【.*?】|全.*?巻|第\d*話/gmi, "").trim() },
      detailURLRE: "//www.mangaz.com/book/detail/|//www.mangaz.com/series/detail/",
      detailTitleXP: '//div[@class="bookHeadContents"]/div[@class="bookHeadDetail"]/h1|//div[@id="seriesContents"]/div[@class="header"]/h2',
      detailElementSearchXP: '//div[@class="bookHeadContents"]/div[@class="bookHeadDetail"]/h1[***]/../../../..|//div[@id="seriesContents"]/div[@class="header"]/h2[***]/../..',
      observe: 1000,
    }, {
      id: 'PICCOMA',
      urlRE: '//piccoma.com/web/waitfree_sale_list/',
      listTitleXP: '//p[@class="PCM-productCoverImage_title"]/span',
      listTitleSearchXP: '//p[@class="PCM-productCoverImage_title"]/span[+++]/../../../../..',
      listTitleMemoSearchXP: '//p[@class="PCM-productCoverImage_title"]/span[+++]',
      listGen: 5,
      observe: 3000,
    }, {
      id: 'TAMESHIYOMI',
      urlRE: '//www.cmoa.jp/freecontents/',
      listTitleXP: '//p[@class="titile_name"]/a',
      listTitleSearchXP: '//p[@class="titile_name"]/a[+++]/../../../..',
      listTitleMemoSearchXP: '//p[@class="titile_name"]/a[+++]',
      listGen: 4,
    }, {
      id: 'ALIEXPRESS',
      urlRE: '//ja.aliexpress.com/af/|//ja.aliexpress.com/item/|//ja.aliexpress.com/wholesale',
      listTitleXP: '//a[@class="item-title"]',
      listTitleSearchXP: '//a[@class="item-title" and ***]/../../../../..',
      listTitleMemoSearchXP: '//a[@class="item-title" and ***]|//h1[@class="product-title-text" and ***]',
      listGen: 6,
      detailURLRE: /ja.aliexpress.com\/item\//,
      detailTitleXP: '//h1[@class="product-title-text"]',
      detailElementSearchXP: '//h1[@class="product-title-text" and +++]/../../../../..',
      observe: 500,
      func: () => { // 商品名を全行表示する
        elegeta('//a[@class="item-title"]').forEach(e => { e.style.whiteSpace = ""; });
        elegeta('//div[@class="item-title-wrap"]').forEach(e => {
          e.style.height = "auto";
          e.style.whiteSpace = "normal";
        })
      },
    }, {
      id: 'GREASYFORK',
      urlRE: '//greasyfork.org/.*?/scripts',
      listTitleXP: '//article/h2/a',
      listTitleSearchXP: '//article/h2/a[+++]/../../..',
      listTitleMemoSearchXP: '//article/h2/a[+++]',
      listGen: 6,
    }, {
      id: 'JMTY',
      urlRE: '//jmty.jp/',
      listTitleXP: '//div/h2[@class="p-item-title"]/a',
      listTitleSearchXP: '//div/h2[@class="p-item-title"]/a[+++]/../../..',
      listTitleMemoSearchXP: '//div/h2[@class="p-item-title"]/a[+++]',
      listGen: 4,
    }, {
      id: 'EBAY',
      urlRE: 'ebay.com/',
      listTitleXP: '//h3[@class="s-item__title"]|//h1[@id="itemTitle"]',
      listTitleSearchXP: '//h3[@class="s-item__title" and ***]/../../../..',
      listTitleMemoSearchXP: '//h3[@class="s-item__title" and ***]|//h1[@id="itemTitle" and ***]/..',
      listGen: 6,
      detailURLRE: /www.ebay.com\/itm\//,
      detailTitleXP: '//h1[@id="itemTitle"]',
      detailElementSearchXP: '//h1[@id="itemTitle" and ***]/../../../..',
      titleProcessFunc: title => { return title.replace(/^NEW LISTING|^Details about\s*/, "") },
      listHelpJQS: 'li.s-item',
      maxpriceXP: '//div/input[@aria-label="Maximum Value"]',
    }, {
      id: '5CH',
      urlRE: '5ch.net/',
      listTitleXP: '//span[@class="number"]',
      listTitleSearchXP: '//span[@class="number" and +++]/../..',
      listTitleMemoSearchXP: '//span[@class="number" and +++]',
      listGen: 2,
      funcQ: function() {
        setTimeout(() => {
          $('div.post:hidden').next("br").css("display", "none");
          $('div.post:visible').next("br:hidden").css("display", "block");
        }, 200);
      }, //余計な改行を詰める
      func: () => SITE.funcQ(),
    }, {
      id: 'NICODOUGA',
      urlRE: '//www.nicovideo.jp/search/|//www.nicovideo.jp/tag/',
      listTitleXP: '//div/p[@class="itemTitle"]/a',
      listTitleSearchXP: '//div/p[@class="itemTitle"]/a[**title**]/../../..',
      listTitleMemoSearchXP: '//div/p[@class="itemTitle"]/a[**title**]',
      listGen: 7,
      //      func: function(node) { for (let ele of elegeta('//div/p[@class="itemTitle"]/a', node)) ele.textContent = ele.title; }, // 長いタイトルが...で省略されているとヒットしないのでtitleプロパティから取り出す
    }, {
      id: 'NICODOUGA',
      urlRE: '//www.nicovideo.jp/user/.*/video',
      listTitleXP: '//div[@class="section VideoItem-videoDetail"]/h5/a',
      listTitleSearchXP: '//div[@class="section VideoItem-videoDetail"]/h5/a[+++]/../../..',
      listTitleMemoSearchXP: '//div[@class="section VideoItem-videoDetail"]/h5/a[+++]',
      listGen: 5,
      //      func: function(node) { for (let ele of elegeta('//div/p[@class="itemTitle"]/a', node)) ele.textContent = ele.title; }, // 長いタイトルが...で省略されているとヒットしないのでtitleプロパティから取り出す
    }, {
      id: 'RTINGS',
      urlRE: 'www.rtings.com/.*?/tools/table|//www.rtings.com/.*?/reviews/',
      listTitleXP: '//a[@class="table_cell_product-link"]/span',
      listTitleSearchXP: '//a[@class="table_cell_product-link"]/span[***]/../../../..|//div[@class="product_page-banner-header"]/div[@class="product_page-title"]/h1/span[***]/../..',
      listTitleMemoSearchXP: '//a[@class="table_cell_product-link"]/span[***]/..|//div[@class="product_page-title"]/h1/span[***]',
      listGen: 3,
      listTitleXPIgnoreNotExist: 1,
      delay: 3000,
      observe: 1000,
      detailURLRE: /\/\/www.rtings.com\/.*?\/reviews\//,
      detailTitleXP: '//div[@class="product_page-title"]/h1/span[1]',
      detailElementSearchXP: '//div[@class="product_page-title"]/h1/span[1 and ***]/../../../../..',
    }, {
      id: 'TAMESHIYOMI',
      urlRE: 'csbs.shogakukan.co.jp',
      listTitleXP: '//div[1]/img[@class="is-item-cover loaded"]',
      listTitleSearchXP: '//div[1]/img[@class="is-item-cover loaded" and **alt**]/../../..',
      listTitleMemoSearchXP: '//div[1]/img[@class="is-item-cover loaded" and **alt**]',
      listGen: 3,
      listTitleXPIgnoreNotExist: 1,
      delay: 1000,
      observe: 1500,
    }, {
      id: 'SOKUYOMI',
      urlRE: '//sokuyomi.jp/free_',
      listTitleXP: '//p[@class="title"]/a|//h1[@class="title"]',
      listTitleSearchXP: '//p[@class="title"]/a[**title**]/../..',
      listTitleMemoSearchXP: '//p[@class="title"]/a[**title**]',
      listGen: 3,
      observe: 900,
    }, {
      id: 'SOKUYOMI',
      urlRE: '//sokuyomi.jp/free\.',
      listTitleXP: '//img[@class="waku"]',
      listTitleSearchXP: '//img[@class="waku" and **alt**]/../..',
      listTitleMemoSearchXP: '//img[@class="waku" and **alt**]',
      listGen: 3,
      observe: 600,
    },
    {
      id: 'TAMESHIYOMI',
      urlRE: '//ebookjapan.yahoo.co.jp/free|//ebookjapan.yahoo.co.jp/ranking/free/',
      listTitleXP: '//p[@class="book-item__title"]',
      listTitleSearchXP: '//p[@class="book-item__title" and ***]/../../../..',
      listTitleMemoSearchXP: '//p[@class="book-item__title" and ***]',
      listGen: 3,
      titleProcessFunc: (title) => { return title.replace(/[0-90-9]+巻?$/gmi, "").replace(/[(\(][0-90-9]+巻?[)\)]$/gmi, "").replace(/【期間限定.*?】|【フルカラー】/g, "").replace(/\s\d+冊/gmi, "").trim() },
      observe: 500,
    },
    {
      id: 'TAMESHIYOMI',
      urlRE: 'booklive.jp/index/no-charge',
      listTitleXP: '//div[@class="title"]/a',
      listTitleSearchXP: '//div[@class="title"]/a[***]/../..',
      listTitleMemoSearchXP: '//div[@class="title"]/a[***]',
      listGen: 4,
      titleProcessFunc: (title) => { return title.replace(/[0-90-9]+巻?$/gmi, "").replace(/[(\(][0-90-9]+巻?[)\)]/gmi, "").replace(/【期間限定.*?】|【無料.*?】|【見本】|\s?【?分冊版】?|【単話売】/g, "").trim() },
      listTitleXPIgnoreNotExist: 1,
      observe: 1000,
    }, {
      id: 'WCA',
      urlRE: 'webcomics\.jp',
      listTitleXP: '//div[@class="entry-title"]/a[1]',

      //listTitleSearchXP: '//div[@class="entry-title"]/a[***]/../..|//div/div[@class="entry-site"]/a[+++]/../..', // 部分一致でヒット+漫画サイト名にもヒット(低速)
      //listTitleSearchXP: '//div[@class="entry-title"]/a[***]/../..', // 部分一致でヒット+漫画サイト名にはヒットしない(中速)
      //listTitleSearchXP: '//div[@class="entry-title"]/a[+++]/../..|//div/div[@class="entry-site"]/a[+++]/../..', // 完全一致のみヒット+漫画サイト名にもヒット(中高速)
      listTitleSearchXP: '//div[@class="entry-title"]/a[+++]/../..', // 完全一致のキーワードのみヒット+漫画サイト名にはヒットしない(高速)

      listTitleMemoSearchXP: '//div[@class="entry-title"]/a[+++]',
      listGen: 5,
      listHelpJQS: 'div.entry',
      func: function(node) { // width 880-600→1180-900
        if (node === document.body && document.documentElement.clientWidth > 1200 && ($("#page").css("width")) == "880px") {
          $("#main-container").css("width", "900px");
          $("#page").css("width", "1180px");
        }
        if (WCA_HIDE_SOME_SITES) { for (let ele of elegeta(SITES_TO_BE_HIDDEN_XP, node)) hideByTitle(ele) }
      },
      autoTranslucentURLRE: /mylist|bookmark/,
    }, {
      id: 'YAJ2',
      urlRE: '://auctions.yahoo.co.jp/search/|://page.auctions.yahoo.co.jp/jp/auction/|://auctions.yahoo.co.jp/category/list/',
      listTitleXP: '//a[@class="Product__titleLink"]|.//a[@class="Product__titleLink u-textBold"]|.//div[@class="a1wrp"]/h3/a',
      listGen: 4,
      listHelpJQS: "li[class='Product']",
      wholeHelp: " " + KEYMAXP + ":価格上限",
      listTitleMemoSearchXP: '//a[contains(@class,"Product__titleLink") and ***]|.//h1[@class="ProductTitle__text" and ***]/..|.//div[@class="a1wrp"]/h3/a[***]',
      listTitleSearchXP: '//a[contains(@class,"Product__titleLink") and ***]/../../../../..|.//div[@class="a1wrp"]/h3/a[***]/../../../..|.//div[@class="a1wrp"]/h3/a/em[***]/../../../..',
      detailURLRE: /:\/\/page.auctions.yahoo.co.jp\/jp\/auction\//,
      detailTitleXP: '//h1[@class="ProductTitle__text"]',
      detailElementSearchXP: '//h1[@class="ProductTitle__text" and ***]/../../../..',
      maxpriceXP: '//input[@class="InputText__input" and @name="max"]',
      automemoURLRE: "://page.auctions.yahoo.co.jp/jp/auction/",
      automemoSearchFunc: () => { return eletext('//div[@class="ProductExplanation__commentArea"]') + "\n" + eletext('//div[@id="ProductProcedures"]') + "\n" + eletext('//h1[@class="ProductTitle__text"]') + '\n' + eletext('//ul[@class="ProductInformation__items"]/li[2]'); },
      automemoFunc: () => {
        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*[::]?(.*[都道府県]は[0-9,0-9,]*円[-~]?)/m);
        autoMemo(/(Pentium.*?GHz)|(Celeron.*?GHz)|(Atom.*?GHz)|(Core\s?i\d.*?GHz)|(AMD.*APU)/mi) ? 0 :
          autoMemo(/(CPU[\s\S]{1,30}?GHz)/mi) ? 0 :
          autoMemo(/^(.*GHz)/gmi) ? 0 :
          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(/発送元:(.{1,4}[都道府県])/m);
      }
    }, {
      id: 'YAJ2',
      urlRE: '://auctions.yahoo.co.jp/seller/',
      listTitleXP: '//a[@class="Product__titleLink"]|.//a[@class="Product__titleLink u-textBold"]|.//div[@class="a1wrp"]/h3/a',
      listGen: 4,
      listHelpJQS: "div.a1,#list01 table tbody tr td",
      listTitleSearchXP: '//div[@class="a1wrp"]/h3/a[***]/../../../..|.//div[@class="a1wrp"]/h3/a/em[***]/../../../../..',
      listTitleMemoSearchXP: '//div[@class="a1wrp"]/h3/a[***]|.//div[@class="a1wrp"]/h3/a/em[***]/..',
    }, {
      id: 'YAJ2',
      urlRE: 'userbenchmark',
    }, {
      id: 'AMAZON',
      urlRE: /www\.amazon\.co\.jp\/s\?k\=|www\.amazon\.co\.jp.*\/dp\/.*/,
      listTitleXP: '//span[@class="a-size-base-plus a-color-base a-text-normal"]|//span[@id="productTitle"]',
      listTitleSearchXP: '//span[@class="a-size-base-plus a-color-base a-text-normal" and ***]/../../../../../../../..',
      listTitleMemoSearchXP: '//span[@class="a-size-base-plus a-color-base a-text-normal" and ***]/..|//span[@id="productTitle" and ***]/..',
      listGen: 12,
      trim: true,
      //      listHelpJQS: 'div[data-asin]',
      detailURLRE: /\/dp\/|\/product-reviews\//,
      detailTitleXP: '//h1[@id="title"]/span[@id="productTitle"]',
      detailElementSearchXP: '//span[@id="productTitle" and ***]/../../../../../..|//h1/a[@class="a-link-normal" and ***]/../../../../../../../../../../../../..',
    },
    /*    {
          id: '', // GM_setValueで保存するグループ名 同じグループは設定が共通になる
          urlRE: '', // 動作するサイトのURLの一部(正規表現)
          listTitleXP: '', // 項目一覧ページの項目名を特定できる要素のXPath title>text>altの順にあるものから利用される
          listTitleSearchXP: '', // 項目一覧ページの項目を消すブロック要素をサーチするXPath 通常listTitleXPに/..をいくつかつけたもの
          listTitleMemoSearchXP: '', // 項目一覧ページと詳細ページのメモを付ける要素をサーチするXPath(一覧と詳細の両方を|でOR記述) 通常listTitleXPやdetailTitleXPに/..をいくつかつけたもの
            // サーチ用マクロ; ***:textをcontainsで検索 +++:textを=で検索 **alt**:altを=で検索 **title**:titleを=で検索
          listGen: 3, // Q12を押した場所の要素からいくつ上まで遡った要素までを当たり判定にするか 必要最小限にする
          listHelpJQS: '', // 項目一覧ページで1行ヘルプを表示する要素のJQueryセレクタ 省略するとlistTitleXPの2つ親の要素で代用 当たり判定とは関係ない
          detailURLRE: //, // URLにmatchする正規表現、matchすると個別詳細画面だと判断する
          detailTitleXP: '', // 詳細画面で項目名を指すXPath
          detailElementSearchXP: '', // 詳細画面で非表示化時に表示を薄くする要素をサーチするXPath
          func: null, // 処理時にそのサイトでのみ実行したい関数があれば書く
          autoTranslucentURLRE: //, // 強制的に半透明モードにするURLの正規表現 Web漫画アンテナのマイリスト等
          listTitleXPIgnoreNotExist: 0, // 通常listTitleXPにヒットする要素が1つもなくobserveも0なら動作を停止するがこれがtrueだとそれを無視する 項目が動的に追加されるページなどで使用
          delay: 0, // ミリ秒 ページ読み込み後処理を開始するまでの遅延
          observe: 0, // ミリ秒 1以上だと要素追加やトランジション終了ごとにこのミリ秒の遅延を置いて再処理する(とても遅い) 項目が動的に追加されるページなどで使用
          trim: 0, // 1だと項目名をtrimしてから保存 Amazonでは項目名が一覧と詳細で揺れるため1にする
          automemoURLRE: null, // 自動メモを収集するURL
          automemoSearchFunc: null, // 自動メモの対象要素のテキストを収集する関数
          automemoFunc: null, // 自動メモを実行する関数
        },
    */
  ];

  // thissiteを決定
  var thissite = null;
  for (var i = 0; i < SITEINFO.length; i++) {
    if (SITEINFO[i].urlRE == "") break;
    if (location.href.match(SITEINFO[i].urlRE)) {
      thissite = i;
      var SITE = Object.create(SITEINFO[thissite]);
      break;
    }
  }
  if (thissite === null || (!ENABLE_EXCEPT_YAJ && SITE.id != "YAJ2")) return;

  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, /(\d\d鍵)/m];
  //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 alsoClearBenchMemoWhenClearAutoMemo = 0; // 1:Shift+"で自動メモのみ削除する時CPUスコアのメモも削除する 0:CPUスコアのメモは残す

  sw("start")
  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[@class="mcs-table"]/tbody/tr/td[2]/span')).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('YAJ2 : SearchMyMemo') || [];
          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('YAJ2 : SearchMyMemo') || [];
              tmp.push({ t: title, m: memo, c: COLORCPUSCORE })
              pref('YAJ2 : SearchMyMemo', tmp)
            }
          }
        }
      }
      pref("lastItemName", "");
      popup3("Task completed");
    }, 500);
    //return;
  }
  if (location.href.indexOf("userbenchmark.com") != -1) {} else {
    pref("lastItemName") ? (pref("lastItemName", ""), popup3("Task has been cleared")) : 0;
  }

  // GM_設定を前バージョンから引き継ぐ
  if (pref(SITE.id + 'SearchHideTitle') && !pref(SITE.id + ' : SearchHideTitle')) {
    pref(SITE.id + ' : SearchHideTitle', pref(SITE.id + 'SearchHideTitle'));
    pref(SITE.id + 'SearchHideTitle', "");
  }
  if (pref(SITE.id + 'SearchMyMemo') && !pref(SITE.id + ' : SearchMyMemo')) {
    pref(SITE.id + ' : SearchMyMemo', pref(SITE.id + 'SearchMyMemo'));
    pref(SITE.id + 'SearchMyMemo', "");
  }
  if (pref(SITE.id + 'SearchHideTitle') && pref(SITE.id + ' : SearchHideTitle')) {
    pref(SITE.id + 'SearchHideTitle', "");
  }
  if (pref(SITE.id + 'SearchMyMemo') && pref(SITE.id + ' : SearchMyMemo')) {
    pref(SITE.id + 'SearchMyMemo', "");
  }

  // 詳細画面か?
  var isDetail = (SITE.detailURLRE && location.href.match(SITE.detailURLRE)) ? 1 : 0;
  dc("isDetail : " + isDetail)
  // ヤフオク上限価格はIME offにする
  if (SITE.id == "YAJ2") $(eleget0('//input[@class="InputText__input" and @name="max"]')).css('ime-mode', 'inactive');
  // ヤフオクは「画像を大きく」モードでは効かない
  if (SITE.id == "YAJ2" && !isDetail && eleget0('//span[@class="Option__mode Option__mode--gridCurrent"]')) {
    popup2("「ヤフオクで非表示とメモ」は「タイトルと画像」表示でのみ働きます");
    return;
  }
  // 自動的に半透明モードにするページ
  var disableHide = (SITE.autoTranslucentURLRE && location.href.match(SITE.autoTranslucentURLRE)) || (pref("translucent") == "on");

  // 非対応ページ
  if (!isDetail && SITE.listTitleXP && !eleget0(SITE.listTitleXP)) {
    if (debug2) popup3("対象要素がないのでこのページでは働きません");
    if (!(SITE.listTitleXPIgnoreNotExist) && !(SITE.observe)) return;
  }

  String.prototype.replaceTitle = function(title) {
    if (title && SITE.titleProcessFunc) title = SITE.titleProcessFunc(title);
    return this.replace(/\*\*\*/g, "contains(text(),\"" + title + "\")").replace(/\+\+\+/g, "text()=\"" + title + "\"").replace(/\*\*alt\*\*/g, "@alt=\"" + title + "\"").replace(/\*\*title\*\*/g, "@title=\"" + title + "\"");
  };

  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) { // Q::hide
        e.preventDefault();
        var ele = (SITE.detailTitleXP && isDetail) ? eleget0(SITE.detailTitleXP) : document.elementFromPoint(mousex, mousey);
        dc("Q start element : " + ele.tagName);
        blockElement(ele);
        if (SITE.funcQ) SITE.funcQ();
        return false;
      }
      if (key == KEYUNDO) { // W::undo
        e.preventDefault();
        let resist = pref(SITE.id + ' : SearchHideTitle') || [];
        let title = resist.pop();
        pref(SITE.id + ' : SearchHideTitle', resist) || [];
        showByTitle(title);
        if (title) popup2("『" + title + "』<br>を非表示登録から削除しました", 1);
        else popup2("登録された非表示項目はありません", 1);
        //        }
        if (SITE.funcQ) SITE.funcQ();
        return false;
      }
      if (key == KEYBW) { // B::NGword
        e.preventDefault();
        addNGWord();
        return false;
      }
      if (key == KEYTOGGLEtranslucent) { // T:: 半透明
        e.preventDefault();
        pref("translucent", pref("translucent") == "on" ? "off" : "on");;
        popup2(KEYTOGGLEtranslucent + ": 半透明モードを" + pref("translucent") + "にします");
        location.reload();
        return false;
      }

      if (key === KEYEDIT || key === KEYEDIT2) { // edit NGs
        e.preventDefault();
        prefRestrict(SITE.id + ' : SearchHideTitle', "array");
        let sht = (JSON.stringify(pref(SITE.id + ' : SearchHideTitle') || ""));
        if (sht === '""') sht = "";
        let tmp = prompt(KEYEDIT + "/" + KEYEDIT2 + ":\n非表示にするタイトル(現在" + (pref(SITE.id + ' : SearchHideTitle') || []).length + ")をJSON形式で編集してください\n正規表現ではありません\n空欄を入力すれば全削除できます\n\n" + sht, sht);
        if (tmp !== null) { // ESCで抜けたのでなければ
          pref(SITE.id + ' : SearchHideTitle', tmp || "")
          prefRestrict(SITE.id + ' : SearchHideTitle', "array");
          document.body.remove();
          location.reload();
        }
        return false;
      }
      if (key == KEYMEMO1) { // 1memo
        e.preventDefault();
        var ele = eleget0(SITE.detailTitleXP) ? eleget0(SITE.detailTitleXP) : document.elementFromPoint(mousex, mousey);
        memoElement(ele, document);
        return false;
      }
      if (key == KEYMEMO2) { // 2memo
        e.preventDefault();
        var ele = eleget0(SITE.detailTitleXP) ? eleget0(SITE.detailTitleXP) : document.elementFromPoint(mousex, mousey);
        //        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 memo
        e.preventDefault();
        prefRestrict(SITE.id + 'SearchMyMemo', "array");
        let smm = JSON.stringify(pref(SITE.id + ' : SearchMyMemo') || []);
        if (smm === '[]') smm = "";
        let tmp = prompt(KEYRESETMEMO + ":\nメモ(現在" + (pref(SITE.id + ' : SearchMyMemo') || []).length + ")をJSON形式で編集してください\n空欄を入力すれば全削除されます\n\n" + smm, smm);
        if (tmp !== null) { // ESCで抜けたのでなければ
          pref(SITE.id + ' : SearchMyMemo', tmp || []);
          prefRestrict(SITE.id + 'SearchMyMemo', "array");
          document.body.remove();
          location.reload();
        }
        return false;
      }
      if (key == KEYRESETMEMOAUTO) { // reset automemo
        e.preventDefault();
        var str = pref(SITE.id + ' : SearchMyMemo') || [];
        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自動メモ(" + newstr2.length + ")のみ全て削除します。良いですか?\n\n消すもの:\n" + JSON.stringify(newstr2))) {
          pref(SITE.id + ' : SearchMyMemo', JSON.stringify(newstr));
          popup2("自動メモをクリアしました", 1);
          document.body.remove();
          location.reload();
        }
        return false;
      }
      if (SITE.maxpriceXP && !isDetail) {
        if (key == KEYMAXP) { // maxpriceXP
          e.preventDefault();
          let ele = eleget0(SITE.maxpriceXP);
          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);

  // AP継ぎ足しを監視
  setTimeout(() => { run() }, SITE.delay || 0);
  document.body.addEventListener('AutoPagerize_DOMNodeInserted', function(evt) { run(evt.target); }, false);

  // DOM追加を監視
  var DNIDelay = null;
  if (!isDetail && SITE.observe) {
    dc("observe DNI");
    document.body.addEventListener('DOMNodeInserted', dnifunc, false);
    document.body.addEventListener('transitionend', dnifunc, false);

    function dnifunc() {
      if (DNIDelay) { return; }
      DNIDelay = setTimeout(() => {
        run(document.body, "observed");
        DNIDelay = null;
      }, SITE.observe);
    }
  }

  // ヤフオク キーワードの検索対象を切り替えるボタン
  if (SITE.id == "YAJ2") {
    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, mode = "") {
    sw("reset");
    sw("run");
    // サイトごとの個別処理
    if (SITE.func) { SITE.func(node); }

    if (ENABLE_HELP) {
      // ホバー時の操作案内のポップアップを登録
      // 1行単位=検索結果&セラー画面の方
      var 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:2px; right: 20em;' title='クリックでこのガイドを一時的に消す'>Q:非表示 W:アンドゥ 1:○メモ 2:×メモ</span>");
      if (SITE.listHelpJQS) {
        $(node).find(SITE.listHelpJQS).hover(function() {
          ih.appendTo(this).click(function() { $(this).fadeOut(100).queue(function() { $(this).remove() }) });
        }, function() { $(".phov").remove() });
      } else {
        if (mode === "observed") $(node).find(elegeta(SITE.listTitleXP)).parent().parent().off("mouseenter mouseleave");
        $(node).find(elegeta(SITE.listTitleXP)).parent().parent().hover(function() {
          $("<span class='phov' style='all:initial; cursor:pointer; z-index:2147483647; color:#505050; font-size:90%; background:#ffffffc0; padding:3px; border-radius:9px;border:#505050 1px solid; position:fixed; bottom:1em; right: 1em;' title='クリックでこのガイドを一時的に消す'>Q:非表示 W:アンドゥ 1:○メモ 2:×メモ</span>").appendTo(document.body).click(function() { $(this).fadeOut(100).queue(function() { $(this).remove() }) });
        }, function() { $(".phov").remove() });
      }
      sw("1gyou help");
      // 画面全体=詳細画面の方
      if (SITE.detailURLRE && location.href.match(SITE.detailURLRE)) {
        $('span.phov').remove();
        $("<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;' title='クリックでこのガイドを一時的に消す'>Q:非表示 W:アンドゥ 1:○メモ 2:×メモ</span>").appendTo(document.body).click(function() { $(this).fadeOut(100).queue(function() { $(this).remove() }) });
      }
      sw("zentai help");
    }

    // メモ貼りを実行
    if (mode === "observed") $('span[data-mbt="1"]').remove();
    if (pref(SITE.id + ' : SearchMyMemo')) {
      for (let a of pref(SITE.id + ' : SearchMyMemo').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");

    // 非表示を実行
    var help = (KEYHIDE + ":非表示 " + KEYUNDO + ":アンドゥ " + KEYBW + ":NGワード " + KEYEDIT + ":NG編集 " + KEYMEMO1 + KEYMEMO2 + ":メモを追加 " + KEYMEMO1S + KEYMEMO2S + ":自由メモ " + KEYRESETMEMO + ":メモを編集 " + KEYRESETMEMOAUTO + ":自動メモのみ全削除 " + KEYTOGGLEtranslucent + ":半透明") + (SITE.wholeHelp || "");
    if (pref(SITE.id + ' : SearchHideTitle')) {
      var i = 0;
      for (let title of pref(SITE.id + ' : SearchHideTitle') || []) {
        i += hideByTitle(title, node);
      }
      if (i) { help = i + "個を非表示にしました<BR>" + help; }
    }
    // 全体ヘルプを表示
    if (ENABLE_HELP && mode !== "observed") popup2(help, 1);
    sw("block");

    // 自動メモを探索&製作
    if (isDetail) { for (let t = 0; t < ENABLE_AUTOMEMO; t++) { setTimeout(makeautomemo, 500 + t * 3000); } } //debug&&t>0?popup3( t * t / 2 * 1000,2,1):0; }

    function makeautomemo() {
      if (ENABLE_AUTOMEMO && SITE.automemoURLRE && (location.href.match(SITE.automemoURLRE))) {
        SITE.automemoFunc();
      }
    }
    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 = SITE.automemoSearchFunc();
    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(SITE.id + ' : SearchMyMemo') || [];
      var isExist = tmp.filter(e => e.t == title && e.m == memo);
      if (isExist.length == 0) {
        if (debug) popup3(memo, 2, 1, 5000);
        storeMemo(title, memo, COLOR3, node);
      }
      return true;
    }
    return false;
  }

  function getTitle(x, y) {
    var ele = (SITE.detailTitleXP && isDetail) ? eleget0(SITE.detailTitleXP) : document.elementFromPoint(mousex, mousey);
    //    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 getTitleFromParent(ele) { // ele要素の親の出品物タイトルを返す
    dc("start at : " + ele.innerText);
    if (isDetail) return tri((ele.title || ele.textContent.replace(/\|/g, '\|') || ele.alt));
    for (let i = 0; i < (SITE.listGen); i++) {
      dc("go up to now : " + ele.innerText)
      var ele2 = elegeta(SITE.listTitleXP, ele);
      dc("length:" + ele2.length)
      if (ele2.length == 1) {
        dc("title : " + tri((ele2[0].title + " \ntextContent : " + ele2[0].textContent.replace(/\|/g, '\|') + " \nalt : " + ele2[0].alt)));
        return tri((ele2[0].title || ele2[0].textContent.replace(/\|/g, '\|') || ele2[0].alt));
      }
      if (ele === document) return;
      ele = ele.parentNode;
    }
    return;
  }

  function tri(str) {
    if (str.match(/\"/)) { popup3("項目名に \" を含むので多分うまく処理できません"); return ""; }
    return (SITE.trim) ? str.trim() : str;
  }

  function memoElement(ele, node, color = COLOR1) { //12 memo
    if (!ele) return;
    var title = getTitleFromParent(ele);
    if (!title) return;
    if (SITE.titleProcessFunc) title = SITE.titleProcessFunc(title);
    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(SITE.id + ' : SearchMyMemo') || [];
      tmp.push({ t: title, m: memo, c: color })
      pref(SITE.id + ' : SearchMyMemo', tmp)
      memoByTitle(title, memo, node, color);
    }
  }

  function memoByTitle(title, memo, node, color) {
    if (title.indexOf('"') != -1) return; // todo:タイトルに"があると正しく検索できないので処理しない
    var xp = SITE.listTitleMemoSearchXP.replaceTitle(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|AMD.*APU/i);
        ele.innerHTML = '<span data-mbt="1" 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="all:initial; cursor:' + (isCPU ? "help" : "pointer") + '; font-size:80%; font-weight:bold; margin:0px 1px; text-align:center; padding:0px 6px 0px 6px; line-height: 1.4em; border-radius:12px; background-color:' + color + '; color:white;font-family:sans-serif;word-warp:">' + memo + '</span>';
        $(ele).hide().fadeIn(SITE.observe ? 0 : 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(SITE.id + ' : SearchMyMemo', (pref(SITE.id + ' : SearchMyMemo') || []).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();
      e.preventDefault();
      e.stopPropagation();
    }
  }

  function blockElement(ele) { //Q:: toggle
    if (!ele) return;
    var title = getTitleFromParent(ele);
    dc("got : " + title)
    addNG(title);
  }

  function hideByTitle(title, node) {
    let i = 0;
    if (!isDetail) {
      // 1項目ずつ
      for (let ele of typeof title === "object" ? [title] : elegeta(SITE.listTitleSearchXP.replaceTitle(title), node)) { // titleがテキストなら項目タイトルにヒットする要素、DOM要素なら直接それを隠す
        i++;
        if (!disableHide) {
          $(ele).fadeOut(34);
          ele.dataset.hidden = "1";
        } else {
          ele.style.opacity = "0.75";
          setTimeout(function() { ele.style.opacity = "0.50" }, 17 * 1);
        }
      }
    } else {
      // 詳細:画面全体
      if (isDetail && SITE.detailTitleXP && SITE.detailElementSearchXP) {
        var xp = SITE.detailElementSearchXP.replaceTitle(title) // isearでハイライトされていると×
        for (let ele of elegeta(xp, node)) {
          dc(xp, ele, ele.textContent);
          i++;
          ele.style.opacity = "0.5";
        }
      }
    }
    return i;
  }

  function showByTitle(title) {
    if (!isDetail) {
      // 1項目ずつ
      var xp = SITE.listTitleSearchXP.replaceTitle(title);
      for (let ele of elegeta(xp)) {
        $(ele).fadeIn(34);
        delete ele.dataset.hidden;
        setTimeout(function() { ele.style.opacity = "1" }, 17 * 2);
      }
    } else {
      // 詳細:画面全体
      if (isDetail && SITE.detailTitleXP && SITE.detailElementSearchXP) {
        var xp = SITE.detailElementSearchXP.replaceTitle(title) // isearでハイライトされていると×
        for (let ele of elegeta(xp)) { ele.style.opacity = "1"; }
      }
    }
  }

  function addNGWord() {
    var newWord = (prompt("非表示にしたい項目のタイトルが含むNGワードを入力してください\n\n現在の全体\n" + JSON.stringify(pref(SITE.id + ' : SearchHideTitle') || []) + "\nに追加されます\n\n") || "").trim();
    addNG(newWord);
  }

  function addNG(title) {
    if (!title) return;
    if (SITE.titleProcessFunc) title = SITE.titleProcessFunc(title);
    //let titler=title.replace(/(\(|\)|\[|\]|\?|\*|\^|\$|\.|\+|\{|\}|\|)/gm, "\\$1");
    let resist = pref(SITE.id + ' : SearchHideTitle') || [];
    let i = resist.indexOf(title);
    if (i !== -1) {
      resist.splice(i, 1);
      pref(SITE.id + ' : SearchHideTitle', resist);;
      popup2("『" + title + "』<br>を非表示登録から削除しました", 1);
      //      popup2("『" + title + "』<br>を非表示登録から削除しました", 1);
      showByTitle(title);
    } else {
      //      let sht = pref(SITE.id + ' : SearchHideTitle') || [];
      resist.push(title);
      pref(SITE.id + ' : SearchHideTitle', resist);
      //      popup2("『" + title + "』<br>を非表示登録しました(" + resist.length + ")(" + KEYUNDO + ":取り消し " + KEYEDIT + "/" + KEYEDIT2 + ":編集)", 1);
      popup2("『" + title + "』<br>を非表示登録しました(" + KEYUNDO + ":取り消し " + KEYEDIT + "/" + KEYEDIT2 + ":編集)", 1);
      hideByTitle(title);
    }
  }

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

  function elegeta(xpath, node = document) {
    if (!xpath) return [];
    if (xpath === elegetaCacheXP && node === elegetaCacheNode && ((new Date().getTime() - elegetaCacheLastTime) < 100)) {
      //console.log(++ehit,emiss,ehit/(ehit+emiss)*100+"% hits");
      //elegetaCacheLastTime = new Date().getTime();
      return elegetaCacheResult;
    } // 100ms以内ならキャッシュを返す
    elegetaCacheXP = xpath;
    elegetaCacheLastTime = new Date().getTime();
    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) { popup2(e + "<br>" + xpath, 1); 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 + "<br>" + xpath, 1); return null; }
  }

  function popup3(text, i = 0, lf = 1, timer = 5000, alignY = "bottom") {
    if (!ENABLE_HELP) return;
    if (text == undefined) return;
    if (typeof text == "string") text = text.slice(0, 100);
    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:0em; ' + alignY + ':' + ((maey + i) * 1 + 0) + '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 + 1;
    if (typeof text == "string") { maey += (text.match(/<br>/gmi) || []).length || 0; } //console.log((text.match(/<br>/gmi) || [] ).length) }
    setTimeout(() => {
      eleget0('//span[@id="mllbox' + id + '"]').remove();
      maey = 0;
    }, timer);
  }
  var maet;

  function popup2(text, i = 0) {
    if (!ENABLE_HELP) return;
    var mae = eleget0('//span[@id="mllbox"]');
    if (maet && mae) {
      mae.remove();
      clearTimeout(maet);
    }
    let bgcol = (pref("translucent") != "on") ? "#6080ff" : "#909090";
    var ele = $('<span id="mllbox" style="all:initial; cursor:pointer; position: fixed; right:0em; bottom: ' + (i * 2 + 2) + '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:' + bgcol + '; 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) || 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) {
          alert("データベースがバグってるのでクリアします\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) {
        alert("データベースがバグってるのでクリアします\n" + e);
        pref(name, "");
      }
      return store;
    }
  }

  function prefRestrict(name, type) {
    let data = pref(name);
    if (!data) return data;
    if (type === "array") {
      if (typeof data === "object") {
        //            alert("correct");
        return data;
      } else {
        alert("データベースの形式に誤りがある(配列/オブジェクトでない)ためクリアします\n");
        pref(name, "");
        return [];
      }
    }
    return data;
  }

  function debugEle(ele, force = "") {
    if (ENABLE_HELP && (debug || force == "force")) {
      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 advertiseEle(ele, force = "") {
    if (debug || force == "force") {
      if (ele) ele.style.outline = "4px dotted red";
    }
  }

  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 (ENABLE_MEASURE_TIME_SPENT == 0) return;
    if (job !== "reset") dc(job + " : " + ((new Date().getTime()) - (swb.getTime())) + " ms");
    swb = new Date();
  }

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

  function dc(str) {
    if (debug >= 1) console.log(str);
    if (debug >= 2) popup3(str, 0, 1, 5000, "top");

    return str;
  }

})()