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 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 define(obj, key, value) {
        Object.defineProperty(obj, key, {
          value,
          enumerable: true,
          configurable: true,
          writable: true
        });
        return obj[key];
      }
      try {
        define({}, "");
      } catch (err) {
        define = 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 = {};
      define(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 = define(
        GeneratorFunctionPrototype,
        toStringTagSymbol,
        "GeneratorFunction"
      );
      function defineIteratorMethods(prototype) {
        ["next", "throw", "return"].forEach(function(method) {
          define(prototype, method, function(arg) {
            return this._invoke(method, arg);
          });
        });
      }
      exports2.isGeneratorFunction = function(genFun) {
        var ctor = typeof genFun === "function" && genFun.constructor;
        return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can
        // do is to check its .name property.
        (ctor.displayName || ctor.name) === "GeneratorFunction" : false;
      };
      exports2.mark = function(genFun) {
        if (Object.setPrototypeOf) {
          Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
        } else {
          genFun.__proto__ = GeneratorFunctionPrototype;
          define(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);
      define(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);
      define(Gp, toStringTagSymbol, "Generator");
      define(Gp, iteratorSymbol, function() {
        return this;
      });
      define(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) {
    "use strict";
    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) {
    "use strict";
    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) {
    "use strict";
    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) {
    "use strict";
    var createJob = require_createJob();
    var { log } = 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();
          }
        });
        log(`[${id}]: Add ${job.id} to JobQueue`);
        log(`[${id}]: JobQueue length=${jobQueue.length}`);
        dequeue();
      });
      const addWorker = (w) => {
        workers[w.id] = w;
        log(`[${id}]: Add ${w.id}`);
        log(`[${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/tesseract.js/src/utils/getEnvironment.js
var require_getEnvironment = __commonJS({
  "node_modules/tesseract.js/src/utils/getEnvironment.js"(exports, module) {
    "use strict";
    module.exports = (key) => {
      const env = {};
      if (typeof WorkerGlobalScope !== "undefined") {
        env.type = "webworker";
      } else if (typeof document === "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/tesseract.js/src/utils/resolvePaths.js
var require_resolvePaths = __commonJS({
  "node_modules/tesseract.js/src/utils/resolvePaths.js"(exports, module) {
    "use strict";
    var isBrowser = require_getEnvironment()("type") === "browser";
    var resolveURL = isBrowser ? (s) => new URL(s, window.location.href).href : (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/constants/OEM.js
var require_OEM = __commonJS({
  "node_modules/tesseract.js/src/constants/OEM.js"(exports, module) {
    "use strict";
    module.exports = {
      TESSERACT_ONLY: 0,
      LSTM_ONLY: 1,
      TESSERACT_LSTM_COMBINED: 2,
      DEFAULT: 3
    };
  }
});

// node_modules/tesseract.js/package.json
var require_package = __commonJS({
  "node_modules/tesseract.js/package.json"(exports, module) {
    module.exports = {
      name: "tesseract.js",
      version: "6.0.1",
      description: "Pure Javascript Multilingual OCR",
      main: "src/index.js",
      type: "commonjs",
      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.mjs",
        "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.min.js",
        test: "npm-run-all -p -r start test:all",
        "test:all": "npm-run-all wait test:browser test:node:all",
        "test:browser": "karma start karma.conf.js",
        "test:node": "nyc mocha --exit --bail --require ./scripts/test-helper.mjs",
        "test:node:all": "npm run test:node -- ./tests/*.test.mjs",
        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.21.4",
        "@babel/eslint-parser": "^7.21.3",
        "@babel/preset-env": "^7.21.4",
        "@rollup/plugin-commonjs": "^24.1.0",
        acorn: "^8.8.2",
        "babel-loader": "^9.1.2",
        buffer: "^6.0.3",
        cors: "^2.8.5",
        eslint: "^7.32.0",
        "eslint-config-airbnb-base": "^14.2.1",
        "eslint-plugin-import": "^2.27.5",
        "expect.js": "^0.3.1",
        express: "^4.18.2",
        mocha: "^10.2.0",
        "npm-run-all": "^4.1.5",
        karma: "^6.4.2",
        "karma-chrome-launcher": "^3.2.0",
        "karma-firefox-launcher": "^2.1.2",
        "karma-mocha": "^2.0.1",
        "karma-webpack": "^5.0.0",
        nyc: "^15.1.0",
        rimraf: "^5.0.0",
        rollup: "^3.20.7",
        "wait-on": "^7.0.1",
        webpack: "^5.79.0",
        "webpack-bundle-analyzer": "^4.8.0",
        "webpack-cli": "^5.0.1",
        "webpack-dev-middleware": "^6.0.2",
        "rollup-plugin-sourcemaps": "^0.6.3"
      },
      dependencies: {
        "bmp-js": "^0.1.0",
        "idb-keyval": "^6.2.0",
        "is-url": "^1.2.4",
        "node-fetch": "^2.6.9",
        "opencollective-postinstall": "^2.0.3",
        "regenerator-runtime": "^0.13.3",
        "tesseract.js-core": "^6.0.0",
        "wasm-feature-detect": "^1.2.11",
        zlibjs: "^0.3.1"
      },
      overrides: {
        "@rollup/pluginutils": "^5.0.2"
      },
      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) {
    "use strict";
    module.exports = {
      /*
       * 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) {
    "use strict";
    var version = require_package().version;
    var defaultOptions = require_defaultOptions();
    module.exports = {
      ...defaultOptions,
      workerPath: `https://cdn.jsdelivr.net/npm/tesseract.js@v${version}/dist/worker.min.js`
    };
  }
});

// node_modules/tesseract.js/src/worker/browser/spawnWorker.js
var require_spawnWorker = __commonJS({
  "node_modules/tesseract.js/src/worker/browser/spawnWorker.js"(exports, module) {
    "use strict";
    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) {
    "use strict";
    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) {
    "use strict";
    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) {
    "use strict";
    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) {
    "use strict";
    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 loadImage = 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(image);
          data = await resp.arrayBuffer();
        }
      } else if (typeof HTMLElement !== "undefined" && image instanceof HTMLElement) {
        if (image.tagName === "IMG") {
          data = await loadImage(image.src);
        }
        if (image.tagName === "VIDEO") {
          data = await loadImage(image.poster);
        }
        if (image.tagName === "CANVAS") {
          await new Promise((resolve) => {
            image.toBlob(async (blob) => {
              data = await readFromBlobOrFile(blob);
              resolve();
            });
          });
        }
      } else if (typeof OffscreenCanvas !== "undefined" && image instanceof OffscreenCanvas) {
        const blob = await image.convertToBlob();
        data = await readFromBlobOrFile(blob);
      } else if (image instanceof File || image instanceof Blob) {
        data = await readFromBlobOrFile(image);
      }
      return new Uint8Array(data);
    };
    module.exports = loadImage;
  }
});

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

// node_modules/tesseract.js/src/createWorker.js
var require_createWorker = __commonJS({
  "node_modules/tesseract.js/src/createWorker.js"(exports, module) {
    "use strict";
    var resolvePaths = require_resolvePaths();
    var createJob = require_createJob();
    var { log } = require_log();
    var getId = require_getId();
    var OEM = require_OEM();
    var {
      defaultOptions,
      spawnWorker,
      terminateWorker,
      onMessage,
      loadImage,
      send: send2
    } = require_browser();
    var workerCounter = 0;
    module.exports = async (langs = "eng", oem = OEM.LSTM_ONLY, _options = {}, config = {}) => {
      const id = getId("Worker", workerCounter);
      const {
        logger,
        errorHandler,
        ...options
      } = resolvePaths({
        ...defaultOptions,
        ..._options
      });
      const promises = {};
      const currentLangs = typeof langs === "string" ? langs.split("+") : langs;
      let currentOem = oem;
      let currentConfig = config;
      const lstmOnlyCore = [OEM.DEFAULT, OEM.LSTM_ONLY].includes(oem) && !options.legacyCore;
      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 startJob = ({ id: jobId, action, payload }) => new Promise((resolve, reject) => {
        log(`[${id}]: Start ${jobId}, action=${action}`);
        const promiseId = `${action}-${jobId}`;
        promises[promiseId] = { resolve, reject };
        send2(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: { lstmOnly: lstmOnlyCore, corePath: options.corePath, logging: options.logging } }
      }));
      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 loadLanguageInternal = (_langs, jobId) => startJob(createJob({
        id: jobId,
        action: "loadLanguage",
        payload: {
          langs: _langs,
          options: {
            langPath: options.langPath,
            dataPath: options.dataPath,
            cachePath: options.cachePath,
            cacheMethod: options.cacheMethod,
            gzip: options.gzip,
            lstmOnly: [OEM.DEFAULT, OEM.LSTM_ONLY].includes(currentOem) && !options.legacyLang
          }
        }
      }));
      const initializeInternal = (_langs, _oem, _config, jobId) => startJob(createJob({
        id: jobId,
        action: "initialize",
        payload: { langs: _langs, oem: _oem, config: _config }
      }));
      const reinitialize = (langs2 = "eng", oem2, config2, jobId) => {
        if (lstmOnlyCore && [OEM.TESSERACT_ONLY, OEM.TESSERACT_LSTM_COMBINED].includes(oem2)) throw Error("Legacy model requested but code missing.");
        const _oem = oem2 || currentOem;
        currentOem = _oem;
        const _config = config2 || currentConfig;
        currentConfig = _config;
        const langsArr = typeof langs2 === "string" ? langs2.split("+") : langs2;
        const _langs = langsArr.filter((x) => !currentLangs.includes(x));
        currentLangs.push(..._langs);
        if (_langs.length > 0) {
          return loadLanguageInternal(_langs, jobId).then(() => initializeInternal(langs2, _oem, _config, jobId));
        }
        return initializeInternal(langs2, _oem, _config, jobId);
      };
      const setParameters = (params = {}, jobId) => startJob(createJob({
        id: jobId,
        action: "setParameters",
        payload: { params }
      }));
      const recognize = async (image, opts = {}, output = {
        text: true
      }, jobId) => startJob(createJob({
        id: jobId,
        action: "recognize",
        payload: { image: await loadImage(image), options: opts, output }
      }));
      const detect = async (image, jobId) => {
        if (lstmOnlyCore) throw Error("`worker.detect` requires Legacy model, which was not loaded.");
        return startJob(createJob({
          id: jobId,
          action: "detect",
          payload: { image: await loadImage(image) }
        }));
      };
      const terminate = async () => {
        if (worker !== null) {
          terminateWorker(worker);
          worker = null;
        }
        return Promise.resolve();
      };
      onMessage(worker, ({
        workerId,
        jobId,
        status,
        action,
        data
      }) => {
        const promiseId = `${action}-${jobId}`;
        if (status === "resolve") {
          log(`[${workerId}]: Complete ${jobId}`);
          promises[promiseId].resolve({ jobId, data });
          delete promises[promiseId];
        } else if (status === "reject") {
          promises[promiseId].reject(data);
          delete promises[promiseId];
          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,
        load,
        writeText,
        readText,
        removeFile,
        FS,
        reinitialize,
        setParameters,
        recognize,
        detect,
        terminate
      };
      loadInternal().then(() => loadLanguageInternal(langs)).then(() => initializeInternal(langs, oem, config)).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) {
    "use strict";
    var createWorker2 = require_createWorker();
    var recognize = async (image, langs, options) => {
      const worker = await createWorker2(langs, 1, options);
      return worker.recognize(image).finally(async () => {
        await worker.terminate();
      });
    };
    var detect = async (image, options) => {
      const worker = await createWorker2("osd", 0, options);
      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) {
    "use strict";
    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) {
    "use strict";
    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) {
    "use strict";
    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
    };
  }
});

// shared/ocrScreenshot.ts
var import_tesseract = __toESM(require_src());

// shared/types.ts
var MIN_TEXT_CHARS = 100;

// shared/ocrScreenshot.ts
var MIN_OCR_CHARS = MIN_TEXT_CHARS;
function normalizeOcrLines(raw) {
  return raw.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").map((line) => line.replace(/[^\S\n]+/g, " ").trim()).join("\n").replace(/\n{3,}/g, "\n\n").trim();
}
function suggestedTitleFromOcr(text, filename) {
  const fromName = filename.replace(/\.[^.]+$/, "") || "Screenshot";
  const lines = text.split(/\n/).map((l) => l.trim()).filter((l) => l.length >= 8);
  const bodyLike = lines.find(
    (l) => !/^@\w+$/i.test(l) && !/^[\d,.\sKMB]+$/i.test(l) && !/^(for you|following|likes?|reposts?|share|comment)$/i.test(l)
  );
  return (bodyLike ?? lines[0] ?? fromName).slice(0, 120);
}
async function ocrScreenshotFile(file) {
  if (!file || file.size < 32) {
    throw new Error("Clipboard/image was empty. Copy the screenshot again, then \u2318V.");
  }
  const workerPath = chrome.runtime.getURL("vendor/tesseract/worker.min.js");
  const corePath = chrome.runtime.getURL("vendor/tesseract/");
  const langPath = chrome.runtime.getURL("vendor/tesseract/");
  let worker = null;
  try {
    worker = await (0, import_tesseract.createWorker)("eng", 1, {
      workerPath,
      corePath,
      langPath,
      workerBlobURL: false,
      // Avoid IndexedDB quirks inside some Safari Web Extension sandboxes.
      cacheMethod: "none"
    });
    const {
      data: { text: raw }
    } = await worker.recognize(file);
    const text = normalizeOcrLines(raw ?? "");
    const flatLen = text.replace(/\s+/g, " ").trim().length;
    if (flatLen < MIN_OCR_CHARS) {
      throw new Error(
        `Not enough readable text (${flatLen} chars). Need at least ${MIN_OCR_CHARS}. Try a clearer crop of the post body.`
      );
    }
    return {
      text,
      suggestedTitle: suggestedTitleFromOcr(text, file.name || "screenshot.png"),
      charCount: flatLen
    };
  } catch (e) {
    const msg = e instanceof Error ? e.message : String(e);
    if (/Worker|CSP|Failed to construct|importScripts|wasm|network/i.test(msg)) {
      throw new Error(
        `OCR engine failed to start (${msg}). Reinstall Blackhorse Reader, or drop the file instead of paste.`
      );
    }
    throw e instanceof Error ? e : new Error(msg || "OCR failed");
  } finally {
    if (worker) {
      try {
        await worker.terminate();
      } catch {
      }
    }
  }
}

// chrome/popup.ts
var analyzeBtn = document.getElementById("analyze-btn");
var connectBtn = document.getElementById("connect-btn");
var disconnectBtn = document.getElementById("disconnect-btn");
var autoAnalyze = document.getElementById("auto-analyze");
var connectionLabel = document.getElementById("connection-label");
var messageEl = document.getElementById("message");
var recentSection = document.getElementById("recent");
var recentList = document.getElementById("recent-list");
var dashboardLink = document.getElementById("dashboard-link");
var dropzone = document.getElementById("screenshot-drop");
var dropLabel = document.getElementById("drop-label");
var screenshotInput = document.getElementById("screenshot-input");
function showMessage(text, isError = false) {
  messageEl.textContent = text;
  messageEl.classList.toggle("error", isError);
  messageEl.classList.remove("hidden");
}
function formatErr(e) {
  if (e instanceof Error && e.message) return e.message;
  if (typeof e === "string" && e.trim()) return e;
  try {
    return JSON.stringify(e);
  } catch {
    return "Screenshot analyze failed";
  }
}
function send(message) {
  return chrome.runtime.sendMessage(message).then((res) => {
    if (res == null) {
      throw new Error("Extension background did not respond. Quit Safari, reopen Blackhorse Reader, try again.");
    }
    return res;
  });
}
async function refresh() {
  const state = await send({ type: "GET_STATE" });
  if (!state.ok) {
    connectionLabel.textContent = "Extension error";
    return;
  }
  if (state.connected) {
    connectionLabel.textContent = state.hasOAuth ? "Account connected" : "Connected";
    disconnectBtn.classList.remove("hidden");
    connectBtn.textContent = "Reconnect account";
  } else {
    connectionLabel.textContent = "Not connected \u2014 connect your Sentinel account";
    disconnectBtn.classList.add("hidden");
    connectBtn.textContent = "Connect account";
  }
  autoAnalyze.checked = Boolean(state.autoAnalyze);
  if (state.baseUrl) dashboardLink.href = `${state.baseUrl}/dashboard/reader`;
  const reports = state.recentReports ?? [];
  if (reports.length > 0) {
    recentSection.classList.remove("hidden");
    recentList.innerHTML = reports.map((r) => {
      const meta = [r.tier ? `Tier ${r.tier}` : null, r.driftScore != null ? `Drift ${r.driftScore.toFixed(2)}` : null].filter(Boolean).join(" \xB7 ");
      const href = `${state.baseUrl ?? "https://blackhorsesentinel.com"}/dashboard/reports/${r.reportId}`;
      return `<li><a href="${href}" target="_blank" rel="noopener">${escapeHtml(r.title.slice(0, 48))}</a>${meta ? `<br /><span style="color:#6b7280;font-size:11px">${meta}</span>` : ""}</li>`;
    }).join("");
  } else {
    recentSection.classList.add("hidden");
  }
}
function escapeHtml(s) {
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
}
function setDropBusy(label, busy) {
  dropLabel.textContent = label;
  dropzone.classList.toggle("busy", busy);
  dropzone.setAttribute("aria-busy", busy ? "true" : "false");
}
var IDLE_DROP_LABEL = "Paste or drop screenshot";
function fileFromClipboard(data) {
  if (!data) return null;
  const fromFiles = data.files?.[0];
  if (fromFiles && (fromFiles.type.startsWith("image/") || /\.(png|jpe?g|webp)$/i.test(fromFiles.name))) {
    return fromFiles;
  }
  for (const item of Array.from(data.items ?? [])) {
    if (item.kind === "file" && item.type.startsWith("image/")) {
      const file = item.getAsFile();
      if (file) return file;
    }
  }
  return null;
}
function normalizeClipboardImage(file) {
  if (file.name && file.name !== "image.png" && !file.name.startsWith("image.")) return file;
  const ext = file.type === "image/jpeg" || file.type === "image/jpg" ? "jpg" : file.type === "image/webp" ? "webp" : "png";
  return new File([file], `screenshot.${ext}`, { type: file.type || `image/${ext}` });
}
async function analyzeScreenshot(file) {
  if (!file.type.startsWith("image/") && !/\.(png|jpe?g|webp)$/i.test(file.name)) {
    showMessage("Paste or drop a PNG, JPEG, or WebP screenshot.", true);
    return;
  }
  setDropBusy("OCR\u2026", true);
  messageEl.classList.add("hidden");
  try {
    const ocr = await ocrScreenshotFile(file);
    setDropBusy("Analyzing\u2026", true);
    const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
    const sourceUrl = tab?.url && /^https?:\/\//i.test(tab.url) ? tab.url : "screenshot://local";
    const res = await send({
      type: "ANALYZE_SCREENSHOT",
      payload: {
        sourceUrl,
        title: ocr.suggestedTitle,
        text: ocr.text,
        sourceOutlet: "Social screenshot",
        voiceSegment: "journalist_obligation",
        contentKind: "screenshot"
      }
    });
    if (!res?.ok) showMessage(res?.error ?? "Analysis failed", true);
    else {
      showMessage("Report ready \u2014 opening\u2026");
      await refresh();
    }
  } catch (e) {
    showMessage(formatErr(e), true);
  } finally {
    setDropBusy(IDLE_DROP_LABEL, false);
    dropzone.classList.remove("dragover");
  }
}
async function tryReadClipboardImage() {
  try {
    if (!navigator.clipboard?.read) return null;
    const items = await navigator.clipboard.read();
    for (const item of items) {
      const type = item.types.find((t) => t.startsWith("image/"));
      if (!type) continue;
      const blob = await item.getType(type);
      const ext = type === "image/jpeg" ? "jpg" : type === "image/webp" ? "webp" : "png";
      return new File([blob], `screenshot.${ext}`, { type });
    }
  } catch {
  }
  return null;
}
analyzeBtn.addEventListener("click", async () => {
  analyzeBtn.disabled = true;
  messageEl.classList.add("hidden");
  try {
    const res = await send({ type: "ANALYZE_TAB" });
    if (!res.ok) showMessage(res.error ?? "Analysis failed", true);
    else showMessage("Analyzing\u2026 check notification for report link.");
  } catch (e) {
    showMessage(e instanceof Error ? e.message : "Failed", true);
  } finally {
    analyzeBtn.disabled = false;
  }
});
connectBtn.addEventListener("click", async () => {
  connectBtn.disabled = true;
  try {
    const res = await send({ type: "CONNECT_OAUTH" });
    if (!res.ok) showMessage(res.error ?? "Connect failed", true);
    else showMessage("Account connected.");
    await refresh();
  } catch (e) {
    showMessage(e instanceof Error ? e.message : "Connect failed", true);
  } finally {
    connectBtn.disabled = false;
  }
});
disconnectBtn.addEventListener("click", async () => {
  await send({ type: "DISCONNECT" });
  await refresh();
  showMessage("Disconnected.");
});
autoAnalyze.addEventListener("change", async () => {
  await send({ type: "SET_AUTO_ANALYZE", enabled: autoAnalyze.checked });
});
dropzone.addEventListener("click", () => {
  if (dropzone.classList.contains("busy")) return;
  screenshotInput.click();
});
dropzone.addEventListener("keydown", (e) => {
  if (e.key === "Enter" || e.key === " ") {
    e.preventDefault();
    screenshotInput.click();
  }
});
screenshotInput.addEventListener("change", () => {
  const file = screenshotInput.files?.[0];
  screenshotInput.value = "";
  if (file) void analyzeScreenshot(file);
});
dropzone.addEventListener("dragenter", (e) => {
  e.preventDefault();
  dropzone.classList.add("dragover");
});
dropzone.addEventListener("dragover", (e) => {
  e.preventDefault();
  dropzone.classList.add("dragover");
});
dropzone.addEventListener("dragleave", () => {
  dropzone.classList.remove("dragover");
});
dropzone.addEventListener("drop", (e) => {
  e.preventDefault();
  dropzone.classList.remove("dragover");
  const file = e.dataTransfer?.files?.[0];
  if (file) void analyzeScreenshot(file);
});
var pasteHandledAt = 0;
document.addEventListener("paste", (e) => {
  if (dropzone.classList.contains("busy")) return;
  const raw = fileFromClipboard(e.clipboardData);
  if (!raw) return;
  e.preventDefault();
  pasteHandledAt = Date.now();
  void analyzeScreenshot(normalizeClipboardImage(raw));
});
document.addEventListener("keydown", (e) => {
  const isPaste = (e.key === "v" || e.key === "V") && (e.metaKey || e.ctrlKey);
  if (!isPaste || dropzone.classList.contains("busy")) return;
  window.setTimeout(() => {
    if (dropzone.classList.contains("busy")) return;
    if (Date.now() - pasteHandledAt < 400) return;
    void (async () => {
      const file = await tryReadClipboardImage();
      if (file && !dropzone.classList.contains("busy")) void analyzeScreenshot(file);
    })();
  }, 80);
});
void refresh();
//# sourceMappingURL=popup.js.map
