🐭️ MouseHunt - Minluck & Catch Rate Estimate

View the minluck and catch rate estimate, right on the camp page.

目前为 2024-03-26 提交的版本。查看 最新版本

// ==UserScript==
// @name        🐭️ MouseHunt - Minluck & Catch Rate Estimate
// @description View the minluck and catch rate estimate, right on the camp page.
// @version     2.0.1
// @license     MIT
// @author      bradp
// @namespace   bradp
// @match       https://www.mousehuntgame.com/*
// @icon        https://i.mouse.rip/mh-improved/icon-64.png
// @run-at      document-end
// @grant       none
// @require     https://cdn.jsdelivr.net/npm/[email protected]
// ==/UserScript==

var mhui = (() => {
  var __defProp = Object.defineProperty;
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  var __getOwnPropNames = Object.getOwnPropertyNames;
  var __hasOwnProp = Object.prototype.hasOwnProperty;
  var __export = (target, all) => {
    for (var name in all)
      __defProp(target, name, { get: all[name], enumerable: true });
  };
  var __copyProps = (to, from, except, desc) => {
    if (from && typeof from === "object" || typeof from === "function") {
      for (let key of __getOwnPropNames(from))
        if (!__hasOwnProp.call(to, key) && key !== except)
          __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
    }
    return to;
  };
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  var __async = (__this, __arguments, generator) => {
    return new Promise((resolve, reject) => {
      var fulfilled = (value) => {
        try {
          step(generator.next(value));
        } catch (e) {
          reject(e);
        }
      };
      var rejected = (value) => {
        try {
          step(generator.throw(value));
        } catch (e) {
          reject(e);
        }
      };
      var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
      step((generator = generator.apply(__this, __arguments)).next());
    });
  };

  // src/modules/catch-rate-estimate/index.js
  var catch_rate_estimate_exports = {};
  __export(catch_rate_estimate_exports, {
    default: () => catch_rate_estimate_default
  });

  // src/utils/event-registry.js
  var doEvent2 = (eventName, params) => {
    if (!eventRegistry) {
      return;
    }
    eventRegistry.doEvent(eventName, params);
  };
  var onEvent = (event, callback, remove = false) => {
    if (!eventRegistry) {
      return;
    }
    eventRegistry.addEventListener(event, callback, null, remove);
  };

  // src/utils/styles.js
  var addModuleStyles = (styles, identifier = "mh-improved-styles", replace = false) => {
    const existingStyles = document.querySelector(`#${identifier}`);
    styles = Array.isArray(styles) ? styles.join("\n") : styles;
    if (existingStyles) {
      if (replace) {
        existingStyles.innerHTML = styles;
      } else {
        existingStyles.innerHTML += styles;
      }
      return existingStyles;
    }
    const style = document.createElement("style");
    style.id = identifier;
    style.innerHTML = styles;
    document.head.append(style);
    return style;
  };
  var addStyles = (styles, module = false, identifier = "mh-improved-styles") => {
    if (!module) {
      throw new Error("Module ID is required for adding module styles.", module);
    }
    const key = `${identifier}-${module}`;
    let stylesEl = addModuleStyles(styles, key, true);
    onEvent(`mh-improved-settings-changed-${module}`, (enabled) => {
      if (enabled) {
        stylesEl = addModuleStyles(styles, key, true);
      } else if (stylesEl) {
        stylesEl.remove();
      }
    });
  };

  // src/utils/settings.js
  var getSettingDirect = (key = null, defaultValue = null, identifier = "mousehunt-improved-settings") => {
    const settings = JSON.parse(localStorage.getItem(identifier)) || {};
    if (!key) {
      return settings;
    }
    if (!key.includes(".")) {
      if (settings[key] === void 0) {
        return defaultValue;
      }
      return settings[key];
    }
    const groupAndKey = getGroupAndKey(key);
    if (!groupAndKey.group) {
      if (settings[groupAndKey.key] === void 0) {
        return defaultValue;
      }
      return settings[groupAndKey.key];
    }
    const groupSettings = settings[groupAndKey.group] || {};
    if (groupSettings[groupAndKey.key] === void 0) {
      return defaultValue;
    }
    return groupSettings[groupAndKey.key];
  };
  var getGroupAndKey = (key) => {
    const split = key.split(".");
    if (split.length === 1) {
      return {
        group: null,
        key: split[0]
      };
    }
    if (split[0] === "location-huds-enabled") {
      return {
        group: "location-huds-enabled",
        key: split[1]
      };
    }
    return {
      group: `${split[0]}-settings`,
      key: split[1]
    };
  };
  var getSetting = (key, defaultValue = false) => {
    return getSettingDirect(key, defaultValue, "mousehunt-improved-settings");
  };

  // src/utils/elements.js
  var makeElement = (tag, classes = "", text = "", appendTo = null) => {
    const element = document.createElement(tag);
    if (Array.isArray(classes)) {
      classes = classes.join(" ");
    }
    if (classes && classes.length) {
      element.className = classes;
    }
    element.innerHTML = text;
    if (appendTo) {
      appendTo.append(element);
      return appendTo;
    }
    return element;
  };

  // src/utils/db.js
  var database = (databaseName) => __async(void 0, null, function* () {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open(`mh-improved-${databaseName}`, 6);
      request.onerror = (event) => {
        reject(event.target.error);
      };
      request.onsuccess = (event) => {
        resolve(event.target.result);
      };
      request.onupgradeneeded = (event) => {
        const db = event.target.result;
        if (!db.objectStoreNames.contains(databaseName)) {
          db.createObjectStore(databaseName, { keyPath: "id" });
        }
      };
    });
  });
  var dbGet = (databaseName, id) => __async(void 0, null, function* () {
    const db = yield database(databaseName);
    const transaction = db.transaction(databaseName, "readonly");
    transaction.onerror = (event) => {
      throw new Error(event.target.error);
    };
    const objectStore = transaction.objectStore(databaseName);
    const request = objectStore.get(id);
    return new Promise((resolve, reject) => {
      request.onsuccess = () => {
        resolve(request.result);
      };
      request.onerror = () => {
        reject(request.error);
      };
      transaction.oncomplete = () => {
        db.close();
      };
    });
  });
  var dbSet = (databaseName, data) => __async(void 0, null, function* () {
    const db = yield database(databaseName);
    const transaction = db.transaction(databaseName, "readwrite");
    const objectStore = transaction.objectStore(databaseName);
    data = {
      data,
      id: data.id || Date.now()
    };
    const request = objectStore.put(data);
    return new Promise((resolve, reject) => {
      request.onsuccess = () => {
        resolve(request.result);
      };
      request.onerror = () => {
        reject(request.error);
      };
      transaction.oncomplete = () => {
        db.close();
      };
    });
  });

  // src/utils/global.js
  var getGlobal = (key) => {
    if (window.mhui) {
      return window.mhui[key] || false;
    }
    if (app.mhui) {
      return app.mhui[key] || false;
    }
    return false;
  };

  // src/utils/debug.js
  var debuglog = (module, message, ...args) => {
    if (getSetting("debug.all", false) || getSetting(`debug.${module}`, false) || getGlobal("mh-improved-updating", false)) {
      console.log(
        `%cMH Improved %c${module}%c ${message}`,
        "color: #90588c; font-weight: 900",
        "color: #90588c; font-weight: 400",
        "color: inherit; font-weight: inherit",
        ...args
      );
    }
  };

  // src/utils/data.js
  var validDataFiles = /* @__PURE__ */ new Set([
    "effs",
    "environments-events",
    "environments",
    "item-thumbnails",
    "items-tradable",
    "m400-locations",
    "marketplace-hidden-items",
    "mice-groups",
    "mice-regions",
    "mice-thumbnails",
    "minlucks",
    "relic-hunter-hints",
    "scoreboards",
    "ultimate-checkmark",
    "upscaled-images",
    "wisdom"
  ]);
  var isValidDataFile = (file) => {
    return validDataFiles.has(file);
  };
  var getCacheExpiration = (key = null) => __async(void 0, null, function* () {
    return yield cacheGet(`expiration-${key}`, false);
  });
  var setCacheExpiration = (key) => __async(void 0, null, function* () {
    debuglog("utils-data", `Setting cache expiration for ${key}`);
    cacheSet(`expiration-${key}`, Date.now() + (Math.floor(Math.random() * 7) + 7) * 24 * 60 * 60 * 1e3);
  });
  var isCacheExpired = (key) => __async(void 0, null, function* () {
    const expiration = yield getCacheExpiration(key);
    if (!expiration) {
      return true;
    }
    return expiration.date < Date.now();
  });
  var fetchData = (key) => __async(void 0, null, function* () {
    const data = yield fetch(`https://api.mouse.rip/${key}`, {
      method: "GET",
      headers: getHeaders()
    });
    return yield data.json();
  });
  var getData = (key) => __async(void 0, null, function* () {
    if (!isValidDataFile(key)) {
      debuglog("utils-data", `Cannot get data for ${key}, invalid key`);
      return false;
    }
    const isExpired = yield isCacheExpired(key);
    if (!isExpired) {
      const cachedData = yield dataCacheGet(key, false);
      if (cachedData) {
        return cachedData;
      }
    }
    debuglog("utils-data", `Fetching data for ${key}\u2026`);
    const data = yield fetchData(key);
    debuglog("utils-data", `Fetched data for ${key}`, data);
    if (data) {
      dataCacheSet(key, data);
      setCacheExpiration(key);
    }
    return data;
  });
  var getHeaders = () => {
    return {
      "Content-Type": "application/json",
      "X-MH-Improved": "true",
      "X-MH-Improved-Version": mhImprovedVersion || "unknown",
      "X-MH-Improved-Platform": mhImprovedPlatform || "unknown"
    };
  };
  var cacheSet = (key, value) => {
    dbSet("cache", { id: key, value });
  };
  var dataCacheSet = (key, value) => {
    dbSet("data", { id: key, value });
  };
  var cacheGetHelper = (key, defaultValue = false, db = "cache") => __async(void 0, null, function* () {
    var _a;
    const cached = yield dbGet(db, key);
    if (!((_a = cached == null ? void 0 : cached.data) == null ? void 0 : _a.value)) {
      return defaultValue;
    }
    return cached.data.value;
  });
  var cacheGet = (key, defaultValue = false) => __async(void 0, null, function* () {
    return yield cacheGetHelper(key, defaultValue, "cache");
  });
  var dataCacheGet = (key, defaultValue = false) => __async(void 0, null, function* () {
    return yield cacheGetHelper(key, defaultValue, "data");
  });

  // src/utils/page.js
  var getCurrentPage = () => {
    var _a, _b;
    if (!((_b = (_a = hg == null ? void 0 : hg.utils) == null ? void 0 : _a.PageUtil) == null ? void 0 : _b.getCurrentPage)) {
      return null;
    }
    const page = hg.utils.PageUtil.getCurrentPage();
    if (!page) {
      return null;
    }
    return page.toLowerCase();
  };

  // src/utils/location.js
  var getCurrentLocation = () => {
    const location = (user == null ? void 0 : user.environment_type) || "";
    return location.toLowerCase();
  };

  // src/utils/horn.js
  var showHornMessage = (options) => {
    const huntersHornView = document.querySelector(".huntersHornView__messageContainer");
    if (!huntersHornView) {
      return;
    }
    const settings = {
      title: options.title || "Hunters Horn",
      text: options.text || "This is a message from the Hunters Horn",
      button: options.button || "OK",
      action: options.action || (() => {
      }),
      dismiss: options.dismiss || null,
      type: options.type || "recent_linked_turn",
      classname: options.classname || "",
      image: options.image || null,
      imageLink: options.imageLink || null,
      imageCallback: options.imageCallback || null
    };
    const backdrop = document.querySelector(".huntersHornView__backdrop");
    if (backdrop) {
      backdrop.classList.add("huntersHornView__backdrop--active");
    }
    const gameInfo = document.querySelector(".mousehuntHud-gameInfo");
    if (gameInfo) {
      gameInfo.classList.add("blur");
    }
    const messageWrapper = makeElement("div", ["huntersHornView__message huntersHornView__message--active", settings.classname]);
    const message = makeElement("div", ["huntersHornMessageView", `huntersHornMessageView--${settings.type}`]);
    makeElement("div", "huntersHornMessageView__title", settings.title, message);
    const content = makeElement("div", "huntersHornMessageView__content");
    if (settings.image) {
      const imgWrapper = makeElement("div", "huntersHornMessageView__friend");
      const img = makeElement("a", "huntersHornMessageView__friendProfilePic");
      if (settings.imageLink) {
        img.href = settings.imageLink;
      } else if (settings.imageCallback) {
        img.addEventListener("click", settings.imageCallback);
      } else {
        img.href = "#";
      }
      img.style.backgroundImage = `url(${settings.image})`;
      imgWrapper.append(img);
      content.append(imgWrapper);
    }
    makeElement("div", "huntersHornMessageView__text", settings.text, content);
    const buttonSpacer = makeElement("div", "huntersHornMessageView__buttonSpacer");
    const button = makeElement("button", "huntersHornMessageView__action");
    const buttonLabel = makeElement("div", "huntersHornMessageView__actionLabel");
    makeElement("span", "huntersHornMessageView__actionText", settings.button, buttonLabel);
    button.append(buttonLabel);
    button.addEventListener("click", () => {
      if (settings.action) {
        settings.action();
      }
      messageWrapper.innerHTML = "";
      backdrop.classList.remove("huntersHornView__backdrop--active");
      gameInfo.classList.remove("blur");
    });
    buttonSpacer.append(button);
    content.append(buttonSpacer);
    message.append(content);
    if (settings.dismiss) {
      const countdown = makeElement("button", ["huntersHornMessageView__countdown"]);
      makeElement("div", "huntersHornMessageView__countdownButtonImage", "", countdown);
      const svgMarkup = `<svg class="huntersHornMessageView__countdownSVG">
        <circle r="46%" cx="50%" cy="50%" class="huntersHornMessageView__countdownCircleTrack"></circle>
        <circle r="46%" cx="50%" cy="50%" class="huntersHornMessageView__countdownCircle" style="animation-duration: ${settings.dismiss}ms;"></circle>
    </svg>`;
      countdown.innerHTML += svgMarkup;
      countdown.addEventListener("click", () => {
        countdown.classList.add("huntersHornMessageView__countdown--complete");
        messageWrapper.innerHTML = "";
        backdrop.classList.remove("huntersHornView__backdrop--active");
        gameInfo.classList.remove("blur");
      });
      message.append(countdown);
    }
    messageWrapper.append(message);
    const existingMessages = huntersHornView.querySelector(".huntersHornView__message");
    if (existingMessages) {
      existingMessages.remove();
    }
    huntersHornView.append(messageWrapper);
    if (settings.dismiss) {
      setTimeout(() => {
        const countdown = messageWrapper.querySelector(".huntersHornMessageView__countdown");
        if (countdown) {
          countdown.classList.add("huntersHornMessageView__countdown--complete");
        }
        messageWrapper.innerHTML = "";
        backdrop.classList.remove("huntersHornView__backdrop--active");
        gameInfo.classList.remove("blur");
      }, settings.dismiss);
    }
  };

  // src/utils/events.js
  var requestCallbacks = {};
  var onRequestHolder = null;
  var onRequest = (url = null, callback = null, skipSuccess = false) => {
    url = "*" === url ? "*" : `managers/ajax/${url}`;
    if (!callback) {
      return;
    }
    if (!requestCallbacks[url]) {
      requestCallbacks[url] = [];
    }
    requestCallbacks[url].push({
      callback,
      skipSuccess
    });
    if (onRequestHolder) {
      return;
    }
    const req = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function() {
      this.addEventListener("load", function() {
        if (this.responseText) {
          let response = {};
          try {
            response = JSON.parse(this.responseText);
          } catch (e) {
            return;
          }
          Object.keys(requestCallbacks).forEach((key) => {
            if ("*" === key || this.responseURL.includes(key)) {
              requestCallbacks[key].forEach((item) => {
                if (item.callback && typeof item.callback === "function" && (item.skipSuccess || (response == null ? void 0 : response.success))) {
                  item.callback(response);
                }
              });
            }
          });
        }
      });
      Reflect.apply(req, this, arguments);
    };
    onRequestHolder = true;
  };
  var runCallbacks = (settings, parentNode, callbacks) => {
    Object.keys(settings).forEach((key) => {
      if (parentNode && parentNode.classList && parentNode.classList.contains(settings[key].selector)) {
        settings[key].isVisible = true;
        if (callbacks[key] && callbacks[key].show) {
          callbacks[key].show();
        }
      } else if (settings[key].isVisible) {
        settings[key].isVisible = false;
        if (callbacks[key] && callbacks[key].hide) {
          callbacks[key].hide();
        }
      }
    });
    return settings;
  };
  var pageChangeCallbacks = [];
  var pageChangeObserver = null;
  var onPageChange = (callbacks) => {
    let tabData = {
      blueprint: { isVisible: null, selector: "showBlueprint" },
      tem: { isVisible: false, selector: "showTrapEffectiveness" },
      trap: { isVisible: false, selector: "editTrap" },
      camp: { isVisible: false, selector: "PageCamp" },
      travel: { isVisible: false, selector: "PageTravel" },
      inventory: { isVisible: false, selector: "PageInventory" },
      shop: { isVisible: false, selector: "PageShops" },
      mice: { isVisible: false, selector: "PageAdversaries" },
      friends: { isVisible: false, selector: "PageFriends" },
      sendSupplies: { isVisible: false, selector: "PageSupplyTransfer" },
      team: { isVisible: false, selector: "PageTeam" },
      tournament: { isVisible: false, selector: "PageTournament" },
      news: { isVisible: false, selector: "PageNews" },
      scoreboards: { isVisible: false, selector: "PageScoreboards" },
      discord: { isVisible: false, selector: "PageJoinDiscord" },
      preferences: { isVisible: false, selector: "PagePreferences" },
      profile: { isVisible: false, selector: "HunterProfile" }
    };
    pageChangeCallbacks.push(callbacks);
    if (pageChangeObserver) {
      return;
    }
    pageChangeObserver = true;
    const observer = new MutationObserver(() => {
      pageChangeCallbacks.forEach((callback) => {
        if (callback.change) {
          callback.change();
        }
        const mhContainer = document.querySelector("#mousehuntContainer");
        if (mhContainer && mhContainer.classList.length > 0) {
          tabData = runCallbacks(tabData, mhContainer, callback);
        }
      });
    });
    const observeTarget = document.querySelector("#mousehuntContainer");
    if (observeTarget) {
      observer.observe(observeTarget, {
        attributes: true,
        attributeFilter: ["class"]
      });
    }
  };
  var onTravel = (location, options) => {
    eventRegistry.addEventListener("travel_complete", () => onTravelCallback(location, options));
  };
  var onTravelCallback = (location, options) => {
    if (location && location !== getCurrentLocation()) {
      return;
    }
    if (options == null ? void 0 : options.shouldAddReminder) {
      showHornMessage({
        title: options.title || "",
        text: options.text || "",
        button: options.button || "Dismiss",
        action: options.action || null
      });
    }
    if (options.callback) {
      options.callback();
    }
  };

  // src/utils/messages.js
  hadAddedErrorStyles = false;

  // src/utils/utils.js
  var doRequest = (_0, ..._1) => __async(void 0, [_0, ..._1], function* (url, formData = {}) {
    var _a;
    if ("undefined" === typeof lastReadJournalEntryId || "undefined" === typeof user) {
      return;
    }
    if (!lastReadJournalEntryId || !user || !(user == null ? void 0 : user.unique_hash)) {
      return;
    }
    const form = new FormData();
    form.append("sn", "Hitgrab");
    form.append("hg_is_ajax", 1);
    form.append("last_read_journal_entry_id", lastReadJournalEntryId != null ? lastReadJournalEntryId : 0);
    form.append("uh", (_a = user == null ? void 0 : user.unique_hash) != null ? _a : "");
    for (const key in formData) {
      form.append(key, formData[key]);
    }
    const requestBody = new URLSearchParams(form).toString();
    const response = yield fetch(
      callbackurl ? callbackurl + url : "https://www.mousehuntgame.com/" + url,
      {
        method: "POST",
        body: requestBody,
        headers: {
          "Content-Type": "application/x-www-form-urlencoded"
        }
      }
    );
    const data = yield response.json();
    return data;
  });

  // src/modules/catch-rate-estimate/data.js
  var miceEffs;
  var hasGottenEffs = false;
  var getMiceEffectiveness = () => __async(void 0, null, function* () {
    if (!hasGottenEffs) {
      miceEffs = yield getData("effs");
      hasGottenEffs = true;
    }
    const response = yield doRequest("managers/ajax/users/getmiceeffectiveness.php");
    return response == null ? void 0 : response.effectiveness;
  });
  var getMouse = (mouseId) => __async(void 0, null, function* () {
    if (!miceEffs || !hasGottenEffs) {
      miceEffs = yield getData("effs");
      hasGottenEffs = true;
    }
    const mouse = miceEffs.find((m) => m.type === mouseId);
    return mouse;
  });
  var getMousePower = (mouseId) => __async(void 0, null, function* () {
    var _a;
    const mouse = yield getMouse(mouseId);
    return (_a = mouse == null ? void 0 : mouse.effectivenesses) == null ? void 0 : _a.power;
  });
  var getMouseEffectiveness = (mouseId) => __async(void 0, null, function* () {
    const mouse = yield getMouse(mouseId);
    return mouse.effectivenesses[user.trap_power_type_name.toLowerCase()];
  });
  var getMinluck = (mousePower, effectiveness) => __async(void 0, null, function* () {
    if (effectiveness === 0) {
      return "\u221E";
    }
    const minluck = Math.ceil(
      Math.ceil(Math.sqrt(mousePower / 2)) / Math.min(effectiveness / 100, 1.4)
    );
    const checkCatchRate = getCatchRate(mousePower, effectiveness, 0, minluck);
    return checkCatchRate.rate === 1 ? minluck : minluck + 1;
  });
  var getPercent = (rate) => {
    if (rate === 1) {
      return "100%";
    }
    const percent = (rate * 100).toFixed(2);
    return `${percent}%`;
  };
  var getCatchRate = (mousePower, effectiveness, power = null, luck = null) => {
    effectiveness = effectiveness / 100;
    if (null === power) {
      power = user.trap_power;
    }
    if (null === luck) {
      luck = user.trap_luck;
    }
    const rate = Math.min(
      1,
      (effectiveness * power + 2 * Math.pow(Math.floor(Math.min(effectiveness, 1.4) * luck), 2)) / (effectiveness * power + mousePower)
    );
    return {
      rate,
      percent: getPercent(rate)
    };
  };

  // src/modules/catch-rate-estimate/styles.css
  var styles_default = '#mh-improved-cre{padding-right:5px;margin:5px 0;cursor:default}#mh-improved-cre table{width:100%}#mh-improved-cre thead{box-shadow:0 -1px #d3cecb inset}.mh-dark-mode #mh-improved-cre thead{box-shadow:0 -1px #5c5c5c inset}#mh-improved-cre table th{font-weight:700;text-align:center}#mh-improved-cre table th.name,#mh-improved-cre table:first-child{text-align:left}.mh-improved-cre-data{min-width:70px;text-align:center}.mh-improved-cre-data-good{color:#138f13}.mh-dark-mode .mh-improved-cre-data-good{color:#4fe54f}.mh-improved-cre-data-bad{color:#bb4646}.mh-dark-mode .mh-improved-cre-data-bad{color:#fb9b9b}.mh-improved-cre-name{padding-left:5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mh-improved-cre-name a{color:inherit}#mh-improved-cre.cre-loading{display:flex;align-items:flex-end;justify-content:center;height:100%;min-height:50px;padding:20px 0;background-image:url(https://www.mousehuntgame.com/images/ui/loaders/drip_spinner.gif?asset_cache_version=2);background-repeat:no-repeat;background-position:center 10px;background-size:55px}#mh-improved-cre.cre-loading:after{position:absolute;right:0;bottom:-5px;left:0;font-weight:400;color:#926944;text-align:center;content:"Loading Catch Rate Estimator\\2026"}\n';

  // src/modules/catch-rate-estimate/index.js
  var updateMinLucks = () => __async(void 0, null, function* () {
    if ("camp" !== getCurrentPage()) {
      return;
    }
    let minluckList = document.querySelector("#mh-improved-cre");
    if (!minluckList) {
      minluckList = makeElement("div", ["campPage-trap-trapEffectiveness", "cre-loading"]);
      minluckList.id = "mh-improved-cre";
      const statsContainer = document.querySelector(".trapSelectorView__trapStatSummaryContainer");
      if (!statsContainer) {
        return;
      }
      statsContainer.append(minluckList);
    }
    const effectiveness = yield getMiceEffectiveness();
    if (!effectiveness) {
      return;
    }
    const miceIds = Object.values(effectiveness).flatMap(({ mice }) => mice).map((mouse) => {
      return {
        name: mouse.name,
        type: mouse.type
      };
    });
    renderList(miceIds);
  });
  var renderList = (list) => __async(void 0, null, function* () {
    let minluckList = document.querySelector("#mh-improved-cre");
    if (!minluckList) {
      minluckList = makeElement("div", "campPage-trap-trapEffectiveness");
      minluckList.id = "mh-improved-cre";
      const statsContainer = document.querySelector(".trapSelectorView__trapStatSummaryContainer");
      if (!statsContainer) {
        return;
      }
      statsContainer.append(minluckList);
      doEvent2("mh-improved-cre-list-rendered");
    }
    const existing = document.querySelector("#mh-improved-cre-table");
    if (existing) {
      existing.remove();
    }
    minluckList.classList.remove("cre-loading");
    const table = makeElement("table");
    table.id = "mh-improved-cre-table";
    const tableheader = makeElement("thead");
    makeElement("th", "name", "Mouse", tableheader);
    makeElement("th", "", "Minluck", tableheader);
    makeElement("th", "", "Catch Rate", tableheader);
    table.append(tableheader);
    const rows = [];
    for (const mouse of list) {
      const mousePower = yield getMousePower(mouse.type);
      const mouseEffectiveness = yield getMouseEffectiveness(mouse.type);
      const minluck = yield getMinluck(mousePower, mouseEffectiveness);
      const catchRate = yield getCatchRate(mousePower, mouseEffectiveness);
      const crClass = ["mh-improved-cre-data"];
      if (catchRate.rate * 100 >= 100) {
        crClass.push("mh-improved-cre-data-good");
      } else if (catchRate.rate * 100 <= 60) {
        crClass.push("mh-improved-cre-data-bad");
      }
      if (user.trap_luck >= minluck) {
        crClass.push("mh-improved-cre-data-minlucked");
      }
      rows.push({
        mouse: mouse.name,
        type: mouse.type,
        minluck,
        catchRateValue: catchRate.rate,
        catchRate: catchRate.percent,
        crClass
      });
    }
    rows.sort((a, b) => {
      if (a.catchRateValue !== b.catchRateValue) {
        return a.catchRateValue - b.catchRateValue;
      }
      return b.minluck - a.minluck;
    });
    rows.forEach(({ mouse, type, minluck, catchRate, crClass }) => {
      const row = makeElement("tr", "mh-improved-cre-row");
      const name = makeElement("td", "mh-improved-cre-name");
      const nameLink = makeElement("a", "", mouse);
      nameLink.addEventListener("click", (e) => {
        e.preventDefault();
        hg.views.MouseView.show(type);
      });
      name.append(nameLink);
      row.append(name);
      makeElement("td", crClass, minluck, row);
      makeElement("td", crClass, catchRate, row);
      table.append(row);
    });
    minluckList.append(table);
  });
  var main = () => __async(void 0, null, function* () {
    if ("camp" === getCurrentPage()) {
      yield updateMinLucks();
    }
    onPageChange({ camp: { show: updateMinLucks } });
    onRequest("*", updateMinLucks);
    onTravel(null, { callback: updateMinLucks });
  });
  var init = () => __async(void 0, null, function* () {
    addStyles(styles_default, "catch-rate-estimate");
    main();
  });
  var catch_rate_estimate_default = {
    id: "catch-rate-estimate",
    name: "Catch Rate Estimator & Minlucks",
    type: "feature",
    default: true,
    description: "Minluck and catch rate estimates.",
    order: 200,
    load: init
  };
  return __toCommonJS(catch_rate_estimate_exports);
})();
mhui.default.load();
migrateUserscript('Minluck & Catch Rate Estimate', '2.0.1', 'https://greasyfork.org/en/scripts/449334-mousehunt-minluck-catch-rate-estimate');