Greasy Fork is available in English.

Mousehunt Auto Horn & KR Solver

A new automatic horn & KR solving userscript, with a focus on code readability and modularity. Note that the published userscript is generated by a JS bundler, so don't try to debug it directly. Instead, go to the script's GitHub repo (linked below) and download the source code. The repo has instructions on how to run the bundler yourself.

// ==UserScript==
// @name         Mousehunt Auto Horn & KR Solver
// @namespace    http://tampermonkey.net/
// @version      0.6
// @description  A new automatic horn & KR solving userscript, with a focus on code readability and modularity. Note that the published userscript is generated by a JS bundler, so don't try to debug it directly. Instead, go to the script's GitHub repo (linked below) and download the source code. The repo has instructions on how to run the bundler yourself.
// @author       daniellok
// @license      MIT
// @website      https://github.com/daniellok/mousehunt-auto-kr
// @match        http://mousehuntgame.com/*
// @match        https://mousehuntgame.com/*
// @match        http://www.mousehuntgame.com/*
// @match        https://www.mousehuntgame.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=mousehuntgame.com
// @grant        GM_addStyle
// ==/UserScript==

(() => {
  var __create = Object.create;
  var __defProp = Object.defineProperty;
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  var __getOwnPropNames = Object.getOwnPropertyNames;
  var __getProtoOf = Object.getPrototypeOf;
  var __hasOwnProp = Object.prototype.hasOwnProperty;
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
    get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
  }) : x)(function(x) {
    if (typeof require !== "undefined")
      return require.apply(this, arguments);
    throw new Error('Dynamic require of "' + x + '" is not supported');
  });
  var __commonJS = (cb, mod) => function __require2() {
    return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
  };
  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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
    // If the importer is in node compatibility mode or this is not an ESM
    // file that has been converted to a CommonJS file using a Babel-
    // compatible transform (i.e. "__esModule" has not been set), then set
    // "default" to the CommonJS "module.exports" for node compatibility.
    isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
    mod
  ));

  // node_modules/regenerator-runtime/runtime.js
  var require_runtime = __commonJS({
    "node_modules/regenerator-runtime/runtime.js"(exports, module) {
      var runtime = function(exports2) {
        "use strict";
        var Op = Object.prototype;
        var hasOwn = Op.hasOwnProperty;
        var defineProperty = Object.defineProperty || function(obj, key, desc) {
          obj[key] = desc.value;
        };
        var undefined;
        var $Symbol = typeof Symbol === "function" ? Symbol : {};
        var iteratorSymbol = $Symbol.iterator || "@@iterator";
        var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
        var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
        function define2(obj, key, value) {
          Object.defineProperty(obj, key, {
            value,
            enumerable: true,
            configurable: true,
            writable: true
          });
          return obj[key];
        }
        try {
          define2({}, "");
        } catch (err) {
          define2 = function(obj, key, value) {
            return obj[key] = value;
          };
        }
        function wrap(innerFn, outerFn, self, tryLocsList) {
          var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
          var generator = Object.create(protoGenerator.prototype);
          var context = new Context(tryLocsList || []);
          defineProperty(generator, "_invoke", { value: makeInvokeMethod(innerFn, self, context) });
          return generator;
        }
        exports2.wrap = wrap;
        function tryCatch(fn, obj, arg) {
          try {
            return { type: "normal", arg: fn.call(obj, arg) };
          } catch (err) {
            return { type: "throw", arg: err };
          }
        }
        var GenStateSuspendedStart = "suspendedStart";
        var GenStateSuspendedYield = "suspendedYield";
        var GenStateExecuting = "executing";
        var GenStateCompleted = "completed";
        var ContinueSentinel = {};
        function Generator() {
        }
        function GeneratorFunction() {
        }
        function GeneratorFunctionPrototype() {
        }
        var IteratorPrototype = {};
        define2(IteratorPrototype, iteratorSymbol, function() {
          return this;
        });
        var getProto = Object.getPrototypeOf;
        var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
        if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
          IteratorPrototype = NativeIteratorPrototype;
        }
        var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
        GeneratorFunction.prototype = GeneratorFunctionPrototype;
        defineProperty(Gp, "constructor", { value: GeneratorFunctionPrototype, configurable: true });
        defineProperty(
          GeneratorFunctionPrototype,
          "constructor",
          { value: GeneratorFunction, configurable: true }
        );
        GeneratorFunction.displayName = define2(
          GeneratorFunctionPrototype,
          toStringTagSymbol,
          "GeneratorFunction"
        );
        function defineIteratorMethods(prototype) {
          ["next", "throw", "return"].forEach(function(method) {
            define2(prototype, method, function(arg) {
              return this._invoke(method, arg);
            });
          });
        }
        exports2.isGeneratorFunction = function(genFun) {
          var ctor = typeof genFun === "function" && genFun.constructor;
          return ctor ? ctor === GeneratorFunction || (ctor.displayName || ctor.name) === "GeneratorFunction" : false;
        };
        exports2.mark = function(genFun) {
          if (Object.setPrototypeOf) {
            Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
          } else {
            genFun.__proto__ = GeneratorFunctionPrototype;
            define2(genFun, toStringTagSymbol, "GeneratorFunction");
          }
          genFun.prototype = Object.create(Gp);
          return genFun;
        };
        exports2.awrap = function(arg) {
          return { __await: arg };
        };
        function AsyncIterator(generator, PromiseImpl) {
          function invoke(method, arg, resolve, reject) {
            var record = tryCatch(generator[method], generator, arg);
            if (record.type === "throw") {
              reject(record.arg);
            } else {
              var result = record.arg;
              var value = result.value;
              if (value && typeof value === "object" && hasOwn.call(value, "__await")) {
                return PromiseImpl.resolve(value.__await).then(function(value2) {
                  invoke("next", value2, resolve, reject);
                }, function(err) {
                  invoke("throw", err, resolve, reject);
                });
              }
              return PromiseImpl.resolve(value).then(function(unwrapped) {
                result.value = unwrapped;
                resolve(result);
              }, function(error) {
                return invoke("throw", error, resolve, reject);
              });
            }
          }
          var previousPromise;
          function enqueue(method, arg) {
            function callInvokeWithMethodAndArg() {
              return new PromiseImpl(function(resolve, reject) {
                invoke(method, arg, resolve, reject);
              });
            }
            return previousPromise = // If enqueue has been called before, then we want to wait until
            // all previous Promises have been resolved before calling invoke,
            // so that results are always delivered in the correct order. If
            // enqueue has not been called before, then it is important to
            // call invoke immediately, without waiting on a callback to fire,
            // so that the async generator function has the opportunity to do
            // any necessary setup in a predictable way. This predictability
            // is why the Promise constructor synchronously invokes its
            // executor callback, and why async functions synchronously
            // execute code before the first await. Since we implement simple
            // async functions in terms of async generators, it is especially
            // important to get this right, even though it requires care.
            previousPromise ? previousPromise.then(
              callInvokeWithMethodAndArg,
              // Avoid propagating failures to Promises returned by later
              // invocations of the iterator.
              callInvokeWithMethodAndArg
            ) : callInvokeWithMethodAndArg();
          }
          defineProperty(this, "_invoke", { value: enqueue });
        }
        defineIteratorMethods(AsyncIterator.prototype);
        define2(AsyncIterator.prototype, asyncIteratorSymbol, function() {
          return this;
        });
        exports2.AsyncIterator = AsyncIterator;
        exports2.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {
          if (PromiseImpl === void 0)
            PromiseImpl = Promise;
          var iter = new AsyncIterator(
            wrap(innerFn, outerFn, self, tryLocsList),
            PromiseImpl
          );
          return exports2.isGeneratorFunction(outerFn) ? iter : iter.next().then(function(result) {
            return result.done ? result.value : iter.next();
          });
        };
        function makeInvokeMethod(innerFn, self, context) {
          var state = GenStateSuspendedStart;
          return function invoke(method, arg) {
            if (state === GenStateExecuting) {
              throw new Error("Generator is already running");
            }
            if (state === GenStateCompleted) {
              if (method === "throw") {
                throw arg;
              }
              return doneResult();
            }
            context.method = method;
            context.arg = arg;
            while (true) {
              var delegate = context.delegate;
              if (delegate) {
                var delegateResult = maybeInvokeDelegate(delegate, context);
                if (delegateResult) {
                  if (delegateResult === ContinueSentinel)
                    continue;
                  return delegateResult;
                }
              }
              if (context.method === "next") {
                context.sent = context._sent = context.arg;
              } else if (context.method === "throw") {
                if (state === GenStateSuspendedStart) {
                  state = GenStateCompleted;
                  throw context.arg;
                }
                context.dispatchException(context.arg);
              } else if (context.method === "return") {
                context.abrupt("return", context.arg);
              }
              state = GenStateExecuting;
              var record = tryCatch(innerFn, self, context);
              if (record.type === "normal") {
                state = context.done ? GenStateCompleted : GenStateSuspendedYield;
                if (record.arg === ContinueSentinel) {
                  continue;
                }
                return {
                  value: record.arg,
                  done: context.done
                };
              } else if (record.type === "throw") {
                state = GenStateCompleted;
                context.method = "throw";
                context.arg = record.arg;
              }
            }
          };
        }
        function maybeInvokeDelegate(delegate, context) {
          var methodName = context.method;
          var method = delegate.iterator[methodName];
          if (method === undefined) {
            context.delegate = null;
            if (methodName === "throw" && delegate.iterator["return"]) {
              context.method = "return";
              context.arg = undefined;
              maybeInvokeDelegate(delegate, context);
              if (context.method === "throw") {
                return ContinueSentinel;
              }
            }
            if (methodName !== "return") {
              context.method = "throw";
              context.arg = new TypeError(
                "The iterator does not provide a '" + methodName + "' method"
              );
            }
            return ContinueSentinel;
          }
          var record = tryCatch(method, delegate.iterator, context.arg);
          if (record.type === "throw") {
            context.method = "throw";
            context.arg = record.arg;
            context.delegate = null;
            return ContinueSentinel;
          }
          var info = record.arg;
          if (!info) {
            context.method = "throw";
            context.arg = new TypeError("iterator result is not an object");
            context.delegate = null;
            return ContinueSentinel;
          }
          if (info.done) {
            context[delegate.resultName] = info.value;
            context.next = delegate.nextLoc;
            if (context.method !== "return") {
              context.method = "next";
              context.arg = undefined;
            }
          } else {
            return info;
          }
          context.delegate = null;
          return ContinueSentinel;
        }
        defineIteratorMethods(Gp);
        define2(Gp, toStringTagSymbol, "Generator");
        define2(Gp, iteratorSymbol, function() {
          return this;
        });
        define2(Gp, "toString", function() {
          return "[object Generator]";
        });
        function pushTryEntry(locs) {
          var entry = { tryLoc: locs[0] };
          if (1 in locs) {
            entry.catchLoc = locs[1];
          }
          if (2 in locs) {
            entry.finallyLoc = locs[2];
            entry.afterLoc = locs[3];
          }
          this.tryEntries.push(entry);
        }
        function resetTryEntry(entry) {
          var record = entry.completion || {};
          record.type = "normal";
          delete record.arg;
          entry.completion = record;
        }
        function Context(tryLocsList) {
          this.tryEntries = [{ tryLoc: "root" }];
          tryLocsList.forEach(pushTryEntry, this);
          this.reset(true);
        }
        exports2.keys = function(val) {
          var object = Object(val);
          var keys = [];
          for (var key in object) {
            keys.push(key);
          }
          keys.reverse();
          return function next() {
            while (keys.length) {
              var key2 = keys.pop();
              if (key2 in object) {
                next.value = key2;
                next.done = false;
                return next;
              }
            }
            next.done = true;
            return next;
          };
        };
        function values(iterable) {
          if (iterable) {
            var iteratorMethod = iterable[iteratorSymbol];
            if (iteratorMethod) {
              return iteratorMethod.call(iterable);
            }
            if (typeof iterable.next === "function") {
              return iterable;
            }
            if (!isNaN(iterable.length)) {
              var i = -1, next = function next2() {
                while (++i < iterable.length) {
                  if (hasOwn.call(iterable, i)) {
                    next2.value = iterable[i];
                    next2.done = false;
                    return next2;
                  }
                }
                next2.value = undefined;
                next2.done = true;
                return next2;
              };
              return next.next = next;
            }
          }
          return { next: doneResult };
        }
        exports2.values = values;
        function doneResult() {
          return { value: undefined, done: true };
        }
        Context.prototype = {
          constructor: Context,
          reset: function(skipTempReset) {
            this.prev = 0;
            this.next = 0;
            this.sent = this._sent = undefined;
            this.done = false;
            this.delegate = null;
            this.method = "next";
            this.arg = undefined;
            this.tryEntries.forEach(resetTryEntry);
            if (!skipTempReset) {
              for (var name in this) {
                if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) {
                  this[name] = undefined;
                }
              }
            }
          },
          stop: function() {
            this.done = true;
            var rootEntry = this.tryEntries[0];
            var rootRecord = rootEntry.completion;
            if (rootRecord.type === "throw") {
              throw rootRecord.arg;
            }
            return this.rval;
          },
          dispatchException: function(exception) {
            if (this.done) {
              throw exception;
            }
            var context = this;
            function handle(loc, caught) {
              record.type = "throw";
              record.arg = exception;
              context.next = loc;
              if (caught) {
                context.method = "next";
                context.arg = undefined;
              }
              return !!caught;
            }
            for (var i = this.tryEntries.length - 1; i >= 0; --i) {
              var entry = this.tryEntries[i];
              var record = entry.completion;
              if (entry.tryLoc === "root") {
                return handle("end");
              }
              if (entry.tryLoc <= this.prev) {
                var hasCatch = hasOwn.call(entry, "catchLoc");
                var hasFinally = hasOwn.call(entry, "finallyLoc");
                if (hasCatch && hasFinally) {
                  if (this.prev < entry.catchLoc) {
                    return handle(entry.catchLoc, true);
                  } else if (this.prev < entry.finallyLoc) {
                    return handle(entry.finallyLoc);
                  }
                } else if (hasCatch) {
                  if (this.prev < entry.catchLoc) {
                    return handle(entry.catchLoc, true);
                  }
                } else if (hasFinally) {
                  if (this.prev < entry.finallyLoc) {
                    return handle(entry.finallyLoc);
                  }
                } else {
                  throw new Error("try statement without catch or finally");
                }
              }
            }
          },
          abrupt: function(type, arg) {
            for (var i = this.tryEntries.length - 1; i >= 0; --i) {
              var entry = this.tryEntries[i];
              if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
                var finallyEntry = entry;
                break;
              }
            }
            if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) {
              finallyEntry = null;
            }
            var record = finallyEntry ? finallyEntry.completion : {};
            record.type = type;
            record.arg = arg;
            if (finallyEntry) {
              this.method = "next";
              this.next = finallyEntry.finallyLoc;
              return ContinueSentinel;
            }
            return this.complete(record);
          },
          complete: function(record, afterLoc) {
            if (record.type === "throw") {
              throw record.arg;
            }
            if (record.type === "break" || record.type === "continue") {
              this.next = record.arg;
            } else if (record.type === "return") {
              this.rval = this.arg = record.arg;
              this.method = "return";
              this.next = "end";
            } else if (record.type === "normal" && afterLoc) {
              this.next = afterLoc;
            }
            return ContinueSentinel;
          },
          finish: function(finallyLoc) {
            for (var i = this.tryEntries.length - 1; i >= 0; --i) {
              var entry = this.tryEntries[i];
              if (entry.finallyLoc === finallyLoc) {
                this.complete(entry.completion, entry.afterLoc);
                resetTryEntry(entry);
                return ContinueSentinel;
              }
            }
          },
          "catch": function(tryLoc) {
            for (var i = this.tryEntries.length - 1; i >= 0; --i) {
              var entry = this.tryEntries[i];
              if (entry.tryLoc === tryLoc) {
                var record = entry.completion;
                if (record.type === "throw") {
                  var thrown = record.arg;
                  resetTryEntry(entry);
                }
                return thrown;
              }
            }
            throw new Error("illegal catch attempt");
          },
          delegateYield: function(iterable, resultName, nextLoc) {
            this.delegate = {
              iterator: values(iterable),
              resultName,
              nextLoc
            };
            if (this.method === "next") {
              this.arg = undefined;
            }
            return ContinueSentinel;
          }
        };
        return exports2;
      }(
        // If this script is executing as a CommonJS module, use module.exports
        // as the regeneratorRuntime namespace. Otherwise create a new empty
        // object. Either way, the resulting object will be used to initialize
        // the regeneratorRuntime variable at the top of this file.
        typeof module === "object" ? module.exports : {}
      );
      try {
        regeneratorRuntime = runtime;
      } catch (accidentalStrictMode) {
        if (typeof globalThis === "object") {
          globalThis.regeneratorRuntime = runtime;
        } else {
          Function("r", "regeneratorRuntime = r")(runtime);
        }
      }
    }
  });

  // node_modules/tesseract.js/src/utils/getId.js
  var require_getId = __commonJS({
    "node_modules/tesseract.js/src/utils/getId.js"(exports, module) {
      module.exports = (prefix, cnt) => `${prefix}-${cnt}-${Math.random().toString(16).slice(3, 8)}`;
    }
  });

  // node_modules/tesseract.js/src/createJob.js
  var require_createJob = __commonJS({
    "node_modules/tesseract.js/src/createJob.js"(exports, module) {
      var getId = require_getId();
      var jobCounter = 0;
      module.exports = ({
        id: _id,
        action,
        payload = {}
      }) => {
        let id = _id;
        if (typeof id === "undefined") {
          id = getId("Job", jobCounter);
          jobCounter += 1;
        }
        return {
          id,
          action,
          payload
        };
      };
    }
  });

  // node_modules/tesseract.js/src/utils/log.js
  var require_log = __commonJS({
    "node_modules/tesseract.js/src/utils/log.js"(exports) {
      var logging = false;
      exports.logging = logging;
      exports.setLogging = (_logging) => {
        logging = _logging;
      };
      exports.log = (...args) => logging ? console.log.apply(exports, args) : null;
    }
  });

  // node_modules/tesseract.js/src/createScheduler.js
  var require_createScheduler = __commonJS({
    "node_modules/tesseract.js/src/createScheduler.js"(exports, module) {
      var createJob = require_createJob();
      var { log: log2 } = require_log();
      var getId = require_getId();
      var schedulerCounter = 0;
      module.exports = () => {
        const id = getId("Scheduler", schedulerCounter);
        const workers = {};
        const runningWorkers = {};
        let jobQueue = [];
        schedulerCounter += 1;
        const getQueueLen = () => jobQueue.length;
        const getNumWorkers = () => Object.keys(workers).length;
        const dequeue = () => {
          if (jobQueue.length !== 0) {
            const wIds = Object.keys(workers);
            for (let i = 0; i < wIds.length; i += 1) {
              if (typeof runningWorkers[wIds[i]] === "undefined") {
                jobQueue[0](workers[wIds[i]]);
                break;
              }
            }
          }
        };
        const queue = (action, payload) => new Promise((resolve, reject) => {
          const job = createJob({ action, payload });
          jobQueue.push(async (w) => {
            jobQueue.shift();
            runningWorkers[w.id] = job;
            try {
              resolve(await w[action].apply(exports, [...payload, job.id]));
            } catch (err) {
              reject(err);
            } finally {
              delete runningWorkers[w.id];
              dequeue();
            }
          });
          log2(`[${id}]: Add ${job.id} to JobQueue`);
          log2(`[${id}]: JobQueue length=${jobQueue.length}`);
          dequeue();
        });
        const addWorker = (w) => {
          workers[w.id] = w;
          log2(`[${id}]: Add ${w.id}`);
          log2(`[${id}]: Number of workers=${getNumWorkers()}`);
          dequeue();
          return w.id;
        };
        const addJob = async (action, ...payload) => {
          if (getNumWorkers() === 0) {
            throw Error(`[${id}]: You need to have at least one worker before adding jobs`);
          }
          return queue(action, payload);
        };
        const terminate = async () => {
          Object.keys(workers).forEach(async (wid) => {
            await workers[wid].terminate();
          });
          jobQueue = [];
        };
        return {
          addWorker,
          addJob,
          terminate,
          getQueueLen,
          getNumWorkers
        };
      };
    }
  });

  // node_modules/is-electron/index.js
  var require_is_electron = __commonJS({
    "node_modules/is-electron/index.js"(exports, module) {
      function isElectron() {
        if (typeof window !== "undefined" && typeof window.process === "object" && window.process.type === "renderer") {
          return true;
        }
        if (typeof process !== "undefined" && typeof process.versions === "object" && !!process.versions.electron) {
          return true;
        }
        if (typeof navigator === "object" && typeof navigator.userAgent === "string" && navigator.userAgent.indexOf("Electron") >= 0) {
          return true;
        }
        return false;
      }
      module.exports = isElectron;
    }
  });

  // node_modules/tesseract.js/src/utils/getEnvironment.js
  var require_getEnvironment = __commonJS({
    "node_modules/tesseract.js/src/utils/getEnvironment.js"(exports, module) {
      var isElectron = require_is_electron();
      module.exports = (key) => {
        const env = {};
        if (typeof WorkerGlobalScope !== "undefined") {
          env.type = "webworker";
        } else if (isElectron()) {
          env.type = "electron";
        } else if (typeof window === "object") {
          env.type = "browser";
        } else if (typeof process === "object" && typeof __require === "function") {
          env.type = "node";
        }
        if (typeof key === "undefined") {
          return env;
        }
        return env[key];
      };
    }
  });

  // node_modules/resolve-url/resolve-url.js
  var require_resolve_url = __commonJS({
    "node_modules/resolve-url/resolve-url.js"(exports, module) {
      void function(root, factory) {
        if (typeof define === "function" && define.amd) {
          define(factory);
        } else if (typeof exports === "object") {
          module.exports = factory();
        } else {
          root.resolveUrl = factory();
        }
      }(exports, function() {
        function resolveUrl() {
          var numUrls = arguments.length;
          if (numUrls === 0) {
            throw new Error("resolveUrl requires at least one argument; got none.");
          }
          var base = document.createElement("base");
          base.href = arguments[0];
          if (numUrls === 1) {
            return base.href;
          }
          var head = document.getElementsByTagName("head")[0];
          head.insertBefore(base, head.firstChild);
          var a = document.createElement("a");
          var resolved;
          for (var index = 1; index < numUrls; index++) {
            a.href = arguments[index];
            resolved = a.href;
            base.href = resolved;
          }
          head.removeChild(base);
          return resolved;
        }
        return resolveUrl;
      });
    }
  });

  // node_modules/tesseract.js/src/utils/resolvePaths.js
  var require_resolvePaths = __commonJS({
    "node_modules/tesseract.js/src/utils/resolvePaths.js"(exports, module) {
      var isBrowser = require_getEnvironment()("type") === "browser";
      var resolveURL = isBrowser ? require_resolve_url() : (s) => s;
      module.exports = (options) => {
        const opts = { ...options };
        ["corePath", "workerPath", "langPath"].forEach((key) => {
          if (options[key]) {
            opts[key] = resolveURL(opts[key]);
          }
        });
        return opts;
      };
    }
  });

  // node_modules/tesseract.js/src/utils/circularize.js
  var require_circularize = __commonJS({
    "node_modules/tesseract.js/src/utils/circularize.js"(exports, module) {
      module.exports = (page) => {
        const blocks = [];
        const paragraphs = [];
        const lines = [];
        const words = [];
        const symbols = [];
        if (page.blocks) {
          page.blocks.forEach((block) => {
            block.paragraphs.forEach((paragraph) => {
              paragraph.lines.forEach((line) => {
                line.words.forEach((word) => {
                  word.symbols.forEach((sym) => {
                    symbols.push({
                      ...sym,
                      page,
                      block,
                      paragraph,
                      line,
                      word
                    });
                  });
                  words.push({
                    ...word,
                    page,
                    block,
                    paragraph,
                    line
                  });
                });
                lines.push({
                  ...line,
                  page,
                  block,
                  paragraph
                });
              });
              paragraphs.push({
                ...paragraph,
                page,
                block
              });
            });
            blocks.push({
              ...block,
              page
            });
          });
        }
        return {
          ...page,
          blocks,
          paragraphs,
          lines,
          words,
          symbols
        };
      };
    }
  });

  // node_modules/tesseract.js/src/constants/OEM.js
  var require_OEM = __commonJS({
    "node_modules/tesseract.js/src/constants/OEM.js"(exports, module) {
      module.exports = {
        TESSERACT_ONLY: 0,
        LSTM_ONLY: 1,
        TESSERACT_LSTM_COMBINED: 2,
        DEFAULT: 3
      };
    }
  });

  // node_modules/tesseract.js/src/constants/config.js
  var require_config = __commonJS({
    "node_modules/tesseract.js/src/constants/config.js"(exports, module) {
      var OEM = require_OEM();
      module.exports = {
        defaultOEM: OEM.DEFAULT
      };
    }
  });

  // node_modules/tesseract.js/package.json
  var require_package = __commonJS({
    "node_modules/tesseract.js/package.json"(exports, module) {
      module.exports = {
        name: "tesseract.js",
        version: "4.0.2",
        description: "Pure Javascript Multilingual OCR",
        main: "src/index.js",
        types: "src/index.d.ts",
        unpkg: "dist/tesseract.min.js",
        jsdelivr: "dist/tesseract.min.js",
        scripts: {
          start: "node scripts/server.js",
          build: "rimraf dist && webpack --config scripts/webpack.config.prod.js && rollup -c scripts/rollup.esm.js",
          "profile:tesseract": "webpack-bundle-analyzer dist/tesseract-stats.json",
          "profile:worker": "webpack-bundle-analyzer dist/worker-stats.json",
          prepublishOnly: "npm run build",
          wait: "rimraf dist && wait-on http://localhost:3000/dist/tesseract.dev.js",
          test: "npm-run-all -p -r start test:all",
          "test:all": "npm-run-all wait test:browser:* test:node:all",
          "test:node": "nyc mocha --exit --bail --require ./scripts/test-helper.js",
          "test:node:all": "npm run test:node -- ./tests/*.test.js",
          "test:browser-tpl": "mocha-headless-chrome -a incognito -a no-sandbox -a disable-setuid-sandbox -a disable-logging -t 300000",
          "test:browser:detect": "npm run test:browser-tpl -- -f ./tests/detect.test.html",
          "test:browser:recognize": "npm run test:browser-tpl -- -f ./tests/recognize.test.html",
          "test:browser:scheduler": "npm run test:browser-tpl -- -f ./tests/scheduler.test.html",
          "test:browser:FS": "npm run test:browser-tpl -- -f ./tests/FS.test.html",
          lint: "eslint src",
          "lint:fix": "eslint --fix src",
          postinstall: "opencollective-postinstall || true"
        },
        browser: {
          "./src/worker/node/index.js": "./src/worker/browser/index.js"
        },
        author: "",
        contributors: [
          "jeromewu"
        ],
        license: "Apache-2.0",
        devDependencies: {
          "@babel/core": "^7.18.7",
          "@babel/preset-env": "^7.18.7",
          "@rollup/plugin-commonjs": "^22.0.2",
          acorn: "^6.4.0",
          "babel-loader": "^8.2.0",
          buffer: "^6.0.3",
          cors: "^2.8.5",
          eslint: "^7.2.0",
          "eslint-config-airbnb-base": "^14.2.0",
          "eslint-plugin-import": "^2.22.1",
          "expect.js": "^0.3.1",
          express: "^4.17.1",
          mocha: "^10.0.0",
          "mocha-headless-chrome": "^4.0.0",
          "npm-run-all": "^4.1.5",
          nyc: "^15.1.0",
          rimraf: "^2.7.1",
          rollup: "^2.79.0",
          "wait-on": "^3.3.0",
          webpack: "^5.74.0",
          "webpack-bundle-analyzer": "^4.6.0",
          "webpack-cli": "^4.10.0",
          "webpack-dev-middleware": "^5.3.3"
        },
        dependencies: {
          "babel-eslint": "^10.1.0",
          "bmp-js": "^0.1.0",
          "file-type": "^12.4.1",
          "idb-keyval": "^3.2.0",
          "is-electron": "^2.2.0",
          "is-url": "^1.2.4",
          "node-fetch": "^2.6.0",
          "opencollective-postinstall": "^2.0.2",
          "regenerator-runtime": "^0.13.3",
          "resolve-url": "^0.2.1",
          "tesseract.js-core": "^4.0.2",
          "wasm-feature-detect": "^1.2.11",
          zlibjs: "^0.3.1"
        },
        repository: {
          type: "git",
          url: "https://github.com/naptha/tesseract.js.git"
        },
        bugs: {
          url: "https://github.com/naptha/tesseract.js/issues"
        },
        homepage: "https://github.com/naptha/tesseract.js",
        collective: {
          type: "opencollective",
          url: "https://opencollective.com/tesseractjs"
        }
      };
    }
  });

  // node_modules/tesseract.js/src/constants/defaultOptions.js
  var require_defaultOptions = __commonJS({
    "node_modules/tesseract.js/src/constants/defaultOptions.js"(exports, module) {
      module.exports = {
        /*
         * default path for downloading *.traineddata
         */
        langPath: "https://tessdata.projectnaptha.com/4.0.0",
        /*
         * Use BlobURL for worker script by default
         * TODO: remove this option
         *
         */
        workerBlobURL: true,
        logger: () => {
        }
      };
    }
  });

  // node_modules/tesseract.js/src/worker/browser/defaultOptions.js
  var require_defaultOptions2 = __commonJS({
    "node_modules/tesseract.js/src/worker/browser/defaultOptions.js"(exports, module) {
      var resolveURL = require_resolve_url();
      var { version } = require_package();
      var defaultOptions = require_defaultOptions();
      module.exports = {
        ...defaultOptions,
        workerPath: typeof process !== "undefined" && process.env.TESS_ENV === "development" ? resolveURL(`/dist/worker.dev.js?nocache=${Math.random().toString(36).slice(3)}`) : `https://unpkg.com/tesseract.js@v${version}/dist/worker.min.js`,
        /*
         * If browser doesn't support WebAssembly,
         * load ASM version instead
         */
        corePath: null
      };
    }
  });

  // node_modules/tesseract.js/src/worker/browser/spawnWorker.js
  var require_spawnWorker = __commonJS({
    "node_modules/tesseract.js/src/worker/browser/spawnWorker.js"(exports, module) {
      module.exports = ({ workerPath, workerBlobURL }) => {
        let worker;
        if (Blob && URL && workerBlobURL) {
          const blob = new Blob([`importScripts("${workerPath}");`], {
            type: "application/javascript"
          });
          worker = new Worker(URL.createObjectURL(blob));
        } else {
          worker = new Worker(workerPath);
        }
        return worker;
      };
    }
  });

  // node_modules/tesseract.js/src/worker/browser/terminateWorker.js
  var require_terminateWorker = __commonJS({
    "node_modules/tesseract.js/src/worker/browser/terminateWorker.js"(exports, module) {
      module.exports = (worker) => {
        worker.terminate();
      };
    }
  });

  // node_modules/tesseract.js/src/worker/browser/onMessage.js
  var require_onMessage = __commonJS({
    "node_modules/tesseract.js/src/worker/browser/onMessage.js"(exports, module) {
      module.exports = (worker, handler) => {
        worker.onmessage = ({ data }) => {
          handler(data);
        };
      };
    }
  });

  // node_modules/tesseract.js/src/worker/browser/send.js
  var require_send = __commonJS({
    "node_modules/tesseract.js/src/worker/browser/send.js"(exports, module) {
      module.exports = async (worker, packet) => {
        worker.postMessage(packet);
      };
    }
  });

  // node_modules/tesseract.js/src/worker/browser/loadImage.js
  var require_loadImage = __commonJS({
    "node_modules/tesseract.js/src/worker/browser/loadImage.js"(exports, module) {
      var resolveURL = require_resolve_url();
      var readFromBlobOrFile = (blob) => new Promise((resolve, reject) => {
        const fileReader = new FileReader();
        fileReader.onload = () => {
          resolve(fileReader.result);
        };
        fileReader.onerror = ({ target: { error: { code } } }) => {
          reject(Error(`File could not be read! Code=${code}`));
        };
        fileReader.readAsArrayBuffer(blob);
      });
      var loadImage2 = async (image) => {
        let data = image;
        if (typeof image === "undefined") {
          return "undefined";
        }
        if (typeof image === "string") {
          if (/data:image\/([a-zA-Z]*);base64,([^"]*)/.test(image)) {
            data = atob(image.split(",")[1]).split("").map((c) => c.charCodeAt(0));
          } else {
            const resp = await fetch(resolveURL(image));
            data = await resp.arrayBuffer();
          }
        } else if (image instanceof HTMLElement) {
          if (image.tagName === "IMG") {
            data = await loadImage2(image.src);
          }
          if (image.tagName === "VIDEO") {
            data = await loadImage2(image.poster);
          }
          if (image.tagName === "CANVAS") {
            await new Promise((resolve) => {
              image.toBlob(async (blob) => {
                data = await readFromBlobOrFile(blob);
                resolve();
              });
            });
          }
        } else if (image instanceof File || image instanceof Blob) {
          data = await readFromBlobOrFile(image);
        }
        return new Uint8Array(data);
      };
      module.exports = loadImage2;
    }
  });

  // node_modules/tesseract.js/src/worker/browser/index.js
  var require_browser = __commonJS({
    "node_modules/tesseract.js/src/worker/browser/index.js"(exports, module) {
      var defaultOptions = require_defaultOptions2();
      var spawnWorker = require_spawnWorker();
      var terminateWorker = require_terminateWorker();
      var onMessage = require_onMessage();
      var send = require_send();
      var loadImage2 = require_loadImage();
      module.exports = {
        defaultOptions,
        spawnWorker,
        terminateWorker,
        onMessage,
        send,
        loadImage: loadImage2
      };
    }
  });

  // node_modules/tesseract.js/src/createWorker.js
  var require_createWorker = __commonJS({
    "node_modules/tesseract.js/src/createWorker.js"(exports, module) {
      var resolvePaths = require_resolvePaths();
      var circularize = require_circularize();
      var createJob = require_createJob();
      var { log: log2 } = require_log();
      var getId = require_getId();
      var { defaultOEM } = require_config();
      var {
        defaultOptions,
        spawnWorker,
        terminateWorker,
        onMessage,
        loadImage: loadImage2,
        send
      } = require_browser();
      var workerCounter = 0;
      module.exports = async (_options = {}) => {
        const id = getId("Worker", workerCounter);
        const {
          logger,
          errorHandler,
          ...options
        } = resolvePaths({
          ...defaultOptions,
          ..._options
        });
        const resolves = {};
        const rejects = {};
        let workerResReject;
        let workerResResolve;
        const workerRes = new Promise((resolve, reject) => {
          workerResResolve = resolve;
          workerResReject = reject;
        });
        const workerError = (event) => {
          workerResReject(event.message);
        };
        let worker = spawnWorker(options);
        worker.onerror = workerError;
        workerCounter += 1;
        const setResolve = (action, res) => {
          resolves[action] = res;
        };
        const setReject = (action, rej) => {
          rejects[action] = rej;
        };
        const startJob = ({ id: jobId, action, payload }) => new Promise((resolve, reject) => {
          log2(`[${id}]: Start ${jobId}, action=${action}`);
          setResolve(action, resolve);
          setReject(action, reject);
          send(worker, {
            workerId: id,
            jobId,
            action,
            payload
          });
        });
        const load = () => console.warn("`load` is depreciated and should be removed from code (workers now come pre-loaded)");
        const loadInternal = (jobId) => startJob(createJob({
          id: jobId,
          action: "load",
          payload: { options }
        }));
        const writeText = (path, text, jobId) => startJob(createJob({
          id: jobId,
          action: "FS",
          payload: { method: "writeFile", args: [path, text] }
        }));
        const readText = (path, jobId) => startJob(createJob({
          id: jobId,
          action: "FS",
          payload: { method: "readFile", args: [path, { encoding: "utf8" }] }
        }));
        const removeFile = (path, jobId) => startJob(createJob({
          id: jobId,
          action: "FS",
          payload: { method: "unlink", args: [path] }
        }));
        const FS = (method, args, jobId) => startJob(createJob({
          id: jobId,
          action: "FS",
          payload: { method, args }
        }));
        const loadLanguage = (langs = "eng", jobId) => startJob(createJob({
          id: jobId,
          action: "loadLanguage",
          payload: { langs, options }
        }));
        const initialize = (langs = "eng", oem = defaultOEM, config, jobId) => startJob(createJob({
          id: jobId,
          action: "initialize",
          payload: { langs, oem, config }
        }));
        const setParameters = (params = {}, jobId) => startJob(createJob({
          id: jobId,
          action: "setParameters",
          payload: { params }
        }));
        const recognize = async (image, opts = {}, output = {
          blocks: true,
          text: true,
          hocr: true,
          tsv: true
        }, jobId) => startJob(createJob({
          id: jobId,
          action: "recognize",
          payload: { image: await loadImage2(image), options: opts, output }
        }));
        const getPDF = (title = "Tesseract OCR Result", textonly = false, jobId) => {
          console.log("`getPDF` function is depreciated. `recognize` option `savePDF` should be used instead.");
          return startJob(createJob({
            id: jobId,
            action: "getPDF",
            payload: { title, textonly }
          }));
        };
        const detect = async (image, jobId) => startJob(createJob({
          id: jobId,
          action: "detect",
          payload: { image: await loadImage2(image) }
        }));
        const terminate = async () => {
          if (worker !== null) {
            terminateWorker(worker);
            worker = null;
          }
          return Promise.resolve();
        };
        onMessage(worker, ({
          workerId,
          jobId,
          status,
          action,
          data
        }) => {
          if (status === "resolve") {
            log2(`[${workerId}]: Complete ${jobId}`);
            let d = data;
            if (action === "recognize") {
              d = circularize(data);
            } else if (action === "getPDF") {
              d = Array.from({ ...data, length: Object.keys(data).length });
            }
            resolves[action]({ jobId, data: d });
          } else if (status === "reject") {
            rejects[action](data);
            if (action === "load")
              workerResReject(data);
            if (errorHandler) {
              errorHandler(data);
            } else {
              throw Error(data);
            }
          } else if (status === "progress") {
            logger({ ...data, userJobId: jobId });
          }
        });
        const resolveObj = {
          id,
          worker,
          setResolve,
          setReject,
          load,
          writeText,
          readText,
          removeFile,
          FS,
          loadLanguage,
          initialize,
          setParameters,
          recognize,
          getPDF,
          detect,
          terminate
        };
        loadInternal().then(() => workerResResolve(resolveObj)).catch(() => {
        });
        return workerRes;
      };
    }
  });

  // node_modules/tesseract.js/src/Tesseract.js
  var require_Tesseract = __commonJS({
    "node_modules/tesseract.js/src/Tesseract.js"(exports, module) {
      var createWorker2 = require_createWorker();
      var recognize = async (image, langs, options) => {
        const worker = await createWorker2(options);
        await worker.loadLanguage(langs);
        await worker.initialize(langs);
        return worker.recognize(image).finally(async () => {
          await worker.terminate();
        });
      };
      var detect = async (image, options) => {
        const worker = await createWorker2(options);
        await worker.loadLanguage("osd");
        await worker.initialize("osd");
        return worker.detect(image).finally(async () => {
          await worker.terminate();
        });
      };
      module.exports = {
        recognize,
        detect
      };
    }
  });

  // node_modules/tesseract.js/src/constants/languages.js
  var require_languages = __commonJS({
    "node_modules/tesseract.js/src/constants/languages.js"(exports, module) {
      module.exports = {
        AFR: "afr",
        AMH: "amh",
        ARA: "ara",
        ASM: "asm",
        AZE: "aze",
        AZE_CYRL: "aze_cyrl",
        BEL: "bel",
        BEN: "ben",
        BOD: "bod",
        BOS: "bos",
        BUL: "bul",
        CAT: "cat",
        CEB: "ceb",
        CES: "ces",
        CHI_SIM: "chi_sim",
        CHI_TRA: "chi_tra",
        CHR: "chr",
        CYM: "cym",
        DAN: "dan",
        DEU: "deu",
        DZO: "dzo",
        ELL: "ell",
        ENG: "eng",
        ENM: "enm",
        EPO: "epo",
        EST: "est",
        EUS: "eus",
        FAS: "fas",
        FIN: "fin",
        FRA: "fra",
        FRK: "frk",
        FRM: "frm",
        GLE: "gle",
        GLG: "glg",
        GRC: "grc",
        GUJ: "guj",
        HAT: "hat",
        HEB: "heb",
        HIN: "hin",
        HRV: "hrv",
        HUN: "hun",
        IKU: "iku",
        IND: "ind",
        ISL: "isl",
        ITA: "ita",
        ITA_OLD: "ita_old",
        JAV: "jav",
        JPN: "jpn",
        KAN: "kan",
        KAT: "kat",
        KAT_OLD: "kat_old",
        KAZ: "kaz",
        KHM: "khm",
        KIR: "kir",
        KOR: "kor",
        KUR: "kur",
        LAO: "lao",
        LAT: "lat",
        LAV: "lav",
        LIT: "lit",
        MAL: "mal",
        MAR: "mar",
        MKD: "mkd",
        MLT: "mlt",
        MSA: "msa",
        MYA: "mya",
        NEP: "nep",
        NLD: "nld",
        NOR: "nor",
        ORI: "ori",
        PAN: "pan",
        POL: "pol",
        POR: "por",
        PUS: "pus",
        RON: "ron",
        RUS: "rus",
        SAN: "san",
        SIN: "sin",
        SLK: "slk",
        SLV: "slv",
        SPA: "spa",
        SPA_OLD: "spa_old",
        SQI: "sqi",
        SRP: "srp",
        SRP_LATN: "srp_latn",
        SWA: "swa",
        SWE: "swe",
        SYR: "syr",
        TAM: "tam",
        TEL: "tel",
        TGK: "tgk",
        TGL: "tgl",
        THA: "tha",
        TIR: "tir",
        TUR: "tur",
        UIG: "uig",
        UKR: "ukr",
        URD: "urd",
        UZB: "uzb",
        UZB_CYRL: "uzb_cyrl",
        VIE: "vie",
        YID: "yid"
      };
    }
  });

  // node_modules/tesseract.js/src/constants/PSM.js
  var require_PSM = __commonJS({
    "node_modules/tesseract.js/src/constants/PSM.js"(exports, module) {
      module.exports = {
        OSD_ONLY: "0",
        AUTO_OSD: "1",
        AUTO_ONLY: "2",
        AUTO: "3",
        SINGLE_COLUMN: "4",
        SINGLE_BLOCK_VERT_TEXT: "5",
        SINGLE_BLOCK: "6",
        SINGLE_LINE: "7",
        SINGLE_WORD: "8",
        CIRCLE_WORD: "9",
        SINGLE_CHAR: "10",
        SPARSE_TEXT: "11",
        SPARSE_TEXT_OSD: "12",
        RAW_LINE: "13"
      };
    }
  });

  // node_modules/tesseract.js/src/index.js
  var require_src = __commonJS({
    "node_modules/tesseract.js/src/index.js"(exports, module) {
      require_runtime();
      var createScheduler = require_createScheduler();
      var createWorker2 = require_createWorker();
      var Tesseract = require_Tesseract();
      var languages = require_languages();
      var OEM = require_OEM();
      var PSM = require_PSM();
      var { setLogging } = require_log();
      module.exports = {
        languages,
        OEM,
        PSM,
        createScheduler,
        createWorker: createWorker2,
        setLogging,
        ...Tesseract
      };
    }
  });

  // src/constants.js
  var HORN_DELAY_MIN_SECS = 10;
  var HORN_DELAY_MAX_SECS = 180;
  var PUZZLE_ACTIVE_SELECTOR = ".puzzleView--active";
  var PUZZLE_IMAGE_SELECTOR = ".puzzleView__image > img";
  var PUZZLE_CODE_INPUT = ".puzzleView__code";
  var PUZZLE_SUBMIT_BUTTON = ".puzzleView__solveButton";
  var PUZZLE_RESUME_BUTTON = ".puzzleView__resumeButton";
  var PUZZLE_NEW_CODE_LINK = ".puzzleView__requestNewPuzzleButton";
  var HORN_READY_SELECTOR = ".huntersHornView__horn--reveal";

  // src/utils.js
  async function sleep(ms) {
    return new Promise((_) => setTimeout(_, ms));
  }
  async function soundHorn() {
    const horn = document.querySelector(".huntersHornView__horn--reveal");
    const mouseDown = new MouseEvent("mousedown", {
      bubbles: true,
      cancelable: true
    });
    const mouseUp = new MouseEvent("mouseup", {
      bubbles: true,
      cancelable: true
    });
    horn.dispatchEvent(mouseDown);
    await sleep(500);
    horn.dispatchEvent(mouseUp);
    await sleep(2e3);
    const messageText = document.querySelector(
      ".huntersHornView__message"
    ).textContent;
    if (messageText !== "") {
      window.location.reload();
    }
  }
  function getSecsToNextHorn() {
    const timerText = document.querySelector(
      ".huntersHornView__timerState--type-countdown"
    ).textContent;
    const [mins, secs] = timerText.split(":");
    return Number(mins) * 60 + Number(secs);
  }
  function formatTime(date) {
    const hours = date.getHours().toString().padStart(2, "0");
    const mins = date.getMinutes().toString().padStart(2, "0");
    const secs = date.getSeconds().toString().padStart(2, "0");
    return `${hours}:${mins}:${secs}`;
  }
  function log(message) {
    const time = formatTime(new Date());
    console.log(`${time}: ${message}`);
  }
  function getRandomHornDelay() {
    return Math.max(Math.random() * HORN_DELAY_MAX_SECS, HORN_DELAY_MIN_SECS);
  }

  // src/kr.js
  var import_tesseract = __toESM(require_src());
  async function solveKR() {
    const img = document.querySelector(PUZZLE_IMAGE_SELECTOR);
    const newImg = await loadImage(img);
    const canvas = document.createElement("canvas");
    canvas.width = 200;
    canvas.height = 58;
    const ctx = canvas.getContext("2d");
    ctx.drawImage(newImg, 0, 0);
    const worker = await (0, import_tesseract.createWorker)();
    await worker.loadLanguage("eng");
    await worker.initialize("eng");
    const { data } = await worker.recognize(canvas);
    const rawCode = data.text.trim();
    const code = rawCode.replaceAll(/[^A-Za-z0-9]/g, "");
    if (code.length !== 5) {
      log("OCR failed! Couldn't determine characters");
      await getNewCodeImage();
      return false;
    }
    log("OCR success! Code: " + code);
    const codeInput = document.querySelector(PUZZLE_CODE_INPUT);
    codeInput.value = code;
    codeInput.dispatchEvent(new KeyboardEvent("keyup"));
    await sleep(1e3);
    const submit = document.querySelector(PUZZLE_SUBMIT_BUTTON);
    submit.click();
    await sleep(8e3);
    const resumeButton = document.querySelector(PUZZLE_RESUME_BUTTON);
    return resumeButton.checkVisibility();
  }
  async function getNewCodeImage() {
    const newCodeLink = document.querySelector(PUZZLE_NEW_CODE_LINK);
    newCodeLink.click();
    await sleep(5e3);
  }
  function loadImage(img) {
    return new Promise((resolve, reject) => {
      const newImg = new Image();
      newImg.crossorigin = "Anonymous";
      newImg.onload = () => resolve(newImg);
      newImg.onerror = () => reject();
      newImg.src = img.src;
    });
  }

  // src/ui.js
  var CONTAINER_ID = "mh-bot-container";
  var HEADER_ID = "mh-bot-header";
  var STATE_TEXT_ID = "mh-bot-state-text";
  var css = `
#${CONTAINER_ID} {
  font-size: 12px;
  border: 1px solid black;
  display: flex;
  flex-direction: column;
  padding: 18px;
  background: white;
}

#${HEADER_ID} {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 8px;
}

#${STATE_TEXT_ID} {
  font-size: 12px;
  margin: 0px;
}
`;
  function injectCSS() {
    GM_addStyle(css);
  }
  function initUI() {
    injectCSS();
    const container = document.createElement("div");
    container.className = CONTAINER_ID;
    container.id = CONTAINER_ID;
    const header = document.createElement("h2");
    header.className = HEADER_ID;
    header.id = HEADER_ID;
    header.textContent = "MouseHunt Auto Horn & KR Solver";
    container.appendChild(header);
    const stateText = document.createElement("p");
    stateText.id = STATE_TEXT_ID;
    stateText.textContent = "Initializing...";
    container.appendChild(stateText);
    const mhContainer = document.getElementById("mousehuntContainer");
    mhContainer.insertBefore(container, mhContainer.firstChild);
  }
  function renderWaitingForHorn(nextHornTime) {
    const secsToNextHorn = Math.floor((nextHornTime - Date.now()) / 1e3);
    const formattedTime = formatTime(new Date(nextHornTime));
    const stateText = getStateTextElement();
    stateText.textContent = `Waiting for next horn. Next horn at ${formattedTime} (${secsToNextHorn} seconds)`;
  }
  function renderSolvingKR(attempt) {
    const stateText = getStateTextElement();
    stateText.textContent = `Solving KR (attempt ${attempt + 1}/${3})`;
  }
  function renderStopped() {
    const stateText = getStateTextElement();
    stateText.textContent = `Script stopped! Please refresh to restart.`;
  }
  function getStateTextElement() {
    return document.getElementById(STATE_TEXT_ID);
  }

  // src/index.js
  async function getState() {
    const hornImage = document.querySelector(HORN_READY_SELECTOR);
    if (hornImage) {
      log("Sounding horn...");
      await soundHorn();
      log("Horn sounded!");
    }
    const hasPuzzle = document.querySelector(PUZZLE_ACTIVE_SELECTOR);
    if (hasPuzzle) {
      log("Solving KR...");
      let success = false;
      let retryCount = 0;
      while (!success && retryCount < 3) {
        renderSolvingKR(retryCount);
        success = await solveKR();
        retryCount++;
        if (!success) {
          log("Failed to solve KR, retrying...");
        }
      }
      if (success) {
        log("KR solved!");
        window.location.reload();
      } else {
        alert(
          "Failed to solve KR 3 times. Please solve it manually and refresh the page when finished!"
        );
        return -1;
      }
    }
    const secsToNextHorn = getSecsToNextHorn();
    const randomDelay = getRandomHornDelay();
    const nextHornTime = Date.now() + (secsToNextHorn + randomDelay) * 1e3;
    const formattedTime = formatTime(new Date(nextHornTime));
    renderWaitingForHorn(nextHornTime);
    log("Next horn time: " + formattedTime);
    return nextHornTime;
  }
  async function loop() {
    let nextHornTime = 0;
    let lastRefreshTime = Date.now();
    while (true) {
      if (Date.now() - lastRefreshTime > 18e5) {
        window.location.reload();
      }
      if (nextHornTime === -1) {
        break;
      } else if (nextHornTime > Date.now()) {
        if (nextHornTime < getSecsToNextHorn()) {
          nextHornTime = await getState();
        }
        renderWaitingForHorn(nextHornTime);
        await sleep(1e3);
      } else {
        nextHornTime = await getState();
      }
    }
    renderStopped();
  }
  initUI();
  loop();
})();