Greasy Fork

steam价格转换

steam商店中的价格转换为人民币

目前为 2023-07-04 提交的版本。查看 最新版本

// ==UserScript==
// @name         steam价格转换
// @namespace    https://github.com/marioplus/steam-price-converter
// @version      2.3.0
// @author       marioplus
// @description  steam商店中的价格转换为人民币
// @license      GPL-3.0-or-later
// @icon         https://vitejs.dev/logo.svg
// @homepage     https://github.com/marioplus
// @match        https://store.steampowered.com/*
// @match        https://steamcommunity.com/*
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/js/mdui.min.js
// @require      data:application/javascript,%3Bvar%20Reflect%3Dwindow.Reflect%3B
// @require      https://cdn.jsdelivr.net/npm/[email protected]/Reflect.min.js
// @connect      api.augmentedsteam.com
// @connect      store.steampowered.com
// @grant        GM_addValueChangeListener
// @grant        GM_cookie
// @grant        GM_deleteValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @grant        unsafeWindow
// ==/UserScript==

(e=>{const t=document.createElement("style");t.dataset.source="vite-plugin-monkey",t.textContent=e,document.head.append(t)})(" #spc-menu{position:absolute;top:0px;width:100px;height:100px;z-index:99999;padding:0;margin:0}.tab_item_discount{min-width:113px!important;width:unset}.discount_final_price{display:inline-block!important}.search_result_row .col.search_price{width:175px}.search_result_row .col.search_name{width:200px}.market_listing_their_price{width:160px} ");

(function (reflectMetadata, vue, mdui) {
  'use strict';

  var __defProp = Object.defineProperty;
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  var __publicField = (obj, key, value) => {
    __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
    return value;
  };
  class AbstractConverter {
    /**
     * 匹配到的元素,是否匹配这个 exchanger
     * @param elementSnap 选择器选择到的元素快照
     */
    match(elementSnap) {
      if (!elementSnap || !elementSnap.element) {
        return false;
      }
      const content = elementSnap.textContext;
      if (!content) {
        return false;
      }
      if (content.match(/\d/) === null) {
        return false;
      }
      if (/^[,.\d\s]+$/.test(content)) {
        return false;
      }
      const parent = elementSnap.element.parentElement;
      if (!parent) {
        return false;
      }
      for (const selector of this.getCssSelectors()) {
        const element = parent.querySelector(selector);
        if (element && element === elementSnap.element) {
          elementSnap.selector = selector;
          return true;
        }
      }
      return false;
    }
    /**
     * 替换之后的操作
     * @param elementSnap 选择器选择到的元素快照
     */
    // @ts-ignore
    afterConvert(elementSnap) {
    }
  }
  const metadataKey = "Metadata:JsonProperty";
  function JsonProperty(config = {}) {
    return (target, property) => {
      config.alias = config.alias || property;
      Reflect.defineMetadata(metadataKey, config, target, property);
    };
  }
  function JsonAlias(alias) {
    return (target, property) => {
      const config = Reflect.getMetadata(metadataKey, target, property) || {};
      config.alias = alias || property;
      Reflect.defineMetadata(metadataKey, config, target, property);
    };
  }
  class Serializable {
    toJson() {
      const anyThis = this;
      const json = {};
      Object.keys(this).forEach((propKey) => {
        const config = Reflect.getMetadata(metadataKey, this, propKey);
        const prop = anyThis[propKey];
        if (!config || prop === void 0) {
          return;
        }
        if (config.typeAs || config.typeAs === Map) {
          json[config.alias] = {};
          prop.forEach((v, k) => {
            json[config.alias][k] = v;
          });
          return;
        }
        if (prop instanceof Serializable) {
          json[config.alias] = prop.toJson();
          return;
        }
        json[config.alias] = prop;
      });
      return json;
    }
    toJsonString() {
      return JSON.stringify(this.toJson());
    }
    readJson(json) {
      const anyThis = this;
      Object.keys(this).forEach((propKey) => {
        const config = Reflect.getMetadata(metadataKey, this, propKey);
        const prop = anyThis[propKey];
        const jsonNode = json[config.alias];
        if (!config || jsonNode === void 0) {
          return;
        }
        if (config.typeAs || config.typeAs === Map) {
          let entries = Object.entries(jsonNode);
          if (config.mapValue) {
            entries = entries.map(([k, v]) => {
              if (v instanceof Object) {
                return [k, new Map(Object.entries(v))];
              }
              return [k, v];
            });
          }
          anyThis[propKey] = new Map(entries);
          return;
        }
        if (prop instanceof Serializable) {
          prop.readJson(jsonNode);
          return;
        }
        anyThis[propKey] = jsonNode;
      });
      return this;
    }
    readJsonString(jsonString) {
      return this.readJson(JSON.parse(jsonString));
    }
  }
  var __defProp$2 = Object.defineProperty;
  var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
  var __decorateClass$2 = (decorators, target, key, kind) => {
    var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
    for (var i = decorators.length - 1, decorator; i >= 0; i--)
      if (decorator = decorators[i])
        result = (kind ? decorator(target, key, result) : decorator(result)) || result;
    if (kind && result)
      __defProp$2(target, key, result);
    return result;
  };
  class Setting extends Serializable {
    constructor() {
      super(...arguments);
      __publicField(this, "countyCode", "CN");
      __publicField(this, "currencySymbol", "¥");
      __publicField(this, "currencySymbolBeforeValue", true);
      __publicField(this, "rateCacheExpired", 1e3 * 60 * 60);
      __publicField(this, "useCustomRate", false);
      __publicField(this, "customRate", 1);
    }
  }
  __decorateClass$2([
    JsonProperty()
  ], Setting.prototype, "countyCode", 2);
  __decorateClass$2([
    JsonProperty()
  ], Setting.prototype, "currencySymbol", 2);
  __decorateClass$2([
    JsonProperty()
  ], Setting.prototype, "currencySymbolBeforeValue", 2);
  __decorateClass$2([
    JsonProperty()
  ], Setting.prototype, "rateCacheExpired", 2);
  __decorateClass$2([
    JsonProperty()
  ], Setting.prototype, "useCustomRate", 2);
  __decorateClass$2([
    JsonProperty()
  ], Setting.prototype, "customRate", 2);
  var _GM_addValueChangeListener = /* @__PURE__ */ (() => typeof GM_addValueChangeListener != "undefined" ? GM_addValueChangeListener : void 0)();
  var _GM_cookie = /* @__PURE__ */ (() => typeof GM_cookie != "undefined" ? GM_cookie : void 0)();
  var _GM_deleteValue = /* @__PURE__ */ (() => typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0)();
  var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
  var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)();
  var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
  var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
  var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
  const STORAGE_KEY_PREFIX = "Storage:";
  const STORAGE_KEY_RATE_CACHES = STORAGE_KEY_PREFIX + "RateCache";
  const STORAGE_KEY_SETTING = STORAGE_KEY_PREFIX + "Setting";
  const IM_KEY_PREFIX = "Im:";
  const IM_KEY_MENU_STATUS = IM_KEY_PREFIX + "MenuStatus";
  const IM_KEY_OPEN_MENU = IM_KEY_PREFIX + "Open";
  const IM_KEY_CLOSE_MENU = IM_KEY_PREFIX + "Close";
  const countyCurrencyCodes = [
    {
      code: "AL",
      name: "阿尔巴尼亚",
      nameEn: "Albania",
      currencyCode: "ALL"
    },
    {
      code: "DZ",
      name: "阿尔及利亚",
      nameEn: "Algeria",
      currencyCode: "DZD"
    },
    {
      code: "AF",
      name: "阿富汗",
      nameEn: "Afghanistan",
      currencyCode: "AFN"
    },
    {
      code: "AR",
      name: "阿根廷",
      nameEn: "Argentina",
      currencyCode: "ARS"
    },
    {
      code: "AE",
      name: "阿联酋",
      nameEn: "United Arab Emirates",
      currencyCode: "AED"
    },
    {
      code: "AW",
      name: "阿鲁巴",
      nameEn: "Aruba",
      currencyCode: "AWG"
    },
    {
      code: "OM",
      name: "阿曼",
      nameEn: "Oman",
      currencyCode: "OMR"
    },
    {
      code: "AZ",
      name: "阿塞拜疆",
      nameEn: "Azerbaijan",
      currencyCode: "AZN"
    },
    {
      code: "EG",
      name: "埃及",
      nameEn: "Egypt",
      currencyCode: "EGP"
    },
    {
      code: "ET",
      name: "埃塞俄比亚",
      nameEn: "Ethiopia",
      currencyCode: "ETB"
    },
    {
      code: "IE",
      name: "爱尔兰",
      nameEn: "Ireland",
      currencyCode: "EUR"
    },
    {
      code: "EE",
      name: "爱沙尼亚",
      nameEn: "Estonia",
      currencyCode: "EUR"
    },
    {
      code: "AD",
      name: "安道尔",
      nameEn: "Andorra",
      currencyCode: "EUR"
    },
    {
      code: "AO",
      name: "安哥拉",
      nameEn: "Angola",
      currencyCode: "AOA"
    },
    {
      code: "AI",
      name: "安圭拉",
      nameEn: "Anguilla",
      currencyCode: "XCD"
    },
    {
      code: "AG",
      name: "安提瓜和巴布达",
      nameEn: "Antigua and Barbuda",
      currencyCode: "XCD"
    },
    {
      code: "AT",
      name: "奥地利",
      nameEn: "Austria",
      currencyCode: "EUR"
    },
    {
      code: "AU",
      name: "澳大利亚",
      nameEn: "Australia",
      currencyCode: "AUD"
    },
    {
      code: "MO",
      name: "澳门",
      nameEn: "Macao",
      currencyCode: "MOP"
    },
    {
      code: "BB",
      name: "巴巴多斯",
      nameEn: "Barbados",
      currencyCode: "BBD"
    },
    {
      code: "PG",
      name: "巴布亚新几内亚",
      nameEn: "Papua New Guinea",
      currencyCode: "PGK"
    },
    {
      code: "BS",
      name: "巴哈马",
      nameEn: "Bahamas",
      currencyCode: "BSD"
    },
    {
      code: "PK",
      name: "巴基斯坦",
      nameEn: "Pakistan",
      currencyCode: "PKR"
    },
    {
      code: "PY",
      name: "巴拉圭",
      nameEn: "Paraguay",
      currencyCode: "PYG"
    },
    {
      code: "PS",
      name: "巴勒斯坦",
      nameEn: "Palestine, State of",
      currencyCode: "ILS"
    },
    {
      code: "BH",
      name: "巴林",
      nameEn: "Bahrain",
      currencyCode: "BHD"
    },
    {
      code: "PA",
      name: "巴拿马",
      nameEn: "Panama",
      currencyCode: "PAB"
    },
    {
      code: "BR",
      name: "巴西",
      nameEn: "Brazil",
      currencyCode: "BRL"
    },
    {
      code: "BY",
      name: "白俄罗斯",
      nameEn: "Belarus",
      currencyCode: "BYN"
    },
    {
      code: "BM",
      name: "百慕大",
      nameEn: "Bermuda",
      currencyCode: "BMD"
    },
    {
      code: "BG",
      name: "保加利亚",
      nameEn: "Bulgaria",
      currencyCode: "BGN"
    },
    {
      code: "MP",
      name: "北马里亚纳群岛",
      nameEn: "Northern Mariana Islands",
      currencyCode: "USD"
    },
    {
      code: "BJ",
      name: "贝宁",
      nameEn: "Benin",
      currencyCode: "XOF"
    },
    {
      code: "BE",
      name: "比利时",
      nameEn: "Belgium",
      currencyCode: "EUR"
    },
    {
      code: "IS",
      name: "冰岛",
      nameEn: "Iceland",
      currencyCode: "ISK"
    },
    {
      code: "PR",
      name: "波多黎各",
      nameEn: "Puerto Rico",
      currencyCode: "USD"
    },
    {
      code: "BA",
      name: "波黑",
      nameEn: "Bosnia and Herzegovina",
      currencyCode: "BAM"
    },
    {
      code: "PL",
      name: "波兰",
      nameEn: "Poland",
      currencyCode: "PLN"
    },
    {
      code: "BO",
      name: "玻利维亚",
      nameEn: "Bolivia, Plurinational State of",
      currencyCode: "BOB"
    },
    {
      code: "BZ",
      name: "伯利兹",
      nameEn: "Belize",
      currencyCode: "BZD"
    },
    {
      code: "BW",
      name: "博茨瓦纳",
      nameEn: "Botswana",
      currencyCode: "BWP"
    },
    {
      code: "BT",
      name: "不丹",
      nameEn: "Bhutan",
      currencyCode: "BTN"
    },
    {
      code: "BF",
      name: "布基纳法索",
      nameEn: "Burkina Faso",
      currencyCode: "XOF"
    },
    {
      code: "BI",
      name: "布隆迪",
      nameEn: "Burundi",
      currencyCode: "BIF"
    },
    {
      code: "BV",
      name: "布韦岛",
      nameEn: "Bouvet Island",
      currencyCode: "NOK"
    },
    {
      code: "KP",
      name: "朝鲜",
      nameEn: "Korea, Democratic People's Republic of",
      currencyCode: "KPW"
    },
    {
      code: "GQ",
      name: "赤道几内亚",
      nameEn: "Equatorial Guinea",
      currencyCode: "XAF"
    },
    {
      code: "DK",
      name: "丹麦",
      nameEn: "Denmark",
      currencyCode: "DKK"
    },
    {
      code: "DE",
      name: "德国",
      nameEn: "Germany",
      currencyCode: "EUR"
    },
    {
      code: "TL",
      name: "东帝汶",
      nameEn: "Timor-Leste",
      currencyCode: "USD"
    },
    {
      code: "TG",
      name: "多哥",
      nameEn: "Togo",
      currencyCode: "XOF"
    },
    {
      code: "DO",
      name: "多米尼加",
      nameEn: "Dominican Republic",
      currencyCode: "DOP"
    },
    {
      code: "DM",
      name: "多米尼克",
      nameEn: "Dominica",
      currencyCode: "XCD"
    },
    {
      code: "RU",
      name: "俄罗斯",
      nameEn: "Russian Federation",
      currencyCode: "RUB"
    },
    {
      code: "EC",
      name: "厄瓜多尔",
      nameEn: "Ecuador",
      currencyCode: "USD"
    },
    {
      code: "ER",
      name: "厄立特里亚",
      nameEn: "Eritrea",
      currencyCode: "ERN"
    },
    {
      code: "FR",
      name: "法国",
      nameEn: "France",
      currencyCode: "EUR"
    },
    {
      code: "FO",
      name: "法罗群岛",
      nameEn: "Faroe Islands",
      currencyCode: "DKK"
    },
    {
      code: "PF",
      name: "法属波利尼西亚",
      nameEn: "French Polynesia",
      currencyCode: "XPF"
    },
    {
      code: "VA",
      name: "梵蒂冈",
      nameEn: "Holy See",
      currencyCode: "EUR"
    },
    {
      code: "PH",
      name: "菲律宾",
      nameEn: "Philippines",
      currencyCode: "PHP"
    },
    {
      code: "FJ",
      name: "斐济",
      nameEn: "Fiji",
      currencyCode: "FJD"
    },
    {
      code: "FI",
      name: "芬兰",
      nameEn: "Finland",
      currencyCode: "EUR"
    },
    {
      code: "CV",
      name: "佛得角",
      nameEn: "Cabo Verde",
      currencyCode: "CVE"
    },
    {
      code: "FK",
      name: "福克兰群岛",
      nameEn: "Falkland Islands (Malvinas)",
      currencyCode: "FKP"
    },
    {
      code: "GM",
      name: "冈比亚",
      nameEn: "Gambia",
      currencyCode: "GMD"
    },
    {
      code: "CG",
      name: "刚果共和国",
      nameEn: "Congo",
      currencyCode: "XAF"
    },
    {
      code: "CD",
      name: "刚果民主共和国",
      nameEn: "Congo, the Democratic Republic of the",
      currencyCode: "CDF"
    },
    {
      code: "CO",
      name: "哥伦比亚",
      nameEn: "Colombia",
      currencyCode: "COP"
    },
    {
      code: "CR",
      name: "哥斯达黎加",
      nameEn: "Costa Rica",
      currencyCode: "CRC"
    },
    {
      code: "GD",
      name: "格林纳达",
      nameEn: "Grenada",
      currencyCode: "XCD"
    },
    {
      code: "GL",
      name: "格陵兰",
      nameEn: "Greenland",
      currencyCode: "DKK"
    },
    {
      code: "GE",
      name: "格鲁吉亚",
      nameEn: "Georgia",
      currencyCode: "GEL"
    },
    {
      code: "GG",
      name: "根西",
      nameEn: "Guernsey",
      currencyCode: "GBP"
    },
    {
      code: "CU",
      name: "古巴",
      nameEn: "Cuba",
      currencyCode: "CUP"
    },
    {
      code: "GP",
      name: "瓜德罗普",
      nameEn: "Guadeloupe",
      currencyCode: "EUR"
    },
    {
      code: "GU",
      name: "关岛",
      nameEn: "Guam",
      currencyCode: "USD"
    },
    {
      code: "GY",
      name: "圭亚那",
      nameEn: "Guyana",
      currencyCode: "GYD"
    },
    {
      code: "KZ",
      name: "哈萨克斯坦",
      nameEn: "Kazakhstan",
      currencyCode: "KZT"
    },
    {
      code: "HT",
      name: "海地",
      nameEn: "Haiti",
      currencyCode: "HTG"
    },
    {
      code: "KR",
      name: "韩国",
      nameEn: "Korea, Republic of",
      currencyCode: "KRW"
    },
    {
      code: "NL",
      name: "荷兰",
      nameEn: "Netherlands",
      currencyCode: "EUR"
    },
    {
      code: "SX",
      name: "荷属圣马丁",
      nameEn: "Sint Maarten (Dutch part)",
      currencyCode: "ANG"
    },
    {
      code: "HM",
      name: "赫德岛和麦克唐纳群岛",
      nameEn: "Heard Island and McDonald Islands",
      currencyCode: "AUD"
    },
    {
      code: "ME",
      name: "黑山",
      nameEn: "Montenegro",
      currencyCode: "EUR"
    },
    {
      code: "HN",
      name: "洪都拉斯",
      nameEn: "Honduras",
      currencyCode: "HNL"
    },
    {
      code: "KI",
      name: "基里巴斯",
      nameEn: "Kiribati",
      currencyCode: "AUD"
    },
    {
      code: "DJ",
      name: "吉布提",
      nameEn: "Djibouti",
      currencyCode: "DJF"
    },
    {
      code: "KG",
      name: "吉尔吉斯斯坦",
      nameEn: "Kyrgyzstan",
      currencyCode: "KGS"
    },
    {
      code: "GN",
      name: "几内亚",
      nameEn: "Guinea",
      currencyCode: "GNF"
    },
    {
      code: "GW",
      name: "几内亚比绍",
      nameEn: "Guinea-Bissau",
      currencyCode: "XOF"
    },
    {
      code: "CA",
      name: "加拿大",
      nameEn: "Canada",
      currencyCode: "CAD"
    },
    {
      code: "GH",
      name: "加纳",
      nameEn: "Ghana",
      currencyCode: "GHS"
    },
    {
      code: "GA",
      name: "加蓬",
      nameEn: "Gabon",
      currencyCode: "XAF"
    },
    {
      code: "KH",
      name: "柬埔寨",
      nameEn: "Cambodia",
      currencyCode: "KHR"
    },
    {
      code: "CZ",
      name: "捷克",
      nameEn: "Czechia",
      currencyCode: "CZK"
    },
    {
      code: "ZW",
      name: "津巴布韦",
      nameEn: "Zimbabwe",
      currencyCode: "ZWL"
    },
    {
      code: "CM",
      name: "喀麦隆",
      nameEn: "Cameroon",
      currencyCode: "XAF"
    },
    {
      code: "QA",
      name: "卡塔尔",
      nameEn: "Qatar",
      currencyCode: "QAR"
    },
    {
      code: "KY",
      name: "开曼群岛",
      nameEn: "Cayman Islands",
      currencyCode: "KYD"
    },
    {
      code: "CC",
      name: "科科斯(基林)群岛",
      nameEn: "Cocos (Keeling) Islands",
      currencyCode: "AUD"
    },
    {
      code: "KM",
      name: "科摩罗",
      nameEn: "Comoros",
      currencyCode: "KMF"
    },
    {
      code: "CI",
      name: "科特迪瓦",
      nameEn: "Côte d'Ivoire",
      currencyCode: "XOF"
    },
    {
      code: "KW",
      name: "科威特",
      nameEn: "Kuwait",
      currencyCode: "KWD"
    },
    {
      code: "HR",
      name: "克罗地亚",
      nameEn: "Croatia",
      currencyCode: "HRK"
    },
    {
      code: "KE",
      name: "肯尼亚",
      nameEn: "Kenya",
      currencyCode: "KES"
    },
    {
      code: "CK",
      name: "库克群岛",
      nameEn: "Cook Islands",
      currencyCode: "NZD"
    },
    {
      code: "CW",
      name: "库拉索",
      nameEn: "Curaçao",
      currencyCode: "ANG"
    },
    {
      code: "LV",
      name: "拉脱维亚",
      nameEn: "Latvia",
      currencyCode: "EUR"
    },
    {
      code: "LS",
      name: "莱索托",
      nameEn: "Lesotho",
      currencyCode: "LSL"
    },
    {
      code: "LA",
      name: "老挝",
      nameEn: "Lao People's Democratic Republic",
      currencyCode: "LAK"
    },
    {
      code: "LB",
      name: "黎巴嫩",
      nameEn: "Lebanon",
      currencyCode: "LBP"
    },
    {
      code: "LT",
      name: "立陶宛",
      nameEn: "Lithuania",
      currencyCode: "EUR"
    },
    {
      code: "LR",
      name: "利比里亚",
      nameEn: "Liberia",
      currencyCode: "LRD"
    },
    {
      code: "LY",
      name: "利比亚",
      nameEn: "Libya",
      currencyCode: "LYD"
    },
    {
      code: "LI",
      name: "列支敦士登",
      nameEn: "Liechtenstein",
      currencyCode: "CHF"
    },
    {
      code: "RE",
      name: "留尼汪",
      nameEn: "Réunion",
      currencyCode: "EUR"
    },
    {
      code: "LU",
      name: "卢森堡",
      nameEn: "Luxembourg",
      currencyCode: "EUR"
    },
    {
      code: "RW",
      name: "卢旺达",
      nameEn: "Rwanda",
      currencyCode: "RWF"
    },
    {
      code: "RO",
      name: "罗马尼亚",
      nameEn: "Romania",
      currencyCode: "RON"
    },
    {
      code: "MG",
      name: "马达加斯加",
      nameEn: "Madagascar",
      currencyCode: "MGA"
    },
    {
      code: "IM",
      name: "马恩岛",
      nameEn: "Isle of Man",
      currencyCode: "GBP"
    },
    {
      code: "MV",
      name: "马尔代夫",
      nameEn: "Maldives",
      currencyCode: "MVR"
    },
    {
      code: "MT",
      name: "马耳他",
      nameEn: "Malta",
      currencyCode: "EUR"
    },
    {
      code: "MW",
      name: "马拉维",
      nameEn: "Malawi",
      currencyCode: "MWK"
    },
    {
      code: "MY",
      name: "马来西亚",
      nameEn: "Malaysia",
      currencyCode: "MYR"
    },
    {
      code: "ML",
      name: "马里",
      nameEn: "Mali",
      currencyCode: "XOF"
    },
    {
      code: "MH",
      name: "马绍尔群岛",
      nameEn: "Marshall Islands",
      currencyCode: "USD"
    },
    {
      code: "MQ",
      name: "马提尼克",
      nameEn: "Martinique",
      currencyCode: "EUR"
    },
    {
      code: "YT",
      name: "马约特",
      nameEn: "Mayotte",
      currencyCode: "EUR"
    },
    {
      code: "MU",
      name: "毛里求斯",
      nameEn: "Mauritius",
      currencyCode: "MUR"
    },
    {
      code: "MR",
      name: "毛里塔尼亚",
      nameEn: "Mauritania",
      currencyCode: "MRU"
    },
    {
      code: "US",
      name: "美国",
      nameEn: "United States of America",
      currencyCode: "USD"
    },
    {
      code: "AS",
      name: "美属萨摩亚",
      nameEn: "American Samoa",
      currencyCode: "USD"
    },
    {
      code: "VI",
      name: "美属维尔京群岛",
      nameEn: "Virgin Islands, U.S.",
      currencyCode: "USD"
    },
    {
      code: "MN",
      name: "蒙古",
      nameEn: "Mongolia",
      currencyCode: "MNT"
    },
    {
      code: "MS",
      name: "蒙特塞拉特",
      nameEn: "Montserrat",
      currencyCode: "XCD"
    },
    {
      code: "BD",
      name: "孟加拉国",
      nameEn: "Bangladesh",
      currencyCode: "BDT"
    },
    {
      code: "PE",
      name: "秘鲁",
      nameEn: "Peru",
      currencyCode: "PEN"
    },
    {
      code: "FM",
      name: "密克罗尼西亚联邦",
      nameEn: "Micronesia, Federated States of",
      currencyCode: "USD"
    },
    {
      code: "MM",
      name: "缅甸",
      nameEn: "Myanmar",
      currencyCode: "MMK"
    },
    {
      code: "MD",
      name: "摩尔多瓦",
      nameEn: "Moldova, Republic of",
      currencyCode: "MDL"
    },
    {
      code: "MA",
      name: "摩洛哥",
      nameEn: "Morocco",
      currencyCode: "MAD"
    },
    {
      code: "MC",
      name: "摩纳哥",
      nameEn: "Monaco",
      currencyCode: "EUR"
    },
    {
      code: "MZ",
      name: "莫桑比克",
      nameEn: "Mozambique",
      currencyCode: "MZN"
    },
    {
      code: "MX",
      name: "墨西哥",
      nameEn: "Mexico",
      currencyCode: "MXN"
    },
    {
      code: "NA",
      name: "纳米比亚",
      nameEn: "Namibia",
      currencyCode: "NAD"
    },
    {
      code: "ZA",
      name: "南非",
      nameEn: "South Africa",
      currencyCode: "ZAR"
    },
    {
      code: "GS",
      name: "南乔治亚和南桑威奇群岛",
      nameEn: "South Georgia and the South Sandwich Islands",
      currencyCode: "GBP"
    },
    {
      code: "SS",
      name: "南苏丹",
      nameEn: "South Sudan",
      currencyCode: "SSP"
    },
    {
      code: "NR",
      name: "瑙鲁",
      nameEn: "Nauru",
      currencyCode: "AUD"
    },
    {
      code: "NI",
      name: "尼加拉瓜",
      nameEn: "Nicaragua",
      currencyCode: "NIO"
    },
    {
      code: "NP",
      name: "尼泊尔",
      nameEn: "Nepal",
      currencyCode: "NPR"
    },
    {
      code: "NG",
      name: "尼日利亚",
      nameEn: "Nigeria",
      currencyCode: "NGN"
    },
    {
      code: "NU",
      name: "纽埃",
      nameEn: "Niue",
      currencyCode: "NZD"
    },
    {
      code: "NO",
      name: "挪威",
      nameEn: "Norway",
      currencyCode: "NOK"
    },
    {
      code: "NF",
      name: "诺福克岛",
      nameEn: "Norfolk Island",
      currencyCode: "AUD"
    },
    {
      code: "PW",
      name: "帕劳",
      nameEn: "Palau",
      currencyCode: "USD"
    },
    {
      code: "PN",
      name: "皮特凯恩群岛",
      nameEn: "Pitcairn",
      currencyCode: "NZD"
    },
    {
      code: "PT",
      name: "葡萄牙",
      nameEn: "Portugal",
      currencyCode: "EUR"
    },
    {
      code: "JP",
      name: "日本",
      nameEn: "Japan",
      currencyCode: "JPY"
    },
    {
      code: "SE",
      name: "瑞典",
      nameEn: "Sweden",
      currencyCode: "SEK"
    },
    {
      code: "CH",
      name: "瑞士",
      nameEn: "Switzerland",
      currencyCode: "CHF"
    },
    {
      code: "SV",
      name: "萨尔瓦多",
      nameEn: "El Salvador",
      currencyCode: "USD"
    },
    {
      code: "WS",
      name: "萨摩亚",
      nameEn: "Samoa",
      currencyCode: "WST"
    },
    {
      code: "RS",
      name: "塞尔维亚",
      nameEn: "Serbia",
      currencyCode: "RSD"
    },
    {
      code: "SL",
      name: "塞拉利昂",
      nameEn: "Sierra Leone",
      currencyCode: "SLL"
    },
    {
      code: "SN",
      name: "塞内加尔",
      nameEn: "Senegal",
      currencyCode: "XOF"
    },
    {
      code: "CY",
      name: "塞浦路斯",
      nameEn: "Cyprus",
      currencyCode: "EUR"
    },
    {
      code: "SC",
      name: "塞舌尔",
      nameEn: "Seychelles",
      currencyCode: "SCR"
    },
    {
      code: "SA",
      name: "沙特阿拉伯",
      nameEn: "Saudi Arabia",
      currencyCode: "SAR"
    },
    {
      code: "BL",
      name: "圣巴泰勒米",
      nameEn: "Saint Barthélemy",
      currencyCode: "EUR"
    },
    {
      code: "CX",
      name: "圣诞岛",
      nameEn: "Christmas Island",
      currencyCode: "AUD"
    },
    {
      code: "ST",
      name: "圣多美和普林西比",
      nameEn: "Sao Tome and Principe",
      currencyCode: "STN"
    },
    {
      code: "SH",
      name: "圣赫勒拿、阿森松和特里斯坦-达库尼亚",
      nameEn: "Saint Helena, Ascension and Tristan da Cunha",
      currencyCode: "SHP"
    },
    {
      code: "KN",
      name: "圣基茨和尼维斯",
      nameEn: "Saint Kitts and Nevis",
      currencyCode: "XCD"
    },
    {
      code: "LC",
      name: "圣卢西亚",
      nameEn: "Saint Lucia",
      currencyCode: "XCD"
    },
    {
      code: "SM",
      name: "圣马力诺",
      nameEn: "San Marino",
      currencyCode: "EUR"
    },
    {
      code: "PM",
      name: "圣皮埃尔和密克隆",
      nameEn: "Saint Pierre and Miquelon",
      currencyCode: "EUR"
    },
    {
      code: "VC",
      name: "圣文森特和格林纳丁斯",
      nameEn: "Saint Vincent and the Grenadines",
      currencyCode: "XCD"
    },
    {
      code: "LK",
      name: "斯里兰卡",
      nameEn: "Sri Lanka",
      currencyCode: "LKR"
    },
    {
      code: "SK",
      name: "斯洛伐克",
      nameEn: "Slovakia",
      currencyCode: "EUR"
    },
    {
      code: "SI",
      name: "斯洛文尼亚",
      nameEn: "Slovenia",
      currencyCode: "EUR"
    },
    {
      code: "SJ",
      name: "斯瓦尔巴和扬马延",
      nameEn: "Svalbard and Jan Mayen",
      currencyCode: "NOK"
    },
    {
      code: "SZ",
      name: "斯威士兰",
      nameEn: "Eswatini",
      currencyCode: "SZL"
    },
    {
      code: "SD",
      name: "苏丹",
      nameEn: "Sudan",
      currencyCode: "SDG"
    },
    {
      code: "SR",
      name: "苏里南",
      nameEn: "Suriname",
      currencyCode: "SRD"
    },
    {
      code: "SB",
      name: "所罗门群岛",
      nameEn: "Solomon Islands",
      currencyCode: "SBD"
    },
    {
      code: "SO",
      name: "索马里",
      nameEn: "Somalia",
      currencyCode: "SOS"
    },
    {
      code: "TJ",
      name: "塔吉克斯坦",
      nameEn: "Tajikistan",
      currencyCode: "TJS"
    },
    {
      code: "TH",
      name: "泰国",
      nameEn: "Thailand",
      currencyCode: "THB"
    },
    {
      code: "TZ",
      name: "坦桑尼亚",
      nameEn: "Tanzania, United Republic of",
      currencyCode: "TZS"
    },
    {
      code: "TO",
      name: "汤加",
      nameEn: "Tonga",
      currencyCode: "TOP"
    },
    {
      code: "TC",
      name: "特克斯和凯科斯群岛",
      nameEn: "Turks and Caicos Islands",
      currencyCode: "USD"
    },
    {
      code: "TT",
      name: "特立尼达和多巴哥",
      nameEn: "Trinidad and Tobago",
      currencyCode: "TTD"
    },
    {
      code: "TN",
      name: "突尼斯",
      nameEn: "Tunisia",
      currencyCode: "TND"
    },
    {
      code: "TV",
      name: "图瓦卢",
      nameEn: "Tuvalu",
      currencyCode: "AUD"
    },
    {
      code: "TR",
      name: "土耳其",
      nameEn: "Turkey",
      currencyCode: "TRY"
    },
    {
      code: "TM",
      name: "土库曼斯坦",
      nameEn: "Turkmenistan",
      currencyCode: "TMT"
    },
    {
      code: "TK",
      name: "托克劳",
      nameEn: "Tokelau",
      currencyCode: "NZD"
    },
    {
      code: "WF",
      name: "瓦利斯和富图纳",
      nameEn: "Wallis and Futuna",
      currencyCode: "XPF"
    },
    {
      code: "VU",
      name: "瓦努阿图",
      nameEn: "Vanuatu",
      currencyCode: "VUV"
    },
    {
      code: "GT",
      name: "危地马拉",
      nameEn: "Guatemala",
      currencyCode: "GTQ"
    },
    {
      code: "VE",
      name: "委内瑞拉",
      nameEn: "Venezuela, Bolivarian Republic of",
      currencyCode: "VES"
    },
    {
      code: "BN",
      name: "文莱",
      nameEn: "Brunei Darussalam",
      currencyCode: "BND"
    },
    {
      code: "UG",
      name: "乌干达",
      nameEn: "Uganda",
      currencyCode: "UGX"
    },
    {
      code: "UA",
      name: "乌克兰",
      nameEn: "Ukraine",
      currencyCode: "UAH"
    },
    {
      code: "UY",
      name: "乌拉圭",
      nameEn: "Uruguay",
      currencyCode: "UYU"
    },
    {
      code: "UZ",
      name: "乌兹别克斯坦",
      nameEn: "Uzbekistan",
      currencyCode: "UZS"
    },
    {
      code: "ES",
      name: "西班牙",
      nameEn: "Spain",
      currencyCode: "EUR"
    },
    {
      code: "GR",
      name: "希腊",
      nameEn: "Greece",
      currencyCode: "EUR"
    },
    {
      code: "SG",
      name: "新加坡",
      nameEn: "Singapore",
      currencyCode: "SGD"
    },
    {
      code: "NC",
      name: "新喀里多尼亚",
      nameEn: "New Caledonia",
      currencyCode: "XPF"
    },
    {
      code: "NZ",
      name: "新西兰",
      nameEn: "New Zealand",
      currencyCode: "NZD"
    },
    {
      code: "HU",
      name: "匈牙利",
      nameEn: "Hungary",
      currencyCode: "HUF"
    },
    {
      code: "SY",
      name: "叙利亚",
      nameEn: "Syrian Arab Republic",
      currencyCode: "SYP"
    },
    {
      code: "JM",
      name: "牙买加",
      nameEn: "Jamaica",
      currencyCode: "JMD"
    },
    {
      code: "AM",
      name: "亚美尼亚",
      nameEn: "Armenia",
      currencyCode: "AMD"
    },
    {
      code: "YE",
      name: "也门",
      nameEn: "Yemen",
      currencyCode: "YER"
    },
    {
      code: "IQ",
      name: "伊拉克",
      nameEn: "Iraq",
      currencyCode: "IQD"
    },
    {
      code: "IR",
      name: "伊朗",
      nameEn: "Iran, Islamic Republic of",
      currencyCode: "IRR"
    },
    {
      code: "IL",
      name: "以色列",
      nameEn: "Israel",
      currencyCode: "ILS"
    },
    {
      code: "IT",
      name: "意大利",
      nameEn: "Italy",
      currencyCode: "EUR"
    },
    {
      code: "IN",
      name: "印度",
      nameEn: "India",
      currencyCode: "INR"
    },
    {
      code: "ID",
      name: "印度尼西亚",
      nameEn: "Indonesia",
      currencyCode: "IDR"
    },
    {
      code: "GB",
      name: "英国",
      nameEn: "United Kingdom of Great Britain and Northern Ireland",
      currencyCode: "GBP"
    },
    {
      code: "VG",
      name: "英属维尔京群岛",
      nameEn: "Virgin Islands, British",
      currencyCode: "USD"
    },
    {
      code: "IO",
      name: "英属印度洋领地",
      nameEn: "British Indian Ocean Territory",
      currencyCode: "GBP"
    },
    {
      code: "IO",
      name: "英属印度洋领地",
      nameEn: "British Indian Ocean Territory",
      currencyCode: "USD"
    },
    {
      code: "JO",
      name: "约旦",
      nameEn: "Jordan",
      currencyCode: "JOD"
    },
    {
      code: "VN",
      name: "越南",
      nameEn: "Viet Nam",
      currencyCode: "VND"
    },
    {
      code: "ZM",
      name: "赞比亚",
      nameEn: "Zambia",
      currencyCode: "ZMW"
    },
    {
      code: "JE",
      name: "泽西",
      nameEn: "Jersey",
      currencyCode: "GBP"
    },
    {
      code: "TD",
      name: "乍得",
      nameEn: "Chad",
      currencyCode: "XAF"
    },
    {
      code: "GI",
      name: "直布罗陀",
      nameEn: "Gibraltar",
      currencyCode: "GIP"
    },
    {
      code: "CL",
      name: "智利",
      nameEn: "Chile",
      currencyCode: "CLF"
    },
    {
      code: "CL",
      name: "智利",
      nameEn: "Chile",
      currencyCode: "CLP"
    },
    {
      code: "CF",
      name: "中非",
      nameEn: "Central African Republic",
      currencyCode: "XAF"
    },
    {
      code: "CN",
      name: "中国",
      nameEn: "China",
      currencyCode: "CNY"
    },
    {
      code: "TW",
      name: "中国台湾",
      nameEn: "Taiwan, Province of China",
      currencyCode: "TWD"
    },
    {
      code: "HK",
      name: "中国香港",
      nameEn: "Hong Kong",
      currencyCode: "HKD"
    }
  ];
  const CountyCode2CountyInfo = new Map(countyCurrencyCodes.map((v) => [v.code, v]));
  new Map(countyCurrencyCodes.map((v) => [v.currencyCode, v]));
  const title = `[steam-price-convertor ${( new Date()).getMilliseconds()}] `;
  function format(format2, ...args) {
    args = args || [];
    let message = format2;
    for (let arg of args) {
      message = message.replace("%s", arg);
    }
    return title + message;
  }
  const _SettingManager = class {
    constructor() {
      __publicField(this, "setting");
      this.setting = this.loadSetting();
    }
    loadSetting() {
      const json = _GM_getValue(STORAGE_KEY_SETTING, new Setting().toJsonString());
      const setting = new Setting().readJsonString(json);
      console.log(format("读取设置"), setting);
      return setting;
    }
    /**
     * 保存设置
     * @param setting  设置
     */
    saveSetting(setting) {
      console.log(format("保存设置"), setting);
      _GM_setValue(STORAGE_KEY_SETTING, setting.toJsonString());
    }
    setCountyCode(countyCode) {
      const county = CountyCode2CountyInfo.get(countyCode);
      if (!county) {
        throw Error(`国家代码不存在:${countyCode}`);
      }
      this.setting.countyCode = countyCode;
      this.saveSetting(this.setting);
    }
    setCurrencySymbol(currencySymbol) {
      this.setting.currencySymbol = currencySymbol;
      this.saveSetting(this.setting);
    }
    setCurrencySymbolBeforeValue(isCurrencySymbolBeforeValue) {
      this.setting.currencySymbolBeforeValue = isCurrencySymbolBeforeValue;
      this.saveSetting(this.setting);
    }
    reset() {
      this.saveSetting(new Setting());
    }
    setRateCacheExpired(rateCacheExpired) {
      this.setting.rateCacheExpired = rateCacheExpired;
      this.saveSetting(this.setting);
    }
    setUseCustomRate(isUseCustomRate) {
      this.setting.useCustomRate = isUseCustomRate;
      this.saveSetting(this.setting);
    }
    setCustomRate(customRate) {
      this.setting.customRate = customRate;
      this.saveSetting(this.setting);
    }
  };
  let SettingManager = _SettingManager;
  __publicField(SettingManager, "instance", new _SettingManager());
  function parsePrice(content) {
    const matches = content.match(new RegExp("(?<=^\\D*)\\d+[\\d,.\\s]*?(?=\\D*$)"));
    if (!matches) {
      throw Error("提取价格失败:content:" + content);
    }
    let priceStr = matches[0].replaceAll(/\D/g, "");
    let price = Number.parseInt(priceStr);
    if (matches[0].match(/\D\d\d$/)) {
      price = price / 100;
    }
    return price;
  }
  function convertPrice(price, rate) {
    return Number.parseFloat((price / rate).toFixed(2));
  }
  function convertPriceContent(originalContent, rate) {
    const safeContent = originalContent.trim().replaceAll(/\(.+$/g, "").trim();
    const price = parsePrice(safeContent);
    const convertedPrice = convertPrice(price, rate);
    const setting = SettingManager.instance.setting;
    let finalContent;
    if (setting.currencySymbolBeforeValue) {
      finalContent = `${safeContent}(${setting.currencySymbol}${convertedPrice})`;
    } else {
      finalContent = `${safeContent}(${convertedPrice}${setting.currencySymbol})`;
    }
    console.debug(format(
      "转换前文本:%s; 提取到的价格:%s; 转换后的价格:%s; 转换后文本:%s",
      safeContent,
      price,
      convertedPrice,
      finalContent
    ));
    return finalContent;
  }
  class ElementConverter extends AbstractConverter {
    getCssSelectors() {
      return [
        // 商店
        // 首页
        ".discount_original_price",
        ".discount_final_price",
        ".col.search_price.responsive_secondrow strike",
        // 头像旁边
        "#header_wallet_balance > span.tooltip",
        // 愿望单总价值
        ".esi-wishlist-stat > .num",
        // // 新版卡片
        ".salepreviewwidgets_StoreOriginalPrice_1EKGZ",
        ".salepreviewwidgets_StoreSalePriceBox_Wh0L8",
        // 分类查看游戏
        ".contenthubshared_OriginalPrice_3hBh3",
        ".contenthubshared_FinalPrice_F_tGv",
        ".salepreviewwidgets_StoreSalePriceBox_Wh0L8:not(.salepreviewwidgets_StoreSalePrepurchaseLabel_Wxeyn)",
        // 购物车
        ".cart_item_price.with_discount > .original_price",
        ".cart_item_price.with_discount > div.price:not(.original_price)",
        "#cart_estimated_total",
        // 购物车 复核
        ".checkout_review_item_price > .price",
        "#review_subtotal_value.price",
        "#review_total_value.price",
        ".cart_item_price > .price",
        // 市场
        // 总余额
        "#marketWalletBalanceAmount",
        // 列表
        "span.normal_price[data-price]",
        "span.sale_price",
        // 求购、求售统计
        ".market_commodity_orders_header_promote:nth-child(even)",
        // 求购、求售列表
        ".market_commodity_orders_table td:nth-child(odd)",
        // 详情列表
        ".market_table_value > span",
        ".jqplot-highlighter-tooltip",
        // 消费记录
        "tr.wallet_table_row > td.wht_total",
        "tr.wallet_table_row > td.wht_wallet_change.wallet_column",
        "tr.wallet_table_row > td.wht_wallet_balance.wallet_column",
        // dlc
        ".game_area_dlc_row > .game_area_dlc_price",
        // 捆绑包
        ".package_totals_row > .price:not(.bundle_discount)",
        "#package_savings_bar > .savings.bundle_savings",
        // 低于xxx 分类标题
        ".home_page_content_title a.btn_small_tall > span"
      ];
    }
    convert(elementSnap, rate) {
      elementSnap.element.textContent = convertPriceContent(elementSnap.textContext, rate);
      return true;
    }
  }
  class TextNodeConverter extends AbstractConverter {
    constructor() {
      super(...arguments);
      // @ts-ignore
      __publicField(this, "parseFirstChildTextNodeFn", (el) => el.firstChild);
      // @ts-ignore
      __publicField(this, "targets", /* @__PURE__ */ new Map([
        [
          ".col.search_price.responsive_secondrow",
          [
            // @ts-ignore
            (el) => el.firstChild.nextSibling.nextSibling.nextSibling,
            this.parseFirstChildTextNodeFn
          ]
        ],
        ["#header_wallet_balance", [this.parseFirstChildTextNodeFn]],
        // iframe
        [".game_purchase_price.price", [this.parseFirstChildTextNodeFn]],
        // 低于xxx 分类标题
        [".home_page_content_title", [this.parseFirstChildTextNodeFn]]
      ]));
    }
    getCssSelectors() {
      return [...this.targets.keys()];
    }
    convert(elementSnap, rate) {
      const selector = elementSnap.selector;
      this.targets.get(selector);
      const parseNodeFns = this.targets.get(selector);
      if (!parseNodeFns) {
        return false;
      }
      const textNode = this.safeParseNode(selector, elementSnap.element, parseNodeFns);
      if (!textNode) {
        return false;
      }
      const content = textNode.nodeValue;
      if (!content || content.trim().length === 0) {
        return false;
      }
      textNode.nodeValue = convertPriceContent(content, rate);
      return true;
    }
    safeParseNode(selector, el, fns) {
      for (let fn of fns) {
        try {
          const node = fn(el);
          if (node.nodeName === "#text" && node.nodeValue && node.nodeValue.length > 0) {
            return node;
          }
        } catch (e) {
          console.debug("获取文本节点失败,但不确定该节点是否一定会出现。selector:" + selector);
        }
      }
      return null;
    }
  }
  const _ConverterManager = class {
    constructor() {
      __publicField(this, "converters");
      this.converters = [
        new ElementConverter(),
        new TextNodeConverter()
      ];
    }
    getSelector() {
      return this.converters.map((exchanger) => exchanger.getCssSelectors()).flat(1).join(", ");
    }
    convert(elements, rate) {
      if (!elements) {
        return;
      }
      elements.forEach((element) => {
        const elementSnap = {
          element,
          textContext: element.textContent,
          classList: element.classList,
          attributes: element.attributes
        };
        this.converters.filter((converter) => converter.match(elementSnap)).forEach((converter) => {
          try {
            const exchanged = converter.convert(elementSnap, rate);
            if (exchanged) {
              converter.afterConvert(elementSnap);
            }
          } catch (e) {
            console.group("转换失败");
            console.error(e);
            console.error("转换失败请将下列内容反馈给开发者,右键 > 复制(copy) > 复制元素(copy element)");
            console.error("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓");
            console.error(element);
            console.error("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑");
            console.groupEnd();
          }
        });
      });
    }
  };
  let ConverterManager = _ConverterManager;
  __publicField(ConverterManager, "instance", new _ConverterManager());
  var __defProp$1 = Object.defineProperty;
  var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
  var __decorateClass$1 = (decorators, target, key, kind) => {
    var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
    for (var i = decorators.length - 1, decorator; i >= 0; i--)
      if (decorator = decorators[i])
        result = (kind ? decorator(target, key, result) : decorator(result)) || result;
    if (kind && result)
      __defProp$1(target, key, result);
    return result;
  };
  class RateCache extends Serializable {
    constructor(from, to, rate, createdAt) {
      super();
      __publicField(this, "from");
      __publicField(this, "to");
      __publicField(this, "createdAt");
      __publicField(this, "rate");
      this.from = from;
      this.to = to;
      this.createdAt = createdAt || 0;
      this.rate = rate || 0;
    }
  }
  __decorateClass$1([
    JsonProperty()
  ], RateCache.prototype, "from", 2);
  __decorateClass$1([
    JsonProperty()
  ], RateCache.prototype, "to", 2);
  __decorateClass$1([
    JsonProperty()
  ], RateCache.prototype, "createdAt", 2);
  __decorateClass$1([
    JsonProperty()
  ], RateCache.prototype, "rate", 2);
  class RateCaches extends Serializable {
    constructor() {
      super(...arguments);
      __publicField(this, "caches", /* @__PURE__ */ new Map());
    }
    getCache(from, to) {
      return this.caches.get(this.buildCacheKey(from, to));
    }
    setCache(cache) {
      this.caches.set(this.buildCacheKey(cache.from, cache.to), cache);
    }
    buildCacheKey(from, to) {
      return `${from}:${to}`;
    }
  }
  __decorateClass$1([
    JsonProperty({ typeAs: Map })
  ], RateCaches.prototype, "caches", 2);
  class Http {
    static get(url, respType, details) {
      if (!details) {
        details = { url };
      }
      details.method = "GET";
      return this.request(details, respType);
    }
    static post(url, respType, details) {
      if (!details) {
        details = { url };
      }
      details.method = "POST";
      return this.request(details, respType);
    }
    static parseResponse(response, respType) {
      const data = JSON.parse(response.response);
      const res = new respType();
      return res.readJson(data);
    }
    static request(details, respType) {
      return new Promise((resolve, reject) => {
        details.onload = (response) => resolve(this.parseResponse(response, respType));
        details.onerror = (error) => reject(error);
        _GM_xmlhttpRequest(details);
      });
    }
  }
  var __defProp2 = Object.defineProperty;
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  var __decorateClass = (decorators, target, key, kind) => {
    var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
    for (var i = decorators.length - 1, decorator; i >= 0; i--)
      if (decorator = decorators[i])
        result = (kind ? decorator(target, key, result) : decorator(result)) || result;
    if (kind && result)
      __defProp2(target, key, result);
    return result;
  };
  class AugmentedSteamRateResponse extends Serializable {
    constructor() {
      super(...arguments);
      __publicField(this, "result");
      __publicField(this, "data");
    }
  }
  __decorateClass([
    JsonAlias()
  ], AugmentedSteamRateResponse.prototype, "result", 2);
  __decorateClass([
    JsonProperty({
      typeAs: Map,
      mapValue: true
    })
  ], AugmentedSteamRateResponse.prototype, "data", 2);
  class AugmentedSteamRateApi {
    getName() {
      return "AugmentedSteamRateApi";
    }
    async getRate(currCounty, targetCounty) {
      console.info(format(
        "通过 AugmentedSteam 获取汇率 %s(%s) -> %s(%s)...",
        currCounty.currencyCode,
        currCounty.name,
        targetCounty.currencyCode,
        targetCounty.name
      ));
      const url = `https://api.augmentedsteam.com/v01/rates/?to=${currCounty.currencyCode}`;
      let rate = await Http.get(url, AugmentedSteamRateResponse).then((res) => {
        var _a, _b;
        if ("success" !== (res == null ? void 0 : res.result)) {
          return null;
        }
        return (_b = (_a = res.data) == null ? void 0 : _a.get(targetCounty.currencyCode)) == null ? void 0 : _b.get(currCounty.currencyCode);
      }).catch((err) => console.log(format("通过 AugmentedSteam 获取汇率失败:%s", err)));
      if (rate) {
        return rate;
      }
      throw new Error(`通过 ${this.getName()} 获取汇率失败。`);
    }
  }
  const _RateManager = class {
    constructor() {
      __publicField(this, "rateApis");
      __publicField(this, "rateCaches");
      this.rateApis = [
        new AugmentedSteamRateApi()
      ];
      this.rateCaches = this.loadRateCache();
    }
    getName() {
      return "RateManager";
    }
    async getRate4Remote(currCounty, targetCounty) {
      console.log(format("远程获取汇率..."));
      let rate;
      for (let rateApi of this.rateApis) {
        try {
          rate = await rateApi.getRate(currCounty, targetCounty);
        } catch (e) {
          console.error(`使用实现(${rateApi.getName()})获取汇率失败`);
        }
        if (rate) {
          return rate;
        }
      }
      throw Error("所有汇率获取实现获取汇率均失败");
    }
    async getRate(currCounty, targetCounty) {
      const setting = SettingManager.instance.setting;
      if (setting.useCustomRate) {
        console.log("使用自定义汇率");
        return setting.customRate;
      }
      let cache = this.rateCaches.getCache(currCounty.code, targetCounty.code);
      const now = (/* @__PURE__ */ new Date()).getTime();
      const expired = setting.rateCacheExpired;
      if (!cache || !cache.rate || now > cache.createdAt + expired) {
        console.info(format(`本地缓存已过期`));
        cache = new RateCache(currCounty.code, targetCounty.code);
        cache.rate = await this.getRate4Remote(currCounty, targetCounty);
        cache.createdAt = (/* @__PURE__ */ new Date()).getTime();
        this.rateCaches.setCache(cache);
        this.saveRateCache();
      }
      return cache.rate;
    }
    loadRateCache() {
      const jsonString = _GM_getValue(STORAGE_KEY_RATE_CACHES, "{}");
      const caches = new RateCaches();
      console.info(format(`读取汇率缓存`));
      return caches.readJsonString(jsonString);
    }
    saveRateCache() {
      console.info(format("保存汇率缓存"), this.rateCaches);
      _GM_setValue(STORAGE_KEY_RATE_CACHES, this.rateCaches.toJsonString());
    }
    clear() {
      _GM_deleteValue(STORAGE_KEY_RATE_CACHES);
    }
  };
  let RateManager = _RateManager;
  __publicField(RateManager, "instance", new _RateManager());
  class CookieCountyInfoGetter {
    match() {
      return true;
    }
    async getCountyCode() {
      console.info(format("通过 cookie 获取区域代码..."));
      let code;
      await new Promise((resolve) => _GM_cookie.list({ name: "steamCountry" }, (cookies) => {
        if (cookies && cookies.length > 0) {
          const match = cookies[0].value.match(/^[a-zA-Z][a-zA-Z]/);
          if (match) {
            code = match[0];
            resolve(code);
          }
        }
      })).then((res) => code = res);
      if (code) {
        console.info(format("通过 cookie 获取区域代码成功:" + code));
        return code;
      }
      throw Error("通过 cookie 获取区域代码失败。");
    }
  }
  class RequestStorePageCountyCodeGetter {
    match() {
      return !window.location.href.includes("store.steampowered.com");
    }
    async getCountyCode() {
      console.info(format("通过 请求商店页面 获取区域代码..."));
      let countyCode = void 0;
      await new Promise((resolve) => _GM_xmlhttpRequest({
        url: "https://store.steampowered.com/",
        onload: (response) => resolve(response.responseText)
      })).then((res) => {
        const match = res.match(new RegExp("(?<=GDynamicStore.Init\\(.+')[A-Z][A-Z](?=',)"));
        if (match) {
          countyCode = match[0];
          console.info(format("通过 请求商店页面 获取区域代码成功:" + countyCode));
        }
      });
      if (countyCode) {
        return countyCode;
      }
      throw Error("通过 请求商店页面 获取区域代码失败。");
    }
  }
  class StorePageCountyCodeGetter {
    match() {
      return window.location.href.includes("store.steampowered.com");
    }
    getCountyCode() {
      console.info(format("通过 商店页面 获取区域代码..."));
      return new Promise((resolve) => {
        document.querySelectorAll("script").forEach((scriptEl) => {
          const scriptInnerText = scriptEl.innerText;
          if (scriptInnerText.includes("$J( InitMiniprofileHovers );") || scriptInnerText.includes(`$J( InitMiniprofileHovers( 'https%3A%2F%2Fstore.steampowered.com%2F' ) );`)) {
            const matcher = new RegExp("(?<=')[A-Z]{2}(?!=')", "g");
            const match = scriptInnerText.match(matcher);
            if (match) {
              const countyCode = match.toString();
              console.info(format("通过 商店页面 获取区域代码成功:" + countyCode));
              resolve(countyCode);
            }
          }
        });
        throw Error(format("通过 商店页面 获取区域代码失败。"));
      });
    }
  }
  class MarketPageCountyCodeGetter {
    match() {
      return window.location.href.includes("steamcommunity.com");
    }
    getCountyCode() {
      console.info(format("通过 市场页面 获取区域代码..."));
      const code = g_strCountryCode;
      if (code) {
        return new Promise((resolve) => resolve(code));
      }
      throw Error(format("通过 市场页面 获取区域代码失败。"));
    }
  }
  const _CountyCodeGetterManager = class {
    constructor() {
      __publicField(this, "getters");
      this.getters = [
        new StorePageCountyCodeGetter(),
        new MarketPageCountyCodeGetter(),
        new RequestStorePageCountyCodeGetter(),
        new CookieCountyInfoGetter()
      ];
    }
    match() {
      return true;
    }
    async getCountyCode() {
      console.info(format("获取区域代码..."));
      let code;
      for (let getter of this.getters) {
        if (getter.match()) {
          try {
            code = await getter.getCountyCode();
          } catch (e) {
            console.error(e);
          }
        }
        if (code) {
          return code;
        }
      }
      throw new Error(format("获取区域代码失败。"));
    }
  };
  let CountyCodeGetterManager = _CountyCodeGetterManager;
  __publicField(CountyCodeGetterManager, "instance", new _CountyCodeGetterManager());
  const _SpcManager = class {
    constructor() {
    }
    setCountyCode(code) {
      SettingManager.instance.setCountyCode(code);
    }
    setCurrencySymbol(symbol) {
      SettingManager.instance.setCurrencySymbol(symbol);
    }
    setCurrencySymbolBeforeValue(isCurrencySymbolBeforeValue) {
      SettingManager.instance.setCurrencySymbolBeforeValue(isCurrencySymbolBeforeValue);
    }
    setRateCacheExpired(expired) {
      SettingManager.instance.setRateCacheExpired(expired);
    }
    resetSetting() {
      SettingManager.instance.reset();
    }
    clearCache() {
      RateManager.instance.clear();
    }
    setUseCustomRate(isUseCustomRate) {
      SettingManager.instance.setUseCustomRate(isUseCustomRate);
    }
    setCustomRate(customRate) {
      SettingManager.instance.setCustomRate(customRate);
    }
  };
  let SpcManager = _SpcManager;
  __publicField(SpcManager, "instance", new _SpcManager());
  async function main(targetCounty) {
    _unsafeWindow.SpcManager = SpcManager.instance;
    let countyCode = await CountyCodeGetterManager.instance.getCountyCode();
    if (targetCounty.code === countyCode) {
      console.info(format(`${targetCounty.name}无需转换`));
      return;
    }
    const currCounty = CountyCode2CountyInfo.get(countyCode);
    if (!currCounty) {
      throw Error("获取货币代码失败");
    }
    console.info(format("获取区域对应信息:"), currCounty);
    const rate = await RateManager.instance.getRate(currCounty, targetCounty);
    if (!rate) {
      throw Error("获取汇率失败");
    }
    console.info(format(`汇率 ${currCounty.currencyCode} -> ${targetCounty.currencyCode}:${rate}`));
    await convert(rate);
  }
  async function convert(rate) {
    const exchangerManager = ConverterManager.instance;
    const elements = document.querySelectorAll(exchangerManager.getSelector());
    exchangerManager.convert(elements, rate);
    const selector = exchangerManager.getSelector();
    const priceObserver = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        const target = mutation.target;
        const priceEls = target.querySelectorAll(selector);
        if (!priceEls || priceEls.length === 0) {
          return;
        }
        exchangerManager.convert(priceEls, rate);
      });
    });
    priceObserver.observe(document.body, {
      childList: true,
      subtree: true
    });
  }
  function addCdnCss(urls) {
    urls.forEach((url) => {
      const linkEl = document.createElement("link");
      linkEl.href = url;
      linkEl.type = "text/css";
      linkEl.rel = "stylesheet";
      document.head.append(linkEl);
    });
  }
  const _hoisted_1 = { class: "mdui-theme-primary-indigo mdui-theme-accent-indigo" };
  const _hoisted_2 = { class: "mdui-container" };
  const _hoisted_3 = {
    class: "mdui-dialog",
    id: "spc-dialog-menu"
  };
  const _hoisted_4 = /* @__PURE__ */ vue.createElementVNode("div", { class: "mdui-dialog-title" }, "Setting", -1);
  const _hoisted_5 = { class: "mdui-dialog-content" };
  const _hoisted_6 = { class: "mdui-list" };
  const _hoisted_7 = { class: "mdui-list-item mdui-ripple" };
  const _hoisted_8 = /* @__PURE__ */ vue.createElementVNode("i", { class: "mdui-list-item-icon mdui-icon material-icons" }, "", -1);
  const _hoisted_9 = /* @__PURE__ */ vue.createElementVNode("div", { class: "mdui-list-item-content" }, "目标区域", -1);
  const _hoisted_10 = ["value", "selected"];
  const _hoisted_11 = { class: "mdui-list-item mdui-ripple" };
  const _hoisted_12 = /* @__PURE__ */ vue.createElementVNode("i", { class: "mdui-list-item-icon mdui-icon material-icons" }, "", -1);
  const _hoisted_13 = /* @__PURE__ */ vue.createElementVNode("div", { class: "mdui-list-item-content" }, "货币符号", -1);
  const _hoisted_14 = {
    class: "mdui-textfield",
    style: { "width": "40px" }
  };
  const _hoisted_15 = { class: "mdui-list-item mdui-ripple" };
  const _hoisted_16 = /* @__PURE__ */ vue.createElementVNode("i", { class: "mdui-list-item-icon mdui-icon material-icons" }, "", -1);
  const _hoisted_17 = /* @__PURE__ */ vue.createElementVNode("div", { class: "mdui-list-item-content" }, "货币符号是否在价格之前", -1);
  const _hoisted_18 = { class: "mdui-switch" };
  const _hoisted_19 = /* @__PURE__ */ vue.createElementVNode("i", { class: "mdui-switch-icon" }, null, -1);
  const _hoisted_20 = { class: "mdui-list-item mdui-ripple" };
  const _hoisted_21 = /* @__PURE__ */ vue.createElementVNode("i", { class: "mdui-list-item-icon mdui-icon material-icons" }, "", -1);
  const _hoisted_22 = /* @__PURE__ */ vue.createElementVNode("div", { class: "mdui-list-item-content" }, "使用自定义汇率", -1);
  const _hoisted_23 = { class: "mdui-switch" };
  const _hoisted_24 = /* @__PURE__ */ vue.createElementVNode("i", { class: "mdui-switch-icon" }, null, -1);
  const _hoisted_25 = {
    key: 0,
    class: "mdui-list-item mdui-ripple"
  };
  const _hoisted_26 = /* @__PURE__ */ vue.createElementVNode("i", { class: "mdui-list-item-icon mdui-icon material-icons" }, "", -1);
  const _hoisted_27 = /* @__PURE__ */ vue.createElementVNode("div", { class: "mdui-list-item-content" }, "自定义汇率", -1);
  const _hoisted_28 = {
    class: "mdui-textfield",
    style: { "width": "40px" }
  };
  const _hoisted_29 = {
    key: 1,
    class: "mdui-list-item mdui-ripple"
  };
  const _hoisted_30 = /* @__PURE__ */ vue.createElementVNode("i", { class: "mdui-list-item-icon mdui-icon material-icons" }, "", -1);
  const _hoisted_31 = /* @__PURE__ */ vue.createElementVNode("div", { class: "mdui-list-item-content" }, "汇率缓存时间(小时)", -1);
  const _hoisted_32 = {
    class: "mdui-textfield",
    style: { "width": "40px" }
  };
  const _hoisted_33 = /* @__PURE__ */ vue.createElementVNode("div", { class: "mdui-dialog-actions" }, [
    /* @__PURE__ */ vue.createElementVNode("button", {
      class: "mdui-btn mdui-ripple",
      onclick: "location.reload()"
    }, "关闭并刷新"),
    /* @__PURE__ */ vue.createElementVNode("button", {
      class: "mdui-btn mdui-ripple",
      "mdui-dialog-close": ""
    }, "关闭")
  ], -1);
  const _sfc_main = /* @__PURE__ */ vue.defineComponent({
    __name: "App",
    setup(__props) {
      vue.onMounted(() => {
        const menu = new mdui.Dialog("#spc-dialog-menu");
        _GM_addValueChangeListener(IM_KEY_MENU_STATUS, (name, oldValue, newValue) => {
          if (IM_KEY_OPEN_MENU !== newValue) {
            return;
          }
          _GM_setValue(IM_KEY_MENU_STATUS, IM_KEY_CLOSE_MENU);
          menu.open();
        });
      });
      const settingManager = SettingManager.instance;
      const countyInfos = vue.reactive(countyCurrencyCodes);
      const countySelectStyle = vue.reactive(initCountySelectStyle());
      const setting = vue.reactive({
        countyCode: settingManager.setting.countyCode,
        currencySymbol: settingManager.setting.currencySymbol,
        currencySymbolBeforeValue: settingManager.setting.currencySymbolBeforeValue,
        rateCacheExpired: settingManager.setting.rateCacheExpired / (60 * 60 * 1e3),
        customRate: settingManager.setting.customRate,
        useCustomRate: settingManager.setting.useCustomRate
      });
      vue.watch(setting, (newSetting) => {
        settingManager.setting.readJson(newSetting);
        settingManager.setting.rateCacheExpired *= 60 * 60 * 1e3;
        settingManager.saveSetting(settingManager.setting);
      });
      function initCountySelectStyle() {
        const countyInfo = CountyCode2CountyInfo.get(settingManager.setting.countyCode);
        return {
          width: `${countyInfo.name.length * 16 + 25}px`
        };
      }
      function changeCounty(code) {
        const countyInfo = CountyCode2CountyInfo.get(code);
        countySelectStyle.width = `${countyInfo.name.length * 16 + 25}px`;
        setting.countyCode = countyInfo.code;
      }
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
          vue.createElementVNode("div", _hoisted_2, [
            vue.createElementVNode("div", _hoisted_3, [
              _hoisted_4,
              vue.createElementVNode("div", _hoisted_5, [
                vue.createElementVNode("div", _hoisted_6, [
                  vue.createElementVNode("li", _hoisted_7, [
                    _hoisted_8,
                    _hoisted_9,
                    vue.createElementVNode("select", {
                      class: "mdui-select",
                      style: vue.normalizeStyle(countySelectStyle),
                      onChange: _cache[0] || (_cache[0] = ($event) => (
                        // @ts-ignore
                        changeCounty($event.target.value)
                      ))
                    }, [
                      (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(countyInfos, (countyInfo) => {
                        return vue.openBlock(), vue.createElementBlock("option", {
                          value: countyInfo.code,
                          selected: countyInfo.code === setting.countyCode
                        }, vue.toDisplayString(countyInfo.name), 9, _hoisted_10);
                      }), 256))
                    ], 36)
                  ]),
                  vue.createElementVNode("li", _hoisted_11, [
                    _hoisted_12,
                    _hoisted_13,
                    vue.createElementVNode("label", _hoisted_14, [
                      vue.withDirectives(vue.createElementVNode("input", {
                        class: "mdui-textfield-input",
                        type: "text",
                        "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => setting.currencySymbol = $event)
                      }, null, 512), [
                        [vue.vModelText, setting.currencySymbol]
                      ])
                    ])
                  ]),
                  vue.createElementVNode("li", _hoisted_15, [
                    _hoisted_16,
                    _hoisted_17,
                    vue.createElementVNode("label", _hoisted_18, [
                      vue.withDirectives(vue.createElementVNode("input", {
                        type: "checkbox",
                        "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => setting.currencySymbolBeforeValue = $event),
                        onChange: _cache[3] || (_cache[3] = ($event) => (
                          // @ts-ignore
                          setting.currencySymbolBeforeValue = $event.target.checked
                        ))
                      }, null, 544), [
                        [vue.vModelCheckbox, setting.currencySymbolBeforeValue]
                      ]),
                      _hoisted_19
                    ])
                  ]),
                  vue.createElementVNode("li", _hoisted_20, [
                    _hoisted_21,
                    _hoisted_22,
                    vue.createElementVNode("label", _hoisted_23, [
                      vue.withDirectives(vue.createElementVNode("input", {
                        type: "checkbox",
                        "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => setting.useCustomRate = $event)
                      }, null, 512), [
                        [vue.vModelCheckbox, setting.useCustomRate]
                      ]),
                      _hoisted_24
                    ])
                  ]),
                  setting.useCustomRate ? (vue.openBlock(), vue.createElementBlock("li", _hoisted_25, [
                    _hoisted_26,
                    _hoisted_27,
                    vue.createElementVNode("label", _hoisted_28, [
                      vue.withDirectives(vue.createElementVNode("input", {
                        class: "mdui-textfield-input",
                        type: "number",
                        "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => setting.customRate = $event)
                      }, null, 512), [
                        [vue.vModelText, setting.customRate]
                      ])
                    ])
                  ])) : vue.createCommentVNode("", true),
                  !setting.useCustomRate ? (vue.openBlock(), vue.createElementBlock("li", _hoisted_29, [
                    _hoisted_30,
                    _hoisted_31,
                    vue.createElementVNode("label", _hoisted_32, [
                      vue.withDirectives(vue.createElementVNode("input", {
                        class: "mdui-textfield-input",
                        type: "number",
                        "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => setting.rateCacheExpired = $event)
                      }, null, 512), [
                        [vue.vModelText, setting.rateCacheExpired]
                      ])
                    ])
                  ])) : vue.createCommentVNode("", true)
                ])
              ]),
              _hoisted_33
            ])
          ])
        ]);
      };
    }
  });
  (async () => {
    if (window.location.href.match("store.steampowered.com")) {
      initCdn();
      initApp();
      initMenu();
    }
    await doConvert();
  })();
  function initCdn() {
    addCdnCss([
      "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/mdui.min.css",
      "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/ionicons.min.css"
    ]);
  }
  function initApp() {
    vue.createApp(_sfc_main).mount(
      (() => {
        const app = document.createElement("div");
        app.setAttribute("id", "spc-menu");
        document.body.append(app);
        return app;
      })()
    );
    mdui.mutation();
  }
  async function doConvert() {
    const countyCode = SettingManager.instance.setting.countyCode;
    const county = CountyCode2CountyInfo.get(countyCode);
    if (!county) {
      throw Error("获取转换后的国家信息失败,国家代码:" + countyCode);
    }
    await main(county);
  }
  function initMenu() {
    _GM_setValue(IM_KEY_MENU_STATUS, IM_KEY_CLOSE_MENU);
    _GM_registerMenuCommand("设置", () => {
      _GM_setValue(IM_KEY_MENU_STATUS, IM_KEY_OPEN_MENU);
    });
  }

})(Reflect, Vue, mdui);