您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
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(); })();